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; }
/* _ase_load: * loads a 3dsmax ase model file. */ static picoModel_t *_ase_load( PM_PARAMS_LOAD ) { picoModel_t *model; picoParser_t *p; char lastNodeName[ 1024 ]; aseVertex_t* vertices = NULL; aseTexCoord_t* texcoords = NULL; aseColor_t* colors = NULL; aseFace_t* faces = NULL; int numVertices = 0; int numFaces = 0; int numTextureVertices = 0; int numTextureVertexFaces = 0; int numColorVertices = 0; int numColorVertexFaces = 0; int vertexId = 0; int currentVertexFace=0; int currentVertexIndex=0; int counter=0; int submodel=0; aseMaterial_t* materials = NULL; #ifdef DEBUG_PM_ASE clock_t start, finish; double elapsed; start = clock(); #endif /* helper */ #define _ase_error_return(m) \ { \ _pico_printf( PICO_ERROR,"%s in ASE, line %d.",m,p->curLine); \ _pico_free_parser( p ); \ PicoFreeModel( model ); \ return NULL; \ } /* create a new pico parser */ p = _pico_new_parser( (picoByte_t *)buffer,bufSize ); if (p == NULL) return NULL; /* create a new pico model */ model = PicoNewModel(); if (model == NULL) { _pico_free_parser( p ); return NULL; } /* do model setup */ PicoSetModelFrameNum( model, frameNum ); PicoSetModelName( model, fileName ); PicoSetModelFileName( model, fileName ); /* initialize some stuff */ memset( lastNodeName,0,sizeof(lastNodeName) ); /* parse ase model file */ while( 1 ) { /* get first token on line */ if (_pico_parse_first( p ) == NULL) break; /* we just skip empty lines */ if (p->token == NULL || !strlen( p->token )) continue; /* we skip invalid ase statements */ if (p->token[0] != '*' && p->token[0] != '{' && p->token[0] != '}') { _pico_parse_skip_rest( p ); continue; } /* remember node name */ if (!_pico_stricmp(p->token,"*node_name")) { /* read node name */ char *ptr = _pico_parse( p,0 ); if (ptr == NULL) _ase_error_return("Node name parse error"); /* remember node name */ strncpy( lastNodeName,ptr,sizeof(lastNodeName) ); } /* model mesh (originally contained within geomobject) */ else if (!_pico_stricmp(p->token,"*mesh")) { /* finish existing surface */ _ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces,numVertices,submodel++); _pico_free(faces); _pico_free(vertices); _pico_free(texcoords); _pico_free(colors); } else if (!_pico_stricmp(p->token,"*mesh_numvertex")) { if (!_pico_parse_int( p, &numVertices) ) _ase_error_return("Missing MESH_NUMVERTEX value"); vertices = _pico_calloc(numVertices, sizeof(aseVertex_t)); currentVertexIndex=0; } else if (!_pico_stricmp(p->token,"*mesh_numfaces")) { if (!_pico_parse_int( p, &numFaces) ) _ase_error_return("Missing MESH_NUMFACES value"); faces = _pico_calloc(numFaces, sizeof(aseFace_t)); } else if (!_pico_stricmp(p->token,"*mesh_numtvertex")) { if (!_pico_parse_int( p, &numTextureVertices) ) _ase_error_return("Missing MESH_NUMTVERTEX value"); texcoords = _pico_calloc(numTextureVertices, sizeof(aseTexCoord_t)); } else if (!_pico_stricmp(p->token,"*mesh_numtvfaces")) { if (!_pico_parse_int( p, &numTextureVertexFaces) ) _ase_error_return("Missing MESH_NUMTVFACES value"); } else if (!_pico_stricmp(p->token,"*mesh_numcvertex")) { if (!_pico_parse_int( p, &numColorVertices) ) _ase_error_return("Missing MESH_NUMCVERTEX value"); colors = _pico_calloc(numColorVertices, sizeof(aseColor_t)); memset( colors, 255, numColorVertices * sizeof( aseColor_t ) ); /* ydnar: force colors to white initially */ } else if (!_pico_stricmp(p->token,"*mesh_numcvfaces")) { if (!_pico_parse_int( p, &numColorVertexFaces) ) _ase_error_return("Missing MESH_NUMCVFACES value"); } /* mesh material reference. this usually comes at the end of */ /* geomobjects after the mesh blocks. we must assume that the */ /* new mesh was already created so all we can do here is assign */ /* the material reference id (shader index) now. */ else if (!_pico_stricmp(p->token,"*material_ref")) { int mtlId; /* get the material ref (0..n) */ if (!_pico_parse_int( p,&mtlId) ) _ase_error_return("Missing material reference ID"); { int i = 0; /* fix up all of the aseFaceList in the surface to point to the parent material */ /* we've already saved off their subMtl */ for(; i < numFaces; ++i) { faces[i].materialId = mtlId; } } } /* model mesh vertex */ else if (!_pico_stricmp(p->token,"*mesh_vertex")) { int index; if( numVertices == 0 ) _ase_error_return("Vertex parse error"); /* get vertex data (orig: index +y -x +z) */ if (!_pico_parse_int( p,&index )) _ase_error_return("Vertex parse error"); if (!_pico_parse_vec( p,vertices[index].xyz )) _ase_error_return("Vertex parse error"); vertices[index].id = vertexId++; } else if (!_pico_stricmp(p->token,"*mesh_facenormal")) { //Grab the faceindex for the next vertex normals. if( numVertices == 0 ) _ase_error_return("Vertex parse error (facenormals)"); if (!_pico_parse_int( p,¤tVertexFace )) _ase_error_return("Vertex parse error"); if (!_pico_parse_vec( p,faces[currentVertexFace].facenormal )) _ase_error_return("Vertex parse error"); } /* model mesh vertex normal */ else if (!_pico_stricmp(p->token,"*mesh_vertexnormal")) { int index; if( numVertices == 0 ) _ase_error_return("Vertex parse error"); /* get vertex data (orig: index +y -x +z) */ if (!_pico_parse_int( p,&index )) _ase_error_return("Vertex parse error"); //^^ Index is 'wrong' in .ase models. they reference the same vert index with multiple normals.. // I've tried, this is a lost cause. Use the SG's // /* if (!_pico_parse_vec( p,vertices[counter].normal )) _ase_error_return("Vertex parse error"); vertices[counter].faceid=index; counter++; */ } /* model mesh face */ else if (!_pico_stricmp(p->token,"*mesh_normals")) { // counter=0; //part of the above vertex normals fix } /* model mesh face */ else if (!_pico_stricmp(p->token,"*mesh_face")) { picoIndex_t indexes[3]; int index; if( numFaces == 0 ) _ase_error_return("Face parse error"); /* get face index */ if (!_pico_parse_int( p,&index )) _ase_error_return("Face parse error"); /* get 1st vertex index */ _pico_parse( p,0 ); if (!_pico_parse_int( p,&indexes[0] )) _ase_error_return("Face parse error"); /* get 2nd vertex index */ _pico_parse( p,0 ); if (!_pico_parse_int( p,&indexes[1] )) _ase_error_return("Face parse error"); /* get 3rd vertex index */ _pico_parse( p,0 ); if (!_pico_parse_int( p,&indexes[2] )) _ase_error_return("Face parse error"); /* parse to the subMaterial ID */ while ( 1 ) { if (!_pico_parse (p,0)) /* EOL */ { break; } if (!_pico_stricmp (p->token,"*MESH_SMOOTHING" )) { int total=0; char* point; char* start; _pico_parse(p,0); point=p->token; start=point; faces[index].smoothingGroup=0; //Super dodgy comma delimited string parse while (*point<'A') { if (*point<=32 || *point==',') { total=atoi(start); if (total!=0) { faces[index].smoothingGroup+=1<<total; } start=point+1; } point++; } } if (!_pico_stricmp (p->token,"*MESH_MTLID" )) { _pico_parse_int ( p , &faces[index].subMaterialId ); } } faces[index].materialId = 0; faces[index].indices[0] = indexes[2]; faces[index].indices[1] = indexes[1]; faces[index].indices[2] = indexes[0]; } /* model texture vertex */ else if (!_pico_stricmp(p->token,"*mesh_tvert")) { int index; if( numVertices == 0 ) _ase_error_return("Vertex parse error"); /* get uv vertex index */ if (!_pico_parse_int( p,&index )) _ase_error_return("UV vertex parse error"); /* get uv vertex s */ if (!_pico_parse_float( p,&texcoords[index].texcoord[0] )) _ase_error_return("UV vertex parse error"); /* get uv vertex t */ if (!_pico_parse_float( p,&texcoords[index].texcoord[1] )) _ase_error_return("UV vertex parse error"); /* ydnar: invert t */ texcoords[index].texcoord[ 1 ] = 1.0f - texcoords[index].texcoord[ 1 ]; } /* ydnar: model mesh texture face */ else if( !_pico_stricmp( p->token, "*mesh_tface" ) ) { picoIndex_t indexes[3]; int index; if( numFaces == 0 ) _ase_error_return("Texture face parse error"); /* get face index */ if (!_pico_parse_int( p,&index )) _ase_error_return("Texture face parse error"); /* get 1st vertex index */ if (!_pico_parse_int( p,&indexes[0] )) _ase_error_return("Texture face parse error"); /* get 2nd vertex index */ if (!_pico_parse_int( p,&indexes[1] )) _ase_error_return("Texture face parse error"); /* get 3rd vertex index */ if (!_pico_parse_int( p,&indexes[2] )) _ase_error_return("Texture face parse error"); faces[index].indices[3] = indexes[2]; faces[index].indices[4] = indexes[1]; faces[index].indices[5] = indexes[0]; } /* model color vertex */ else if (!_pico_stricmp(p->token,"*mesh_vertcol")) { int index; float colorInput; if( numVertices == 0 ) _ase_error_return("Color Vertex parse error"); /* get color vertex index */ if (!_pico_parse_int( p,&index )) _ase_error_return("Color vertex parse error"); /* get R component */ if (!_pico_parse_float( p,&colorInput )) _ase_error_return("Color vertex parse error"); colors[index].color[0] = (picoByte_t)(colorInput * 255); /* get G component */ if (!_pico_parse_float( p,&colorInput )) _ase_error_return("Color vertex parse error"); colors[index].color[1] = (picoByte_t)(colorInput * 255); /* get B component */ if (!_pico_parse_float( p,&colorInput )) _ase_error_return("Color vertex parse error"); colors[index].color[2] = (picoByte_t)(colorInput * 255); /* leave alpha alone since we don't get any data from the ASE format */ colors[index].color[3] = 255; /* 27 hack, red as alpha */ colors[index].color[3]=colors[index].color[0]; colors[index].color[0]=255; colors[index].color[1]=255; colors[index].color[2]=255; } /* model color face */ else if (!_pico_stricmp(p->token,"*mesh_cface")) { picoIndex_t indexes[3]; int index; if( numFaces == 0 ) _ase_error_return("Face parse error"); /* get face index */ if (!_pico_parse_int( p,&index )) _ase_error_return("Face parse error"); /* get 1st cvertex index */ // _pico_parse( p,0 ); if (!_pico_parse_int( p,&indexes[0] )) _ase_error_return("Face parse error"); /* get 2nd cvertex index */ // _pico_parse( p,0 ); if (!_pico_parse_int( p,&indexes[1] )) _ase_error_return("Face parse error"); /* get 3rd cvertex index */ // _pico_parse( p,0 ); if (!_pico_parse_int( p,&indexes[2] )) _ase_error_return("Face parse error"); faces[index].indices[6] = indexes[2]; faces[index].indices[7] = indexes[1]; faces[index].indices[8] = indexes[0]; } /* model material */ else if( !_pico_stricmp( p->token, "*material" ) ) { aseSubMaterial_t* subMaterial = NULL; picoShader_t *shader; int level = 1, index; char materialName[ 1024 ]; float transValue = 0.0f, shineValue = 1.0f; picoColor_t ambientColor, diffuseColor, specularColor; char *mapname = NULL; int subMtlId, subMaterialLevel = -1; /* get material index */ _pico_parse_int( p,&index ); /* check brace */ if (!_pico_parse_check(p,1,"{")) _ase_error_return("Material missing opening brace"); /* parse material block */ while( 1 ) { /* get next token */ if (_pico_parse(p,1) == NULL) break; if (!strlen(p->token)) continue; /* handle levels */ if (p->token[0] == '{') level++; if (p->token[0] == '}') level--; if (!level) break; if( level == subMaterialLevel ) { /* set material name */ _pico_first_token( materialName ); PicoSetShaderName( shader, materialName); /* set shader's transparency */ PicoSetShaderTransparency( shader,transValue ); /* set shader's ambient color */ PicoSetShaderAmbientColor( shader,ambientColor ); /* set diffuse alpha to transparency */ diffuseColor[3] = (picoByte_t)( transValue * 255.0 ); /* set shader's diffuse color */ PicoSetShaderDiffuseColor( shader,diffuseColor ); /* set shader's specular color */ PicoSetShaderSpecularColor( shader,specularColor ); /* set shader's shininess */ PicoSetShaderShininess( shader,shineValue ); /* set material map name */ PicoSetShaderMapName( shader, mapname ); subMaterial = _ase_add_submaterial( &materials, index, subMtlId, shader ); subMaterialLevel = -1; } /* parse submaterial index */ if (!_pico_stricmp(p->token,"*submaterial")) { /* allocate new pico shader */ _pico_parse_int( p , &subMtlId ); shader = PicoNewShader( model ); if (shader == NULL) { PicoFreeModel( model ); return NULL; } subMaterialLevel = level; } /* parse material name */ else if (!_pico_stricmp(p->token,"*material_name")) { char* name = _pico_parse(p,0); if ( name == NULL) _ase_error_return("Missing material name"); strcpy ( materialName , name ); /* skip rest and continue with next token */ _pico_parse_skip_rest( p ); continue; } /* parse material transparency */ else if (!_pico_stricmp(p->token,"*material_transparency")) { /* get transparency value from ase */ if (!_pico_parse_float( p,&transValue )) _ase_error_return("Material transparency parse error"); /* skip rest and continue with next token */ _pico_parse_skip_rest( p ); continue; } /* parse material shininess */ else if (!_pico_stricmp(p->token,"*material_shine")) { /* remark: * - not sure but instead of '*material_shine' i might * need to use '*material_shinestrength' */ /* get shine value from ase */ if (!_pico_parse_float( p,&shineValue )) _ase_error_return("Material shine parse error"); /* scale ase shine range 0..1 to pico range 0..127 */ shineValue *= 128.0; /* skip rest and continue with next token */ _pico_parse_skip_rest( p ); continue; } /* parse ambient material color */ else if (!_pico_stricmp(p->token,"*material_ambient")) { picoVec3_t vec; /* get r,g,b float values from ase */ if (!_pico_parse_vec( p,vec )) _ase_error_return("Material color parse error"); /* setup 0..255 range color values */ ambientColor[ 0 ] = (int)( vec[ 0 ] * 255.0 ); ambientColor[ 1 ] = (int)( vec[ 1 ] * 255.0 ); ambientColor[ 2 ] = (int)( vec[ 2 ] * 255.0 ); ambientColor[ 3 ] = (int)( 255 ); /* skip rest and continue with next token */ _pico_parse_skip_rest( p ); continue; } /* parse diffuse material color */ else if (!_pico_stricmp(p->token,"*material_diffuse")) { picoVec3_t vec; /* get r,g,b float values from ase */ if (!_pico_parse_vec( p,vec )) _ase_error_return("Material color parse error"); /* setup 0..255 range color */ diffuseColor[ 0 ] = (int)( vec[ 0 ] * 255.0 ); diffuseColor[ 1 ] = (int)( vec[ 1 ] * 255.0 ); diffuseColor[ 2 ] = (int)( vec[ 2 ] * 255.0 ); diffuseColor[ 3 ] = (int)( 255 ); /* skip rest and continue with next token */ _pico_parse_skip_rest( p ); continue; } /* parse specular material color */ else if (!_pico_stricmp(p->token,"*material_specular")) { picoVec3_t vec; /* get r,g,b float values from ase */ if (!_pico_parse_vec( p,vec )) _ase_error_return("Material color parse error"); /* setup 0..255 range color */ specularColor[ 0 ] = (int)( vec[ 0 ] * 255 ); specularColor[ 1 ] = (int)( vec[ 1 ] * 255 ); specularColor[ 2 ] = (int)( vec[ 2 ] * 255 ); specularColor[ 3 ] = (int)( 255 ); /* skip rest and continue with next token */ _pico_parse_skip_rest( p ); continue; } /* material diffuse map */ else if (!_pico_stricmp(p->token,"*map_diffuse") ) { int sublevel = 0; /* parse material block */ while( 1 ) { /* get next token */ if (_pico_parse(p,1) == NULL) break; if (!strlen(p->token)) continue; /* handle levels */ if (p->token[0] == '{') sublevel++; if (p->token[0] == '}') sublevel--; if (!sublevel) break; /* parse diffuse map bitmap */ if (!_pico_stricmp(p->token,"*bitmap")) { char* name = _pico_parse(p,0); if (name == NULL) _ase_error_return("Missing material map bitmap name"); mapname = _pico_alloc ( strlen ( name ) + 1 ); strcpy ( mapname, name ); /* skip rest and continue with next token */ _pico_parse_skip_rest( p ); continue; } } } /* end map_diffuse block */ } /* end material block */ if( subMaterial == NULL ) { /* allocate new pico shader */ shader = PicoNewShader( model ); if (shader == NULL) { PicoFreeModel( model ); return NULL; } /* set material name */ PicoSetShaderName( shader,materialName ); /* set shader's transparency */ PicoSetShaderTransparency( shader,transValue ); /* set shader's ambient color */ PicoSetShaderAmbientColor( shader,ambientColor ); /* set diffuse alpha to transparency */ diffuseColor[3] = (picoByte_t)( transValue * 255.0 ); /* set shader's diffuse color */ PicoSetShaderDiffuseColor( shader,diffuseColor ); /* set shader's specular color */ PicoSetShaderSpecularColor( shader,specularColor ); /* set shader's shininess */ PicoSetShaderShininess( shader,shineValue ); /* set material map name */ PicoSetShaderMapName( shader, mapname ); /* extract shadername from bitmap path */ if(mapname != NULL) { char* p = mapname; /* convert to shader-name format */ { /* unix-style path separators */ char* s = mapname; for(; *s != '\0'; ++s) { if(*s == '\\') { *s = '/'; } } } { /* remove extension */ char* last_period = strrchr(p, '.'); if(last_period != NULL) { *last_period = '\0'; } } /* find game root */ for(; *p != '\0'; ++p) { if(_pico_strnicmp(p, "quake", 5) == 0 || _pico_strnicmp(p, "doom", 4) == 0) { break; } } /* root-relative */ for(; *p != '\0'; ++p) { if(*p == '/') { ++p; break; } } /* game-relative */ for(; *p != '\0'; ++p) { if(*p == '/') { ++p; break; } } if(*p != '\0') { /* set material name */ PicoSetShaderName( shader,p ); } } /* this is just a material with 1 submaterial */ subMaterial = _ase_add_submaterial( &materials, index, 0, shader ); } /* ydnar: free mapname */ if( mapname != NULL ) _pico_free( mapname ); } // !_pico_stricmp ( "*material" ) /* skip unparsed rest of line and continue */ _pico_parse_skip_rest( p ); } /* ydnar: finish existing surface */ _ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces,numVertices,submodel++); _pico_free(faces); _pico_free(vertices); _pico_free(texcoords); _pico_free(colors); #ifdef DEBUG_PM_ASE _ase_print_materials(materials); finish = clock(); elapsed = (double)(finish - start) / CLOCKS_PER_SEC; _pico_printf( PICO_NORMAL, "Loaded model in in %-.2f second(s)\n", elapsed ); #endif //DEBUG_PM_ASE _ase_free_materials(&materials); _pico_free_parser( p ); /* return allocated pico model */ return model; }
static int GetMeshShader (T3dsLoaderPers *pers) { char shaderName[255] = { 0 }; picoShader_t *shader; int numSharedVerts; int setShaderName = 0; int i; /* the shader is either the color or the texture map of the */ /* object. it can also hold other information like the brightness, */ /* shine, etc. stuff we don't really care about. we just want the */ /* color, or the texture map file name really */ /* get in the shader name */ if (!GetASCIIZ(pers,shaderName,sizeof(shaderName))) return 0; /* ydnar: trim to first whitespace */ _pico_first_token( shaderName ); /* now that we have the shader name we need to go through all of */ /* the shaders and check the name against each shader. when we */ /* find a shader in our shader list that matches this name we */ /* just read in, then we assign the shader's id of the object to */ /* that shader */ /* get shader id for shader name */ shader = PicoFindShader( pers->model, shaderName, 1 ); /* we've found a matching shader */ if ((shader != NULL) && pers->surface) { char mapName[1024+1]; char *mapNamePtr; memset( mapName,0,sizeof(mapName) ); /* get ptr to shader's map name */ mapNamePtr = PicoGetShaderMapName( shader ); /* we have a valid map name ptr */ if (mapNamePtr != NULL) { char temp[128]; const char *name; /* copy map name to local buffer */ strcpy( mapName,mapNamePtr ); /* extract file name */ name = _pico_nopath( mapName ); strncpy( temp, name, sizeof(temp) ); /* remove file extension */ /* name = _pico_setfext( name,"" ); */ /* assign default name if no name available */ if (strlen(temp) < 1) strcpy(temp,pers->basename); /* build shader name */ _pico_strlwr( temp ); /* gaynux update -sea */ sprintf( mapName,"models/mapobjects/%s/%s",pers->basename,temp ); /* set shader name */ /* PicoSetShaderName( shader,mapName ); */ /* ydnar: this will screw up the named shader */ /* set surface's shader index */ PicoSetSurfaceShader( pers->surface, shader ); setShaderName = 1; } } /* we didn't set a shader name; throw out warning */ if (!setShaderName) { _pico_printf( PICO_WARNING,"3DS mesh is missing shader name"); } /* we don't process the list of shared vertices here; there is a */ /* short int that gives the number of faces of the mesh concerned */ /* by this shader, then there is the list itself of these faces. */ /* 0000 means the first face of the (4120) face list */ /* get number of shared verts */ numSharedVerts = GetWord(pers); #ifdef DEBUG_PM_3DS printf("GetMeshShader: uses shader '%s' (nsv %d)\n",shaderName,numSharedVerts); #endif /* skip list of shared verts */ for (i=0; i<numSharedVerts; i++) { GetWord(pers); } /* success (no errors occured) */ return 1; }