mirror of
https://github.com/TTimo/GtkRadiant.git
synced 2025-01-27 03:41:03 +00:00
1891 lines
55 KiB
Diff
1891 lines
55 KiB
Diff
Index: tools/quake3/q3map2/writebsp.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/writebsp.c (revision 158)
|
|
+++ tools/quake3/q3map2/writebsp.c (working copy)
|
|
@@ -136,7 +136,6 @@
|
|
bspLeaf_t *leaf_p;
|
|
brush_t *b;
|
|
drawSurfRef_t *dsr;
|
|
- int i = 0;
|
|
|
|
|
|
/* check limits */
|
|
Index: tools/quake3/q3map2/facebsp.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/facebsp.c (revision 158)
|
|
+++ tools/quake3/q3map2/facebsp.c (working copy)
|
|
@@ -180,7 +180,7 @@
|
|
|
|
|
|
c = 0;
|
|
- for( list; list != NULL; list = list->next )
|
|
+ for( ; list != NULL; list = list->next )
|
|
c++;
|
|
return c;
|
|
}
|
|
Index: tools/quake3/q3map2/light_ydnar.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/light_ydnar.c (revision 158)
|
|
+++ tools/quake3/q3map2/light_ydnar.c (working copy)
|
|
@@ -49,6 +49,7 @@
|
|
int i;
|
|
float max, gamma;
|
|
vec3_t sample;
|
|
+ float inv, dif;
|
|
|
|
|
|
/* ydnar: scaling necessary for simulating r_overbrightBits on external lightmaps */
|
|
@@ -72,16 +73,51 @@
|
|
/* gamma */
|
|
sample[ i ] = pow( sample[ i ] / 255.0f, gamma ) * 255.0f;
|
|
}
|
|
+
|
|
+ if (lightmapExposure == 1)
|
|
+ {
|
|
+ /* clamp with color normalization */
|
|
+ max = sample[ 0 ];
|
|
+ if( sample[ 1 ] > max )
|
|
+ max = sample[ 1 ];
|
|
+ if( sample[ 2 ] > max )
|
|
+ max = sample[ 2 ];
|
|
+ if( max > 255.0f )
|
|
+ VectorScale( sample, (255.0f / max), sample );
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ if (lightmapExposure==0)
|
|
+ {
|
|
+ lightmapExposure=1.0f;
|
|
+ }
|
|
+ inv=1.f/lightmapExposure;
|
|
+ //Exposure
|
|
+
|
|
+ max = sample[ 0 ];
|
|
+ if( sample[ 1 ] > max )
|
|
+ max = sample[ 1 ];
|
|
+ if( sample[ 2 ] > max )
|
|
+ max = sample[ 2 ];
|
|
+
|
|
+ dif = (1- exp(-max * inv) ) * 255;
|
|
+
|
|
+ if (max >0)
|
|
+ {
|
|
+ dif = dif / max;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ dif = 0;
|
|
+ }
|
|
+
|
|
+ for (i=0;i<3;i++)
|
|
+ {
|
|
+ sample[i]*=dif;
|
|
+ }
|
|
+ }
|
|
+
|
|
|
|
- /* clamp with color normalization */
|
|
- max = sample[ 0 ];
|
|
- if( sample[ 1 ] > max )
|
|
- max = sample[ 1 ];
|
|
- if( sample[ 2 ] > max )
|
|
- max = sample[ 2 ];
|
|
- if( max > 255.0f )
|
|
- VectorScale( sample, (255.0f / max), sample );
|
|
-
|
|
/* compensate for ingame overbrighting/bitshifting */
|
|
VectorScale( sample, (1.0f / lightmapCompensate), sample );
|
|
|
|
@@ -384,7 +420,7 @@
|
|
#define NUDGE 0.5f
|
|
#define BOGUS_NUDGE -99999.0f
|
|
|
|
-static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv, vec4_t plane, float pass, vec3_t stv[ 3 ], vec3_t ttv[ 3 ] )
|
|
+static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv, vec4_t plane, float pass, vec3_t stv[ 3 ], vec3_t ttv[ 3 ], vec3_t worldverts[ 3 ] )
|
|
{
|
|
int i, x, y, numClusters, *clusters, pointCluster, *cluster;
|
|
float *luxel, *origin, *normal, d, lightmapSampleOffset;
|
|
@@ -392,6 +428,12 @@
|
|
vec3_t pNormal;
|
|
vec3_t vecs[ 3 ];
|
|
vec3_t nudged;
|
|
+ vec3_t cverts[ 3 ];
|
|
+ vec3_t temp;
|
|
+ vec4_t sideplane, hostplane;
|
|
+ vec3_t origintwo;
|
|
+ int j, next;
|
|
+ float e;
|
|
float *nudge;
|
|
static float nudges[][ 2 ] =
|
|
{
|
|
@@ -485,6 +527,51 @@
|
|
/* non axial lightmap projection (explicit xyz) */
|
|
else
|
|
VectorCopy( dv->xyz, origin );
|
|
+
|
|
+ //////////////////////
|
|
+ //27's test to make sure samples stay within the triangle boundaries
|
|
+ //1) Test the sample origin to see if it lays on the wrong side of any edge (x/y)
|
|
+ //2) if it does, nudge it onto the correct side.
|
|
+
|
|
+ if (worldverts!=NULL)
|
|
+ {
|
|
+ for (j=0;j<3;j++)
|
|
+ {
|
|
+ VectorCopy(worldverts[j],cverts[j]);
|
|
+ }
|
|
+ PlaneFromPoints(hostplane,cverts[0],cverts[1],cverts[2]);
|
|
+
|
|
+ for (j=0;j<3;j++)
|
|
+ {
|
|
+ for (i=0;i<3;i++)
|
|
+ {
|
|
+ //build plane using 2 edges and a normal
|
|
+ next=(i+1)%3;
|
|
+
|
|
+ VectorCopy(cverts[next],temp);
|
|
+ VectorAdd(temp,hostplane,temp);
|
|
+ PlaneFromPoints(sideplane,cverts[i],cverts[ next ], temp);
|
|
+
|
|
+ //planetest sample point
|
|
+ e=DotProduct(origin,sideplane);
|
|
+ e=e-sideplane[3];
|
|
+ if (e>0)
|
|
+ {
|
|
+ //we're bad.
|
|
+ //VectorClear(origin);
|
|
+ //Move the sample point back inside triangle bounds
|
|
+ origin[0]-=sideplane[0]*(e+1);
|
|
+ origin[1]-=sideplane[1]*(e+1);
|
|
+ origin[2]-=sideplane[2]*(e+1);
|
|
+#ifdef DEBUG_27_1
|
|
+ VectorClear(origin);
|
|
+#endif
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ////////////////////////
|
|
|
|
/* planar surfaces have precalculated lightmap vectors for nudging */
|
|
if( lm->plane != NULL )
|
|
@@ -516,8 +603,13 @@
|
|
else
|
|
origin[ lm->axisNum ] += lightmapSampleOffset;
|
|
|
|
+ VectorCopy(origin,origintwo);
|
|
+ origintwo[0]+=vecs[2][0];
|
|
+ origintwo[1]+=vecs[2][1];
|
|
+ origintwo[2]+=vecs[2][2];
|
|
+
|
|
/* get cluster */
|
|
- pointCluster = ClusterForPointExtFilter( origin, LUXEL_EPSILON, numClusters, clusters );
|
|
+ pointCluster = ClusterForPointExtFilter( origintwo, LUXEL_EPSILON, numClusters, clusters );
|
|
|
|
/* another retarded hack, storing nudge count in luxel[ 1 ] */
|
|
luxel[ 1 ] = 0.0f;
|
|
@@ -533,14 +625,14 @@
|
|
for( i = 0; i < 3; i++ )
|
|
{
|
|
/* set nudged point*/
|
|
- nudged[ i ] = origin[ i ] + (nudge[ 0 ] * vecs[ 0 ][ i ]) + (nudge[ 1 ] * vecs[ 1 ][ i ]);
|
|
+ nudged[ i ] = origintwo[ i ] + (nudge[ 0 ] * vecs[ 0 ][ i ]) + (nudge[ 1 ] * vecs[ 1 ][ i ]);
|
|
}
|
|
nudge += 2;
|
|
|
|
/* get pvs cluster */
|
|
pointCluster = ClusterForPointExtFilter( nudged, LUXEL_EPSILON, numClusters, clusters ); //% + 0.625 );
|
|
- if( pointCluster >= 0 )
|
|
- VectorCopy( nudged, origin );
|
|
+ //if( pointCluster >= 0 )
|
|
+ // VectorCopy( nudged, origin );
|
|
luxel[ 1 ] += 1.0f;
|
|
}
|
|
}
|
|
@@ -550,8 +642,8 @@
|
|
{
|
|
VectorMA( dv->xyz, lightmapSampleOffset, dv->normal, nudged );
|
|
pointCluster = ClusterForPointExtFilter( nudged, LUXEL_EPSILON, numClusters, clusters );
|
|
- if( pointCluster >= 0 )
|
|
- VectorCopy( nudged, origin );
|
|
+ //if( pointCluster >= 0 )
|
|
+ // VectorCopy( nudged, origin );
|
|
luxel[ 1 ] += 1.0f;
|
|
}
|
|
|
|
@@ -597,7 +689,7 @@
|
|
than the distance between two luxels (thanks jc :)
|
|
*/
|
|
|
|
-static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 3 ], vec4_t plane, vec3_t stv[ 3 ], vec3_t ttv[ 3 ] )
|
|
+static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv[ 3 ], vec4_t plane, vec3_t stv[ 3 ], vec3_t ttv[ 3 ], vec3_t worldverts[ 3 ] )
|
|
{
|
|
bspDrawVert_t mid, *dv2[ 3 ];
|
|
int max;
|
|
@@ -645,7 +737,7 @@
|
|
|
|
/* split the longest edge and map it */
|
|
LerpDrawVert( dv[ max ], dv[ (max + 1) % 3 ], &mid );
|
|
- MapSingleLuxel( lm, info, &mid, plane, 1, stv, ttv );
|
|
+ MapSingleLuxel( lm, info, &mid, plane, 1, stv, ttv, worldverts );
|
|
|
|
/* push the point up a little bit to account for fp creep (fixme: revisit this) */
|
|
//% VectorMA( mid.xyz, 2.0f, mid.normal, mid.xyz );
|
|
@@ -653,12 +745,12 @@
|
|
/* recurse to first triangle */
|
|
VectorCopy( dv, dv2 );
|
|
dv2[ max ] = ∣
|
|
- MapTriangle_r( lm, info, dv2, plane, stv, ttv );
|
|
+ MapTriangle_r( lm, info, dv2, plane, stv, ttv, worldverts );
|
|
|
|
/* recurse to second triangle */
|
|
VectorCopy( dv, dv2 );
|
|
dv2[ (max + 1) % 3 ] = ∣
|
|
- MapTriangle_r( lm, info, dv2, plane, stv, ttv );
|
|
+ MapTriangle_r( lm, info, dv2, plane, stv, ttv, worldverts );
|
|
}
|
|
|
|
|
|
@@ -674,6 +766,7 @@
|
|
int i;
|
|
vec4_t plane;
|
|
vec3_t *stv, *ttv, stvStatic[ 3 ], ttvStatic[ 3 ];
|
|
+ vec3_t worldverts[ 3 ];
|
|
|
|
|
|
/* get plane if possible */
|
|
@@ -699,16 +792,20 @@
|
|
ttv = NULL;
|
|
}
|
|
|
|
+ VectorCopy( dv[ 0 ]->xyz, worldverts[ 0 ] );
|
|
+ VectorCopy( dv[ 1 ]->xyz, worldverts[ 1 ] );
|
|
+ VectorCopy( dv[ 2 ]->xyz, worldverts[ 2 ] );
|
|
+
|
|
/* map the vertexes */
|
|
- MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv );
|
|
- MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv );
|
|
- MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv );
|
|
+ MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv, worldverts );
|
|
+ MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv, worldverts );
|
|
+ MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv, worldverts );
|
|
|
|
/* 2002-11-20: prefer axial triangle edges */
|
|
if( mapNonAxial )
|
|
{
|
|
/* subdivide the triangle */
|
|
- MapTriangle_r( lm, info, dv, plane, stv, ttv );
|
|
+ MapTriangle_r( lm, info, dv, plane, stv, ttv, worldverts );
|
|
return qtrue;
|
|
}
|
|
|
|
@@ -730,7 +827,7 @@
|
|
dv2[ 2 ] = dv[ (i + 1) % 3 ];
|
|
|
|
/* map the degenerate triangle */
|
|
- MapTriangle_r( lm, info, dv2, plane, stv, ttv );
|
|
+ MapTriangle_r( lm, info, dv2, plane, stv, ttv, worldverts );
|
|
}
|
|
}
|
|
|
|
@@ -792,8 +889,8 @@
|
|
LerpDrawVert( dv[ max + 2 ], dv[ (max + 3) % 4 ], &mid[ 1 ] );
|
|
|
|
/* map the vertexes */
|
|
- MapSingleLuxel( lm, info, &mid[ 0 ], plane, 1, stv, ttv );
|
|
- MapSingleLuxel( lm, info, &mid[ 1 ], plane, 1, stv, ttv );
|
|
+ MapSingleLuxel( lm, info, &mid[ 0 ], plane, 1, stv, ttv, NULL );
|
|
+ MapSingleLuxel( lm, info, &mid[ 1 ], plane, 1, stv, ttv, NULL );
|
|
|
|
/* 0 and 2 */
|
|
if( max == 0 )
|
|
@@ -878,10 +975,10 @@
|
|
}
|
|
|
|
/* map the vertexes */
|
|
- MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv );
|
|
- MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv );
|
|
- MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv );
|
|
- MapSingleLuxel( lm, info, dv[ 3 ], plane, 1, stv, ttv );
|
|
+ MapSingleLuxel( lm, info, dv[ 0 ], plane, 1, stv, ttv, NULL );
|
|
+ MapSingleLuxel( lm, info, dv[ 1 ], plane, 1, stv, ttv, NULL );
|
|
+ MapSingleLuxel( lm, info, dv[ 2 ], plane, 1, stv, ttv, NULL );
|
|
+ MapSingleLuxel( lm, info, dv[ 3 ], plane, 1, stv, ttv, NULL );
|
|
|
|
/* subdivide the quad */
|
|
MapQuad_r( lm, info, dv, plane, stv, ttv );
|
|
@@ -1173,7 +1270,7 @@
|
|
continue;
|
|
|
|
/* map the fake vert */
|
|
- MapSingleLuxel( lm, NULL, &fake, lm->plane, pass, NULL, NULL );
|
|
+ MapSingleLuxel( lm, NULL, &fake, lm->plane, pass, NULL, NULL, NULL );
|
|
}
|
|
}
|
|
}
|
|
@@ -1767,6 +1864,8 @@
|
|
float tests[ 4 ][ 2 ] = { { 0.0f, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } };
|
|
trace_t trace;
|
|
float stackLightLuxels[ STACK_LL_SIZE ];
|
|
+ vec3_t flood;
|
|
+ float *floodlight;
|
|
|
|
|
|
/* bail if this number exceeds the number of raw lightmaps */
|
|
@@ -1963,22 +2062,32 @@
|
|
deluxel = SUPER_DELUXEL( x, y );
|
|
origin = SUPER_ORIGIN( x, y );
|
|
normal = SUPER_NORMAL( x, y );
|
|
-
|
|
- /* set contribution count */
|
|
- lightLuxel[ 3 ] = 1.0f;
|
|
-
|
|
- /* setup trace */
|
|
- trace.cluster = *cluster;
|
|
- VectorCopy( origin, trace.origin );
|
|
- VectorCopy( normal, trace.normal );
|
|
-
|
|
- /* get light for this sample */
|
|
- LightContributionToSample( &trace );
|
|
- VectorCopy( trace.color, lightLuxel );
|
|
-
|
|
- /* add to count */
|
|
- if( trace.color[ 0 ] || trace.color[ 1 ] || trace.color[ 2 ] )
|
|
+
|
|
+ ////////// 27's temp hack for testing edge clipping ////
|
|
+ if( origin[0]==0 && origin[1]==0 && origin[2]==0 )
|
|
+ {
|
|
+ lightLuxel[ 1 ] = 255;
|
|
+ lightLuxel[ 3 ] = 1.0f;
|
|
totalLighted++;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* set contribution count */
|
|
+ lightLuxel[ 3 ] = 1.0f;
|
|
+
|
|
+ /* setup trace */
|
|
+ trace.cluster = *cluster;
|
|
+ VectorCopy( origin, trace.origin );
|
|
+ VectorCopy( normal, trace.normal );
|
|
+
|
|
+ /* get light for this sample */
|
|
+ LightContributionToSample( &trace );
|
|
+ VectorCopy( trace.color, lightLuxel );
|
|
+
|
|
+ /* add to count */
|
|
+ if( trace.color[ 0 ] || trace.color[ 1 ] || trace.color[ 2 ] )
|
|
+ totalLighted++;
|
|
+ }
|
|
|
|
/* add to light direction map (fixme: use luxel normal as starting point for deluxel?) */
|
|
if( deluxemap )
|
|
@@ -2223,6 +2332,78 @@
|
|
FreeTraceLights( &trace );
|
|
|
|
/* -----------------------------------------------------------------
|
|
+ floodlight pass
|
|
+ ----------------------------------------------------------------- */
|
|
+
|
|
+ if( floodlighty )
|
|
+ {
|
|
+ /* walk lightmaps */
|
|
+ for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
|
|
+ {
|
|
+ /* early out */
|
|
+ if( lm->superLuxels[ lightmapNum ] == NULL )
|
|
+ continue;
|
|
+
|
|
+ /* apply floodlight to each luxel */
|
|
+ for( y = 0; y < lm->sh; y++ )
|
|
+ {
|
|
+ for( x = 0; x < lm->sw; x++ )
|
|
+ {
|
|
+ /* get cluster */
|
|
+ cluster = SUPER_CLUSTER( x, y );
|
|
+ //% if( *cluster < 0 )
|
|
+ //% continue;
|
|
+
|
|
+ /* get particulars */
|
|
+ luxel = SUPER_LUXEL( lightmapNum, x, y );
|
|
+ floodlight = SUPER_FLOODLIGHT( x, y );
|
|
+
|
|
+ flood[0]=floodlightRGB[0]*floodlightIntensity;
|
|
+ flood[1]=floodlightRGB[1]*floodlightIntensity;
|
|
+ flood[2]=floodlightRGB[2]*floodlightIntensity;
|
|
+
|
|
+ /* scale light value */
|
|
+ VectorScale( flood, *floodlight, flood );
|
|
+ luxel[0]+=flood[0];
|
|
+ luxel[1]+=flood[1];
|
|
+ luxel[2]+=flood[2];
|
|
+
|
|
+ if (luxel[3]==0) luxel[3]=1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (debugnormals)
|
|
+ {
|
|
+ for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
|
|
+ {
|
|
+ /* early out */
|
|
+ if( lm->superLuxels[ lightmapNum ] == NULL )
|
|
+ continue;
|
|
+
|
|
+ for( y = 0; y < lm->sh; y++ )
|
|
+ {
|
|
+ for( x = 0; x < lm->sw; x++ )
|
|
+ {
|
|
+ /* get cluster */
|
|
+ cluster = SUPER_CLUSTER( x, y );
|
|
+ //% if( *cluster < 0 )
|
|
+ //% continue;
|
|
+
|
|
+ /* get particulars */
|
|
+ luxel = SUPER_LUXEL( lightmapNum, x, y );
|
|
+ normal = SUPER_NORMAL ( x, y );
|
|
+
|
|
+ luxel[0]=(normal[0]*127)+127;
|
|
+ luxel[1]=(normal[1]*127)+127;
|
|
+ luxel[2]=(normal[2]*127)+127;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* -----------------------------------------------------------------
|
|
dirt pass
|
|
----------------------------------------------------------------- */
|
|
|
|
@@ -3112,7 +3293,7 @@
|
|
int i, x, y, z, x1, y1, z1;
|
|
light_t *light, *light2, **owner;
|
|
bspLeaf_t *leaf;
|
|
- vec3_t origin, dir, mins, maxs, nullVector = { 0, 0, 0 };
|
|
+ vec3_t origin, dir, mins, maxs;
|
|
float radius, intensity;
|
|
light_t *buckets[ 256 ];
|
|
|
|
@@ -3587,7 +3768,320 @@
|
|
CreateTraceLightsForBounds( mins, maxs, normal, info->numSurfaceClusters, &surfaceClusters[ info->firstSurfaceCluster ], LIGHT_SURFACES, trace );
|
|
}
|
|
|
|
+/////////////////////////////////////////////////////////////
|
|
|
|
+#define FLOODLIGHT_CONE_ANGLE 88 /* degrees */
|
|
+#define FLOODLIGHT_NUM_ANGLE_STEPS 16
|
|
+#define FLOODLIGHT_NUM_ELEVATION_STEPS 4
|
|
+#define FLOODLIGHT_NUM_VECTORS (FLOODLIGHT_NUM_ANGLE_STEPS * FLOODLIGHT_NUM_ELEVATION_STEPS)
|
|
|
|
+static vec3_t floodVectors[ FLOODLIGHT_NUM_VECTORS ];
|
|
+static int numFloodVectors = 0;
|
|
|
|
+void SetupFloodLight( void )
|
|
+{
|
|
+ int i, j;
|
|
+ float angle, elevation, angleStep, elevationStep;
|
|
+ const char *value;
|
|
+ double v1,v2,v3,v4,v5;
|
|
+
|
|
+ /* note it */
|
|
+ Sys_FPrintf( SYS_VRB, "--- SetupFloodLight ---\n" );
|
|
+
|
|
+ /* calculate angular steps */
|
|
+ angleStep = DEG2RAD( 360.0f / FLOODLIGHT_NUM_ANGLE_STEPS );
|
|
+ elevationStep = DEG2RAD( FLOODLIGHT_CONE_ANGLE / FLOODLIGHT_NUM_ELEVATION_STEPS );
|
|
+
|
|
+ /* iterate angle */
|
|
+ angle = 0.0f;
|
|
+ for( i = 0, angle = 0.0f; i < FLOODLIGHT_NUM_ANGLE_STEPS; i++, angle += angleStep )
|
|
+ {
|
|
+ /* iterate elevation */
|
|
+ for( j = 0, elevation = elevationStep * 0.5f; j < FLOODLIGHT_NUM_ELEVATION_STEPS; j++, elevation += elevationStep )
|
|
+ {
|
|
+ floodVectors[ numFloodVectors ][ 0 ] = sin( elevation ) * cos( angle );
|
|
+ floodVectors[ numFloodVectors ][ 1 ] = sin( elevation ) * sin( angle );
|
|
+ floodVectors[ numFloodVectors ][ 2 ] = cos( elevation );
|
|
+ numFloodVectors++;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* emit some statistics */
|
|
+ Sys_FPrintf( SYS_VRB, "%9d numFloodVectors\n", numFloodVectors );
|
|
|
|
+ /* floodlight */
|
|
+ value = ValueForKey( &entities[ 0 ], "_floodlight" );
|
|
+
|
|
+ if( value[ 0 ] != '\0' )
|
|
+ {
|
|
+ v1=v2=v3=0;
|
|
+ v4=floodlightDistance;
|
|
+ v5=floodlightIntensity;
|
|
+
|
|
+ sscanf( value, "%lf %lf %lf %lf %lf", &v1, &v2, &v3, &v4, &v5);
|
|
+
|
|
+ floodlightRGB[0]=v1;
|
|
+ floodlightRGB[1]=v2;
|
|
+ floodlightRGB[2]=v3;
|
|
+
|
|
+ if (VectorLength(floodlightRGB)==0)
|
|
+ {
|
|
+ VectorSet(floodlightRGB,240,240,255);
|
|
+ }
|
|
+
|
|
+ if (v4<1) v4=1024;
|
|
+ if (v5<1) v5=128;
|
|
+
|
|
+ floodlightDistance=v4;
|
|
+ floodlightIntensity=v5;
|
|
+
|
|
+ floodlighty = qtrue;
|
|
+ Sys_Printf( "FloodLighting enabled via worldspawn _floodlight key.\n" );
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ VectorSet(floodlightRGB,240,240,255);
|
|
+ //floodlighty = qtrue;
|
|
+ //Sys_Printf( "FloodLighting enabled via worldspawn _floodlight key.\n" );
|
|
+ }
|
|
+ VectorNormalize(floodlightRGB,floodlightRGB);
|
|
+}
|
|
+
|
|
+//27 - lighttracer style ambient occlusion light hack.
|
|
+//Kudos to the dirtmapping author for most of this source.
|
|
+void FloodLightRawLightmap( int rawLightmapNum )
|
|
+{
|
|
+ int i, x, y, sx, sy, *cluster;
|
|
+ float *origin, *normal, *floodlight, *floodlight2, average, samples;
|
|
+ rawLightmap_t *lm;
|
|
+ surfaceInfo_t *info;
|
|
+ trace_t trace;
|
|
+
|
|
+ /* bail if this number exceeds the number of raw lightmaps */
|
|
+ if( rawLightmapNum >= numRawLightmaps )
|
|
+ return;
|
|
+
|
|
+ /* get lightmap */
|
|
+ lm = &rawLightmaps[ rawLightmapNum ];
|
|
+
|
|
+ memset(&trace,0,sizeof(trace_t));
|
|
+ /* setup trace */
|
|
+ trace.testOcclusion = qtrue;
|
|
+ trace.forceSunlight = qfalse;
|
|
+ trace.twoSided = qtrue;
|
|
+ trace.recvShadows = lm->recvShadows;
|
|
+ trace.numSurfaces = lm->numLightSurfaces;
|
|
+ trace.surfaces = &lightSurfaces[ lm->firstLightSurface ];
|
|
+ trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS;
|
|
+ trace.testAll = qfalse;
|
|
+ trace.distance = 1024;
|
|
+
|
|
+ /* twosided lighting (may or may not be a good idea for lightmapped stuff) */
|
|
+ //trace.twoSided = qfalse;
|
|
+ for( i = 0; i < trace.numSurfaces; i++ )
|
|
+ {
|
|
+ /* get surface */
|
|
+ info = &surfaceInfos[ trace.surfaces[ i ] ];
|
|
+
|
|
+ /* check twosidedness */
|
|
+ if( info->si->twoSided )
|
|
+ {
|
|
+ trace.twoSided = qtrue;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* gather dirt */
|
|
+ for( y = 0; y < lm->sh; y++ )
|
|
+ {
|
|
+ for( x = 0; x < lm->sw; x++ )
|
|
+ {
|
|
+ /* get luxel */
|
|
+ cluster = SUPER_CLUSTER( x, y );
|
|
+ origin = SUPER_ORIGIN( x, y );
|
|
+ normal = SUPER_NORMAL( x, y );
|
|
+ floodlight = SUPER_FLOODLIGHT( x, y );
|
|
+
|
|
+ /* set default dirt */
|
|
+ *floodlight = 0.0f;
|
|
+
|
|
+ /* only look at mapped luxels */
|
|
+ if( *cluster < 0 )
|
|
+ continue;
|
|
+
|
|
+ /* copy to trace */
|
|
+ trace.cluster = *cluster;
|
|
+ VectorCopy( origin, trace.origin );
|
|
+ VectorCopy( normal, trace.normal );
|
|
+
|
|
+
|
|
+
|
|
+ /* get dirt */
|
|
+ *floodlight = FloodLightForSample( &trace );
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* testing no filtering */
|
|
+ return;
|
|
+
|
|
+ /* filter "dirt" */
|
|
+ for( y = 0; y < lm->sh; y++ )
|
|
+ {
|
|
+ for( x = 0; x < lm->sw; x++ )
|
|
+ {
|
|
+ /* get luxel */
|
|
+ cluster = SUPER_CLUSTER( x, y );
|
|
+ floodlight = SUPER_FLOODLIGHT( x, y );
|
|
+
|
|
+ /* filter dirt by adjacency to unmapped luxels */
|
|
+ average = *floodlight;
|
|
+ samples = 1.0f;
|
|
+ for( sy = (y - 1); sy <= (y + 1); sy++ )
|
|
+ {
|
|
+ if( sy < 0 || sy >= lm->sh )
|
|
+ continue;
|
|
+
|
|
+ for( sx = (x - 1); sx <= (x + 1); sx++ )
|
|
+ {
|
|
+ if( sx < 0 || sx >= lm->sw || (sx == x && sy == y) )
|
|
+ continue;
|
|
+
|
|
+ /* get neighboring luxel */
|
|
+ cluster = SUPER_CLUSTER( sx, sy );
|
|
+ floodlight2 = SUPER_FLOODLIGHT( sx, sy );
|
|
+ if( *cluster < 0 || *floodlight2 <= 0.0f )
|
|
+ continue;
|
|
+
|
|
+ /* add it */
|
|
+ average += *floodlight2;
|
|
+ samples += 1.0f;
|
|
+ }
|
|
+
|
|
+ /* bail */
|
|
+ if( samples <= 0.0f )
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* bail */
|
|
+ if( samples <= 0.0f )
|
|
+ continue;
|
|
+
|
|
+ /* scale dirt */
|
|
+ *floodlight = average / samples;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+FloodLightForSample()
|
|
+calculates floodlight value for a given sample
|
|
+once again, kudos to the dirtmapping coder
|
|
+*/
|
|
+float FloodLightForSample( trace_t *trace )
|
|
+{
|
|
+ int i;
|
|
+ float d;
|
|
+ float contribution;
|
|
+ int sub = 0;
|
|
+ float gatherLight, outLight;
|
|
+ vec3_t normal, worldUp, myUp, myRt, direction, displacement;
|
|
+ float dd;
|
|
+ int vecs = 0;
|
|
+
|
|
+ gatherLight=0;
|
|
+ /* dummy check */
|
|
+ //if( !dirty )
|
|
+ // return 1.0f;
|
|
+ if( trace == NULL || trace->cluster < 0 )
|
|
+ return 0.0f;
|
|
+
|
|
+
|
|
+ /* setup */
|
|
+ dd = floodlightDistance;
|
|
+ VectorCopy( trace->normal, normal );
|
|
+
|
|
+ /* check if the normal is aligned to the world-up */
|
|
+ if( normal[ 0 ] == 0.0f && normal[ 1 ] == 0.0f )
|
|
+ {
|
|
+ if( normal[ 2 ] == 1.0f )
|
|
+ {
|
|
+ VectorSet( myRt, 1.0f, 0.0f, 0.0f );
|
|
+ VectorSet( myUp, 0.0f, 1.0f, 0.0f );
|
|
+ }
|
|
+ else if( normal[ 2 ] == -1.0f )
|
|
+ {
|
|
+ VectorSet( myRt, -1.0f, 0.0f, 0.0f );
|
|
+ VectorSet( myUp, 0.0f, 1.0f, 0.0f );
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ VectorSet( worldUp, 0.0f, 0.0f, 1.0f );
|
|
+ CrossProduct( normal, worldUp, myRt );
|
|
+ VectorNormalize( myRt, myRt );
|
|
+ CrossProduct( myRt, normal, myUp );
|
|
+ VectorNormalize( myUp, myUp );
|
|
+ }
|
|
+
|
|
+ /* iterate through ordered vectors */
|
|
+ for( i = 0; i < numFloodVectors; i++ )
|
|
+ {
|
|
+ if (floodlight_lowquality==qtrue)
|
|
+ {
|
|
+ if (rand()%10 != 0 ) continue;
|
|
+ }
|
|
+
|
|
+ vecs++;
|
|
+
|
|
+ /* transform vector into tangent space */
|
|
+ direction[ 0 ] = myRt[ 0 ] * floodVectors[ i ][ 0 ] + myUp[ 0 ] * floodVectors[ i ][ 1 ] + normal[ 0 ] * floodVectors[ i ][ 2 ];
|
|
+ direction[ 1 ] = myRt[ 1 ] * floodVectors[ i ][ 0 ] + myUp[ 1 ] * floodVectors[ i ][ 1 ] + normal[ 1 ] * floodVectors[ i ][ 2 ];
|
|
+ direction[ 2 ] = myRt[ 2 ] * floodVectors[ i ][ 0 ] + myUp[ 2 ] * floodVectors[ i ][ 1 ] + normal[ 2 ] * floodVectors[ i ][ 2 ];
|
|
+
|
|
+ /* set endpoint */
|
|
+ VectorMA( trace->origin, dd, direction, trace->end );
|
|
+
|
|
+ //VectorMA( trace->origin, 1, direction, trace->origin );
|
|
+
|
|
+ SetupTrace( trace );
|
|
+ /* trace */
|
|
+ TraceLine( trace );
|
|
+ contribution=1;
|
|
+
|
|
+ if (trace->compileFlags & C_SKY )
|
|
+ {
|
|
+ contribution=1.0f;
|
|
+ }
|
|
+ else if ( trace->opaque )
|
|
+ {
|
|
+ VectorSubtract( trace->hit, trace->origin, displacement );
|
|
+ d=VectorLength( displacement );
|
|
+
|
|
+ // d=trace->distance;
|
|
+ //if (d>256) gatherDirt+=1;
|
|
+ contribution=d/dd;
|
|
+ if (contribution>1) contribution=1.0f;
|
|
+
|
|
+ //gatherDirt += 1.0f - ooDepth * VectorLength( displacement );
|
|
+ }
|
|
+
|
|
+ gatherLight+=contribution;
|
|
+ }
|
|
+
|
|
+ /* early out */
|
|
+ if( gatherLight <= 0.0f )
|
|
+ return 0.0f;
|
|
+
|
|
+ sub=vecs;
|
|
+
|
|
+ if (sub<1) sub=1;
|
|
+ gatherLight/=(sub);
|
|
+
|
|
+ outLight=gatherLight;
|
|
+ if( outLight > 1.0f )
|
|
+ outLight = 1.0f;
|
|
+
|
|
+ /* return to sender */
|
|
+ return outLight;
|
|
+}
|
|
+
|
|
Index: tools/quake3/q3map2/light.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/light.c (revision 158)
|
|
+++ tools/quake3/q3map2/light.c (working copy)
|
|
@@ -1378,6 +1378,56 @@
|
|
break;
|
|
}
|
|
|
|
+ /////// Floodlighting for point //////////////////
|
|
+ //do our floodlight ambient occlusion loop, and add a single contribution based on the brightest dir
|
|
+ if (floodlighty)
|
|
+ {
|
|
+ int q;
|
|
+ float addSize,f;
|
|
+ vec3_t col,dir;
|
|
+ col[0]=col[1]=col[2]=floodlightIntensity;
|
|
+ dir[0]=dir[1]=0;
|
|
+ dir[2]=1;
|
|
+
|
|
+ trace.testOcclusion = qtrue;
|
|
+ trace.forceSunlight = qfalse;
|
|
+ trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS;
|
|
+ trace.testAll = qtrue;
|
|
+
|
|
+ for (q=0;q<2;q++)
|
|
+ {
|
|
+ if (q==0) //upper hemisphere
|
|
+ {
|
|
+ trace.normal[0]=0;
|
|
+ trace.normal[1]=0;
|
|
+ trace.normal[2]=1;
|
|
+ }
|
|
+ else //lower hemisphere
|
|
+ {
|
|
+ trace.normal[0]=0;
|
|
+ trace.normal[1]=0;
|
|
+ trace.normal[2]=-1;
|
|
+ }
|
|
+
|
|
+ f = FloodLightForSample(&trace);
|
|
+
|
|
+ contributions[ numCon ].color[0]=col[0]*f;
|
|
+ contributions[ numCon ].color[1]=col[1]*f;
|
|
+ contributions[ numCon ].color[2]=col[2]*f;
|
|
+
|
|
+ contributions[ numCon ].dir[0]=dir[0];
|
|
+ contributions[ numCon ].dir[1]=dir[1];
|
|
+ contributions[ numCon ].dir[2]=dir[2];
|
|
+
|
|
+ contributions[ numCon ].style = 0;
|
|
+ numCon++;
|
|
+ /* push average direction around */
|
|
+ addSize = VectorLength( col );
|
|
+ VectorMA( gp->dir, addSize, dir, gp->dir );
|
|
+ }
|
|
+ }
|
|
+ /////////////////////
|
|
+
|
|
/* normalize to get primary light direction */
|
|
VectorNormalize( gp->dir, gp->dir );
|
|
|
|
@@ -1420,6 +1470,9 @@
|
|
|
|
/* ambient light will be at 1/4 the value of directed light */
|
|
/* (ydnar: nuke this in favor of more dramatic lighting?) */
|
|
+ /* (PM: how about actually making it work? d=1 when it got here for single lights/sun :P */
|
|
+// d = 0.25f;
|
|
+ /* (Hobbes: always setting it to .25 is hardly any better) */
|
|
d = 0.25f * (1.0f - d);
|
|
VectorMA( gp->ambient[ j ], d, contributions[ i ].color, gp->ambient[ j ] );
|
|
}
|
|
@@ -1661,6 +1714,12 @@
|
|
RunThreadsOnIndividual( numRawLightmaps, qtrue, DirtyRawLightmap );
|
|
}
|
|
|
|
+ /* floodlight them up */
|
|
+ if( floodlighty )
|
|
+ {
|
|
+ Sys_Printf( "--- FloodlightRawLightmap ---\n" );
|
|
+ RunThreadsOnIndividual( numRawLightmaps, qtrue, FloodLightRawLightmap );
|
|
+ }
|
|
|
|
/* ydnar: set up light envelopes */
|
|
SetupEnvelopes( qfalse, fast );
|
|
@@ -1836,6 +1895,14 @@
|
|
i++;
|
|
}
|
|
|
|
+ else if( !strcmp( argv[ i ], "-exposure" ) )
|
|
+ {
|
|
+ f = atof( argv[ i + 1 ] );
|
|
+ lightmapExposure = f;
|
|
+ Sys_Printf( "Lighting exposure set to %f\n", lightmapExposure );
|
|
+ i++;
|
|
+ }
|
|
+
|
|
else if( !strcmp( argv[ i ], "-compensate" ) )
|
|
{
|
|
f = atof( argv[ i + 1 ] );
|
|
@@ -2191,6 +2258,21 @@
|
|
cpmaHack = qtrue;
|
|
Sys_Printf( "Enabling Challenge Pro Mode Asstacular Vertex Lighting Mode (tm)\n" );
|
|
}
|
|
+ else if( !strcmp( argv[ i ], "-floodlight" ) )
|
|
+ {
|
|
+ floodlighty = qtrue;
|
|
+ Sys_Printf( "FloodLighting enabled\n" );
|
|
+ }
|
|
+ else if( !strcmp( argv[ i ], "-debugnormals" ) )
|
|
+ {
|
|
+ debugnormals = qtrue;
|
|
+ Sys_Printf( "DebugNormals enabled\n" );
|
|
+ }
|
|
+ else if( !strcmp( argv[ i ], "-lowquality" ) )
|
|
+ {
|
|
+ floodlight_lowquality = qtrue;
|
|
+ Sys_Printf( "Low Quality FloodLighting enabled\n" );
|
|
+ }
|
|
|
|
/* r7: dirtmapping */
|
|
else if( !strcmp( argv[ i ], "-dirty" ) )
|
|
@@ -2279,6 +2361,7 @@
|
|
/* ydnar: set up optimization */
|
|
SetupBrushes();
|
|
SetupDirt();
|
|
+ SetupFloodLight();
|
|
SetupSurfaceLightmaps();
|
|
|
|
/* initialize the surface facet tracing */
|
|
Index: tools/quake3/q3map2/game_etut.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_etut.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_etut.h (working copy)
|
|
@@ -148,6 +148,7 @@
|
|
qfalse, /* wolf lighting model? */
|
|
128, /* lightmap width/height */
|
|
2.2f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"IBSP", /* bsp file prefix */
|
|
47, /* bsp file version */
|
|
Index: tools/quake3/q3map2/brush.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/brush.c (revision 158)
|
|
+++ tools/quake3/q3map2/brush.c (working copy)
|
|
@@ -78,7 +78,7 @@
|
|
|
|
|
|
/* count brushes */
|
|
- for( brushes; brushes != NULL; brushes = brushes->next )
|
|
+ for( ; brushes != NULL; brushes = brushes->next )
|
|
c++;
|
|
return c;
|
|
}
|
|
@@ -122,7 +122,7 @@
|
|
|
|
|
|
/* error check */
|
|
- if( *((int*) b) == 0xFEFEFEFE )
|
|
+ if( *((unsigned int*) b) == 0xFEFEFEFE )
|
|
{
|
|
Sys_FPrintf( SYS_VRB, "WARNING: Attempt to free an already freed brush!\n" );
|
|
return;
|
|
@@ -135,7 +135,7 @@
|
|
|
|
/* ydnar: overwrite it */
|
|
memset( b, 0xFE, (int) &(((brush_t*) 0)->sides[ b->numsides ]) );
|
|
- *((int*) b) = 0xFEFEFEFE;
|
|
+ *((unsigned int*) b) = 0xFEFEFEFE;
|
|
|
|
/* free it */
|
|
free( b );
|
|
@@ -156,7 +156,7 @@
|
|
|
|
|
|
/* walk brush list */
|
|
- for( brushes; brushes != NULL; brushes = next )
|
|
+ for( ; brushes != NULL; brushes = next )
|
|
{
|
|
next = brushes->next;
|
|
FreeBrush( brushes );
|
|
Index: tools/quake3/q3map2/game_jk2.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_jk2.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_jk2.h (working copy)
|
|
@@ -64,6 +64,7 @@
|
|
qfalse, /* wolf lighting model? */
|
|
128, /* lightmap width/height */
|
|
1.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"RBSP", /* bsp file prefix */
|
|
1, /* bsp file version */
|
|
Index: tools/quake3/q3map2/lightmaps_ydnar.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/lightmaps_ydnar.c (revision 158)
|
|
+++ tools/quake3/q3map2/lightmaps_ydnar.c (working copy)
|
|
@@ -414,6 +414,12 @@
|
|
lm->superNormals = safe_malloc( size );
|
|
memset( lm->superNormals, 0, size );
|
|
|
|
+ /* allocate floodlight map storage */
|
|
+ size = lm->sw * lm->sh * SUPER_FLOODLIGHT_SIZE * sizeof( float );
|
|
+ if( lm->superFloodLight == NULL )
|
|
+ lm->superFloodLight = safe_malloc( size );
|
|
+ memset( lm->superFloodLight, 0, size );
|
|
+
|
|
/* allocate cluster map storage */
|
|
size = lm->sw * lm->sh * sizeof( int );
|
|
if( lm->superClusters == NULL )
|
|
Index: tools/quake3/q3map2/game_ja.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_ja.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_ja.h (working copy)
|
|
@@ -67,6 +67,7 @@
|
|
qfalse, /* wolf lighting model? */
|
|
128, /* lightmap width/height */
|
|
1.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"RBSP", /* bsp file prefix */
|
|
1, /* bsp file version */
|
|
Index: tools/quake3/q3map2/game_tremulous.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_tremulous.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_tremulous.h (working copy)
|
|
@@ -70,6 +70,7 @@
|
|
qfalse, /* wolf lighting model? */
|
|
128, /* lightmap width/height */
|
|
1.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"IBSP", /* bsp file prefix */
|
|
46, /* bsp file version */
|
|
Index: tools/quake3/q3map2/game_wolfet.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_wolfet.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_wolfet.h (working copy)
|
|
@@ -66,6 +66,7 @@
|
|
qtrue, /* wolf lighting model? */
|
|
128, /* lightmap width/height */
|
|
1.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"IBSP", /* bsp file prefix */
|
|
47, /* bsp file version */
|
|
Index: tools/quake3/q3map2/model.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/model.c (revision 158)
|
|
+++ tools/quake3/q3map2/model.c (working copy)
|
|
@@ -266,7 +266,7 @@
|
|
continue;
|
|
|
|
/* fix the surface's normals */
|
|
- PicoFixSurfaceNormals( surface );
|
|
+ //PicoFixSurfaceNormals( surface );
|
|
|
|
/* allocate a surface (ydnar: gs mods) */
|
|
ds = AllocDrawSurface( SURFACE_TRIANGLES );
|
|
@@ -521,7 +521,15 @@
|
|
else
|
|
free( buildBrush );
|
|
}
|
|
+ else
|
|
+ {
|
|
+ Sys_Printf( "WARNING: Model %s unable to generate brush - Case 1.\n", name );
|
|
+ }
|
|
}
|
|
+ else
|
|
+ {
|
|
+ Sys_Printf( "WARNING: Model %s unable to generate brush - Case 2.\n", name );
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
Index: tools/quake3/q3map2/light_bounce.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/light_bounce.c (revision 158)
|
|
+++ tools/quake3/q3map2/light_bounce.c (working copy)
|
|
@@ -510,7 +510,7 @@
|
|
break;
|
|
|
|
case MST_TRIANGLE_SOUP:
|
|
- numTriangleDiffuseLights;
|
|
+ numTriangleDiffuseLights++;
|
|
break;
|
|
|
|
case MST_PATCH:
|
|
Index: tools/quake3/q3map2/game_wolf.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_wolf.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_wolf.h (working copy)
|
|
@@ -129,6 +129,7 @@
|
|
qtrue, /* wolf lighting model? */
|
|
128, /* lightmap width/height */
|
|
1.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"IBSP", /* bsp file prefix */
|
|
47, /* bsp file version */
|
|
Index: tools/quake3/q3map2/game_sof2.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_sof2.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_sof2.h (working copy)
|
|
@@ -139,6 +139,7 @@
|
|
qfalse, /* wolf lighting model? */
|
|
128, /* lightmap width/height */
|
|
1.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"RBSP", /* bsp file prefix */
|
|
1, /* bsp file version */
|
|
Index: tools/quake3/q3map2/q3map2.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/q3map2.h (revision 158)
|
|
+++ tools/quake3/q3map2/q3map2.h (working copy)
|
|
@@ -35,8 +35,8 @@
|
|
|
|
|
|
/* version */
|
|
-#define Q3MAP_VERSION "2.5.17"
|
|
-#define Q3MAP_MOTD "Last one turns the lights off"
|
|
+#define Q3MAP_VERSION "2.5.17 base - FS_20g"
|
|
+#define Q3MAP_MOTD "Sorry, it doesn't match my furniture."
|
|
|
|
|
|
|
|
@@ -267,6 +267,7 @@
|
|
#define SUPER_NORMAL_SIZE 4
|
|
#define SUPER_DELUXEL_SIZE 3
|
|
#define BSP_DELUXEL_SIZE 3
|
|
+#define SUPER_FLOODLIGHT_SIZE 1
|
|
|
|
#define VERTEX_LUXEL( s, v ) (vertexLuxels[ s ] + ((v) * VERTEX_LUXEL_SIZE))
|
|
#define RAD_VERTEX_LUXEL( s, v )(radVertexLuxels[ s ] + ((v) * VERTEX_LUXEL_SIZE))
|
|
@@ -279,6 +280,7 @@
|
|
#define SUPER_ORIGIN( x, y ) (lm->superOrigins + ((((y) * lm->sw) + (x)) * SUPER_ORIGIN_SIZE))
|
|
#define SUPER_NORMAL( x, y ) (lm->superNormals + ((((y) * lm->sw) + (x)) * SUPER_NORMAL_SIZE))
|
|
#define SUPER_DIRT( x, y ) (lm->superNormals + ((((y) * lm->sw) + (x)) * SUPER_NORMAL_SIZE) + 3) /* stash dirtyness in normal[ 3 ] */
|
|
+#define SUPER_FLOODLIGHT( x, y ) (lm->superFloodLight + ((((y) * lm->sw) + (x)) * SUPER_FLOODLIGHT_SIZE) )
|
|
|
|
|
|
|
|
@@ -543,6 +545,7 @@
|
|
qboolean wolfLight; /* when true, lights work like wolf q3map */
|
|
int lightmapSize; /* bsp lightmap width/height */
|
|
float lightmapGamma; /* default lightmap gamma */
|
|
+ float lightmapExposure; /* default lightmap exposure */
|
|
float lightmapCompensate; /* default lightmap compensate value */
|
|
char *bspIdent; /* 4-letter bsp file prefix */
|
|
int bspVersion; /* bsp version to use */
|
|
@@ -1392,6 +1395,7 @@
|
|
|
|
float *superDeluxels; /* average light direction */
|
|
float *bspDeluxels;
|
|
+ float *superFloodLight;
|
|
}
|
|
rawLightmap_t;
|
|
|
|
@@ -1704,6 +1708,10 @@
|
|
float DirtForSample( trace_t *trace );
|
|
void DirtyRawLightmap( int num );
|
|
|
|
+void SetupFloodLight();
|
|
+float FloodLightForSample( trace_t *trace );
|
|
+void FloodLightRawLightmap( int num );
|
|
+
|
|
void IlluminateRawLightmap( int num );
|
|
void IlluminateVertexes( int num );
|
|
|
|
@@ -2098,6 +2106,13 @@
|
|
Q_EXTERN float dirtScale Q_ASSIGN( 1.0f );
|
|
Q_EXTERN float dirtGain Q_ASSIGN( 1.0f );
|
|
|
|
+Q_EXTERN qboolean debugnormals Q_ASSIGN( qfalse );
|
|
+Q_EXTERN qboolean floodlighty Q_ASSIGN( qfalse );
|
|
+Q_EXTERN qboolean floodlight_lowquality Q_ASSIGN( qfalse );
|
|
+Q_EXTERN vec3_t floodlightRGB;
|
|
+Q_EXTERN float floodlightIntensity Q_ASSIGN( 512 );
|
|
+Q_EXTERN float floodlightDistance Q_ASSIGN( 1024 );
|
|
+
|
|
Q_EXTERN qboolean dump Q_ASSIGN( qfalse );
|
|
Q_EXTERN qboolean debug Q_ASSIGN( qfalse );
|
|
Q_EXTERN qboolean debugUnused Q_ASSIGN( qfalse );
|
|
@@ -2117,6 +2132,7 @@
|
|
|
|
/* ydnar: lightmap gamma/compensation */
|
|
Q_EXTERN float lightmapGamma Q_ASSIGN( 1.0f );
|
|
+Q_EXTERN float lightmapExposure Q_ASSIGN( 1.0f );
|
|
Q_EXTERN float lightmapCompensate Q_ASSIGN( 1.0f );
|
|
|
|
/* ydnar: for runtime tweaking of falloff tolerance */
|
|
Index: tools/quake3/q3map2/path_init.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/path_init.c (revision 158)
|
|
+++ tools/quake3/q3map2/path_init.c (working copy)
|
|
@@ -383,7 +383,7 @@
|
|
/* remove processed arguments */
|
|
for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
|
|
{
|
|
- for( j; j < *argc && argv[ j ] == NULL; j++ );
|
|
+ for( ; j < *argc && argv[ j ] == NULL; j++ );
|
|
argv[ i ] = argv[ j ];
|
|
if( argv[ i ] != NULL )
|
|
k++;
|
|
Index: tools/quake3/q3map2/game_qfusion.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_qfusion.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_qfusion.h (working copy)
|
|
@@ -115,6 +115,7 @@
|
|
qfalse, /* wolf lighting model? */
|
|
512, /* lightmap width/height */
|
|
1.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"FBSP", /* bsp file prefix */
|
|
1, /* bsp file version */
|
|
Index: tools/quake3/q3map2/game_tenebrae.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_tenebrae.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_tenebrae.h (working copy)
|
|
@@ -112,6 +112,7 @@
|
|
qfalse, /* wolf lighting model? */
|
|
512, /* lightmap width/height */
|
|
2.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"IBSP", /* bsp file prefix */
|
|
46, /* bsp file version */
|
|
Index: tools/quake3/q3map2/q3map2.vcproj
|
|
===================================================================
|
|
--- tools/quake3/q3map2/q3map2.vcproj (revision 158)
|
|
+++ tools/quake3/q3map2/q3map2.vcproj (working copy)
|
|
@@ -180,7 +180,7 @@
|
|
Name="VCLinkerTool"
|
|
AdditionalOptions="/MACHINE:I386"
|
|
AdditionalDependencies="glib-2.0.lib wsock32.lib libxml2.lib libpng.lib libmhash.lib"
|
|
- OutputFile=".\Release/q3map2.exe"
|
|
+ OutputFile=".\Release/q3map2_fs_20g.exe"
|
|
LinkIncremental="1"
|
|
SuppressStartupBanner="true"
|
|
AdditionalLibraryDirectories=""..\..\..\..\mhash-0.9\win32\libmhash\Release";"..\..\..\..\libxml2-2.6\lib";"..\..\..\..\gtk2-2.10\lib""
|
|
Index: tools/quake3/q3map2/game_quake3.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_quake3.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_quake3.h (working copy)
|
|
@@ -112,6 +112,7 @@
|
|
qfalse, /* wolf lighting model? */
|
|
128, /* lightmap width/height */
|
|
1.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"IBSP", /* bsp file prefix */
|
|
46, /* bsp file version */
|
|
Index: tools/quake3/q3map2/game_ef.h
|
|
===================================================================
|
|
--- tools/quake3/q3map2/game_ef.h (revision 158)
|
|
+++ tools/quake3/q3map2/game_ef.h (working copy)
|
|
@@ -113,6 +113,7 @@
|
|
qfalse, /* wolf lighting model? */
|
|
128, /* lightmap width/height */
|
|
1.0f, /* lightmap gamma */
|
|
+ 1.0f, /* lightmap exposure */
|
|
1.0f, /* lightmap compensate */
|
|
"IBSP", /* bsp file prefix */
|
|
46, /* bsp file version */
|
|
Index: tools/quake3/q3map2/surface.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/surface.c (revision 158)
|
|
+++ tools/quake3/q3map2/surface.c (working copy)
|
|
@@ -304,7 +304,7 @@
|
|
out = &mapDrawSurfs[ i ];
|
|
|
|
/* walk the surface list again until a proper surface is found */
|
|
- for( j; j < numMapDrawSurfs; j++ )
|
|
+ for( ; j < numMapDrawSurfs; j++ )
|
|
{
|
|
/* get in surface */
|
|
in = &mapDrawSurfs[ j ];
|
|
@@ -484,7 +484,7 @@
|
|
|
|
|
|
/* walk the list of surfaces */
|
|
- for( numSurfs; numSurfs > 0; numSurfs--, ds++ )
|
|
+ for( ; numSurfs > 0; numSurfs--, ds++ )
|
|
{
|
|
/* ignore bogus (or flare) surfaces */
|
|
if( ds->type == SURFACE_BAD || ds->numVerts <= 0 )
|
|
Index: tools/quake3/q3map2/shaders.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/shaders.c (revision 158)
|
|
+++ tools/quake3/q3map2/shaders.c (working copy)
|
|
@@ -793,8 +793,14 @@
|
|
}
|
|
|
|
if( VectorLength( si->color ) <= 0.0f )
|
|
+ {
|
|
ColorNormalize( color, si->color );
|
|
- VectorScale( color, (1.0f / count), si->averageColor );
|
|
+ VectorScale( color, (1.0f / count), si->averageColor );
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ VectorCopy( si->color, si->averageColor );
|
|
+ }
|
|
}
|
|
|
|
|
|
@@ -1896,12 +1902,14 @@
|
|
si->styleMarker = 2;
|
|
|
|
/* ydnar: default to searching for q3map_<surfaceparm> */
|
|
- else
|
|
+#if 0
|
|
+ else
|
|
{
|
|
- //% Sys_FPrintf( SYS_VRB, "Attempting to match %s with a known surfaceparm\n", token );
|
|
+ Sys_FPrintf( SYS_VRB, "Attempting to match %s with a known surfaceparm\n", token );
|
|
if( ApplySurfaceParm( &token[ 6 ], &si->contentFlags, &si->surfaceFlags, &si->compileFlags ) == qfalse )
|
|
- ;//% Sys_Printf( "WARNING: Unknown q3map_* directive \"%s\"\n", token );
|
|
+ Sys_Printf( "WARNING: Unknown q3map_* directive \"%s\"\n", token );
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
|
|
Index: tools/quake3/q3map2/mesh.c
|
|
===================================================================
|
|
--- tools/quake3/q3map2/mesh.c (revision 158)
|
|
+++ tools/quake3/q3map2/mesh.c (working copy)
|
|
@@ -563,7 +563,7 @@
|
|
}
|
|
|
|
/* keep chopping */
|
|
- for( iterations; iterations > 0; iterations-- )
|
|
+ for( ; iterations > 0; iterations-- )
|
|
{
|
|
/* horizontal subdivisions */
|
|
for( j = 0; j + 2 < out.width; j += 4 )
|
|
Index: libs/picomodel/pm_ase.c
|
|
===================================================================
|
|
--- libs/picomodel/pm_ase.c (revision 158)
|
|
+++ libs/picomodel/pm_ase.c (working copy)
|
|
@@ -32,6 +32,7 @@
|
|
|
|
----------------------------------------------------------------------------- */
|
|
|
|
+void Sys_Printf (const char *format, ...);
|
|
|
|
/* marker */
|
|
#define PM_ASE_C
|
|
@@ -253,7 +254,6 @@
|
|
struct aseVertex_s
|
|
{
|
|
picoVec3_t xyz;
|
|
- picoVec3_t normal;
|
|
picoIndex_t id;
|
|
};
|
|
|
|
@@ -276,6 +276,8 @@
|
|
picoIndex_t smoothingGroup;
|
|
picoIndex_t materialId;
|
|
picoIndex_t subMaterialId;
|
|
+ picoVec3_t facenormal;
|
|
+ picoVec3_t vertexnormal[3];
|
|
};
|
|
typedef aseFace_t* aseFacesIter_t;
|
|
|
|
@@ -455,33 +457,157 @@
|
|
|
|
#endif
|
|
|
|
+static int VectorCompareExtn( picoVec3_t n1, picoVec3_t n2, float epsilon )
|
|
+{
|
|
+ int i;
|
|
+
|
|
+
|
|
+ /* test */
|
|
+ for( i= 0; i < 3; i++ )
|
|
+ if( fabs( n1[ i ] - n2[ i ]) > epsilon )
|
|
+ return -1;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+#define CrossProductTemp(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])
|
|
+
|
|
static void _ase_submit_triangles( picoModel_t* model , aseMaterial_t* materials , aseVertex_t* vertices, aseTexCoord_t* texcoords, aseColor_t* colors, aseFace_t* faces, int numFaces )
|
|
{
|
|
- aseFacesIter_t i = faces, end = faces + numFaces;
|
|
- for(; i != end; ++i)
|
|
+
|
|
+ picoVec3_t accum;
|
|
+ int index;
|
|
+ int counter;
|
|
+ aseFacesIter_t i = faces, end = faces + numFaces;
|
|
+ counter=0;
|
|
+
|
|
+ //rebuild normals
|
|
+ for(i=faces; i != end; ++i)
|
|
+ {
|
|
+
|
|
+ //&(*i).facenormal
|
|
+ //vec3_t v1, v2;
|
|
+ //VectorSubtract(va, vb, v1);
|
|
+ //VectorSubtract(vc, vb, v2);
|
|
+ //CrossProduct(v1, v2, out);
|
|
+
|
|
+ picoVec3_t a,b,c;
|
|
+ picoVec3_t v1,v2,v3;
|
|
+ int j;
|
|
+ counter++;
|
|
+ for (j=0;j<3;j++)
|
|
+ {
|
|
+ a[j] = vertices[(*i).indices[0]].xyz[j];
|
|
+ b[j] = vertices[(*i).indices[1]].xyz[j];
|
|
+ c[j] = vertices[(*i).indices[2]].xyz[j];
|
|
+ }
|
|
+ for (j=0;j<3;j++)
|
|
+ {
|
|
+ v1[j]=a[j]-b[j];
|
|
+ v2[j]=c[j]-b[j];
|
|
+ }
|
|
+
|
|
+ CrossProductTemp(v1,v2,v3);
|
|
+ _pico_normalize_vec(v3);
|
|
+ (*i).facenormal[0]=v3[0];
|
|
+ (*i).facenormal[1]=v3[1];
|
|
+ (*i).facenormal[2]=v3[2];
|
|
+
|
|
+
|
|
+ }
|
|
+
|
|
+
|
|
+ //if (counter>0) Sys_Printf( "Rebuilding %d Normals\n", counter * 3 );
|
|
+ for(i=faces; i != end; ++i)
|
|
{
|
|
- /* look up the shader for the material/submaterial pair */
|
|
+ /* look up the shader for the material/submaterial pair */
|
|
aseSubMaterial_t* subMtl = _ase_get_submaterial_or_default( materials, (*i).materialId, (*i).subMaterialId );
|
|
- if( subMtl == NULL )
|
|
+
|
|
+ if( subMtl == NULL )
|
|
{
|
|
return;
|
|
}
|
|
|
|
{
|
|
picoVec3_t* xyz[3];
|
|
+ picoVec3_t *a[3];
|
|
picoVec3_t* normal[3];
|
|
picoVec2_t* st[3];
|
|
picoColor_t* color[3];
|
|
picoIndex_t smooth[3];
|
|
- int j;
|
|
- /* we pull the data from the vertex, color and texcoord arrays using the face index data */
|
|
- for ( j = 0 ; j < 3 ; j ++ )
|
|
+
|
|
+ int j,z;
|
|
+
|
|
+
|
|
+
|
|
+ /* we pull the data from the vertex, color and texcoord arrays using the face index data */
|
|
+ for ( j = 0 ; j < 3 ; j ++ )
|
|
{
|
|
- xyz[j] = &vertices[(*i).indices[j]].xyz;
|
|
- normal[j] = &vertices[(*i).indices[j]].normal;
|
|
+ aseFacesIter_t q = faces;
|
|
+ aseFacesIter_t qend = faces + numFaces;
|
|
+
|
|
+ xyz[j] = &vertices[(*i).indices[j]].xyz;
|
|
+
|
|
+ // Use Face normal
|
|
+ normal[j] = &(*i).facenormal;
|
|
+
|
|
+
|
|
+ //Oooor we can use the smoothing group
|
|
+
|
|
+ //Slow method, but testing
|
|
+ //Find All faces that use this vertex, average their facenormals.
|
|
+ // skip where smoothgroups both equal 0, or don't have any shared bits (x & y)
|
|
+ index=(*i).indices[j];
|
|
+
|
|
+// accum[0]=0;
|
|
+ // accum[1]=0;
|
|
+ // accum[2]=0;
|
|
+ accum[0]=(*i).facenormal[0];
|
|
+ accum[1]=(*i).facenormal[1];
|
|
+ accum[2]=(*i).facenormal[2];
|
|
+ counter=1;
|
|
+
|
|
+
|
|
+ z=0;
|
|
+ for(; q != qend; ++q)
|
|
+ {
|
|
+ z++;
|
|
+ if (q==i)
|
|
+ continue;
|
|
+ // if ( (*q).indices[0]==index || (*q).indices[1]==index || (*q).indices[2]==index)
|
|
+ a[0]= &vertices[(*q).indices[0] ].xyz;
|
|
+ a[1]= &vertices[(*q).indices[1] ].xyz;
|
|
+ a[2]= &vertices[(*q).indices[2] ].xyz;
|
|
+
|
|
+ if ( VectorCompareExtn(*a[0],*xyz[j],0.01f)>0 ||
|
|
+ VectorCompareExtn(*a[1],*xyz[j],0.01f)>0 ||
|
|
+ VectorCompareExtn(*a[2],*xyz[j],0.01f)>0
|
|
+ )
|
|
+ {
|
|
+ if ( (*i).smoothingGroup==0 && (*q).smoothingGroup ==0 )
|
|
+ continue;
|
|
+
|
|
+ if ( (*i).smoothingGroup & (*q).smoothingGroup )
|
|
+ {
|
|
+ accum[0]+=(*q).facenormal[0];
|
|
+ accum[1]+=(*q).facenormal[1];
|
|
+ accum[2]+=(*q).facenormal[2];
|
|
+
|
|
+ counter++;
|
|
+
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ _pico_normalize_vec(accum);
|
|
+
|
|
+ (*i).vertexnormal[j][0]=accum[0];
|
|
+ (*i).vertexnormal[j][1]=accum[1];
|
|
+ (*i).vertexnormal[j][2]=accum[2];
|
|
+ normal[j]=&(*i).vertexnormal[j];
|
|
+
|
|
+
|
|
st[j] = &texcoords[(*i).indices[j + 3]].texcoord;
|
|
-
|
|
- if( colors != NULL && (*i).indices[j + 6] >= 0 )
|
|
+
|
|
+ if( colors != NULL && (*i).indices[j + 6] >= 0 )
|
|
{
|
|
color[j] = &colors[(*i).indices[j + 6]].color;
|
|
}
|
|
@@ -490,30 +616,18 @@
|
|
color[j] = &white;
|
|
}
|
|
|
|
- smooth[j] = (vertices[(*i).indices[j]].id * (1 << 16)) + (*i).smoothingGroup; /* don't merge vertices */
|
|
+ smooth[j] = 0;// (vertices[(*i).indices[j]].id * (1 << 16)) + (*i).smoothingGroup; /* don't merge vertices */
|
|
|
|
}
|
|
|
|
/* submit the triangle to the model */
|
|
PicoAddTriangleToModel ( model , xyz , normal , 1 , st , 1 , color , subMtl->shader, smooth );
|
|
}
|
|
+
|
|
}
|
|
}
|
|
|
|
-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.
|
|
*/
|
|
@@ -534,6 +648,9 @@
|
|
int numColorVertices = 0;
|
|
int numColorVertexFaces = 0;
|
|
int vertexId = 0;
|
|
+ int currentVertexFace=0;
|
|
+ int currentVertexIndex=0;
|
|
+ int counter=0;
|
|
|
|
aseMaterial_t* materials = NULL;
|
|
|
|
@@ -610,10 +727,11 @@
|
|
}
|
|
else if (!_pico_stricmp(p->token,"*mesh_numvertex"))
|
|
{
|
|
- if (!_pico_parse_int( p, &numVertices) )
|
|
+ if (!_pico_parse_int( p, &numVertices) )
|
|
_ase_error_return("Missing MESH_NUMVERTEX value");
|
|
|
|
vertices = _pico_calloc(numVertices, sizeof(aseVertex_t));
|
|
+ currentVertexIndex=0;
|
|
}
|
|
else if (!_pico_stricmp(p->token,"*mesh_numfaces"))
|
|
{
|
|
@@ -621,6 +739,7 @@
|
|
_ase_error_return("Missing MESH_NUMFACES value");
|
|
|
|
faces = _pico_calloc(numFaces, sizeof(aseFace_t));
|
|
+
|
|
}
|
|
else if (!_pico_stricmp(p->token,"*mesh_numtvertex"))
|
|
{
|
|
@@ -685,7 +804,20 @@
|
|
|
|
vertices[index].id = vertexId++;
|
|
}
|
|
- /* model mesh vertex normal */
|
|
+ else if (!_pico_stricmp(p->token,"*mesh_facenormal"))
|
|
+ {
|
|
+ //Grab the faceindex for the next vertex normals.
|
|
+ if( numVertices == 0 )
|
|
+ _ase_error_return("Vertex parse error (facenormals)");
|
|
+
|
|
+ if (!_pico_parse_int( p,¤tVertexFace ))
|
|
+ _ase_error_return("Vertex parse error");
|
|
+
|
|
+ if (!_pico_parse_vec( p,faces[currentVertexFace].facenormal ))
|
|
+ _ase_error_return("Vertex parse error");
|
|
+
|
|
+ }
|
|
+ /* model mesh vertex normal */
|
|
else if (!_pico_stricmp(p->token,"*mesh_vertexnormal"))
|
|
{
|
|
int index;
|
|
@@ -696,10 +828,25 @@
|
|
/* get vertex data (orig: index +y -x +z) */
|
|
if (!_pico_parse_int( p,&index ))
|
|
_ase_error_return("Vertex parse error");
|
|
- if (!_pico_parse_vec( p,vertices[index].normal ))
|
|
+
|
|
+ //^^ Index is 'wrong' in .ase models. they reference the same vert index with multiple normals..
|
|
+ // I've tried, this is a lost cause. Use the SG's
|
|
+ //
|
|
+ /*
|
|
+
|
|
+ if (!_pico_parse_vec( p,vertices[counter].normal ))
|
|
_ase_error_return("Vertex parse error");
|
|
+ vertices[counter].faceid=index;
|
|
+ counter++;
|
|
+ */
|
|
}
|
|
/* model mesh face */
|
|
+ else if (!_pico_stricmp(p->token,"*mesh_normals"))
|
|
+ {
|
|
+ // counter=0; //part of the above vertex normals fix
|
|
+ }
|
|
+
|
|
+ /* model mesh face */
|
|
else if (!_pico_stricmp(p->token,"*mesh_face"))
|
|
{
|
|
picoIndex_t indexes[3];
|
|
@@ -736,8 +883,35 @@
|
|
}
|
|
if (!_pico_stricmp (p->token,"*MESH_SMOOTHING" ))
|
|
{
|
|
- _pico_parse_int ( p , &faces[index].smoothingGroup );
|
|
- }
|
|
+ int total=0;
|
|
+ char* point;
|
|
+ char* start;
|
|
+ _pico_parse(p,0);
|
|
+
|
|
+ point=p->token;
|
|
+ start=point;
|
|
+ faces[index].smoothingGroup=0;
|
|
+
|
|
+ //Super dodgy comma delimited string parse
|
|
+ while (*point<'A')
|
|
+ {
|
|
+ if (*point<=32 || *point==',')
|
|
+ {
|
|
+ total=atoi(start);
|
|
+ if (total!=0)
|
|
+ {
|
|
+ faces[index].smoothingGroup+=1<<total;
|
|
+ }
|
|
+ start=point+1;
|
|
+ }
|
|
+
|
|
+ point++;
|
|
+ }
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+ }
|
|
if (!_pico_stricmp (p->token,"*MESH_MTLID" ))
|
|
{
|
|
_pico_parse_int ( p , &faces[index].subMaterialId );
|
|
@@ -755,19 +929,19 @@
|
|
int index;
|
|
|
|
if( numVertices == 0 )
|
|
- _ase_error_return("Texture Vertex parse error");
|
|
+ _ase_error_return("Vertex parse error");
|
|
|
|
/* get uv vertex index */
|
|
- if (!_pico_parse_int( p,&index ) || index >= numTextureVertices)
|
|
- _ase_error_return("Texture vertex parse error");
|
|
+ if (!_pico_parse_int( p,&index ))
|
|
+ _ase_error_return("UV vertex parse error");
|
|
|
|
/* get uv vertex s */
|
|
if (!_pico_parse_float( p,&texcoords[index].texcoord[0] ))
|
|
- _ase_error_return("Texture vertex parse error");
|
|
+ _ase_error_return("UV vertex parse error");
|
|
|
|
/* get uv vertex t */
|
|
if (!_pico_parse_float( p,&texcoords[index].texcoord[1] ))
|
|
- _ase_error_return("Texture vertex parse error");
|
|
+ _ase_error_return("UV vertex parse error");
|
|
|
|
/* ydnar: invert t */
|
|
texcoords[index].texcoord[ 1 ] = 1.0f - texcoords[index].texcoord[ 1 ];
|
|
@@ -831,6 +1005,13 @@
|
|
|
|
/* leave alpha alone since we don't get any data from the ASE format */
|
|
colors[index].color[3] = 255;
|
|
+
|
|
+ /* 27 hack, red as alpha */
|
|
+ colors[index].color[3]=colors[index].color[0];
|
|
+ colors[index].color[0]=255;
|
|
+ colors[index].color[1]=255;
|
|
+ colors[index].color[2]=255;
|
|
+
|
|
}
|
|
/* model color face */
|
|
else if (!_pico_stricmp(p->token,"*mesh_cface"))
|
|
@@ -900,7 +1081,6 @@
|
|
{
|
|
/* set material name */
|
|
_pico_first_token( materialName );
|
|
- shadername_convert(materialName);
|
|
PicoSetShaderName( shader, materialName);
|
|
|
|
/* set shader's transparency */
|
|
@@ -1085,7 +1265,6 @@
|
|
}
|
|
|
|
/* set material name */
|
|
- shadername_convert(materialName);
|
|
PicoSetShaderName( shader,materialName );
|
|
|
|
/* set shader's transparency */
|
|
@@ -1115,8 +1294,18 @@
|
|
char* p = mapname;
|
|
|
|
/* convert to shader-name format */
|
|
- shadername_convert(mapname);
|
|
{
|
|
+ /* unix-style path separators */
|
|
+ char* s = mapname;
|
|
+ for(; *s != '\0'; ++s)
|
|
+ {
|
|
+ if(*s == '\\')
|
|
+ {
|
|
+ *s = '/';
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ {
|
|
/* remove extension */
|
|
char* last_period = strrchr(p, '.');
|
|
if(last_period != NULL)
|
|
@@ -1125,14 +1314,32 @@
|
|
}
|
|
}
|
|
|
|
- /* find shader path */
|
|
+ /* find game root */
|
|
for(; *p != '\0'; ++p)
|
|
{
|
|
- if(_pico_strnicmp(p, "models/", 7) == 0 || _pico_strnicmp(p, "textures/", 9) == 0)
|
|
+ if(_pico_strnicmp(p, "quake", 5) == 0 || _pico_strnicmp(p, "doom", 4) == 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
+ /* root-relative */
|
|
+ for(; *p != '\0'; ++p)
|
|
+ {
|
|
+ if(*p == '/')
|
|
+ {
|
|
+ ++p;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ /* game-relative */
|
|
+ for(; *p != '\0'; ++p)
|
|
+ {
|
|
+ if(*p == '/')
|
|
+ {
|
|
+ ++p;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
|
|
if(*p != '\0')
|
|
{
|
|
Index: libs/picomodel/picomodel.c
|
|
===================================================================
|
|
--- libs/picomodel/picomodel.c (revision 158)
|
|
+++ libs/picomodel/picomodel.c (working copy)
|
|
@@ -295,10 +295,7 @@
|
|
model = PicoModuleLoadModel(module, fileName, buffer, bufSize, frameNum);
|
|
}
|
|
|
|
- if(model != 0)
|
|
- {
|
|
- _pico_free(buffer);
|
|
- }
|
|
+ _pico_free(buffer);
|
|
|
|
/* return */
|
|
return model;
|
|
@@ -1573,6 +1570,7 @@
|
|
{
|
|
int i, j;
|
|
|
|
+// Sys_Printf(" %f %f %f\n", normal[0] , normal[1] , normal[2] );
|
|
|
|
/* dummy check */
|
|
if( surface == NULL || surface->numVertexes <= 0 )
|
|
@@ -1861,13 +1859,10 @@
|
|
typedef picoVec3_t* picoNormalIter_t;
|
|
typedef picoIndex_t* picoIndexIter_t;
|
|
|
|
-#define THE_CROSSPRODUCTS_OF_ANY_PAIR_OF_EDGES_OF_A_GIVEN_TRIANGLE_ARE_EQUAL 1
|
|
-
|
|
void _pico_triangles_generate_weighted_normals(picoIndexIter_t first, picoIndexIter_t end, picoVec3_t* xyz, picoVec3_t* normals)
|
|
{
|
|
for(; first != end; first += 3)
|
|
{
|
|
-#if (THE_CROSSPRODUCTS_OF_ANY_PAIR_OF_EDGES_OF_A_GIVEN_TRIANGLE_ARE_EQUAL)
|
|
picoVec3_t weightedNormal;
|
|
{
|
|
float* a = xyz[*(first + 0)];
|
|
@@ -1878,24 +1873,11 @@
|
|
_pico_subtract_vec( c, a, ca );
|
|
_pico_cross_vec( ca, ba, weightedNormal );
|
|
}
|
|
-#endif
|
|
{
|
|
int j = 0;
|
|
for(; j < 3; ++j)
|
|
{
|
|
float* normal = normals[*(first + j)];
|
|
-#if (!THE_CROSSPRODUCTS_OF_ANY_PAIR_OF_EDGES_OF_A_GIVEN_TRIANGLE_ARE_EQUAL)
|
|
- picoVec3_t weightedNormal;
|
|
- {
|
|
- float* a = xyz[*(first + ((j + 0) % 3))];
|
|
- float* b = xyz[*(first + ((j + 1) % 3))];
|
|
- float* c = xyz[*(first + ((j + 2) % 3))];
|
|
- picoVec3_t ba, ca;
|
|
- _pico_subtract_vec( b, a, ba );
|
|
- _pico_subtract_vec( c, a, ca );
|
|
- _pico_cross_vec( ca, ba, weightedNormal );
|
|
- }
|
|
-#endif
|
|
_pico_add_vec(weightedNormal, normal, normal);
|
|
}
|
|
}
|
|
@@ -1941,7 +1923,8 @@
|
|
{
|
|
for(; first != last; ++first, ++generated)
|
|
{
|
|
- if(!_pico_normal_is_unit_length(*first) || !_pico_normal_within_tolerance(*first, *generated))
|
|
+ //27 - fix for badly generated normals thing.
|
|
+ // if(!_pico_normal_is_unit_length(*first) || !_pico_normal_within_tolerance(*first, *generated))
|
|
{
|
|
_pico_copy_vec(*generated, *first);
|
|
}
|
|
@@ -1954,10 +1937,11 @@
|
|
|
|
_pico_normals_zero(normals, normals + surface->numVertexes);
|
|
|
|
+ //Just build standard no sg normals for now
|
|
_pico_triangles_generate_weighted_normals(surface->index, surface->index + surface->numIndexes, surface->xyz, normals);
|
|
_pico_vertices_combine_shared_normals(surface->xyz, surface->smoothingGroup, normals, surface->numVertexes);
|
|
|
|
- _pico_normals_normalize(normals, normals + surface->numVertexes);
|
|
+ _pico_normals_normalize(normals, normals + surface->numVertexes);
|
|
|
|
_pico_normals_assign_generated_normals(surface->normal, surface->normal + surface->numVertexes, normals);
|
|
|
|
@@ -2261,7 +2245,7 @@
|
|
int newVertIndex = PicoGetSurfaceNumIndexes ( workSurface );
|
|
|
|
/* get the index of the vertex that we're going to store at newVertIndex */
|
|
- vertDataIndex = PicoFindSurfaceVertexNum ( workSurface , *xyz[i] , *normals[i] , numSTs , st[i] , numColors , colors[i], smoothingGroup[i]);
|
|
+ vertDataIndex = -1;// PicoFindSurfaceVertexNum ( workSurface , *xyz[i] , *normals[i] , numSTs , st[i] , numColors , colors[i], smoothingGroup[i]);
|
|
|
|
/* the vertex wasn't found, so create a new vertex in the pool from the data we have */
|
|
if ( vertDataIndex == -1 )
|
|
@@ -2290,3 +2274,5 @@
|
|
PicoSetSurfaceIndex ( workSurface , newVertIndex , vertDataIndex );
|
|
}
|
|
}
|
|
+
|
|
+
|