X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=libs%2Fpicomodel%2Fpicointernal.c;h=54866de101522a7440d3952a0b8cea1f22011a67;hb=d8d29a543f2928c2aef158b1c90b92d031826a8b;hp=018ee3a130295869d9294409545e6ca6a7792cb6;hpb=650279d27dcea9bf35dc01eb17531e8c661aa3fa;p=xonotic%2Fnetradiant.git diff --git a/libs/picomodel/picointernal.c b/libs/picomodel/picointernal.c index 018ee3a1..54866de1 100644 --- a/libs/picomodel/picointernal.c +++ b/libs/picomodel/picointernal.c @@ -462,6 +462,8 @@ picoVec_t _pico_calc_plane( picoVec4_t plane, picoVec3_t a, picoVec3_t b, picoVe return _pico_normalize_vec( plane ); } +const picoColor_t picoColor_white = { 255, 255, 255, 255 }; + /* separate from _pico_set_vec4 */ void _pico_set_color( picoColor_t c, int r, int g, int b, int a ){ c[ 0 ] = r; @@ -470,7 +472,7 @@ void _pico_set_color( picoColor_t c, int r, int g, int b, int a ){ c[ 3 ] = a; } -void _pico_copy_color( picoColor_t src, picoColor_t dest ){ +void _pico_copy_color( const picoColor_t src, picoColor_t dest ){ dest[ 0 ] = src[ 0 ]; dest[ 1 ] = src[ 1 ]; dest[ 2 ] = src[ 2 ]; @@ -600,12 +602,12 @@ int _pico_nofname( const char *path, char *dest, int destSize ){ * string otherwise. given 'path' is not altered. -sea */ const char *_pico_nopath( const char *path ){ - const char *src; - src = path + ( strlen( path ) - 1 ); - if ( path == NULL ) { return ""; } + const char *src; + src = path + ( strlen( path ) - 1 ); + if ( !strchr( path,'/' ) && !strchr( path,'\\' ) ) { return ( path ); } @@ -692,6 +694,81 @@ 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; + + /* Detect intentional material name to not replace it with texture name. + + Reimplement commits by Garux: + https://github.com/Garux/netradiant-custom/commit/1bd3e7ae186b55fb61e3738d2493432c0b1f5a7b + https://github.com/Garux/netradiant-custom/commit/ea21eee2254fb2e667732d8f1b0f83c439a89bfa + + This attempts to restore proper material behaviour when the mapper knows what he is doing, + also called Julius' case or correct case because Julius is always correct™ + while keeping the fallback for other situations, also called newbie's case + which may be compatible with third-party tools not following Quake 3 conventions. + + See: https://gitlab.com/xonotic/netradiant/-/merge_requests/179#note_777324051 */ + if ( shadername && *shadername && + ( _pico_strnicmp( shadername, "models/", 7 ) == 0 + || _pico_strnicmp( shadername, "models\\", 7 ) == 0 + || _pico_strnicmp( shadername, "textures/", 9 ) == 0 + || _pico_strnicmp( shadername, "textures\\", 9 ) == 0 ) ) + { + _pico_deduce_shadername( model->fileName, shadername, model->shader[i] ); + } + else 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