www.xbdev.net xbdev - software development
Friday December 14, 2018
home | about | contact | Donations

     
 

3D Formats

Where else are you going to keep your 3D data?...

 

3DS Part 3- "Our Shapes Our Here" - Finally

by bkenwright@xbdev.net

 

<code v6>

With some final tweaking here and there, we can get our colours and texture details for our shapes, and we'll have all our 3D file information (excluding the animations - but we'll get to that later).

 

 

0xafff is our material ...which upto now we've ignored...so if we want our materials...which means colours...we'll need to go into that chunk.

 

Certain things to look for are nested Chunks...as you'll notice that at the bottom of some function calls, there's a SkipChunk(...) function.  So if there are any nested chunks in there, they will be skipped.

 

So how do we go about reading our materials in?  Well thats why where reading this..heheh

 

Now the materials are stored in a seperate list, and so there is a group of materials and they are loaded in, then our objects...3d meshes etc, just reference these materials using there name.

 

Reading in the list of materials is done by first adding to our code:

 

///////////////////////////////////////////////////////////////////////0x3D3D

void ReadEDIT3DS(FILE *fp, stChunk* Chunk)

{

      abc("\n");

      while(Chunk->bytesRead < Chunk->length)

      {

            stChunk tempChunk = {0};

            ReadChunk(fp, &tempChunk);

            DisplayChunkInfo(&tempChunk);

           

            switch( tempChunk.ID)

            {

            // NEW* NEW * NEW * NEW * NEW * NEW *

            case MATERIAL:

                  ReadMATERIAL(fp, &tempChunk);

                  break;

            // NEW* NEW * NEW * NEW * NEW * NEW *

            case NAMED_OBJECT:

                  ReadNAMED_OBJECT(fp, &tempChunk);

                  break;

            default:

                  SkipChunk(fp, &tempChunk);

            }

           

            Chunk->bytesRead += tempChunk.length;

      }

}

 

Now we've added a new sub-section, which reads in all our materials.  This new function has a nice easy name, ReadMATERIAL(...).

This new functions read in our <*>Diffuse Colour <*>Material Name <*>File Name (if there is one).  Below shows the files that read in the material information.

 

///////////////////////////////////////////////////////////////////////0xAFFF

void ReadMATERIAL(FILE *fp, stChunk* Chunk)

{

      abc("\n");

      while(Chunk->bytesRead < Chunk->length)

      {

            stChunk tempChunk = {0};

            ReadChunk(fp, &tempChunk);

            DisplayChunkInfo(&tempChunk);

           

            switch( tempChunk.ID)

            {

            case MAT_NAME: //0xA000 - sz for hte material name "e.g. default 2"

                  Chunk->bytesRead += GetString(fp);

                  break;

            // Each object...has a material set to it!.. .in order, so first

            // object is the first material etc.

            case MAT_DIFFUSE:  // Diffuse Colour  //0xa020

                  ReadMATDIFFUSE(fp, &tempChunk);

                  break;

 

            // MAT_TEXMAP calls itself here. (recursive call)

            case MAT_TEXMAP:  // if there's a texture wrapped to it where here

                  ReadMATERIAL(fp, &tempChunk);

                  break;

            case MAT_TEXFLNM: // get filename of the material

                  Chunk->bytesRead += GetString(fp);

                  break;

            default:

                  SkipChunk(fp, &tempChunk);

            }

 

            Chunk->bytesRead += tempChunk.length;

      }

}

 

///////////////////////////////////////////////////////////////////////0xA020

void ReadMATDIFFUSE(FILE *fp, stChunk* Chunk)

{

      abc("\n");

     

      struct stRGB{ unsigned char r, g, b; };

      stRGB DiffColour;

 

      char ChunkHeader[6];

      Chunk->bytesRead += fread(ChunkHeader, 1, 6, fp);

 

      Chunk->bytesRead += fread(&DiffColour, 1, 3, fp);    

 

      // e.g.  Display our diffuse colour we read in

      char buff[300];

      sprintf(buff, "Diffuse Colour\t r: %x   g: %x    b: %x\n",

                                                DiffColour.r, DiffColour.g, DiffColour.b);

      abc(buff);

 

      SkipChunk(fp, Chunk);

}

 

 

Well we have our materials, but now we have to apply it to our shapes!  As each shape has saves which face uses which Material name.  So as we load in each object we have to compare it with the list of Materials we've loaded in.

 

I've cut the section of code that loads our object into the world below.....

 

 

///////////////////////////////////////////////////////////////////////0x4100

void LoadMeshOBJ_MESH(FILE *fp, stChunk* Chunk)

{

      abc("\n");

     

      while(Chunk->bytesRead < Chunk->length)

      {

            stChunk tempChunk = {0};

            ReadChunk(fp, &tempChunk);

            DisplayChunkInfo(&tempChunk);

           

            switch( tempChunk.ID)

            {

            case MESH_VERTICES:

                  ReadVerticesMESH_VERTICES(fp, &tempChunk);

                  break;

            case MESH_FACES:

                  ReadVertRefsMESH_FACES(fp, &tempChunk);

                  break;

            case MESH_TEX_VERT:

                  ReadTEXVERTS(fp, &tempChunk);

                  break;

            case MESH_MATER:

                  ReadMESHMATERIAL(fp, &tempChunk);

                  break;

            default:

                  SkipChunk(fp, &tempChunk);

            }

           

            Chunk->bytesRead += tempChunk.length;

      }

}

 

 

///////////////////////////////////////////////////////////////////////0x4130

void ReadMESHMATERIAL(FILE *fp, stChunk* Chunk)

{

      abc("\n");

      // Material Name Where Referencing

      unsigned int characterlen = GetString(fp);

      Chunk->bytesRead += characterlen;

 

      unsigned short iNumFaces = 0;

      Chunk->bytesRead += fread(&iNumFaces, 1, 2, fp);

 

      unsigned short *FaceAssignedThisMaterial = new unsigned short[iNumFaces];

      Chunk->bytesRead += fread(FaceAssignedThisMaterial, 1,

                                                      iNumFaces*sizeof(unsigned short), fp);

 

      char buf[1000] = {0};

      sprintf(buf, "Material: FaceCount: %d\n",iNumFaces);

      abc(buf);

 

      for( int i=0; i<iNumFaces; i++ )

      {

            sprintf(buf, "\tFaceAssignedThisMaterial: %d\n",FaceAssignedThisMaterial[i]);

            abc(buf);

      }

 

 

      return;

}

void LoadMeshOBJ_MESH(FILE *fp, stChunk* Chunk); // Forward declaration

///////////////////////////////////////////////////////////////////////0x4120

void ReadVertRefsMESH_FACES(FILE *fp, stChunk* Chunk)

{

      unsigned int iNumberFaces = 0; //= Chunk->length - 6;

      Chunk->bytesRead += fread(&iNumberFaces, 1, 2, fp);  

 

      char buff[100];

      sprintf(buff, "Number of Faces %u\n", iNumberFaces);

      abc(buff);

 

      // Each face is 3 points A TRIANGLE!..WOW

      struct stFace{ unsigned short p1, p2, p3, visibityflag; };

      stFace *pFaces = new stFace[iNumberFaces];

 

      Chunk->bytesRead += fread(pFaces, 1, iNumberFaces*sizeof(stFace), fp);

 

      for( int i=0; i<iNumberFaces; i++ )

      {

            sprintf(buff, "\t Face:  Index1: %d, Index2: %d, Index3 %d\n",

                                  pFaces[i].p1, pFaces[i].p2, pFaces[i].p3);

            abc(buff);

      }

 

      delete pFaces;

 

      // Our face material information is a sub-chunk.

      LoadMeshOBJ_MESH( fp, Chunk );

}

 

///////////////////////////////////////////////////////////////////////0x4110

void ReadVerticesMESH_VERTICES(FILE *fp, stChunk* Chunk)

{

      unsigned int iNumberVertices = 0;

      Chunk->bytesRead += fread(&iNumberVertices, 1, 2, fp);     

 

      // e.g.  8 Vertices make up our simple box!

      char buff[300];

      sprintf(buff, "Number of Vertices %d\n", iNumberVertices);

      abc(buff);

 

      // Allocate Memory and dump our vertices to the screen.

      struct stVect{ float x, y, z; };

      stVect *pVerts = new stVect[iNumberVertices];

 

      Chunk->bytesRead += fread( (void*)pVerts, 1, iNumberVertices*sizeof(stVect), fp);

 

      for(int i=0; i<iNumberVertices; i++)

      {

            sprintf(buff, "\t Vertices Point: x: %.2f, \ty: %.2f, \tz: %.2f\n",

                                pVerts[i].x, pVerts[i].y, pVerts[i].z);

            abc(buff);

      }

 

      delete[] pVerts;

     

 

      SkipChunk(fp, Chunk);

}

///////////////////////////////////////////////////////////////////////0x4140

void ReadTEXVERTS(FILE *fp, stChunk* Chunk)

{

      unsigned short iNumberVertices = 0;

      Chunk->bytesRead += fread(&iNumberVertices, 1, 2, fp);     

 

      // e.g.  8 Vertices make up our simple box!

      char buff[300];

      sprintf(buff, "Number of Vertices %d\n", iNumberVertices);

      abc(buff);

 

      // Allocate Memory and dump our texture for each vertice to the screen.

      struct stTex{ float tu, tv; };

      stTex *pTex = new stTex[iNumberVertices];

 

      Chunk->bytesRead += fread( (void*)pTex, 1, iNumberVertices*sizeof(stTex), fp);

 

      for(int i=0; i<iNumberVertices; i++)

      {

            sprintf(buff, "\t Tex Coord: tu: %.2f,  \t tv: %.2f\n",

                                                       pTex[i].tu, pTex[i].tv);

            abc(buff);

      }

 

      delete[] pTex;

     

 

      SkipChunk(fp, Chunk);

}

 

 

Using the output shown below you should be able to see the data that we've managed to extract...which is a lot!  If you notice, we have all the vertice (x,y,z things) and the texture/colour information.  Note that I've ignored a lot of the texture information, as I only think its necessary to load in the diffuse colour information...but if you wanted to you load in others...specular (0xa020) etc

 

Chunk ID: 0x 4d4d   Size of Chunk: 1417

Chunk ID: 0x 0002   Size of Chunk: 10

Chunk ID: 0x 3d3d   Size of Chunk: 1182

 

Chunk ID: 0x 3d3e   Size of Chunk: 10

 

Chunk ID: 0x afff   Size of Chunk: 226

Chunk ID: 0x a000   Size of Chunk: 18

8 - Default

 

Chunk ID: 0x a010   Size of Chunk: 15

Chunk ID: 0x a020   Size of Chunk: 15

 

Diffuse Colour  r: ff   g: 96    b: 96

Chunk ID: 0x a030   Size of Chunk: 15

Chunk ID: 0x a040   Size of Chunk: 14

Chunk ID: 0x a041   Size of Chunk: 14

Chunk ID: 0x a050   Size of Chunk: 14

Chunk ID: 0x a052   Size of Chunk: 14

Chunk ID: 0x a053   Size of Chunk: 14

Chunk ID: 0x a100   Size of Chunk: 8

Chunk ID: 0x a084   Size of Chunk: 14

Chunk ID: 0x a08a   Size of Chunk: 6

Chunk ID: 0x a087   Size of Chunk: 10

Chunk ID: 0x a200   Size of Chunk: 49

Chunk ID: 0x 0030   Size of Chunk: 8

Chunk ID: 0x a300   Size of Chunk: 17

OCTREE.JPG

 

Chunk ID: 0x a351   Size of Chunk: 8

Chunk ID: 0x a353   Size of Chunk: 10

 

Chunk ID: 0x 0100   Size of Chunk: 10

 

Chunk ID: 0x 4000   Size of Chunk: 930

 

Box03

Chunk ID: 0x 4100   Size of Chunk: 918

 

Chunk ID: 0x 4110   Size of Chunk: 392

Number of Vertices 32

             Vertices Point: x: -6.79,           y: -2.30,           z: 0.00

             Vertices Point: x: -2.93,           y: -2.30,           z: 0.00

             Vertices Point: x: -6.79,           y: 5.29,             z: 0.00

             Vertices Point: x: -2.93,           y: 5.29,             z: 0.00

             Vertices Point: x: -6.79,           y: -2.30,           z: 4.13

             Vertices Point: x: -2.93,           y: -2.30,           z: 4.13

             Vertices Point: x: -6.79,           y: 5.29,             z: 4.13

             Vertices Point: x: -2.93,           y: 5.29,             z: 4.13

             Vertices Point: x: -6.79,           y: -2.30,           z: 0.00

             Vertices Point: x: -2.93,           y: -2.30,           z: 0.00

             Vertices Point: x: -2.93,           y: -2.30,           z: 4.13

             Vertices Point: x: -2.93,           y: -2.30,           z: 4.13

             Vertices Point: x: -6.79,           y: -2.30,           z: 4.13

             Vertices Point: x: -6.79,           y: -2.30,           z: 0.00

             Vertices Point: x: -2.93,           y: -2.30,           z: 0.00

             Vertices Point: x: -2.93,           y: 5.29,             z: 0.00

             Vertices Point: x: -2.93,           y: 5.29,             z: 4.13

             Vertices Point: x: -2.93,           y: 5.29,             z: 4.13

             Vertices Point: x: -2.93,           y: -2.30,           z: 4.13

             Vertices Point: x: -2.93,           y: -2.30,           z: 0.00

             Vertices Point: x: -2.93,           y: 5.29,             z: 0.00

             Vertices Point: x: -6.79,           y: 5.29,             z: 0.00

             Vertices Point: x: -6.79,           y: 5.29,             z: 4.13

             Vertices Point: x: -6.79,           y: 5.29,             z: 4.13

             Vertices Point: x: -2.93,           y: 5.29,             z: 4.13

             Vertices Point: x: -2.93,           y: 5.29,             z: 0.00

             Vertices Point: x: -6.79,           y: 5.29,             z: 0.00

             Vertices Point: x: -6.79,           y: -2.30,           z: 0.00

             Vertices Point: x: -6.79,           y: -2.30,           z: 4.13

             Vertices Point: x: -6.79,           y: -2.30,           z: 4.13

             Vertices Point: x: -6.79,           y: 5.29,             z: 4.13

             Vertices Point: x: -6.79,           y: 5.29,             z: 0.00

 

Chunk ID: 0x 4140   Size of Chunk: 264

Number of Vertices 32

             Tex Coord: tu: 1.00,     tv: 0.00

             Tex Coord: tu: 0.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 0.00

             Tex Coord: tu: 0.00,     tv: 1.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 0.00

             Tex Coord: tu: 0.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 0.00

             Tex Coord: tu: 0.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 0.00

             Tex Coord: tu: 0.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 0.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 1.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 1.00

             Tex Coord: tu: 0.00,     tv: 0.00

 

Chunk ID: 0x 4160   Size of Chunk: 54

Chunk ID: 0x 4120   Size of Chunk: 202

Number of Faces 12

             Face:  Index1: 0, Index2: 2, Index3 3

             Face:  Index1: 3, Index2: 1, Index3 0

             Face:  Index1: 4, Index2: 5, Index3 7

             Face:  Index1: 7, Index2: 6, Index3 4

             Face:  Index1: 8, Index2: 9, Index3 10

             Face:  Index1: 11, Index2: 12, Index3 13

             Face:  Index1: 14, Index2: 15, Index3 16

             Face:  Index1: 17, Index2: 18, Index3 19

             Face:  Index1: 20, Index2: 21, Index3 22

             Face:  Index1: 23, Index2: 24, Index3 25

             Face:  Index1: 26, Index2: 27, Index3 28

             Face:  Index1: 29, Index2: 30, Index3 31

 

Chunk ID: 0x 4130   Size of Chunk: 44

8 - Default

Material: FaceCount: 12

            FaceAssignedThisMaterial: 0

            FaceAssignedThisMaterial: 1

            FaceAssignedThisMaterial: 2

            FaceAssignedThisMaterial: 3

            FaceAssignedThisMaterial: 4

            FaceAssignedThisMaterial: 5

            FaceAssignedThisMaterial: 6

            FaceAssignedThisMaterial: 7

            FaceAssignedThisMaterial: 8

            FaceAssignedThisMaterial: 9

            FaceAssignedThisMaterial: 10

            FaceAssignedThisMaterial: 11

 

Chunk ID: 0x 4150   Size of Chunk: 54

Chunk ID: 0x b000   Size of Chunk: 219

 

 

 

Now to tidy up our code!

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.