[Last Call] Learn how to a build a cloud-first strategyRegister Now

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 393
  • Last Modified:

Help loading a file

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 http://www.gecko-grotto.com/test.b3d 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 daniel@gecko-grotto.com
  • 3
  • 2
1 Solution
Pierre CorneliusCommented:
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.

imnotoAuthor Commented:
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.
Pierre CorneliusCommented:
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^]));

Pierre CorneliusCommented:
sorry, forgot about this:

  TChunkHdr = record
    Tag: array[1..4] of char;
    Len: integer;
imnotoAuthor Commented:
Thanks man works like a champ. I'm a very visual person so this will make it so much easier to get it :)

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now