From 054cfcd15c57e1473429c2e1b074b05318852e1f Mon Sep 17 00:00:00 2001 From: Christophe Mateos Date: Sun, 4 Dec 2016 06:16:39 +0100 Subject: [PATCH] PicoModel: Cleanup, ASE support upgrade test, uncrustify Next to be tested is MD3... --- libs/picomodel.h | 4 +- libs/picomodel/picointernal.c | 13 + libs/picomodel/picointernal.h | 3 +- libs/picomodel/picomodel.c | 14 +- libs/picomodel/pm_ase.c | 483 +++++++++++++++++++--------------- libs/picomodel/pm_obj.c | 2 +- 6 files changed, 293 insertions(+), 226 deletions(-) diff --git a/libs/picomodel.h b/libs/picomodel.h index 181d428a..f33c6da6 100644 --- a/libs/picomodel.h +++ b/libs/picomodel.h @@ -334,12 +334,12 @@ picoVertexCombinationHash_t *PicoFindVertexCombinationInHashTable( picoVertexCom picoVertexCombinationHash_t *PicoAddVertexCombinationToHashTable( picoVertexCombinationHash_t **hashTable, picoVec3_t xyz, picoVec3_t normal, picoVec3_t st, picoColor_t color, picoIndex_t index ); /* specialized functions */ -int PicoFindSurfaceVertexNum( picoSurface_t *surface, picoVec3_t xyz, picoVec3_t normal, int numSTs, picoVec2_t *st, int numColors, picoColor_t *color ); +int PicoFindSurfaceVertexNum( picoSurface_t *surface, picoVec3_t xyz, picoVec3_t normal, int numSTs, picoVec2_t *st, int numColors, picoColor_t *color, picoIndex_t smoothingGroup ); void PicoFixSurfaceNormals( picoSurface_t *surface ); int PicoRemapModel( picoModel_t *model, char *remapFile ); -void PicoAddTriangleToModel( picoModel_t *model, picoVec3_t** xyz, picoVec3_t** normals, int numSTs, picoVec2_t **st, int numColors, picoColor_t **colors, picoShader_t* shader ); +void PicoAddTriangleToModel( picoModel_t *model, picoVec3_t** xyz, picoVec3_t** normals, int numSTs, picoVec2_t **st, int numColors, picoColor_t **colors, picoShader_t* shader, picoIndex_t* smoothingGroup ); /* end marker */ #ifdef __cplusplus diff --git a/libs/picomodel/picointernal.c b/libs/picomodel/picointernal.c index 931e0281..e98b4531 100644 --- a/libs/picomodel/picointernal.c +++ b/libs/picomodel/picointernal.c @@ -262,6 +262,19 @@ void _pico_printf( int level, const char *format, ... ){ _pico_ptr_print( level,str ); } +/* _pico_first_token: +* trims everything after the first whitespace-delimited token +*/ + +void _pico_first_token(char *str) +{ + if (!str || !*str) + return; + while (*str && !isspace(*str)) + *str++; + *str = '\0'; +} + /* _pico_strltrim: * left trims the given string -sea */ diff --git a/libs/picomodel/picointernal.h b/libs/picomodel/picointernal.h index 4dd75cad..8e9bba25 100644 --- a/libs/picomodel/picointernal.h +++ b/libs/picomodel/picointernal.h @@ -116,7 +116,7 @@ extern void ( *_pico_ptr_print )( int, const char* ); void *_pico_alloc( size_t size ); void *_pico_calloc( size_t num, size_t size ); void *_pico_realloc( void **ptr, size_t oldSize, size_t newSize ); -char *_pico_clone_alloc( char *str/*, int size*/ ); +char *_pico_clone_alloc( const char *str ); void _pico_free( void *ptr ); /* files */ @@ -124,6 +124,7 @@ void _pico_load_file( char *name, unsigned char **buffer, int *bufSiz void _pico_free_file( void *buffer ); /* strings */ +void _pico_first_token(char *str); char *_pico_strltrim( char *str ); char *_pico_strrtrim( char *str ); int _pico_strchcount( char *str, int ch ); diff --git a/libs/picomodel/picomodel.c b/libs/picomodel/picomodel.c index 656ddbf2..29e810a5 100644 --- a/libs/picomodel/picomodel.c +++ b/libs/picomodel/picomodel.c @@ -784,7 +784,7 @@ void PicoSetModelName( picoModel_t *model, char *name ){ _pico_free( model->name ); } - model->name = _pico_clone_alloc( name/*,-1*/ ); + model->name = _pico_clone_alloc( name ); } @@ -797,7 +797,7 @@ void PicoSetModelFileName( picoModel_t *model, char *fileName ){ _pico_free( model->fileName ); } - model->fileName = _pico_clone_alloc( fileName/*,-1*/ ); + model->fileName = _pico_clone_alloc( fileName ); } @@ -837,7 +837,7 @@ void PicoSetShaderName( picoShader_t *shader, char *name ){ _pico_free( shader->name ); } - shader->name = _pico_clone_alloc( name/*,-1*/ ); + shader->name = _pico_clone_alloc( name ); } @@ -850,7 +850,7 @@ void PicoSetShaderMapName( picoShader_t *shader, char *mapName ){ _pico_free( shader->mapName ); } - shader->mapName = _pico_clone_alloc( mapName/*,-1*/ ); + shader->mapName = _pico_clone_alloc( mapName ); } @@ -951,7 +951,7 @@ void PicoSetSurfaceName( picoSurface_t *surface, char *name ){ _pico_free( surface->name ); } - surface->name = _pico_clone_alloc( name/*,-1*/ ); + surface->name = _pico_clone_alloc( name ); } @@ -2177,7 +2177,7 @@ int PicoRemapModel( picoModel_t *model, char *remapFile ){ if ( !strlen( p->token ) ) { continue; } - materialName = _pico_clone_alloc( p->token/*,-1*/ ); + materialName = _pico_clone_alloc( p->token ); if ( materialName == NULL ) { _prm_error_return; } @@ -2235,7 +2235,7 @@ int PicoRemapModel( picoModel_t *model, char *remapFile ){ } /* temporary copy of material name */ - tempMaterialName = _pico_clone_alloc( p->token/*,-1*/ ); + tempMaterialName = _pico_clone_alloc( p->token ); if ( tempMaterialName == NULL ) { _prm_error_return; } diff --git a/libs/picomodel/pm_ase.c b/libs/picomodel/pm_ase.c index dc31dd5f..194f7381 100644 --- a/libs/picomodel/pm_ase.c +++ b/libs/picomodel/pm_ase.c @@ -105,6 +105,25 @@ static aseSubMaterial_t* _ase_get_submaterial( aseMaterial_t* list, int mtlIdPar return subMtl; } +aseSubMaterial_t* _ase_get_submaterial_or_default( aseMaterial_t* materials, int mtlIdParent, int subMtlId ){ + aseSubMaterial_t* subMtl = _ase_get_submaterial( materials, mtlIdParent, subMtlId ); + if ( subMtl != NULL ) { + return subMtl; + } + + /* ydnar: trying default submaterial */ + subMtl = _ase_get_submaterial( materials, mtlIdParent, 0 ); + if ( subMtl != NULL ) { + return subMtl; + } + + _pico_printf( PICO_ERROR, "Could not find material/submaterial for id %d/%d\n", mtlIdParent, subMtlId ); + return NULL; +} + + + + static aseMaterial_t* _ase_add_material( aseMaterial_t **list, int mtlIdParent ){ aseMaterial_t *mtl = _pico_calloc( 1, sizeof( aseMaterial_t ) ); mtl->mtlId = mtlIdParent; @@ -173,64 +192,6 @@ static void _ase_print_materials( aseMaterial_t *list ){ } #endif //DEBUG_PM_ASE -/* ASE Face management */ -/* These are used to keep an association between a submaterial and a face definition */ -/* They are kept in parallel with the current picoSurface, */ -/* and are used by _ase_submit_triangles to lookup the proper material/submaterial IDs */ -typedef struct aseFace_s -{ - struct aseFace_s* next; - int mtlId; - int subMtlId; - int index[9]; -} aseFace_t; - -/* ASE Face management functions */ -void _ase_add_face( aseFace_t **list, aseFace_t **tail, aseFace_t *newFace ){ - /* insert as head of list */ - if ( !( *list ) ) { - *list = newFace; - } - else - { - ( *tail )->next = newFace; - } - - *tail = newFace; - newFace->next = NULL; - - //tag the color indices so we can detect them and apply the default color to them - newFace->index[6] = -1; - newFace->index[7] = -1; - newFace->index[8] = -1; -} - -aseFace_t* _ase_get_face_for_index( aseFace_t *list, int index ){ - int counter = 0; - aseFace_t* face = list; - - while ( counter < index ) - { - face = face->next; - counter++; - } - return face; -} -static void _ase_free_faces( aseFace_t** list, aseFace_t** tail ){ - aseFace_t* face = *list; - aseFace_t* tempFace = NULL; - - while ( face ) - { - tempFace = face->next; - _pico_free( face ); - face = tempFace; - } - - ( *list ) = NULL; - ( *tail ) = NULL; -} - /* todo: * - apply material specific uv offsets to uv coordinates */ @@ -274,7 +235,65 @@ static int _ase_canload( PM_PARAMS_CANLOAD ){ return PICO_PMV_OK; } +typedef struct aseVertex_s aseVertex_t; +struct aseVertex_s +{ + picoVec3_t xyz; + picoVec3_t normal; + picoIndex_t id; +}; +typedef struct aseTexCoord_s aseTexCoord_t; +struct aseTexCoord_s +{ + picoVec2_t texcoord; +}; + +typedef struct aseColor_s aseColor_t; +struct aseColor_s +{ + picoColor_t color; +}; + +typedef struct aseFace_s aseFace_t; +struct aseFace_s +{ + picoIndex_t indices[9]; + picoIndex_t smoothingGroup; + picoIndex_t materialId; + picoIndex_t subMaterialId; +}; +typedef aseFace_t* aseFacesIter_t; + +picoSurface_t* PicoModelFindOrAddSurface( picoModel_t *model, picoShader_t* shader ){ + /* see if a surface already has the shader */ + int i = 0; + for ( ; i < model->numSurfaces ; i++ ) + { + picoSurface_t* workSurface = model->surface[i]; + if ( workSurface->shader == shader ) { + return workSurface; + } + } + + /* no surface uses this shader yet, so create a new surface */ + + { + /* create a new surface in the model for the unique shader */ + picoSurface_t* workSurface = PicoNewSurface( model ); + if ( !workSurface ) { + _pico_printf( PICO_ERROR, "Could not allocate a new surface!\n" ); + return 0; + } + + /* do surface setup */ + PicoSetSurfaceType( workSurface, PICO_TRIANGLES ); + PicoSetSurfaceName( workSurface, shader->name ); + PicoSetSurfaceShader( workSurface, shader ); + + return workSurface; + } +} /* _ase_submit_triangles - jhefty use the surface and the current face list to look up material/submaterial IDs @@ -286,65 +305,80 @@ static int _ase_canload( PM_PARAMS_CANLOAD ){ indexes 6 7 8 = color indexes (new) */ -static void _ase_submit_triangles( picoSurface_t* surface, picoModel_t* model, aseMaterial_t* materials, aseFace_t* faces ){ - aseFace_t* face; - aseSubMaterial_t* subMtl; - picoVec3_t* xyz[3]; - picoVec3_t* normal[3]; - picoVec2_t* st[3]; - picoColor_t* color[3]; - int i; - - face = faces; - while ( face != NULL ) +static void _ase_submit_triangles( picoModel_t* model, aseMaterial_t* materials, aseVertex_t* vertices, aseTexCoord_t* texcoords, aseColor_t* colors, aseFace_t* faces, int numFaces ){ + aseFacesIter_t i = faces, end = faces + numFaces; + for (; i != end; ++i ) { /* look up the shader for the material/submaterial pair */ - subMtl = _ase_get_submaterial( materials, face->mtlId, face->subMtlId ); + aseSubMaterial_t* subMtl = _ase_get_submaterial_or_default( materials, ( *i ).materialId, ( *i ).subMaterialId ); if ( subMtl == NULL ) { - /* ydnar: trying default submaterial */ - subMtl = _ase_get_submaterial( materials, face->mtlId, 0 ); - if ( subMtl == NULL ) { - _pico_printf( PICO_ERROR, "Could not find material/submaterial for id %d/%d\n", face->mtlId, face->subMtlId ); - return; - } + return; } - /* we pull the data from the surface using the facelist data */ - for ( i = 0 ; i < 3 ; i++ ) { - xyz[i] = (picoVec3_t*) PicoGetSurfaceXYZ( surface, face->index[ i ] ); - normal[i] = (picoVec3_t*) PicoGetSurfaceNormal( surface, face->index[ i ] ); - st[i] = (picoVec2_t*) PicoGetSurfaceST( surface, 0, face->index[ i + 3 ] ); - - if ( face->index [ i + 6] >= 0 ) { - color[i] = (picoColor_t*)PicoGetSurfaceColor( surface, 0, face->index[ i + 6 ] ); - } - else + picoVec3_t* xyz[3]; + picoVec3_t* normal[3]; + picoVec2_t* st[3]; + picoColor_t* color[3]; + picoIndex_t smooth[3]; + int j; + /* we pull the data from the vertex, color and texcoord arrays using the face index data */ + for ( j = 0 ; j < 3 ; j++ ) { - color[i] = &white; + xyz[j] = &vertices[( *i ).indices[j]].xyz; + normal[j] = &vertices[( *i ).indices[j]].normal; + st[j] = &texcoords[( *i ).indices[j + 3]].texcoord; + + if ( colors != NULL && ( *i ).indices[j + 6] >= 0 ) { + color[j] = &colors[( *i ).indices[j + 6]].color; + } + else + { + color[j] = &white; + } + + smooth[j] = ( vertices[( *i ).indices[j]].id * ( 1 << 16 ) ) + ( *i ).smoothingGroup; /* don't merge vertices */ + } + /* submit the triangle to the model */ + PicoAddTriangleToModel( model, xyz, normal, 1, st, 1, color, subMtl->shader, smooth ); } - - /* submit the triangle to the model */ - PicoAddTriangleToModel( model, xyz, normal, 1, st, 1, color, subMtl->shader ); - - /* advance to the next face */ - face = face->next; } } +static void shadername_convert( char* shaderName ){ + /* unix-style path separators */ + char* s = shaderName; + for (; *s != '\0'; ++s ) + { + if ( *s == '\\' ) { + *s = '/'; + } + } +} + + /* _ase_load: * loads a 3dsmax ase model file. */ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ picoModel_t *model; - picoSurface_t *surface = NULL; picoParser_t *p; char lastNodeName[ 1024 ]; + aseVertex_t* vertices = NULL; + aseTexCoord_t* texcoords = NULL; + aseColor_t* colors = NULL; aseFace_t* faces = NULL; - aseFace_t* facesTail = NULL; + int numVertices = 0; + int numFaces = 0; + int numTextureVertices = 0; + int numTextureVertexFaces = 0; + int numColorVertices = 0; + int numColorVertexFaces = 0; + int vertexId = 0; + aseMaterial_t* materials = NULL; #ifdef DEBUG_PM_ASE @@ -357,8 +391,8 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ #define _ase_error_return( m ) \ { \ _pico_printf( PICO_ERROR,"%s in ASE, line %d.",m,p->curLine ); \ - _pico_free_parser( p ); \ - PicoFreeModel( model ); \ + _pico_free_parser( p ); \ + PicoFreeModel( model ); \ return NULL; \ } /* create a new pico parser */ @@ -413,15 +447,49 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ /* model mesh (originally contained within geomobject) */ else if ( !_pico_stricmp( p->token,"*mesh" ) ) { /* finish existing surface */ - //_ase_make_surface( model, &surface ); - _ase_submit_triangles( surface, model,materials,faces ); - _ase_free_faces( &faces,&facesTail ); + _ase_submit_triangles( model, materials, vertices, texcoords, colors, faces, numFaces ); + _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" ); + } - /* allocate new pico surface */ - surface = PicoNewSurface( NULL ); - if ( surface == NULL ) { - PicoFreeModel( model ); - return NULL; + vertices = _pico_calloc( numVertices, sizeof( aseVertex_t ) ); + } + 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 */ @@ -430,77 +498,63 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ /* the material reference id (shader index) now. */ else if ( !_pico_stricmp( p->token,"*material_ref" ) ) { int mtlId; - aseFace_t* face; - - /* we must have a valid surface */ - if ( surface == NULL ) { - _ase_error_return( "Missing mesh for material reference" ); - } /* get the material ref (0..n) */ if ( !_pico_parse_int( p,&mtlId ) ) { _ase_error_return( "Missing material reference ID" ); } - /* fix up all of the aseFaceList in the surface to point to the parent material */ - /* we've already saved off their subMtl */ - face = faces; - while ( face != NULL ) { - face->mtlId = mtlId; - face = face->next; + 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" ) ) { - picoVec3_t v; int index; - /* we must have a valid surface */ - if ( surface == NULL ) { - continue; + 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,v ) ) { + if ( !_pico_parse_vec( p,vertices[index].xyz ) ) { _ase_error_return( "Vertex parse error" ); } - /* set vertex */ - PicoSetSurfaceXYZ( surface,index,v ); + vertices[index].id = vertexId++; } /* model mesh vertex normal */ else if ( !_pico_stricmp( p->token,"*mesh_vertexnormal" ) ) { - picoVec3_t v; int index; - /* we must have a valid surface */ - if ( surface == NULL ) { - continue; + 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,v ) ) { + if ( !_pico_parse_vec( p,vertices[index].normal ) ) { _ase_error_return( "Vertex parse error" ); } - - /* set vertex */ - PicoSetSurfaceNormal( surface,index,v ); } /* model mesh face */ else if ( !_pico_stricmp( p->token,"*mesh_face" ) ) { picoIndex_t indexes[3]; int index; - /* we must have a valid surface */ - if ( surface == NULL ) { - continue; + if ( numFaces == 0 ) { + _ase_error_return( "Face parse error" ); } /* get face index */ @@ -526,75 +580,58 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ _ase_error_return( "Face parse error" ); } - /* set face indexes (note interleaved offset!) */ - PicoSetSurfaceIndex( surface, ( index * 9 + 0 ), indexes[2] ); - PicoSetSurfaceIndex( surface, ( index * 9 + 1 ), indexes[1] ); - PicoSetSurfaceIndex( surface, ( index * 9 + 2 ), indexes[0] ); - /* parse to the subMaterial ID */ while ( 1 ) { - _pico_parse( p,0 ); - if ( !_pico_stricmp( p->token,"*MESH_MTLID" ) ) { - aseFace_t* newFace; - int subMtlId; - - _pico_parse_int( p, &subMtlId ); - newFace = _pico_calloc( 1, sizeof( aseFace_t ) ); - - /* we fix up the mtlId later when we parse the material_ref */ - newFace->mtlId = 0; - newFace->subMtlId = subMtlId; - newFace->index[0] = indexes[2]; - newFace->index[1] = indexes[1]; - newFace->index[2] = indexes[0]; - - _ase_add_face( &faces,&facesTail,newFace ); + if ( !_pico_parse( p,0 ) ) { /* EOL */ break; } + if ( !_pico_stricmp( p->token,"*MESH_SMOOTHING" ) ) { + _pico_parse_int( p, &faces[index].smoothingGroup ); + } + 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" ) ) { - picoVec2_t uv; int index; - /* we must have a valid surface */ - if ( surface == NULL ) { - continue; + if ( numVertices == 0 ) { + _ase_error_return( "Texture Vertex parse error" ); } /* get uv vertex index */ - if ( !_pico_parse_int( p,&index ) ) { - _ase_error_return( "UV vertex parse error" ); + if ( !_pico_parse_int( p,&index ) || index >= numTextureVertices ) { + _ase_error_return( "Texture vertex parse error" ); } /* get uv vertex s */ - if ( !_pico_parse_float( p,&uv[0] ) ) { - _ase_error_return( "UV vertex parse error" ); + if ( !_pico_parse_float( p,&texcoords[index].texcoord[0] ) ) { + _ase_error_return( "Texture vertex parse error" ); } /* get uv vertex t */ - if ( !_pico_parse_float( p,&uv[1] ) ) { - _ase_error_return( "UV vertex parse error" ); + if ( !_pico_parse_float( p,&texcoords[index].texcoord[1] ) ) { + _ase_error_return( "Texture vertex parse error" ); } /* ydnar: invert t */ - uv[ 1 ] = 1.0f - uv[ 1 ]; - - /* set texture vertex */ - PicoSetSurfaceST( surface,0,index,uv ); + 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; - aseFace_t* face; - /* we must have a valid surface */ - if ( surface == NULL ) { - continue; + if ( numFaces == 0 ) { + _ase_error_return( "Texture face parse error" ); } /* get face index */ @@ -617,65 +654,52 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ _ase_error_return( "Texture face parse error" ); } - /* set face indexes (note interleaved offset!) */ - PicoSetSurfaceIndex( surface, ( index * 9 + 3 ), indexes[2] ); - PicoSetSurfaceIndex( surface, ( index * 9 + 4 ), indexes[1] ); - PicoSetSurfaceIndex( surface, ( index * 9 + 5 ), indexes[0] ); - - face = _ase_get_face_for_index( faces,index ); - face->index[3] = indexes[2]; - face->index[4] = indexes[1]; - face->index[5] = indexes[0]; + 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" ) ) { - picoColor_t color; int index; float colorInput; - /* we must have a valid surface */ - if ( surface == NULL ) { - continue; + if ( numVertices == 0 ) { + _ase_error_return( "Color Vertex parse error" ); } /* get color vertex index */ if ( !_pico_parse_int( p,&index ) ) { - _ase_error_return( "UV vertex parse error" ); + _ase_error_return( "Color vertex parse error" ); } /* get R component */ if ( !_pico_parse_float( p,&colorInput ) ) { - _ase_error_return( "color vertex parse error" ); + _ase_error_return( "Color vertex parse error" ); } - color[0] = (picoByte_t)( colorInput * 255 ); + colors[index].color[0] = (picoByte_t)( colorInput * 255 ); /* get G component */ if ( !_pico_parse_float( p,&colorInput ) ) { - _ase_error_return( "color vertex parse error" ); + _ase_error_return( "Color vertex parse error" ); } - color[1] = (picoByte_t)( colorInput * 255 ); + colors[index].color[1] = (picoByte_t)( colorInput * 255 ); /* get B component */ if ( !_pico_parse_float( p,&colorInput ) ) { - _ase_error_return( "color vertex parse error" ); + _ase_error_return( "Color vertex parse error" ); } - color[2] = (picoByte_t)( colorInput * 255 ); + colors[index].color[2] = (picoByte_t)( colorInput * 255 ); /* leave alpha alone since we don't get any data from the ASE format */ - color[3] = 255; - - /* set texture vertex */ - PicoSetSurfaceColor( surface,0,index,color ); + colors[index].color[3] = 255; } /* model color face */ else if ( !_pico_stricmp( p->token,"*mesh_cface" ) ) { picoIndex_t indexes[3]; int index; - aseFace_t* face; - /* we must have a valid surface */ - if ( surface == NULL ) { - continue; + if ( numFaces == 0 ) { + _ase_error_return( "Face parse error" ); } /* get face index */ @@ -701,20 +725,14 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ _ase_error_return( "Face parse error" ); } - /* set face indexes (note interleaved offset!) */ - PicoSetSurfaceIndex( surface, ( index * 9 + 6 ), indexes[2] ); - PicoSetSurfaceIndex( surface, ( index * 9 + 7 ), indexes[1] ); - PicoSetSurfaceIndex( surface, ( index * 9 + 8 ), indexes[0] ); - - face = _ase_get_face_for_index( faces,index ); - face->index[6] = indexes[2]; - face->index[7] = indexes[1]; - face->index[8] = indexes[0]; + 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 = NULL; + picoShader_t *shader; int level = 1, index; char materialName[ 1024 ]; float transValue = 0.0f, shineValue = 1.0f; @@ -755,6 +773,8 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ if ( level == subMaterialLevel ) { /* set material name */ + _pico_first_token( materialName ); + shadername_convert( materialName ); PicoSetShaderName( shader, materialName ); /* set shader's transparency */ @@ -944,6 +964,7 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ } /* set material name */ + shadername_convert( materialName ); PicoSetShaderName( shader,materialName ); /* set shader's transparency */ @@ -967,6 +988,34 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ /* set material map name */ PicoSetShaderMapName( shader, mapname ); + /* extract shadername from bitmap path */ + if ( mapname != NULL ) { + char* p = mapname; + + /* convert to shader-name format */ + shadername_convert( mapname ); + { + /* remove extension */ + char* last_period = strrchr( p, '.' ); + if ( last_period != NULL ) { + *last_period = '\0'; + } + } + + /* find shader path */ + for (; *p != '\0'; ++p ) + { + if ( _pico_strnicmp( p, "models/", 7 ) == 0 || _pico_strnicmp( p, "textures/", 9 ) == 0 ) { + 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 ); } @@ -982,9 +1031,11 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ } /* ydnar: finish existing surface */ -// _ase_make_surface( model, &surface ); - _ase_submit_triangles( surface, model,materials,faces ); - _ase_free_faces( &faces,&facesTail ); + _ase_submit_triangles( model, materials, vertices, texcoords, colors, faces, numFaces ); + _pico_free( faces ); + _pico_free( vertices ); + _pico_free( texcoords ); + _pico_free( colors ); #ifdef DEBUG_PM_ASE _ase_print_materials( materials ); @@ -995,6 +1046,8 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){ _ase_free_materials( &materials ); + _pico_free_parser( p ); + /* return allocated pico model */ return model; } diff --git a/libs/picomodel/pm_obj.c b/libs/picomodel/pm_obj.c index 2f6e93c4..a8b1dfed 100644 --- a/libs/picomodel/pm_obj.c +++ b/libs/picomodel/pm_obj.c @@ -241,7 +241,7 @@ static int _obj_mtl_load( picoModel_t *model ){ return 0; \ } /* alloc copy of model file name */ - fileName = _pico_clone_alloc( model->fileName,-1 ); + fileName = _pico_clone_alloc( model->fileName ); if ( fileName == NULL ) { return 0; }