Loading 3DS files. So close but yet so far away!
I am using the following code to parse a 3ds file I've stored in a char* pool:
long CModel_3DS::GobbleChunk(char* buffer)
{
CModel_3DS_Chunk chunk;
int i =0;
chunk.id = *(short*)(buffer);
chunk.size = *(long*)(buffer+2);
i = 6;
switch(chunk.id)
{
case MAIN3DS:
{
printf("Main3DS found!\n");
while((*(short*)(buffer+i) != EDIT3DS) &&(*(short*)(buffer+i) != EDITKEYFRAME))
{
i += 2;
}
}
break;
case EDIT3DS:
{
printf("Edit3DS found!\n");
}
break;
case EDITKEYFRAME:
{
printf("Keyframer found!\n");
}
break;
case OBJ_DESC:
{
printf("Object['");
while(*(buffer+i) != 0)
{
printf("%c",*(char*)(buffer+(i++)));
}
printf("'] was found!\n");
i += chunk.size - i;
}
break;
case OBJ_VERTEXLIST:
{
printf("Found a vertex list!\n");
int numVert = *(short*)(buffer+(i+=2));
printf("numVert: %i",numVert);
for(int j=0; j<numVert; j++)
{
CVertex a;
a.x = *(float*)(buffer+(i+=4));
a.y = *(float*)(buffer+(i+=4));
a.z = *(float*)(buffer+(i+=4));
printf("Vertex[%i] { %f, %f, %f }\n",j,a.x,a.y,a.z);
}
// i += chunk.size - i; //If there is any redundant data (for me atleast) left - skip it.
}
break;
case OBJ_FACELIST:
{
printf("Found a face list!\n");
int numFace = *(short*)(buffer+(i+=2));
printf("numFace: %i",numFace);
for(int j=0; j<numFace; j++)
{
CIndex c[3];
c[0].vertexIndex = *(short*)(buffer+(i+=2));
c[1].vertexIndex = *(short*)(buffer+(i+=2));
c[2].vertexIndex = *(short*)(buffer+(i+=2));
i+=2;
printf("Face[%i] { %i, %i, %i }\n",j,c[0].vertexIndex,c[1].vertexIndex,c[2].vertexIndex);
}
// i += chunk.size - i; //If there is any redundant data (for me atleast) left - skip it.
}
break;
default:
{
i = chunk.size;
}
break;
}
while (i < chunk.size)
{
i+= GobbleChunk(buffer+i);
}
return(chunk.size);
}
The prooblem is that it can't find the vertex or the face list, which is terribly odd since it can find practically everything is. =)
Any suggestions? =O
Js
This code looks a bit confusing to me :) But I assume your problem has something to do with the fact, that 3ds has parent- and child-chunks.
One parent-chunk can contain several child chunks. If you skip the parent-chunk, you skip the included child-chunks, too without parsing them.
Well, here is my 3ds-loadercode, maybe it helps. Its not the complete 3ds format, just what i needed when I wrote it.
One parent-chunk can contain several child chunks. If you skip the parent-chunk, you skip the included child-chunks, too without parsing them.
Well, here is my 3ds-loadercode, maybe it helps. Its not the complete 3ds format, just what i needed when I wrote it.
#pragma pack( push, packing )#pragma pack( 1 )struct _3DSChunk { unsigned short id; unsigned long length;};struct _3DSVertex { float x; float y; float z;};struct _3DSTexUV { float u; float v;};struct _3DSTriangles { unsigned short vertex[3]; short flag;};// Default alignment#pragma pack( pop, packing )class C3dsData {public: _3DSVertex* mVertex[64]; _3DSTexUV* mTexuv[64]; _3DSTriangles* mTriangles[64]; unsigned short* mMeshes[64]; int mGroupCtr; unsigned short mFaceCtr[64]; unsigned int mTotalCtr; unsigned int mTotalFaceCtr;public: C3dsData(); ~C3dsData(); };// little ugly helper function to load strings form 3ds filechar* get_string(FILE* file) { char objname[512]; char* ptr=objname; int ctr=0; do{ ctr = fread(ptr, 1, 1, file); }while (ctr && (*ptr++ != '\0')); char* ret = new char[strlen(objname)+1]; strcpy( ret, objname ); return ret;}[...]// some code skippedC3dsData* data = new C3dsData(); if( FILE* file = fopen (filename, "rb") ) { _3DSChunk chunk; fread(&chunk, sizeof (_3DSChunk), 1, file); // Erster Chunk muss immer MAIN3DS sein. // die length dieses chunks ist die Gesamt filelength if(chunk.id != MAIN3DS) { return false; //invalid format } float nMasterScale; while( fread(&chunk, sizeof (_3DSChunk), 1, file) ) { switch( chunk.id ) { case 0x3D3D: // Header chunk break; case 0x3D3E: // Mesh Version; fseek(file, (chunk.length - sizeof(_3DSChunk)), SEEK_CUR); break; case 0xAFFF: // Header chunk break; case 0x0100: // Master Scale fread( &nMasterScale, sizeof(float), 1, file ); break; case 0x1100: { // BIT_MAP char* ptr = get_string(file); break; } case 0x3080: { // Camera_name char* ptr = get_string(file); break; } case 0x4000: { // Named_Object char* ptr = get_string(file); break; } case 0x4100: data->mGroupCtr++; break; case 0x4110: { unsigned short nCtr; fread( &nCtr, sizeof(short), 1, file ); data->mVertex[data->mGroupCtr] = new _3DSVertex[nCtr]; fread( data->mVertex[data->mGroupCtr], sizeof(_3DSVertex), nCtr, file ); break; } case 0x4120: { // FACE_ARRAY unsigned short nCtr; fread( &nCtr, sizeof(short), 1, file ); data->mTriangles[data->mGroupCtr] = new _3DSTriangles[nCtr]; fread( data->mTriangles[data->mGroupCtr], sizeof(_3DSTriangles), nCtr, file ); data->mTotalFaceCtr += nCtr; break; } case 0x4130: { // MSH_MAT_GROUP char* ptr = get_string(file); fread( &(data->mFaceCtr[data->mGroupCtr]), sizeof(short), 1, file ); data->mTotalCtr += data->mFaceCtr[data->mGroupCtr]; data->mMeshes[data->mGroupCtr] = new unsigned short[data->mFaceCtr[data->mGroupCtr]]; fread( data->mMeshes[data->mGroupCtr], sizeof(short), data->mFaceCtr[data->mGroupCtr], file ); break; } case 0x4140: { // TEX_VERTS unsigned short nCtr; fread( &nCtr, sizeof(short), 1, file ); data->mTexuv[data->mGroupCtr] = new _3DSTexUV[nCtr]; fread( data->mTexuv[data->mGroupCtr], sizeof(_3DSTexUV), nCtr, file ); break; } default: fseek(file, (chunk.length - sizeof(_3DSChunk)), SEEK_CUR); } } fclose( file);
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement