callback for picomodel.lib
*/
-void PicoLoadFileFunc( char *name, byte **buffer, int *bufSize )
+void PicoLoadFileFunc( const char *name, byte **buffer, int *bufSize )
{
- *bufSize = vfsLoadFile( (const char*) name, (void**) buffer, 0 );
+ *bufSize = vfsLoadFile( name, (void**) buffer, 0 );
}
finds an existing picoModel and returns a pointer to the picoModel_t struct or NULL if not found
*/
-picoModel_t *FindModel( char *name, int frame )
+picoModel_t *FindModel( const char *name, int frame )
{
int i;
loads a picoModel and returns a pointer to the picoModel_t struct or NULL if not found
*/
-picoModel_t *LoadModel( char *name, int frame )
+picoModel_t *LoadModel( const char *name, int frame )
{
int i;
picoModel_t *model, **pm;
Error( "MAX_MODELS (%d) exceeded, there are too many model files referenced by the map.", MAX_MODELS );
/* attempt to parse model */
- *pm = PicoLoadModel( (char*) name, frame );
+ *pm = PicoLoadModel( name, frame );
/* if loading failed, make a bogus model to silence the rest of the warnings */
if( *pm == NULL )
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 )
+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 )
{
- int i, j, k, s, numSurfaces;
+ int i, j, s, numSurfaces;
m4x4_t identity, nTransform;
picoModel_t *model;
picoShader_t *shader;
byte *color;
picoIndex_t *indexes;
remap_t *rm, *glob;
+ skinfile_t *sf, *sf2;
double normalEpsilon_save;
double distanceEpsilon_save;
+ char skinfilename[ MAX_QPATH ];
+ char *skinfilecontent;
+ int skinfilesize;
+ char *skinfileptr, *skinfilenextptr;
/* 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;
+ skinfilesize = vfsLoadFile(skinfilename, (void**) &skinfilecontent, 0);
+ if(skinfilesize < 0 && skin != 0)
+ {
+ /* fallback to skin 0 if invalid */
+ snprintf(skinfilename, sizeof(skinfilename), "%s_0.skin", name);
+ skinfilename[sizeof(skinfilename)-1] = 0;
+ skinfilesize = vfsLoadFile(skinfilename, (void**) &skinfilecontent, 0);
+ if(skinfilesize >= 0)
+ Sys_Printf( "Skin %d of %s does not exist, using 0 instead\n", skin, name );
+ }
+ sf = NULL;
+ if(skinfilesize >= 0)
+ {
+ Sys_Printf( "Using skin %d of %s\n", skin, name );
+ int pos;
+ for(skinfileptr = skinfilecontent; *skinfileptr; skinfileptr = skinfilenextptr)
+ {
+ // for fscanf
+ char format[64];
+
+ skinfilenextptr = strchr(skinfileptr, '\r');
+ if(skinfilenextptr)
+ {
+ *skinfilenextptr++ = 0;
+ }
+ else
+ {
+ skinfilenextptr = strchr(skinfileptr, '\n');
+ if(skinfilenextptr)
+ *skinfilenextptr++ = 0;
+ else
+ skinfilenextptr = skinfileptr + strlen(skinfileptr);
+ }
+
+ /* create new item */
+ sf2 = sf;
+ sf = safe_malloc( sizeof( *sf ) );
+ sf->next = sf2;
+
+ sprintf(format, "replace %%%ds %%%ds", (int)sizeof(sf->name)-1, (int)sizeof(sf->to)-1);
+ if(sscanf(skinfileptr, format, sf->name, sf->to) == 2)
+ continue;
+ sprintf(format, " %%%d[^, ] ,%%%ds", (int)sizeof(sf->name)-1, (int)sizeof(sf->to)-1);
+ if((pos = sscanf(skinfileptr, format, sf->name, sf->to)) == 2)
+ continue;
+
+ /* invalid input line -> discard sf struct */
+ Sys_Printf( "Discarding skin directive in %s: %s\n", skinfilename, skinfileptr );
+ free(sf);
+ sf = sf2;
+ }
+ free(skinfilecontent);
+ }
/* handle null matrix */
if( transform == NULL )
/* fix bogus lightmap scale */
if( lightmapScale <= 0.0f )
lightmapScale = 1.0f;
+
+ /* fix bogus shade angle */
+ if( shadeAngle <= 0.0f )
+ shadeAngle = 0.0f;
/* each surface on the model will become a new map drawsurface */
numSurfaces = PicoGetModelNumSurfaces( model );
if( PicoGetSurfaceType( surface ) != PICO_TRIANGLES )
continue;
- /* fix the surface's normals */
- PicoFixSurfaceNormals( surface );
-
- /* allocate a surface (ydnar: gs mods) */
- ds = AllocDrawSurface( SURFACE_TRIANGLES );
- ds->entityNum = eNum;
- ds->castShadows = castShadows;
- ds->recvShadows = recvShadows;
-
/* get shader name */
shader = PicoGetSurfaceShader( surface );
if( shader == NULL )
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 )
else
si = ShaderInfoForShader( picoShaderName );
+ /* allocate a surface (ydnar: gs mods) */
+ ds = AllocDrawSurface( SURFACE_TRIANGLES );
+ ds->entityNum = eNum;
+ ds->castShadows = castShadows;
+ ds->recvShadows = recvShadows;
+
/* set shader */
ds->shaderInfo = si;
-
- /* set lightmap scale */
- ds->lightmapScale = lightmapScale;
-
+
/* force to meta? */
if( (si != NULL && si->forceMeta) || (spawnFlags & 4) ) /* 3rd bit */
ds->type = SURFACE_FORCED_META;
+
+ /* fix the surface's normals (jal: conditioned by shader info) */
+ if( !(spawnFlags & 64) && ( shadeAngle == 0.0f || ds->type != SURFACE_FORCED_META ) )
+ PicoFixSurfaceNormals( surface );
+
+ /* set sample size */
+ if( lightmapSampleSize > 0.0f )
+ ds->sampleSize = lightmapSampleSize;
+
+ /* set lightmap scale */
+ if( lightmapScale > 0.0f )
+ ds->lightmapScale = lightmapScale;
+
+ /* set shading angle */
+ if( shadeAngle > 0.0f )
+ ds->shadeAngleDegrees = shadeAngle;
/* set particulars */
ds->numVerts = PicoGetSurfaceNumVertexes( surface );
{
dv->lightmap[ j ][ 0 ] = 0.0f;
dv->lightmap[ j ][ 1 ] = 0.0f;
- dv->color[ j ][ 0 ] = color[ 0 ];
- dv->color[ j ][ 1 ] = color[ 1 ];
- dv->color[ j ][ 2 ] = color[ 2 ];
- dv->color[ j ][ 3 ] = color[ 3 ];
+ if(spawnFlags & 32) // spawnflag 32: model color -> alpha hack
+ {
+ dv->color[ j ][ 0 ] = 255.0f;
+ dv->color[ j ][ 1 ] = 255.0f;
+ dv->color[ j ][ 2 ] = 255.0f;
+ dv->color[ j ][ 3 ] = RGBTOGRAY( color );
+ }
+ else
+ {
+ dv->color[ j ][ 0 ] = color[ 0 ];
+ dv->color[ j ][ 1 ] = color[ 1 ];
+ dv->color[ j ][ 2 ] = color[ 2 ];
+ dv->color[ j ][ 3 ] = color[ 3 ];
+ }
}
}
/* temp hack */
- if( !si->clipModel &&
- ((si->compileFlags & C_TRANSLUCENT) || !(si->compileFlags & C_SOLID)) )
+ if( !si->clipModel && !(si->compileFlags & C_SOLID) )
continue;
/* walk triangle list */
/* copy xyz */
VectorCopy( dv->xyz, points[ j ] );
- VectorCopy( dv->xyz, backs[ j ] );
-
- /* find nearest axial to normal and push back points opposite */
- /* note: this doesn't work as well as simply using the plane of the triangle, below */
- for( k = 0; k < 3; k++ )
- {
- if( fabs( dv->normal[ k ] ) >= fabs( dv->normal[ (k + 1) % 3 ] ) &&
- fabs( dv->normal[ k ] ) >= fabs( dv->normal[ (k + 2) % 3 ] ) )
- {
- backs[ j ][ k ] += dv->normal[ k ] < 0.0f ? 64.0f : -64.0f;
- break;
- }
- }
}
VectorCopy( points[0], points[3] ); // for cyclic usage
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;
char shader[ MAX_QPATH ];
shaderInfo_t *celShader;
float temp, baseLightmapScale, lightmapScale;
+ float shadeAngle;
+ int lightmapSampleSize;
vec3_t origin, scale, angles;
m4x4_t transform;
epair_t *ep;
}
/* get lightmap scale */
- baseLightmapScale = FloatForKey( e, "_lightmapscale" );
- if( baseLightmapScale <= 0.0f )
- baseLightmapScale = 0.0f;
+ /* vortex: added _ls key (short name of lightmapscale) */
+ baseLightmapScale = 0.0f;
+ if( strcmp( "", ValueForKey( e, "lightmapscale" ) ) ||
+ strcmp( "", ValueForKey( e, "_lightmapscale" ) ) ||
+ strcmp( "", ValueForKey( e, "_ls" ) ) )
+ {
+ baseLightmapScale = FloatForKey( e, "lightmapscale" );
+ if( baseLightmapScale <= 0.0f )
+ baseLightmapScale = FloatForKey( e, "_lightmapscale" );
+ if( baseLightmapScale <= 0.0f )
+ baseLightmapScale = FloatForKey( e, "_ls" );
+ if( baseLightmapScale < 0.0f )
+ baseLightmapScale = 0.0f;
+ if( baseLightmapScale > 0.0f )
+ Sys_Printf( "World Entity has lightmap scale of %.4f\n", baseLightmapScale );
+ }
+
/* walk the entity list */
for( num = 1; num < numEntities; num++ )
}
/* get model frame */
- frame = IntForKey( e2, "_frame" );
+ frame = 0;
+ if(strcmp("", ValueForKey( e2, "_frame")))
+ frame = IntForKey(e2, "_frame");
+ else if(strcmp("", ValueForKey( e2, "frame")))
+ frame = IntForKey(e2, "frame");
/* worldspawn (and func_groups) default to cast/recv shadows in worldspawn group */
if( e == entities )
}
else
celShader = *globalCelShader ? ShaderInfoForShader(globalCelShader) : NULL;
-
+
+ /* jal : entity based _samplesize */
+ lightmapSampleSize = 0;
+ if ( strcmp( "", ValueForKey( e2, "_lightmapsamplesize" ) ) )
+ lightmapSampleSize = IntForKey( e2, "_lightmapsamplesize" );
+ else if ( strcmp( "", ValueForKey( e2, "_samplesize" ) ) )
+ lightmapSampleSize = IntForKey( e2, "_samplesize" );
+
+ if( lightmapSampleSize < 0 )
+ lightmapSampleSize = 0;
+
+ if( lightmapSampleSize > 0.0f )
+ Sys_Printf( "misc_model has lightmap sample size of %.d\n", lightmapSampleSize );
+
/* get lightmap scale */
- lightmapScale = FloatForKey( e2, "_lightmapscale" );
- if( lightmapScale <= 0.0f )
- lightmapScale = baseLightmapScale;
-
+ /* vortex: added _ls key (short name of lightmapscale) */
+ lightmapScale = 0.0f;
+ if( strcmp( "", ValueForKey( e2, "lightmapscale" ) ) ||
+ strcmp( "", ValueForKey( e2, "_lightmapscale" ) ) ||
+ strcmp( "", ValueForKey( e2, "_ls" ) ) )
+ {
+ lightmapScale = FloatForKey( e2, "lightmapscale" );
+ if( lightmapScale <= 0.0f )
+ lightmapScale = FloatForKey( e2, "_lightmapscale" );
+ if( lightmapScale <= 0.0f )
+ lightmapScale = FloatForKey( e2, "_ls" );
+ if( lightmapScale < 0.0f )
+ lightmapScale = 0.0f;
+ if( lightmapScale > 0.0f )
+ Sys_Printf( "misc_model has lightmap scale of %.4f\n", lightmapScale );
+ }
+
+ /* jal : entity based _shadeangle */
+ shadeAngle = 0.0f;
+ if ( strcmp( "", ValueForKey( e2, "_shadeangle" ) ) )
+ shadeAngle = FloatForKey( e2, "_shadeangle" );
+ /* vortex' aliases */
+ 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 = 0;
+ if(strcmp("", ValueForKey( e2, "_skin")))
+ skin = IntForKey(e2, "_skin");
+ else if(strcmp("", ValueForKey( e2, "skin")))
+ skin = IntForKey(e2, "skin");
+
/* insert the model */
- InsertModel( (char*) model, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale );
+ InsertModel( model, skin, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle );
/* free shader remappings */
while( remap != NULL )