Advertisement

Loading 3DS files. So close but yet so far away!

Started by July 20, 2004 01:49 PM
1 comment, last by the_recon 20 years, 4 months ago
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.

#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);
Advertisement
Actually, it was a sub-chunk problem! Thanks man =) I needed the eye lid-opener =)
Js

This topic is closed to new replies.

Advertisement