manage model shaders remapping

This commit is contained in:
Garux 2021-01-21 07:19:15 +03:00
parent fe5c0879b4
commit 15e4b8e850
2 changed files with 40 additions and 65 deletions

View File

@ -210,7 +210,7 @@ picoModel_t *LoadModel( const char *name, int frame ){
adds a picomodel into the bsp adds a picomodel into the bsp
*/ */
void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ){ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const std::list<remap_t> *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ){
int i, j, s, k, numSurfaces; int i, j, s, k, numSurfaces;
m4x4_t identity, nTransform; m4x4_t identity, nTransform;
picoModel_t *model; picoModel_t *model;
@ -223,7 +223,6 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
picoVec_t *xyz, *normal, *st; picoVec_t *xyz, *normal, *st;
byte *color; byte *color;
picoIndex_t *indexes; picoIndex_t *indexes;
skinfile_t *sf, *sf2;
char *skinfilecontent; char *skinfilecontent;
int skinfilesize; int skinfilesize;
char *skinfileptr, *skinfilenextptr; char *skinfileptr, *skinfilenextptr;
@ -255,7 +254,7 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
Sys_Printf( "Skin %d of %s does not exist, using 0 instead\n", skin, name ); Sys_Printf( "Skin %d of %s does not exist, using 0 instead\n", skin, name );
} }
} }
sf = NULL; std::list<remap_t> skins;
if ( skinfilesize >= 0 ) { if ( skinfilesize >= 0 ) {
Sys_Printf( "Using skin %d of %s\n", skin, name ); Sys_Printf( "Using skin %d of %s\n", skin, name );
for ( skinfileptr = skinfilecontent; !strEmpty( skinfileptr ); skinfileptr = skinfilenextptr ) for ( skinfileptr = skinfilecontent; !strEmpty( skinfileptr ); skinfileptr = skinfilenextptr )
@ -279,23 +278,21 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
} }
/* create new item */ /* create new item */
sf2 = sf; remap_t skin;
sf = safe_malloc( sizeof( *sf ) );
sf->next = sf2;
sprintf( format, "replace %%%ds %%%ds", (int)sizeof( sf->name ) - 1, (int)sizeof( sf->to ) - 1 ); sprintf( format, "replace %%%ds %%%ds", (int)sizeof( skin.from ) - 1, (int)sizeof( skin.to ) - 1 );
if ( sscanf( skinfileptr, format, sf->name, sf->to ) == 2 ) { if ( sscanf( skinfileptr, format, skin.from, skin.to ) == 2 ) {
skins.push_back( skin );
continue; continue;
} }
sprintf( format, " %%%d[^, ] ,%%%ds", (int)sizeof( sf->name ) - 1, (int)sizeof( sf->to ) - 1 ); sprintf( format, " %%%d[^, ] ,%%%ds", (int)sizeof( skin.from ) - 1, (int)sizeof( skin.to ) - 1 );
if ( sscanf( skinfileptr, format, sf->name, sf->to ) == 2 ) { if ( sscanf( skinfileptr, format, skin.from, skin.to ) == 2 ) {
skins.push_back( skin );
continue; continue;
} }
/* invalid input line -> discard sf struct */ /* invalid input line -> discard skin struct */
Sys_Printf( "Discarding skin directive in %s: %s\n", skinfilename, skinfileptr ); Sys_Printf( "Discarding skin directive in %s: %s\n", skinfilename, skinfileptr );
free( sf );
sf = sf2;
} }
free( skinfilecontent ); free( skinfilecontent );
} }
@ -350,13 +347,13 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
} }
/* handle .skin file */ /* handle .skin file */
if ( sf ) { if ( !skins.empty() ) {
picoShaderName = NULL; picoShaderName = NULL;
for ( sf2 = sf; sf2 != NULL; sf2 = sf2->next ) for( const auto& skin : skins )
{ {
if ( striEqual( surface->name, sf2->name ) ) { if ( striEqual( surface->name, skin.from ) ) {
Sys_FPrintf( SYS_VRB, "Skin file: mapping %s to %s\n", surface->name, sf2->to ); Sys_FPrintf( SYS_VRB, "Skin file: mapping %s to %s\n", surface->name, skin.to );
picoShaderName = sf2->to; picoShaderName = skin.to;
break; break;
} }
} }
@ -367,17 +364,17 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
} }
/* handle shader remapping */ /* handle shader remapping */
{ if( remaps != NULL ){
const char* to = NULL; const char* to = NULL;
size_t fromlen = 0; size_t fromlen = 0;
for ( remap_t *rm = remap; rm != NULL; rm = rm->next ) for( const auto& rm : *remaps )
{ {
if ( strEqual( rm->from, "*" ) && fromlen == 0 ) { // only globbing, if no respective match if ( strEqual( rm.from, "*" ) && fromlen == 0 ) { // only globbing, if no respective match
to = rm->to; to = rm.to;
} }
else if( striEqualSuffix( picoShaderName, rm->from ) && strlen( rm->from ) > fromlen ){ // longer match has priority else if( striEqualSuffix( picoShaderName, rm.from ) && strlen( rm.from ) > fromlen ){ // longer match has priority
to = rm->to; to = rm.to;
fromlen = strlen( rm->from ); fromlen = strlen( rm.from );
} }
} }
if( to != NULL ){ if( to != NULL ){
@ -1427,45 +1424,39 @@ void AddTriangleModels( entity_t *eparent ){
m4x4_pivoted_transform_by_vec3( transform, origin, angles, eXYZ, scale, vec3_origin ); m4x4_pivoted_transform_by_vec3( transform, origin, angles, eXYZ, scale, vec3_origin );
/* get shader remappings */ /* get shader remappings */
remap_t *remap = NULL, *remap2; std::list<remap_t> remaps;
for ( epair_t *ep = e->epairs; ep != NULL; ep = ep->next ) for ( epair_t *ep = e->epairs; ep != NULL; ep = ep->next )
{ {
/* look for keys prefixed with "_remap" */ /* look for keys prefixed with "_remap" */
if ( !strEmptyOrNull( ep->key ) && !strEmptyOrNull( ep->value ) && if ( !strEmptyOrNull( ep->key ) && !strEmptyOrNull( ep->value ) &&
striEqualPrefix( ep->key, "_remap" ) ) { striEqualPrefix( ep->key, "_remap" ) ) {
/* create new remapping */ /* create new remapping */
remap2 = remap; remap_t remap;
remap = safe_malloc( sizeof( *remap ) ); strcpy( remap.from, ep->value );
remap->next = remap2;
strcpy( remap->from, ep->value );
/* split the string */ /* split the string */
char *split = strchr( remap->from, ';' ); char *split = strchr( remap.from, ';' );
if ( split == NULL ) { if ( split == NULL ) {
Sys_Warning( "Shader _remap key found in misc_model without a ; character: '%s'\n", remap->from ); Sys_Warning( "Shader _remap key found in misc_model without a ; character: '%s'\n", remap.from );
continue;
} }
else if( split == remap->from ){ else if( split == remap.from ){
Sys_Warning( "_remap FROM is empty in '%s'\n", remap->from ); Sys_Warning( "_remap FROM is empty in '%s'\n", remap.from );
split = NULL; continue;
} }
else if( strEmpty( split + 1 ) ){ else if( strEmpty( split + 1 ) ){
Sys_Warning( "_remap TO is empty in '%s'\n", remap->from ); Sys_Warning( "_remap TO is empty in '%s'\n", remap.from );
split = NULL; continue;
} }
else if( strlen( split + 1 ) >= sizeof( remap->to ) ){ else if( strlen( split + 1 ) >= sizeof( remap.to ) ){
Sys_Warning( "_remap TO is too long in '%s'\n", remap->from ); Sys_Warning( "_remap TO is too long in '%s'\n", remap.from );
split = NULL;
}
if ( split == NULL ) {
free( remap );
remap = remap2;
continue; continue;
} }
/* store the split */ /* store the split */
strClear( split ); strClear( split );
strcpy( remap->to, ( split + 1 ) ); strcpy( remap.to, ( split + 1 ) );
remaps.push_back( remap );
/* note it */ /* note it */
//% Sys_FPrintf( SYS_VRB, "Remapping %s to %s\n", remap->from, remap->to ); //% Sys_FPrintf( SYS_VRB, "Remapping %s to %s\n", remap->from, remap->to );
@ -1512,15 +1503,7 @@ void AddTriangleModels( entity_t *eparent ){
/* insert the model */ /* insert the model */
InsertModel( model, skin, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle, clipDepth ); InsertModel( model, skin, frame, transform, &remaps, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle, clipDepth );
/* free shader remappings */
while ( remap != NULL )
{
remap2 = remap->next;
free( remap );
remap = remap2;
}
} }
} }

View File

@ -86,6 +86,7 @@
#include "stringfixedsize.h" #include "stringfixedsize.h"
#include "stream/stringstream.h" #include "stream/stringstream.h"
#include <list>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
@ -638,20 +639,11 @@ foliageInstance_t;
typedef struct remap_s typedef struct remap_s
{ {
struct remap_s *next;
char from[ 1024 ]; char from[ 1024 ];
char to[ MAX_QPATH ]; char to[ MAX_QPATH ];
} }
remap_t; remap_t;
typedef struct skinfile_s
{
struct skinfile_s *next;
char name[ 1024 ];
char to[ MAX_QPATH ];
}
skinfile_t;
/* wingdi.h hack, it's the same: 0 */ /* wingdi.h hack, it's the same: 0 */
#undef CM_NONE #undef CM_NONE
@ -1679,7 +1671,7 @@ void PicoPrintFunc( int level, const char *str );
void PicoLoadFileFunc( const char *name, byte **buffer, int *bufSize ); void PicoLoadFileFunc( const char *name, byte **buffer, int *bufSize );
picoModel_t *FindModel( const char *name, int frame ); picoModel_t *FindModel( const char *name, int frame );
picoModel_t *LoadModel( const char *name, int frame ); picoModel_t *LoadModel( const char *name, int frame );
void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ); void InsertModel( const char *name, int skin, int frame, m4x4_t transform, const std::list<remap_t> *remaps, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth );
void AddTriangleModels( entity_t *e ); void AddTriangleModels( entity_t *e );