static int DoNextChunk( T3dsLoaderPers *pers, int endofs ){ T3dsChunk *chunk; #ifdef DEBUG_PM_3DS printf( "DoNextChunk: endofs %d\n",endofs ); #endif while ( pers->cofs < endofs ) { long nextofs = pers->cofs; if ( ( chunk = GetChunk( pers ) ) == NULL ) { return 0; } if ( !chunk->len ) { return 0; } nextofs += chunk->len; #ifdef DEBUG_PM_3DS_EX printf( "Chunk %04x (%s), len %d pers->cofs %x\n",chunk->id,DebugGetChunkName( chunk->id ),chunk->len,pers->cofs ); #endif /*** version ***/ if ( chunk->id == CHUNK_VERSION ) { /* at this point i get the 3ds file version. since there */ /* might be new additions to the 3ds file format in 4.0 */ /* it might be a good idea to store the version somewhere */ /* for later handling or message displaying */ /* get the version */ int version; version = GetWord( pers ); GetWord( pers ); #ifdef DEBUG_PM_3DS printf( "FileVersion: %d\n",version ); #endif /* throw out a warning for version 4 models */ if ( version == 4 ) { _pico_printf( PICO_WARNING, "3DS version is 4. Model might load incorrectly." ); } /* store the 3ds file version in pico special field 0 */ /* PicoSetSurfaceSpecial(pers->surface,0,version); */ /* ydnar: this was causing a crash accessing uninitialized surface */ /* rest of chunk is skipped here */ } /*** editor data ***/ if ( chunk->id == CHUNK_EDITOR_DATA ) { if ( !DoNextEditorDataChunk( pers,nextofs ) ) { return 0; } continue; } /* skip unknown chunk */ pers->cofs = nextofs; if ( pers->cofs >= pers->maxofs ) { break; } } return 1; }
static int DoNextEditorDataChunk (T3dsLoaderPers *pers, long endofs) { T3dsChunk *chunk; #ifdef DEBUG_PM_3DS_EX printf("DoNextEditorDataChunk: endofs %d\n",endofs); #endif while (pers->cofs < endofs) { long nextofs = pers->cofs; if ((chunk = GetChunk(pers)) == NULL) return 0; if (!chunk->len) return 0; nextofs += chunk->len; #ifdef DEBUG_PM_3DS_EX printf("Chunk %04x (%s), len %d pers->cofs %x\n",chunk->id,DebugGetChunkName(chunk->id),chunk->len,pers->cofs); #endif /*** meshes ***/ if (chunk->id == CHUNK_OBJECT) { picoSurface_t *surface; char surfaceName[ 0xff ] = { 0 }; /* read in surface name */ if( !GetASCIIZ(pers,surfaceName,sizeof(surfaceName)) ) return 0; /* this is bad */ //PicoGetSurfaceName /* ignore NULL name surfaces */ // if( surfaceName /* allocate a pico surface */ surface = PicoNewSurface( pers->model ); if( surface == NULL ) { pers->surface = NULL; return 0; /* this is bad too */ } /* assign ptr to current surface */ pers->surface = surface; /* 3ds models surfaces are all triangle meshes */ PicoSetSurfaceType( pers->surface,PICO_TRIANGLES ); /* set surface name */ PicoSetSurfaceName( pers->surface,surfaceName ); /* continue mess with object's sub chunks */ DoNextEditorDataChunk(pers,nextofs); continue; } if (chunk->id == CHUNK_OBJECT_MESH) { /* continue mess with mesh's sub chunks */ if (!DoNextEditorDataChunk(pers,nextofs)) return 0; continue; } if (chunk->id == CHUNK_OBJECT_VERTICES) { if (!GetMeshVertices(pers)) return 0; continue; } if (chunk->id == CHUNK_OBJECT_FACES) { if (!GetMeshFaces(pers)) return 0; continue; } if (chunk->id == CHUNK_OBJECT_UV) { if (!GetMeshTexCoords(pers)) return 0; continue; } if (chunk->id == CHUNK_OBJECT_MATERIAL) { if (!GetMeshShader(pers)) return 0; continue; } /*** materials ***/ if (chunk->id == CHUNK_MATERIAL) { /* new shader specific things should be */ /* initialized right here */ picoShader_t *shader; /* allocate a pico shader */ shader = PicoNewShader( pers->model ); /* ydnar */ if( shader == NULL ) { pers->shader = NULL; return 0; /* this is bad too */ } /* assign ptr to current shader */ pers->shader = shader; /* continue and process the material's sub chunks */ DoNextEditorDataChunk(pers,nextofs); continue; } if (chunk->id == CHUNK_MATNAME) { /* new material's names should be stored here. note that */ /* GetMeshMaterial returns the name of the material that */ /* is used by the mesh. new material names are set HERE. */ /* but for now we skip the new material's name ... */ if (pers->shader) { char *name = (char*) (pers->bufptr + pers->cofs); char *cleanedName = _pico_clone_alloc( name ); _pico_first_token( cleanedName ); PicoSetShaderName( pers->shader, cleanedName ); #ifdef DEBUG_PM_3DS printf( "NewShader: '%s'\n", cleanedName ); #endif _pico_free( cleanedName ); } } if (chunk->id == CHUNK_MATDIFFUSE) { /* todo: color for last inserted new material should be */ /* stored somewhere by GetDiffuseColor */ if (!GetDiffuseColor(pers)) return 0; /* rest of chunk is skipped here */ } if (chunk->id == CHUNK_MATMAP) { /* continue and process the material map sub chunks */ DoNextEditorDataChunk(pers,nextofs); continue; } if (chunk->id == CHUNK_MATMAPFILE) { /* map file name for last inserted new material should */ /* be stored here. but for now we skip this too ... */ if( pers->shader ) { char *name = (char *)(pers->bufptr + pers->cofs); PicoSetShaderMapName( pers->shader,name ); #ifdef DEBUG_PM_3DS printf("NewShaderMapfile: '%s'\n",name); #endif } } /*** keyframes ***/ if (chunk->id == CHUNK_KEYFRAME_DATA) { /* well umm, this is a bit too much since we don't really */ /* need model animation sequences right now. we skip this */ #ifdef DEBUG_PM_3DS printf("KeyframeData: len %d\n",chunk->len); #endif } /* skip unknown chunk */ pers->cofs = nextofs; if (pers->cofs >= pers->maxofs) break; } return 1; }