]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
support .skin files for models (modelname_<n>.skin) like Q3A and DP
authorRudolf Polzer <divverent@alientrap.org>
Fri, 1 Oct 2010 09:28:07 +0000 (11:28 +0200)
committerRudolf Polzer <divverent@alientrap.org>
Fri, 1 Oct 2010 09:29:51 +0000 (11:29 +0200)
tools/quake3/q3map2/model.c
tools/quake3/q3map2/q3map2.h
tools/quake3/q3map2/surface.c
tools/quake3/q3map2/surface_foliage.c

index cbba5c5d3b29001bf0ab15cbb2727344fb6ef46e..62747b48fef7f334ffb4658579320afa60d4ff4e 100644 (file)
@@ -206,7 +206,7 @@ InsertModel() - ydnar
 adds a picomodel into the bsp
 */
 
-void InsertModel( char *name, 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 )
+void InsertModel( 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 )
 {
        int                                     i, j, k, s, numSurfaces;
        m4x4_t                          identity, nTransform;
@@ -222,14 +222,64 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade
        byte                            *color;
        picoIndex_t                     *indexes;
        remap_t                         *rm, *glob;
+       skinfile_t                      *sf, *sf2;
        double                          normalEpsilon_save;
        double                          distanceEpsilon_save;
+       char                            skinfilename[ MAX_QPATH ];
+       FILE                            *skinfilehandle;
        
        
        /* get model */
        model = LoadModel( name, frame );
        if( model == NULL )
                return;
+
+       /* load skin file */
+       snprintf(skinfilename, sizeof(skinfilename), "%s_%d.skin", name, skin);
+       skinfilename[sizeof(skinfilename)-1] = 0;
+       skinfilehandle = fopen(skinfilename, "r");
+       if(!skinfilehandle)
+       {
+               /* fallback to skin 0 if invalid */
+               snprintf(skinfilename, sizeof(skinfilename), "%s_0.skin", name);
+               skinfilename[sizeof(skinfilename)-1] = 0;
+               skinfilehandle = fopen(skinfilename, "r");
+               if(skinfilehandle)
+                       Sys_Printf( "Skin %d of %s does not exist, using 0 instead\n", skin, name );
+       }
+       sf = NULL;
+       if(skinfilehandle)
+       {
+               Sys_Printf( "Using skin %d of %s\n", skin, name );
+               int pos;
+               for(;;)
+               {
+                       // for fscanf
+                       char format[64];
+                       char buf[1024];
+
+                       if(!fgets(buf, sizeof(buf), skinfilehandle))
+                               break;
+
+                       /* create new item */
+                       sf2 = sf;
+                       sf = safe_malloc( sizeof( *sf ) );
+                       sf->next = sf2;
+
+                       sprintf(format, "replace %%%ds %%%ds%%n", (int)sizeof(sf->name)-1, (int)sizeof(sf->to)-1);
+                       pos = 0;
+                       if(sscanf(buf, format, &sf->name, &sf->to, &pos) > 0 && pos > 0)
+                               continue;
+                       sprintf(format, "%%%ds,%%%ds%%n", (int)sizeof(sf->name)-1, (int)sizeof(sf->to)-1);
+                       pos = 0;
+                       if(sscanf(buf, format, &sf->name, &sf->to, &pos) > 0 && pos > 0)
+                               continue;
+
+                       /* invalid input line -> discard sf struct */
+                       free(sf);
+                       sf = sf2;
+               }
+       }
        
        /* handle null matrix */
        if( transform == NULL )
@@ -283,7 +333,27 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade
                        picoShaderName = "";
                else
                        picoShaderName = PicoGetShaderName( shader );
-               
+
+               /* handle .skin file */
+               if(sf)
+               {
+                       picoShaderName = NULL;
+                       for(sf2 = sf; sf2 != NULL; sf2 = sf2->next)
+                       {
+                               if( !Q_stricmp( surface->name, sf2->name ) )
+                               {
+                                       Sys_FPrintf( SYS_VRB, "Skin file: mapping %s to %s\n", surface->name, sf2->to );
+                                       picoShaderName = sf2->to;
+                                       break;
+                               }
+                       }
+                       if(!picoShaderName)
+                       {
+                               Sys_FPrintf( SYS_VRB, "Skin file: not mapping %s\n", surface->name );
+                               continue;
+                       }
+               }
+
                /* handle shader remapping */
                glob = NULL;
                for( rm = remap; rm != NULL; rm = rm->next )
@@ -603,7 +673,7 @@ adds misc_model surfaces to the bsp
 
 void AddTriangleModels( entity_t *e )
 {
-       int                             num, frame, castShadows, recvShadows, spawnFlags;
+       int                             num, frame, skin, castShadows, recvShadows, spawnFlags;
        entity_t                *e2;
        const char              *targetName;
        const char              *target, *model, *value;
@@ -806,21 +876,23 @@ void AddTriangleModels( entity_t *e )
                if ( strcmp( "", ValueForKey( e2, "_shadeangle" ) ) )
                        shadeAngle = FloatForKey( e2, "_shadeangle" );
                /* vortex' aliases */
-               else if ( strcmp( "", ValueForKey( mapEnt, "_smoothnormals" ) ) )
-                       shadeAngle = FloatForKey( mapEnt, "_smoothnormals" );
-               else if ( strcmp( "", ValueForKey( mapEnt, "_sn" ) ) )
-                       shadeAngle = FloatForKey( mapEnt, "_sn" );
-               else if ( strcmp( "", ValueForKey( mapEnt, "_smooth" ) ) )
-                       shadeAngle = FloatForKey( mapEnt, "_smooth" );
+               else if ( strcmp( "", ValueForKey( e2, "_smoothnormals" ) ) )
+                       shadeAngle = FloatForKey( e2, "_smoothnormals" );
+               else if ( strcmp( "", ValueForKey( e2, "_sn" ) ) )
+                       shadeAngle = FloatForKey( e2, "_sn" );
+               else if ( strcmp( "", ValueForKey( e2, "_smooth" ) ) )
+                       shadeAngle = FloatForKey( e2, "_smooth" );
 
                if( shadeAngle < 0.0f )
                        shadeAngle = 0.0f;
 
                if( shadeAngle > 0.0f )
                        Sys_Printf( "misc_model has shading angle of %.4f\n", shadeAngle );
-               
+
+               skin = IntForKey(e2, "skin");
+
                /* insert the model */
-               InsertModel( (char*) model, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle );
+               InsertModel( (char*) model, skin, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle );
                
                /* free shader remappings */
                while( remap != NULL )
index 078f46e214c39c0385af54d0caddbca07fbe59be..d0f903fb8efb77f1a6c02283321414ea22bdbda0 100644 (file)
@@ -645,6 +645,14 @@ typedef struct remap_s
 }
 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 */
 #undef CM_NONE
@@ -1651,7 +1659,7 @@ void                                              PicoPrintFunc( int level, const char *str );
 void                                           PicoLoadFileFunc( char *name, byte **buffer, int *bufSize );
 picoModel_t                                    *FindModel( char *name, int frame );
 picoModel_t                                    *LoadModel( char *name, int frame );
-void                                           InsertModel( char *name, 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 );
+void                                           InsertModel( 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 );
 void                                           AddTriangleModels( entity_t *e );
 
 
index 76385cb3ffd902b13977b066b734c098acffc913..920aff35cbc3380ce40da24f06ca6f21cad7033f 100644 (file)
@@ -3173,7 +3173,7 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, surfaceModel_t *model, b
                        }
                        
                        /* insert the model */
-                       InsertModel( (char *) model->model, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0 );
+                       InsertModel( (char *) model->model, 0, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0 );
                        
                        /* return to sender */
                        return 1;
index 71875af09ce0ade7997ab2ffa10c695bbe895362..cc5452aec5fed549352595233dcb56010a3ccbf4 100644 (file)
@@ -275,7 +275,7 @@ void Foliage( mapDrawSurface_t *src )
                m4x4_scale_for_vec3( transform, scale );
                
                /* add the model to the bsp */
-               InsertModel( foliage->model, 0, transform, NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0 );
+               InsertModel( foliage->model, 0, 0, transform, NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0 );
                
                /* walk each new surface */
                for( i = oldNumMapDrawSurfs; i < numMapDrawSurfs; i++ )