Help loading a file

Posted on 2006-04-02
Last Modified: 2008-02-01
Hey experts, I need help loading a file. I have never really tried loading a binary file without a component like a jpeg bmp or anything else for that matter. I have loaded my own file before without problem.

Here is my problem.
I want to load a b3d file. Its a 3d model file format. I have the info for the file format located here.
I mainly need the vrts section of the file and I can seem to follow most the file down to the vrts section then I get lost.
I can seek down to the vrts section using a loop once I get there this is what I'm trying to do.
//Read length verts
BlockRead(f, Alonginta, 4, amt);
//read flags
BlockRead(f, Vflaga, 4, amt);
//read texture cords
BlockRead(f, Alongintb, 4, amt);
//read texture cords set size
BlockRead(f, Alongintc, 4, amt);
BlockRead(f, xreal, 4, amt);
BlockRead(f, yreal, 4, amt);
BlockRead(f, zreal, 4, amt);
Memo1.Lines.Add('X= '+floattostr(xreal));
Memo1.Lines.Add('Y= '+floattostr(yreal));
Memo1.Lines.Add('Z= '+floattostr(zreal));
If I have done it right so far these should be the x,y,z locations of verts placed in the model...
But the values look like this
and I don't think thats right. So I'm not sure I'm reading it right.

Then it gets really confusing because I'm not sure if any or all of this info comes next

  float nx,ny,nz              ;vertex normal: present if (flags&1)
  float red,green,blue,alpha  ;vertex color: present if (flags&2)
  float tex_coords[tex_coord_sets][tex_coord_set_size]      ;tex coords

or if I'm supposed to start back at here or move on to the next set.

int flags                   ;1=normal values present, 2=rgba values present
int tex_coord_sets          ;texture coords per vertex (eg: 1 for simple U/V) max=8
int tex_coord_set_size      ;components per set (eg: 2 for simple U/V) max=4

So if someone could show me how to do this from the start of the file to the end or even just from the vert section down, I would really appreciate it. I have been trying to figure this out for about a week with no luck.
As you can see right now im just trying to pull the information and place it in a memo so I can learn this.
I'm using delphi 7. I would think this would be easy to do given I have the file format but I'm lost. I assigned 500 points to this because I need help asap.
Thanks in advance

Oh forgot here is a sample b3d file There should be 3 verts in the file.
If you need more info about what should be in that file or something please email me or post a reply question.
Email is
Question by:imnoto
    LVL 14

    Expert Comment

    by:Pierre Cornelius
    You say your fine up to the VRTS tag, so let's pick it up from there.

    From the file specification (per your link) I understand the following:

    - The VRTS chunk has a header portion i.e. flags, tex_coord_sets, tex_coord_set_size (3 integers i.e. 12 bytes)
    - The verticies info follows (loops)
    - The loop  part contains at least x, y, z, tex_coord_sets and tex_coord_set_size (i.e. minimum of 5 floats i.e. 20 bytes)
    - If flag is 1 then the loop part will also contain the vertex normals nx, ny and nz (i.e. loop part is 8 floats i.e. 32 bytes)
    - If flag is 2 then the loop part will also contain the vertex colors r, g, b and alpha (i.e. loop part is 9 floats i.e. 36 bytes)

    So if I break down the demo file you used, I get the following:

    "VRTS 72" -> VRTS header tag; Length = 72
    0 -> Flags value
    1 -> tex_coord_sets value
    2 -> tex_coord_sets_size value

           0 -> x                                  {#0#0#0#0}
        22.25 -> y                               {#0#0#178#65}
         0.5 -> z                                 {#0#0#0#63}
           0 -> tex_coords_sets            {#0#0#0#0}
           0 -> tex_coords_sets_size     {#0#0#0#0}

           0 -> x                                  {#0#0#0#0}
           0 -> y                                  {#0#0#0#0}
      -8.75-> z                                  {#0#0#012#193}
           0 -> tex_coords_sets            {#0#0#0#0}
           0 -> tex_coords_sets_size     {#0#0#0#0}

           0 -> x                                  {#0#0#0#0}
       1.25 -> y                                  {#0#0#160#63}
          16 -> z                                  {#0#0#128#65}
           0 -> tex_coords_sets            {#0#0#0#0}
           0 -> tex_coords_sets_size     {#0#0#0#0}

    P.S. I used the "single" real type for float declarations.


    Author Comment

    Hey Pierre thanks that was my main problem reading them as just real not single.
    That makes a lot of sense now and I can get it kinda down but when it comes to the loops for the vrts and texture cords I'm having some problems.

    I will award you the points as If I mess with it long enough I'm sure I will get it down. It would be nice if you could write the code for just a basic program that will load each part of the file and drop it off in a memo box so I can have working code to go by... Mine is rather a mess right now after days of messing around with it and hard coding seeks in to get past stuff I didn't understand lol.

    Thanks again I will award the points in a day or so, so that you can post a reply not sure if it closes If I give the points.
    LVL 14

    Accepted Solution

    I will help you with the VRTS section but you must do the rest. I have done a sample to dump the info to a memo but it would be better to store it somehow for use later. Anyway you can modify the sample to do that i.e. instead of adding to the memo, save in an array or you could even create a component to read a B3D file.

    On my previous post, I incorrectly stated
    "The loop  part contains at least x, y, z, tex_coord_sets and tex_coord_set_size (i.e. minimum of 5 floats i.e. 20 bytes)"

    The loop part contains at least x,y,z i.e. 3 floats (12 bytes). The Tex_coords are stored in a multidimensional array, the sizes of which are available in the header section. Anyway, you will see from my sample what I mean by the way I dealt with it.

    procedure VRTS_ToMemo(AMemo: TMemo; B3DFile: string);
    var f: TFileStream;
        s: String;
        ch: TChunkHdr;
        pSin: PSingle;
        pInt: PInteger;
        i, j, Flags, NumVertices, VerticesSize, ChunkLen,
        NumTexCoords, TexCoordSets, TexCoordSetsSize: integer;
      f:= TFileStream.Create(B3DFile, fmOpenRead);
        f.ReadBuffer(ch, Sizeof(TChunkHdr));
        SetLength(s, ch.Len);
        f.ReadBuffer(s[1], ch.Len);

      pInt:= @s[1]; AMemo.Lines.Add('BB3d File Ver: ' + IntToStr(pInt^));

      i:= pos('VRTS', s)+4; pInt:= @s[i];
      AMemo.Lines.Add(Format('VRTS Chunk (Length %d)',[pInt^]));
      ChunkLen:= pInt^; //save length of chunk

      AMemo.Lines.Add(Format('  Flags: %d',[pInt^]));
      Flags:= pInt^;

      AMemo.Lines.Add(Format('  tex_coord_sets: %d',[pInt^]));
      TexCoordSets:= pInt^;

      AMemo.Lines.Add(Format('  tex_coord_sets_size: %d',[pInt^]));
      TexCoordSetsSize:= pInt^;

      //calc number of Texture Coords per vertex
      NumTexCoords:= TexCoordSets * TexCoordSetsSize;

      //calc number of vertices
      VerticesSize:= 12 //x,y,z integers
                    +NumTexCoords * 4; //tex_coords
      if (Flags AND 1 = 1) then Inc(VerticesSize, 12); //3 floats for normals
      if (Flags AND 2 = 2) then Inc(VerticesSize, 16); //4 floats for colors
      NumVertices:= (ChunkLen - 12 {3 integers for header part})
                    div VerticesSize;
      //check if correct
      if ChunkLen <> (12 + VerticesSize * NumVertices) then
        raise exception.Create('Error reading vertices');

      pSin:= pointer(pInt);
      for i:= 0 to NumVertices-1 do
        AMemo.Lines.Add(Format('  Vertex %d',[i+1]));

        AMemo.Lines.Add(Format('    x: %g',[pSin^]));

        AMemo.Lines.Add(Format('    y: %g',[pSin^]));

        AMemo.Lines.Add(Format('    z: %g',[pSin^]));

        if (Flags AND 1 = 1) then
          AMemo.Lines.Add('  Vertex normal');

          AMemo.Lines.Add(Format('    nx: %g',[pSin^]));

          AMemo.Lines.Add(Format('    ny: %g',[pSin^]));

          AMemo.Lines.Add(Format('    nz: %g',[pSin^]));

        if (Flags AND 2 = 2) then
          AMemo.Lines.Add('  Vertex color');

          AMemo.Lines.Add(Format('    Red: %g',[pSin^]));

          AMemo.Lines.Add(Format('    Green: %g',[pSin^]));

          AMemo.Lines.Add(Format('    Blue: %g',[pSin^]));

          AMemo.Lines.Add(Format('    Alpha: %g',[pSin^]));

        if NumTexCoords <> 0 then
          AMemo.Lines.Add('    Texture coords');

        for j:= 0 to NumTexCoords-1 do
          AMemo.Lines.Add(Format('      tex_coords %d: %g',[j+1, pSin^]));

    LVL 14

    Expert Comment

    by:Pierre Cornelius
    sorry, forgot about this:

      TChunkHdr = record
        Tag: array[1..4] of char;
        Len: integer;

    Author Comment

    Thanks man works like a champ. I'm a very visual person so this will make it so much easier to get it :)

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
    Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…
    Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    17 Experts available now in Live!

    Get 1:1 Help Now