* picomodel: do some guessings about shader paths to handle more cases out of the box; ones are based on material and diffuse map names:
name w/o path: assume textures are in the folder, where model file is absolute path or with ..: try to cut at "/models/" or "/textures/" (as if leading to game folders); do previous case, if not strip extensions and turn slashes to forward ones anytime * picomodel::obj: fix diffuse map paths loading from .mtl
This commit is contained in:
parent
cf885ea4ea
commit
86904473bb
|
|
@ -694,6 +694,60 @@ int _pico_getline( char *buf, int bufsize, char *dest, int destsize ){
|
|||
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
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ 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 );
|
||||
|
|
|
|||
|
|
@ -180,6 +180,8 @@ picoModel_t *PicoModuleLoadModel( const picoModule_t* pm, const char* fileName,
|
|||
}
|
||||
}
|
||||
|
||||
_pico_deduce_shadernames( model );
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
|
@ -491,16 +493,13 @@ void PicoFreeShader( picoShader_t *shader ){
|
|||
*/
|
||||
|
||||
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 ||
|
||||
|
|
|
|||
|
|
@ -405,17 +405,15 @@ static int GetMeshShader( T3dsLoaderPers *pers ){
|
|||
|
||||
/* 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 );
|
||||
|
|
@ -425,7 +423,7 @@ static int GetMeshShader( T3dsLoaderPers *pers ){
|
|||
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 ) {
|
||||
|
|
@ -438,7 +436,7 @@ static int GetMeshShader( T3dsLoaderPers *pers ){
|
|||
|
||||
/* set shader name */
|
||||
/* PicoSetShaderName( shader,mapName ); */ /* ydnar: this will screw up the named shader */
|
||||
|
||||
#endif
|
||||
/* set surface's shader index */
|
||||
PicoSetSurfaceShader( pers->surface, shader );
|
||||
|
||||
|
|
@ -732,7 +730,7 @@ static picoModel_t *_3ds_load( PM_PARAMS_LOAD ){
|
|||
/* 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;
|
||||
|
|
|
|||
|
|
@ -460,17 +460,6 @@ static void _ase_submit_triangles( picoModel_t* model, aseMaterial_t* materials,
|
|||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
@ -887,7 +876,7 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
if ( level == subMaterialLevel ) {
|
||||
/* set material name */
|
||||
_pico_first_token( materialName );
|
||||
shadername_convert( materialName );
|
||||
_pico_unixify( materialName );
|
||||
PicoSetShaderName( shader, materialName );
|
||||
|
||||
/* set shader's transparency */
|
||||
|
|
@ -1077,7 +1066,7 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
}
|
||||
|
||||
/* set material name */
|
||||
shadername_convert( materialName );
|
||||
_pico_unixify( materialName );
|
||||
PicoSetShaderName( shader,materialName );
|
||||
|
||||
/* set shader's transparency */
|
||||
|
|
@ -1101,34 +1090,6 @@ 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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ static picoModel_t *_fm_load( PM_PARAMS_LOAD ){
|
|||
#endif
|
||||
|
||||
// detox Skin name
|
||||
_pico_setfext( skinname, "" );
|
||||
_pico_setfext( skinname, NULL );
|
||||
_pico_unixify( skinname );
|
||||
|
||||
/* create new pico model */
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ static picoModel_t *_lwo_load( PM_PARAMS_LOAD ){
|
|||
/* 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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ static picoModel_t *_md2_load( PM_PARAMS_LOAD ){
|
|||
_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 */
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ static picoModel_t *_md3_load( PM_PARAMS_LOAD ){
|
|||
|
||||
/* 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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -647,7 +647,7 @@ static picoModel_t *_mdc_load( PM_PARAMS_LOAD ){
|
|||
|
||||
/* 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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -232,9 +232,12 @@ static int _obj_mtl_load( picoModel_t *model ){
|
|||
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 ); \
|
||||
|
|
@ -254,9 +257,11 @@ static int _obj_mtl_load( picoModel_t *model ){
|
|||
|
||||
/* 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 */
|
||||
|
||||
}
|
||||
|
|
@ -273,7 +278,6 @@ static int _obj_mtl_load( picoModel_t *model ){
|
|||
if ( _pico_parse( p,1 ) == NULL ) {
|
||||
break;
|
||||
}
|
||||
#if 1
|
||||
|
||||
/* skip empty lines */
|
||||
if ( p->token == NULL || !strlen( p->token ) ) {
|
||||
|
|
@ -313,7 +317,6 @@ static int _obj_mtl_load( picoModel_t *model ){
|
|||
/* 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 ) {
|
||||
|
|
@ -328,13 +331,8 @@ static int _obj_mtl_load( picoModel_t *model ){
|
|||
_pico_printf( PICO_ERROR,"Missing material map name in MTL, line %d.",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 */
|
||||
|
|
@ -486,12 +484,12 @@ static int _obj_mtl_load( picoModel_t *model ){
|
|||
/* 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 );
|
||||
|
|
@ -567,10 +565,8 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ){
|
|||
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 )
|
||||
|
|
@ -908,7 +904,7 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ){
|
|||
{
|
||||
shader = PicoFindShader( model, name, 1 );
|
||||
if ( shader == NULL ) {
|
||||
_pico_printf( PICO_WARNING,"Undefined material name in OBJ, line %d. Making a default shader.",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 );
|
||||
|
|
@ -927,6 +923,7 @@ static picoModel_t *_obj_load( PM_PARAMS_LOAD ){
|
|||
/* skip unparsed rest of line and continue */
|
||||
_pico_parse_skip_rest( p );
|
||||
}
|
||||
|
||||
/* free memory used by temporary vertexdata */
|
||||
FreeObjVertexData( vertexData );
|
||||
|
||||
|
|
|
|||
|
|
@ -502,7 +502,7 @@ static picoModel_t *_terrain_load( PM_PARAMS_LOAD ){
|
|||
}
|
||||
|
||||
/* detox and set shader name */
|
||||
_pico_setfext( shader, "" );
|
||||
_pico_setfext( shader, NULL );
|
||||
_pico_unixify( shader );
|
||||
PicoSetShaderName( picoShader, shader );
|
||||
_pico_free( shader );
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user