struct CVertex
{
float x,y,z;
};
struct CPolygon
{
int verts[3];
};
struct CModel
{
CVertex* verts;
int numverts;
CPolygon* polys;
int numpolys;
};
CModel g_model;
// Load3DS
//
// Load a .3ds file into memory for parsing
//
int Load3DS(char* filename)
{
ifstream file;
bool doneloading = false;
int filelength;
char* memfile; // file loaded into memory
// load entire file into memory (easier to deal with)
file.open(filename, ios::binary);
file.seekg(0, ios::end);
filelength = file.tellg();
memfile = new char[filelength];
file.seekg(0, ios::beg);
file.read(memfile, filelength);
// parse it
EatChunk(memfile);
delete memfile;
return 0;
}
// EatChunk
//
// This function recursively handles chunks
// in a .3ds file. When the function exits,
// the return value (i) should be the length
// of the current chunk. Right now we only
// create one model (the first one listed in
// the file) and read in verts and polys only.
// To grab other info from the file, create
// a new case label in the switch statement
// for the chunk type you want to react to.
//
long EatChunk(char* buffer)
{
short chunkid;
long chunklength;
int i = 0; // index into current chunk
int j;
chunkid = *(short*)(buffer);
chunklength = *(long*)(buffer+2);
i = 6;
switch (chunkid)
{
case 0x4D4D: // main file
while ((*(short*)(buffer+i) != 0x3D3D) &&
(*(short*)(buffer+i) != 0xB000))
i += 2;
break;
case 0x3D3D: // editor data
break;
case 0x4000: // object description
while (*(buffer+(i++)) != 0); // get past string description
break;
case 0x4100: // triangular polygon list
break;
case 0x4110: // vertex list
if (g_model.numverts == NULL)
{
g_model.numverts = *(short*)(buffer+i);
i+=2;
g_model.verts = new CVertex[g_model.numverts];
for (j=0;j<g_modelnumverts;j++)
{
g_model.verts[j].x = *(float*)(buffer+i);
i+=4;
g_model.verts[j].y = *(float*)(buffer+i);
i+=4;
g_model.verts[j].z = *(float*)(buffer+i);
i+=4;
}
}
else
i = chunklength;
break;
case 0x4120:
if (g_model.numpolys == NULL)
{
g_model.numpolys = *(short*)(buffer+i);
i+=2;
g_model.polys = new CPolygon[g_model.numpolys];
for (j=0;j<numpolys;j++)
{
g_model.polys[j].verts[0] = *(short*)(buffer+i);
i+=2;
g_model.polys[j].verts[1] = *(short*)(buffer+i);
i+=2;
g_model.polys[j].verts[2] = *(short*)(buffer+i);
i+=2;
i+=2; // skip face info
}
}
else
i = chunklength;
break;
default:
i = chunklength; // skips over rest of chunk (ignores it)
break;
}
// eat child chunks
while (i < chunklength)
i += EatChunk(buffer+i);
return chunklength;
} |