return pos;
}
+/* expecting fileName to be relative vfs model path */
+void _pico_deduce_shadername( const char* fileName, const char* srcName, picoShader_t* shader ){
+ if( srcName == NULL || fileName == NULL )
+ return;
+ char name[strlen( srcName ) + 1];
+ strcpy( name, srcName );
+ _pico_unixify( name );
+ _pico_setfext( name, NULL );
+
+ char path[strlen( fileName ) + strlen( name ) + 1];
+ _pico_nofname( fileName, path, strlen( fileName ) + strlen( name ) + 1 );
+ _pico_unixify( path );
+
+ if( !strchr( name , '/' ) ){ /* texture is likely in the folder, where model is */
+ strcat( path, name );
+ }
+ else if( name[0] == '/' || ( name[0] != '\0' && name[1] == ':' ) || strstr( name, ".." ) ){ /* absolute path or with .. */
+ const char* p = name;
+ for (; *p != '\0'; ++p )
+ if ( _pico_strnicmp( p, "/models/", 8 ) == 0 || _pico_strnicmp( p, "/textures/", 10 ) == 0 )
+ break;
+ if( *p != '\0' ){
+ strcpy( path, p + 1 );
+ }
+ else{
+ p = _pico_nopath( name );
+ strcat( path, p );
+ }
+ }
+ else{
+ PicoSetShaderName( shader, name );
+ return;
+ }
+
+ _pico_printf( PICO_NORMAL, "PICO: substituting shader name: %s -> %s", srcName, path );
+ PicoSetShaderName( shader, path );
+}
+
+/* deduce shadernames from bitmap or shadername paths */
+void _pico_deduce_shadernames( picoModel_t *model ){
+ for ( int i = 0; i < model->numShaders; ++i ){
+ /* skip null shaders */
+ if ( model->shader[i] == NULL )
+ continue;
+
+ const char* mapname = model->shader[i]->mapName;
+ const char* shadername = model->shader[i]->name;
+ if( mapname && *mapname )
+ _pico_deduce_shadername( model->fileName, mapname, model->shader[i] );
+ else if( shadername && *shadername )
+ _pico_deduce_shadername( model->fileName, shadername, model->shader[i] );
+ }
+}
+
/* _pico_parse_skip_white:
* skips white spaces in current pico parser, sets *hasLFs
* to 1 if linefeeds were skipped, and either returns the
const char *_pico_stristr( const char *str, const char *substr );
void _pico_unixify( char *path );
int _pico_nofname( const char *path, char *dest, int destSize );
-const char *_pico_nopath( const char *path );
+const char *_pico_nopath( const char *path );
char *_pico_setfext( char *path, const char *ext );
int _pico_getline( char *buf, int bufsize, char *dest, int destsize );
char *_pico_strlwr( char *str );
+void _pico_deduce_shadernames( picoModel_t *model );
/* vectors */
void _pico_zero_bounds( picoVec3_t mins, picoVec3_t maxs );
}
}
+ _pico_deduce_shadernames( model );
+
return model;
}
*/
picoShader_t *PicoFindShader( picoModel_t *model, char *name, int caseSensitive ){
- int i;
-
-
/* sanity checks */
if ( model == NULL || name == NULL ) { /* sea: null name fix */
return NULL;
}
/* walk list */
- for ( i = 0; i < model->numShaders; i++ )
+ for ( int i = 0; i < model->numShaders; i++ )
{
/* skip null shaders or shaders with null names */
if ( model->shader[ i ] == NULL ||
/* 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 );
-
+ const char* mapNamePtr = PicoGetShaderMapName( shader );
/* we have a valid map name ptr */
if ( mapNamePtr != NULL ) {
+#if 0
char temp[128];
const char *name;
+ char mapName[1024 + 1];
+ memset( mapName,0,sizeof( mapName ) );
/* copy map name to local buffer */
strcpy( mapName,mapNamePtr );
strncpy( temp, name, sizeof( temp ) );
/* remove file extension */
- /* name = _pico_setfext( name,"" ); */
+ /* name = _pico_setfext( name, NULL ); */
/* assign default name if no name available */
if ( strlen( temp ) < 1 ) {
/* set shader name */
/* PicoSetShaderName( shader,mapName ); */ /* ydnar: this will screw up the named shader */
-
+#endif
/* set surface's shader index */
PicoSetSurfaceShader( pers->surface, shader );
/* get model's base name (eg. jeep from c:\models\jeep.3ds) */
memset( basename,0,sizeof( basename ) );
strncpy( basename,_pico_nopath( fileName ),sizeof( basename ) );
- _pico_setfext( basename,"" );
+ _pico_setfext( basename, NULL );
/* initialize persistant vars (formerly static) */
pers.model = model;
}
}
-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.
if ( level == subMaterialLevel ) {
/* set material name */
_pico_first_token( materialName );
- shadername_convert( materialName );
+ _pico_unixify( materialName );
PicoSetShaderName( shader, materialName );
/* set shader's transparency */
}
/* set material name */
- shadername_convert( materialName );
+ _pico_unixify( materialName );
PicoSetShaderName( shader,materialName );
/* set shader's transparency */
/* 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 );
}
#endif
// detox Skin name
- _pico_setfext( skinname, "" );
+ _pico_setfext( skinname, NULL );
_pico_unixify( skinname );
/* create new pico model */
/* detox and set shader name */
strncpy( name, surface->name, sizeof( name ) );
_pico_first_token( name );
- _pico_setfext( name, "" );
+ _pico_setfext( name, NULL );
_pico_unixify( name );
PicoSetShaderName( picoShader, name );
_pico_printf( PICO_VERBOSE,"Skins: %d Verts: %d STs: %d Triangles: %d Frames: %d\nSkin Name \"%s\"\n", md2->numSkins, md2->numXYZ, md2->numST, md2->numTris, md2->numFrames, &skinname );
// detox Skin name
- _pico_setfext( skinname, "" );
+ _pico_setfext( skinname, NULL );
_pico_unixify( skinname );
/* create new pico model */
/* detox and set shader name */
shader = (md3Shader_t*) ( (picoByte_t*) surface + surface->ofsShaders );
- _pico_setfext( shader->name, "" );
+ _pico_setfext( shader->name, NULL );
_pico_unixify( shader->name );
PicoSetShaderName( picoShader, shader->name );
/* detox and set shader name */
shader = (mdcShader_t*) ( (picoByte_t*) surface + surface->ofsShaders );
- _pico_setfext( shader->name, "" );
+ _pico_setfext( shader->name, NULL );
_pico_unixify( shader->name );
PicoSetShaderName( picoShader, shader->name );
return 0;
}
- /* helper */
+ /* helpers */
+ #define _obj_mtl_print_ok _pico_printf( PICO_NORMAL, "PICO: loading %s...OK\n", fileName )
+ #define _obj_mtl_print_fail _pico_printf( PICO_WARNING, "PICO: loading %s...FAIL\n", fileName )
#define _obj_mtl_error_return \
{ \
+ _obj_mtl_print_fail; \
_pico_free_parser( p ); \
_pico_free_file( mtlBuffer ); \
_pico_free( fileName ); \
/* check result */
if ( mtlBufSize == 0 ) {
+ _obj_mtl_print_fail;
return 1; /* file is empty: no error */
}
if ( mtlBufSize < 0 ) {
+ _obj_mtl_print_fail;
return 0; /* load failed: error */
}
if ( _pico_parse( p,1 ) == NULL ) {
break;
}
-#if 1
/* skip empty lines */
if ( p->token == NULL || !strlen( p->token ) ) {
/* diffuse map name */
else if ( !_pico_stricmp( p->token,"map_kd" ) ) {
char *mapName;
- picoShader_t *shader;
/* pointer to current shader must be valid */
if ( curShader == NULL ) {
_pico_printf( PICO_ERROR,"Missing material map name in MTL %s, line %d.",fileName,p->curLine );
_obj_mtl_error_return;
}
- /* create a new pico shader */
- shader = PicoNewShader( model );
- if ( shader == NULL ) {
- _obj_mtl_error_return;
- }
/* set shader map name */
- PicoSetShaderMapName( shader,mapName );
+ PicoSetShaderMapName( curShader, mapName );
}
/* dissolve factor (pseudo transparency 0..1) */
/* where 0 means 100% transparent and 1 means opaque */
/* set specular color */
PicoSetShaderSpecularColor( curShader,color );
}
-#endif
/* skip rest of line */
_pico_parse_skip_rest( p );
}
/* free parser, file buffer, and file name */
+ _obj_mtl_print_ok;
_pico_free_parser( p );
_pico_free_file( mtlBuffer );
_pico_free( fileName );
PicoSetModelName( model,fileName );
PicoSetModelFileName( model,fileName );
- /* try loading the materials; we don't handle the result */
-#if 1
+ /* try loading the materials */
_obj_mtl_load( model );
-#endif
/* parse obj line by line */
while ( 1 )
{
shader = PicoFindShader( model, name, 1 );
if ( shader == NULL ) {
- _pico_printf( PICO_WARNING,"Undefined material name \"%s\" in OBJ %s, line %d. Making a default shader.",name,model->fileName,p->curLine );
+ _pico_printf( PICO_WARNING, "Undefined material name \"%s\" in OBJ, line %d. Making a default shader.", name, p->curLine );
/* create a new pico shader */
shader = PicoNewShader( model );
/* skip unparsed rest of line and continue */
_pico_parse_skip_rest( p );
}
+
/* free memory used by temporary vertexdata */
FreeObjVertexData( vertexData );
}
/* detox and set shader name */
- _pico_setfext( shader, "" );
+ _pico_setfext( shader, NULL );
_pico_unixify( shader );
PicoSetShaderName( picoShader, shader );
_pico_free( shader );