From b388770c659d3956bf1761cc5d6279a6de8fee5f Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Sat, 13 Sep 2008 20:28:57 +0200 Subject: [PATCH 1/3] netradiant/tools: initial former commit name: initial this commit only backports changes from tools/ --- tools/quake3/q3map2/bsp.c | 2 + tools/quake3/q3map2/game__null.h | 1 + tools/quake3/q3map2/game_ef.h | 1 + tools/quake3/q3map2/game_etut.h | 1 + tools/quake3/q3map2/game_ja.h | 1 + tools/quake3/q3map2/game_jk2.h | 1 + tools/quake3/q3map2/game_nexuiz.h | 1 + tools/quake3/q3map2/game_qfusion.h | 1 + tools/quake3/q3map2/game_quake3.h | 1 + tools/quake3/q3map2/game_quakelive.h | 1 + tools/quake3/q3map2/game_reaction.h | 1 + tools/quake3/q3map2/game_sof2.h | 1 + tools/quake3/q3map2/game_tenebrae.h | 1 + tools/quake3/q3map2/game_tremulous.h | 1 + tools/quake3/q3map2/game_unvanquished.h | 1 + tools/quake3/q3map2/game_wolf.h | 1 + tools/quake3/q3map2/game_wolfet.h | 1 + tools/quake3/q3map2/light.c | 76 ++- tools/quake3/q3map2/light_ydnar.c | 588 ++++++++++++++++++++++-- tools/quake3/q3map2/lightmaps_ydnar.c | 12 +- tools/quake3/q3map2/map.c | 24 +- tools/quake3/q3map2/model.c | 176 ++++--- tools/quake3/q3map2/q3map2.h | 18 +- 23 files changed, 797 insertions(+), 115 deletions(-) diff --git a/tools/quake3/q3map2/bsp.c b/tools/quake3/q3map2/bsp.c index 929aa93c..e0f16d71 100644 --- a/tools/quake3/q3map2/bsp.c +++ b/tools/quake3/q3map2/bsp.c @@ -852,7 +852,9 @@ int BSPMain( int argc, char **argv ){ deepBSP = qtrue; } else if( !strcmp( argv[ i ], "-bsp" ) ) + { Sys_Printf( "-bsp argument unnecessary\n" ); + } else { Sys_Printf( "WARNING: Unknown option \"%s\"\n", argv[ i ] ); diff --git a/tools/quake3/q3map2/game__null.h b/tools/quake3/q3map2/game__null.h index 9191051b..33719775 100644 --- a/tools/quake3/q3map2/game__null.h +++ b/tools/quake3/q3map2/game__null.h @@ -63,6 +63,7 @@ qfalse, /* wolf lighting model? */ 0, /* lightmap width/height */ 0, /* lightmap gamma */ + 0, /* lightmap exposure */ 0, /* lightmap compensate */ 0, /* minimap size */ 0, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_ef.h b/tools/quake3/q3map2/game_ef.h index 0a8168a0..5a924e88 100644 --- a/tools/quake3/q3map2/game_ef.h +++ b/tools/quake3/q3map2/game_ef.h @@ -113,6 +113,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_etut.h b/tools/quake3/q3map2/game_etut.h index 1f0a8962..4e15d10f 100644 --- a/tools/quake3/q3map2/game_etut.h +++ b/tools/quake3/q3map2/game_etut.h @@ -148,6 +148,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 2.2f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_ja.h b/tools/quake3/q3map2/game_ja.h index f4778043..67ddf27a 100644 --- a/tools/quake3/q3map2/game_ja.h +++ b/tools/quake3/q3map2/game_ja.h @@ -67,6 +67,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_jk2.h b/tools/quake3/q3map2/game_jk2.h index 90351e0f..f08d05a3 100644 --- a/tools/quake3/q3map2/game_jk2.h +++ b/tools/quake3/q3map2/game_jk2.h @@ -64,6 +64,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_nexuiz.h b/tools/quake3/q3map2/game_nexuiz.h index f909c4bc..41dc2b83 100644 --- a/tools/quake3/q3map2/game_nexuiz.h +++ b/tools/quake3/q3map2/game_nexuiz.h @@ -63,6 +63,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_qfusion.h b/tools/quake3/q3map2/game_qfusion.h index 9ddebdc1..5ddc91bf 100644 --- a/tools/quake3/q3map2/game_qfusion.h +++ b/tools/quake3/q3map2/game_qfusion.h @@ -112,6 +112,7 @@ qfalse, /* wolf lighting model? */ 512, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 256, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_quake3.h b/tools/quake3/q3map2/game_quake3.h index 07a1c9a2..6dc0edba 100644 --- a/tools/quake3/q3map2/game_quake3.h +++ b/tools/quake3/q3map2/game_quake3.h @@ -112,6 +112,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_quakelive.h b/tools/quake3/q3map2/game_quakelive.h index 78b1329d..e5d38075 100644 --- a/tools/quake3/q3map2/game_quakelive.h +++ b/tools/quake3/q3map2/game_quakelive.h @@ -76,6 +76,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_reaction.h b/tools/quake3/q3map2/game_reaction.h index 970ccd25..242ff6a9 100644 --- a/tools/quake3/q3map2/game_reaction.h +++ b/tools/quake3/q3map2/game_reaction.h @@ -84,6 +84,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_sof2.h b/tools/quake3/q3map2/game_sof2.h index 91b26df4..7d86612b 100644 --- a/tools/quake3/q3map2/game_sof2.h +++ b/tools/quake3/q3map2/game_sof2.h @@ -139,6 +139,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_tenebrae.h b/tools/quake3/q3map2/game_tenebrae.h index 57e45eca..57e81c4f 100644 --- a/tools/quake3/q3map2/game_tenebrae.h +++ b/tools/quake3/q3map2/game_tenebrae.h @@ -112,6 +112,7 @@ qfalse, /* wolf lighting model? */ 512, /* lightmap width/height */ 2.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_tremulous.h b/tools/quake3/q3map2/game_tremulous.h index 0f6d050f..d9b25e29 100644 --- a/tools/quake3/q3map2/game_tremulous.h +++ b/tools/quake3/q3map2/game_tremulous.h @@ -70,6 +70,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_unvanquished.h b/tools/quake3/q3map2/game_unvanquished.h index e56d7347..4264f449 100644 --- a/tools/quake3/q3map2/game_unvanquished.h +++ b/tools/quake3/q3map2/game_unvanquished.h @@ -72,6 +72,7 @@ game_t struct qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_wolf.h b/tools/quake3/q3map2/game_wolf.h index 6fed3761..ac4b7526 100644 --- a/tools/quake3/q3map2/game_wolf.h +++ b/tools/quake3/q3map2/game_wolf.h @@ -129,6 +129,7 @@ qtrue, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_wolfet.h b/tools/quake3/q3map2/game_wolfet.h index 57151e29..95b30918 100644 --- a/tools/quake3/q3map2/game_wolfet.h +++ b/tools/quake3/q3map2/game_wolfet.h @@ -66,6 +66,7 @@ qtrue, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ + 1.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/light.c b/tools/quake3/q3map2/light.c index c01d7209..81441b39 100644 --- a/tools/quake3/q3map2/light.c +++ b/tools/quake3/q3map2/light.c @@ -978,7 +978,7 @@ int LightContributionToSample( trace_t *trace ){ /* return to sender */ return 1; - } + } else { Error( "Light of undefined type!" ); } @@ -1442,6 +1442,54 @@ void TraceGrid( int num ){ } } + /////// 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 ); @@ -1725,6 +1773,11 @@ void LightWorld( void ){ 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 ); @@ -1767,6 +1820,7 @@ void LightWorld( void ){ /* flag bouncing */ bouncing = qtrue; VectorClear( ambientColor ); + floodlighty = qfalse; /* generate diffuse lights */ RadFreeLights(); @@ -1894,6 +1948,13 @@ int LightMain( int argc, char **argv ){ 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 ] ); if ( f <= 0.0f ) { @@ -2204,6 +2265,18 @@ int LightMain( int argc, char **argv ){ 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" ) ) { @@ -2294,6 +2367,7 @@ int LightMain( int argc, char **argv ){ /* ydnar: set up optimization */ SetupBrushes(); SetupDirt(); + SetupFloodLight(); SetupSurfaceLightmaps(); /* initialize the surface facet tracing */ diff --git a/tools/quake3/q3map2/light_ydnar.c b/tools/quake3/q3map2/light_ydnar.c index 38690791..98df332b 100644 --- a/tools/quake3/q3map2/light_ydnar.c +++ b/tools/quake3/q3map2/light_ydnar.c @@ -48,6 +48,7 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ int i; float max, gamma; vec3_t sample; + float inv, dif; /* ydnar: scaling necessary for simulating r_overbrightBits on external lightmaps */ @@ -72,16 +73,49 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ sample[ i ] = pow( sample[ i ] / 255.0f, gamma ) * 255.0f; } - /* clamp with color normalization */ - max = sample[ 0 ]; - if ( sample[ 1 ] > max ) { - max = sample[ 1 ]; + 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 ); + } } - 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; + } } /* compensate for ingame overbrighting/bitshifting */ @@ -390,13 +424,19 @@ static void PerturbNormal( bspDrawVert_t *dv, shaderInfo_t *si, vec3_t pNormal, #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; shaderInfo_t *si; 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 ] = { @@ -497,6 +537,49 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t 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 ) { VectorCopy( lm->vecs[ 0 ], vecs[ 0 ] ); @@ -533,8 +616,12 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t 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; @@ -549,7 +636,7 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t 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; @@ -615,7 +702,7 @@ static int MapSingleLuxel( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t 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; @@ -662,7 +749,7 @@ static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t /* 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 ); @@ -670,12 +757,12 @@ static void MapTriangle_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t /* 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 ); } @@ -690,6 +777,7 @@ static qboolean MapTriangle( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert int i; vec4_t plane; vec3_t *stv, *ttv, stvStatic[ 3 ], ttvStatic[ 3 ]; + vec3_t worldverts[ 3 ]; /* get plane if possible */ @@ -714,15 +802,18 @@ static qboolean MapTriangle( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert 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; } @@ -743,7 +834,7 @@ static qboolean MapTriangle( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert 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 ); } } @@ -804,8 +895,8 @@ static void MapQuad_r( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t *dv 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 ) { @@ -888,10 +979,10 @@ static qboolean MapQuad( rawLightmap_t *lm, surfaceInfo_t *info, bspDrawVert_t * } /* 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 ); @@ -1196,7 +1287,7 @@ void MapRawLightmap( int rawLightmapNum ){ } /* map the fake vert */ - MapSingleLuxel( lm, NULL, &fake, lm->plane, pass, NULL, NULL ); + MapSingleLuxel( lm, NULL, &fake, lm->plane, pass, NULL, NULL, NULL ); } } } @@ -1784,6 +1875,8 @@ void IlluminateRawLightmap( int rawLightmapNum ){ 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 */ @@ -1987,22 +2080,31 @@ void IlluminateRawLightmap( int rawLightmapNum ){ 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 ) { @@ -2255,6 +2357,80 @@ void IlluminateRawLightmap( int rawLightmapNum ){ /* free light list */ 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 ----------------------------------------------------------------- */ @@ -2775,8 +2951,7 @@ void IlluminateVertexes( int num ){ determines opaque brushes in the world and find sky shaders for sunlight calculations */ -void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned int mask_all, unsigned int test_all ) -{ +void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned int mask_all, unsigned int test_all ){ int i, j, b; unsigned int compileFlags, allCompileFlags; qboolean inside; @@ -3659,3 +3834,328 @@ void CreateTraceLightsForSurface( int num, trace_t *trace ){ /* create the lights for the bounding box */ 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; +} diff --git a/tools/quake3/q3map2/lightmaps_ydnar.c b/tools/quake3/q3map2/lightmaps_ydnar.c index b3ac49ba..a42bcd6f 100644 --- a/tools/quake3/q3map2/lightmaps_ydnar.c +++ b/tools/quake3/q3map2/lightmaps_ydnar.c @@ -410,6 +410,13 @@ void FinishRawLightmap( rawLightmap_t *lm ){ } memset( lm->superNormals, 0, size ); + /* allocate cluster 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 ) { @@ -1210,7 +1217,7 @@ void StitchSurfaceLightmaps( void ){ numStitched, numCandidates, numLuxels, f, fOld, start; rawLightmap_t *lm, *a, *b, *c[ MAX_STITCH_CANDIDATES ]; float *luxel, *luxel2, *origin, *origin2, *normal, *normal2, - sampleSize, average[ 3 ], totalColor, ootc, *luxels[ MAX_STITCH_LUXELS ]; + sampleSize, average[ 3 ], totalColor, ootc, *luxels[ MAX_STITCH_LUXELS ]; /* disabled for now */ @@ -2111,8 +2118,7 @@ static void FindOutLightmaps( rawLightmap_t *lm ){ /* allocate two new output lightmaps */ numOutLightmaps += 2; olm = safe_malloc( numOutLightmaps * sizeof( outLightmap_t ) ); - if ( !olm ) - { + if ( !olm ) { Error( "FindOutLightmaps: Failed to allocate memory.\n" ); } diff --git a/tools/quake3/q3map2/map.c b/tools/quake3/q3map2/map.c index a7eed1b7..56d579b5 100644 --- a/tools/quake3/q3map2/map.c +++ b/tools/quake3/q3map2/map.c @@ -239,7 +239,7 @@ qboolean SnapNormal( vec3_t normal ){ snaps a plane to normal/distance epsilons */ -void SnapPlane( vec3_t normal, vec_t *dist ){ +void SnapPlane( vec3_t normal, vec_t *dist, vec3_t center ){ // SnapPlane disabled by LordHavoc because it often messes up collision // brushes made from triangles of embedded models, and it has little effect // on anything else (axial planes are usually derived from snapped points) @@ -247,7 +247,13 @@ void SnapPlane( vec3_t normal, vec_t *dist ){ SnapPlane reenabled by namespace because of multiple reports of q3map2-crashes which were triggered by this patch. */ + // div0: ensure the point "center" stays on the plane (actually, this + // rotates the plane around the point center). + // if center lies on the plane, it is guaranteed to stay on the plane by + // this fix. + vec_t centerDist = DotProduct( normal, center ); SnapNormal( normal ); + *dist += ( DotProduct( normal, center ) - centerDist ); // TODO: Rambetter has some serious comments here as well. First off, // in the case where a normal is non-axial, there is nothing special @@ -315,7 +321,7 @@ void SnapPlaneImproved( vec3_t normal, vec_t *dist, int numPoints, const vec3_t must be within an epsilon distance of the plane */ -int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points ) +int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points ) // NOTE: this has a side effect on the normal. Good or bad? #ifdef USE_HASHING @@ -323,12 +329,16 @@ int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points ) int i, j, hash, h; plane_t *p; vec_t d; + vec3_t centerofweight; + VectorClear( centerofweight ); + for ( i = 0; i < numPoints; ++i ) + VectorMA( centerofweight, 1.0 / numPoints, points[i], centerofweight ); #if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points ); #else - SnapPlane( normal, &dist ); + SnapPlane( normal, &dist, centerofweight ); #endif /* hash the plane */ hash = ( PLANE_HASHES - 1 ) & (int) fabs( dist ); @@ -382,7 +392,13 @@ int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points ) #if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points ); #else - SnapPlane( normal, &dist ); + vec3_t centerofweight; + + VectorClear( centerofweight ); + for ( i = 0; i < numPoints; ++i ) + VectorMA( centerofweight, 1.0 / numPoints, points[i], centerofweight ); + + SnapPlane( normal, &dist, centerofweight ); #endif for ( i = 0, p = mapplanes; i < nummapplanes; i++, p++ ) { diff --git a/tools/quake3/q3map2/model.c b/tools/quake3/q3map2/model.c index 68897e48..3804646d 100644 --- a/tools/quake3/q3map2/model.c +++ b/tools/quake3/q3map2/model.c @@ -225,6 +225,8 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade byte *color; picoIndex_t *indexes; remap_t *rm, *glob; + double normalEpsilon_save; + double distanceEpsilon_save; /* get model */ @@ -415,9 +417,8 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade /* ydnar: giant hack land: generate clipping brushes for model triangles */ if ( si->clipModel || ( spawnFlags & 2 ) ) { /* 2nd bit */ - vec3_t points[ 3 ], backs[ 3 ]; + vec3_t points[ 4 ], backs[ 3 ]; vec4_t plane, reverse, pa, pb, pc; - vec3_t nadir; /* temp hack */ @@ -458,8 +459,8 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade /* 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 ] ) ) { + 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; } @@ -467,85 +468,136 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade #endif } + VectorCopy( points[0], points[3] ); // for cyclic usage + /* make plane for triangle */ + // div0: add some extra spawnflags: + // 0: snap normals to axial planes for extrusion + // 8: extrude with the original normals + // 16: extrude only with up/down normals (ideal for terrain) + // 24: extrude by distance zero (may need engine changes) if ( PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] ) ) { + vec3_t bestNormal; + float backPlaneDistance = 2; + + if ( spawnFlags & 8 ) { // use a DOWN normal + if ( spawnFlags & 16 ) { + // 24: normal as is, and zero width (broken) + VectorCopy( plane, bestNormal ); + } + else + { + // 8: normal as is + VectorCopy( plane, bestNormal ); + } + } + else + { + if ( spawnFlags & 16 ) { + // 16: UP/DOWN normal + VectorSet( bestNormal, 0, 0, ( plane[2] >= 0 ? 1 : -1 ) ); + } + else + { + // 0: axial normal + if ( fabs( plane[0] ) > fabs( plane[1] ) ) { // x>y + if ( fabs( plane[1] ) > fabs( plane[2] ) ) { // x>y, y>z + VectorSet( bestNormal, ( plane[0] >= 0 ? 1 : -1 ), 0, 0 ); + } + else // x>y, z>=y + if ( fabs( plane[0] ) > fabs( plane[2] ) ) { // x>z, z>=y + VectorSet( bestNormal, ( plane[0] >= 0 ? 1 : -1 ), 0, 0 ); + } + else{ // z>=x, x>y + VectorSet( bestNormal, 0, 0, ( plane[2] >= 0 ? 1 : -1 ) ); + } + } + else // y>=x + if ( fabs( plane[1] ) > fabs( plane[2] ) ) { // y>z, y>=x + VectorSet( bestNormal, 0, ( plane[1] >= 0 ? 1 : -1 ), 0 ); + } + else{ // z>=y, y>=x + VectorSet( bestNormal, 0, 0, ( plane[2] >= 0 ? 1 : -1 ) ); + } + } + } + + /* build a brush */ + buildBrush = AllocBrush( 48 ); + buildBrush->entityNum = mapEntityNum; + buildBrush->original = buildBrush; + buildBrush->contentShader = si; + buildBrush->compileFlags = si->compileFlags; + buildBrush->contentFlags = si->contentFlags; + normalEpsilon_save = normalEpsilon; + distanceEpsilon_save = distanceEpsilon; + if ( si->compileFlags & C_STRUCTURAL ) { // allow forced structural brushes here + buildBrush->detail = qfalse; + + // only allow EXACT matches when snapping for these (this is mostly for caulk brushes inside a model) + if ( normalEpsilon > 0 ) { + normalEpsilon = 0; + } + if ( distanceEpsilon > 0 ) { + distanceEpsilon = 0; + } + } + else{ + buildBrush->detail = qtrue; + } + /* regenerate back points */ for ( j = 0; j < 3; j++ ) { /* get vertex */ dv = &ds->verts[ ds->indexes[ i + j ] ]; - /* copy xyz */ - VectorCopy( dv->xyz, backs[ j ] ); - - /* find nearest axial to plane normal and push back points opposite */ - for ( k = 0; k < 3; k++ ) - { -#if Q3MAP2_EXPERIMENTAL_MODEL_CLIPPING_FIX - if ( fabs( plane[ k ] ) >= fabs( plane[ ( k + 1 ) % 3 ] ) && - fabs( plane[ k ] ) >= fabs( plane[ ( k + 2 ) % 3 ] ) ) -#else - // This code is broken for 45 degree angles where there - // is no clear winner. - if ( fabs( plane[ k ] ) > fabs( plane[ ( k + 1 ) % 3 ] ) && - fabs( plane[ k ] ) > fabs( plane[ ( k + 2 ) % 3 ] ) ) -#endif - { - backs[ j ][ k ] += plane[ k ] < 0.0f ? 64.0f : -64.0f; - break; - } - } + // shift by some units + VectorMA( dv->xyz, -64.0f, bestNormal, backs[j] ); // 64 prevents roundoff errors a bit } /* make back plane */ VectorScale( plane, -1.0f, reverse ); - reverse[ 3 ] = -( plane[ 3 ] - 1 ); - - /* make back pyramid point */ - VectorCopy( points[ 0 ], nadir ); - VectorAdd( nadir, points[ 1 ], nadir ); - VectorAdd( nadir, points[ 2 ], nadir ); - VectorScale( nadir, 0.3333333333333f, nadir ); - VectorMA( nadir, -2.0f, plane, nadir ); - - /* make 3 more planes */ - //% if( PlaneFromPoints( pa, points[ 2 ], points[ 1 ], nadir ) && - //% PlaneFromPoints( pb, points[ 1 ], points[ 0 ], nadir ) && - //% PlaneFromPoints( pc, points[ 0 ], points[ 2 ], nadir ) ) + reverse[ 3 ] = -plane[ 3 ]; + if ( ( spawnFlags & 24 ) != 24 ) { + reverse[3] += DotProduct( bestNormal, plane ) * backPlaneDistance; + } + // that's at least sqrt(1/3) backPlaneDistance, unless in DOWN mode; in DOWN mode, we are screwed anyway if we encounter a plane that's perpendicular to the xy plane) if ( PlaneFromPoints( pa, points[ 2 ], points[ 1 ], backs[ 1 ] ) && PlaneFromPoints( pb, points[ 1 ], points[ 0 ], backs[ 0 ] ) && PlaneFromPoints( pc, points[ 0 ], points[ 2 ], backs[ 2 ] ) ) { - /* build a brush */ - buildBrush = AllocBrush( 48 ); - - buildBrush->entityNum = mapEntityNum; - buildBrush->original = buildBrush; - buildBrush->contentShader = si; - buildBrush->compileFlags = si->compileFlags; - buildBrush->contentFlags = si->contentFlags; - buildBrush->detail = qtrue; /* set up brush sides */ buildBrush->numsides = 5; for ( j = 0; j < buildBrush->numsides; j++ ) buildBrush->sides[ j ].shaderInfo = si; - buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); - buildBrush->sides[ 1 ].planenum = FindFloatPlane( pa, pa[ 3 ], 1, &points[ 2 ] ); - buildBrush->sides[ 2 ].planenum = FindFloatPlane( pb, pb[ 3 ], 1, &points[ 1 ] ); - buildBrush->sides[ 3 ].planenum = FindFloatPlane( pc, pc[ 3 ], 1, &points[ 0 ] ); - buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 3, points ); - /* add to entity */ - if ( CreateBrushWindings( buildBrush ) ) { - AddBrushBevels(); - //% EmitBrushes( buildBrush, NULL, NULL ); - buildBrush->next = entities[ mapEntityNum ].brushes; - entities[ mapEntityNum ].brushes = buildBrush; - entities[ mapEntityNum ].numBrushes++; - } - else{ - free( buildBrush ); - } + buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); + buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points ); + buildBrush->sides[ 1 ].planenum = FindFloatPlane( pa, pa[ 3 ], 2, &points[ 1 ] ); // pa contains points[1] and points[2] + buildBrush->sides[ 2 ].planenum = FindFloatPlane( pb, pb[ 3 ], 2, &points[ 0 ] ); // pb contains points[0] and points[1] + buildBrush->sides[ 3 ].planenum = FindFloatPlane( pc, pc[ 3 ], 2, &points[ 2 ] ); // pc contains points[2] and points[0] (copied to points[3] + buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 3, backs ); + } + else + { + free( buildBrush ); + continue; + } + + normalEpsilon = normalEpsilon_save; + distanceEpsilon = distanceEpsilon_save; + + /* add to entity */ + if ( CreateBrushWindings( buildBrush ) ) { + AddBrushBevels(); + //% EmitBrushes( buildBrush, NULL, NULL ); + buildBrush->next = entities[ mapEntityNum ].brushes; + entities[ mapEntityNum ].brushes = buildBrush; + entities[ mapEntityNum ].numBrushes++; + } + else{ + free( buildBrush ); } } } diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 65b765fe..45ac915a 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -276,6 +276,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 ) ) @@ -288,6 +289,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 ) ) @@ -572,6 +574,7 @@ typedef struct game_s 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 */ int miniMapSize; /* minimap size */ float miniMapSharpen; /* minimap sharpening coefficient */ @@ -1430,6 +1433,7 @@ typedef struct rawLightmap_s float *superDeluxels; /* average light direction */ float *bspDeluxels; + float *superFloodLight; } rawLightmap_t; @@ -1498,7 +1502,7 @@ int BSPInfoMain( int argc, char **argv ); int ScaleBSPMain( int argc, char **argv ); /* minimap.c */ -int MiniMapBSPMain( int argc, char **argv ); +int MiniMapBSPMain( int argc, char **argv ); /* convert_bsp.c */ int ConvertBSPMain( int argc, char **argv ); @@ -1763,6 +1767,10 @@ void SetupDirt(); 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 ); @@ -2198,6 +2206,13 @@ Q_EXTERN float dirtDepth Q_ASSIGN( 128.0f ); 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 ); @@ -2217,6 +2232,7 @@ Q_EXTERN float bounceScale Q_ASSIGN( 0.25f ); /* 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 */ From 06701fab6949035aa6db37284d8c30b72d7dd0c7 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Tue, 11 Jan 2011 14:39:55 +0100 Subject: [PATCH 2/3] netradiant/tools: ::zerowing-base=422 former commit name: ::zerowing-base=422 --- tools/quake3/q3map2/map.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/tools/quake3/q3map2/map.c b/tools/quake3/q3map2/map.c index 56d579b5..4c1963bc 100644 --- a/tools/quake3/q3map2/map.c +++ b/tools/quake3/q3map2/map.c @@ -247,13 +247,7 @@ void SnapPlane( vec3_t normal, vec_t *dist, vec3_t center ){ SnapPlane reenabled by namespace because of multiple reports of q3map2-crashes which were triggered by this patch. */ - // div0: ensure the point "center" stays on the plane (actually, this - // rotates the plane around the point center). - // if center lies on the plane, it is guaranteed to stay on the plane by - // this fix. - vec_t centerDist = DotProduct( normal, center ); SnapNormal( normal ); - *dist += ( DotProduct( normal, center ) - centerDist ); // TODO: Rambetter has some serious comments here as well. First off, // in the case where a normal is non-axial, there is nothing special @@ -329,16 +323,11 @@ int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points ) / int i, j, hash, h; plane_t *p; vec_t d; - vec3_t centerofweight; - - VectorClear( centerofweight ); - for ( i = 0; i < numPoints; ++i ) - VectorMA( centerofweight, 1.0 / numPoints, points[i], centerofweight ); #if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points ); #else - SnapPlane( normal, &dist, centerofweight ); + SnapPlane( normal, &dist ); #endif /* hash the plane */ hash = ( PLANE_HASHES - 1 ) & (int) fabs( dist ); @@ -392,13 +381,7 @@ int FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points ) / #if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points ); #else - vec3_t centerofweight; - - VectorClear( centerofweight ); - for ( i = 0; i < numPoints; ++i ) - VectorMA( centerofweight, 1.0 / numPoints, points[i], centerofweight ); - - SnapPlane( normal, &dist, centerofweight ); + SnapPlane( normal, &dist ); #endif for ( i = 0, p = mapplanes; i < nummapplanes; i++, p++ ) { From 533587bf2549aaa5258c6e97a4245a97a299f4ec Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Thu, 9 Feb 2012 10:40:48 +0100 Subject: [PATCH 3/3] swap values 0 and 1 for -exposure (now -exposure 0 does nothing, -exposure 1 did what 0 did before) --- tools/quake3/q3map2/game_ef.h | 2 +- tools/quake3/q3map2/game_etut.h | 2 +- tools/quake3/q3map2/game_ja.h | 2 +- tools/quake3/q3map2/game_jk2.h | 2 +- tools/quake3/q3map2/game_nexuiz.h | 2 +- tools/quake3/q3map2/game_qfusion.h | 2 +- tools/quake3/q3map2/game_quake3.h | 2 +- tools/quake3/q3map2/game_quakelive.h | 2 +- tools/quake3/q3map2/game_reaction.h | 2 +- tools/quake3/q3map2/game_sof2.h | 2 +- tools/quake3/q3map2/game_tenebrae.h | 2 +- tools/quake3/q3map2/game_tremulous.h | 2 +- tools/quake3/q3map2/game_wolf.h | 2 +- tools/quake3/q3map2/game_wolfet.h | 2 +- tools/quake3/q3map2/light_ydnar.c | 5 +---- tools/quake3/q3map2/q3map2.h | 2 +- 16 files changed, 16 insertions(+), 19 deletions(-) diff --git a/tools/quake3/q3map2/game_ef.h b/tools/quake3/q3map2/game_ef.h index 5a924e88..639324e7 100644 --- a/tools/quake3/q3map2/game_ef.h +++ b/tools/quake3/q3map2/game_ef.h @@ -113,7 +113,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_etut.h b/tools/quake3/q3map2/game_etut.h index 4e15d10f..2b0cc689 100644 --- a/tools/quake3/q3map2/game_etut.h +++ b/tools/quake3/q3map2/game_etut.h @@ -148,7 +148,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 2.2f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_ja.h b/tools/quake3/q3map2/game_ja.h index 67ddf27a..2931b0a9 100644 --- a/tools/quake3/q3map2/game_ja.h +++ b/tools/quake3/q3map2/game_ja.h @@ -67,7 +67,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_jk2.h b/tools/quake3/q3map2/game_jk2.h index f08d05a3..bd0568e7 100644 --- a/tools/quake3/q3map2/game_jk2.h +++ b/tools/quake3/q3map2/game_jk2.h @@ -64,7 +64,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_nexuiz.h b/tools/quake3/q3map2/game_nexuiz.h index 41dc2b83..2fe63730 100644 --- a/tools/quake3/q3map2/game_nexuiz.h +++ b/tools/quake3/q3map2/game_nexuiz.h @@ -63,7 +63,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_qfusion.h b/tools/quake3/q3map2/game_qfusion.h index 5ddc91bf..3021c1aa 100644 --- a/tools/quake3/q3map2/game_qfusion.h +++ b/tools/quake3/q3map2/game_qfusion.h @@ -112,7 +112,7 @@ qfalse, /* wolf lighting model? */ 512, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 256, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_quake3.h b/tools/quake3/q3map2/game_quake3.h index 6dc0edba..8a60dd54 100644 --- a/tools/quake3/q3map2/game_quake3.h +++ b/tools/quake3/q3map2/game_quake3.h @@ -112,7 +112,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_quakelive.h b/tools/quake3/q3map2/game_quakelive.h index e5d38075..e039adba 100644 --- a/tools/quake3/q3map2/game_quakelive.h +++ b/tools/quake3/q3map2/game_quakelive.h @@ -76,7 +76,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_reaction.h b/tools/quake3/q3map2/game_reaction.h index 242ff6a9..2b8216f9 100644 --- a/tools/quake3/q3map2/game_reaction.h +++ b/tools/quake3/q3map2/game_reaction.h @@ -84,7 +84,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_sof2.h b/tools/quake3/q3map2/game_sof2.h index 7d86612b..cbfbc0fc 100644 --- a/tools/quake3/q3map2/game_sof2.h +++ b/tools/quake3/q3map2/game_sof2.h @@ -139,7 +139,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_tenebrae.h b/tools/quake3/q3map2/game_tenebrae.h index 57e81c4f..ccfc5ad1 100644 --- a/tools/quake3/q3map2/game_tenebrae.h +++ b/tools/quake3/q3map2/game_tenebrae.h @@ -112,7 +112,7 @@ qfalse, /* wolf lighting model? */ 512, /* lightmap width/height */ 2.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_tremulous.h b/tools/quake3/q3map2/game_tremulous.h index d9b25e29..9fc5f3af 100644 --- a/tools/quake3/q3map2/game_tremulous.h +++ b/tools/quake3/q3map2/game_tremulous.h @@ -70,7 +70,7 @@ qfalse, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_wolf.h b/tools/quake3/q3map2/game_wolf.h index ac4b7526..aa5c9f2d 100644 --- a/tools/quake3/q3map2/game_wolf.h +++ b/tools/quake3/q3map2/game_wolf.h @@ -129,7 +129,7 @@ qtrue, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/game_wolfet.h b/tools/quake3/q3map2/game_wolfet.h index 95b30918..fa95eeb0 100644 --- a/tools/quake3/q3map2/game_wolfet.h +++ b/tools/quake3/q3map2/game_wolfet.h @@ -66,7 +66,7 @@ qtrue, /* wolf lighting model? */ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ - 1.0f, /* lightmap exposure */ + 0.0f, /* lightmap exposure */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ diff --git a/tools/quake3/q3map2/light_ydnar.c b/tools/quake3/q3map2/light_ydnar.c index 98df332b..b2114f7c 100644 --- a/tools/quake3/q3map2/light_ydnar.c +++ b/tools/quake3/q3map2/light_ydnar.c @@ -73,7 +73,7 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ sample[ i ] = pow( sample[ i ] / 255.0f, gamma ) * 255.0f; } - if ( lightmapExposure == 1 ) { + if ( lightmapExposure == 0 ) { /* clamp with color normalization */ max = sample[ 0 ]; if ( sample[ 1 ] > max ) { @@ -88,9 +88,6 @@ void ColorToBytes( const float *color, byte *colorBytes, float scale ){ } else { - if ( lightmapExposure == 0 ) { - lightmapExposure = 1.0f; - } inv = 1.f / lightmapExposure; //Exposure diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 45ac915a..0b324618 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -2232,7 +2232,7 @@ Q_EXTERN float bounceScale Q_ASSIGN( 0.25f ); /* ydnar: lightmap gamma/compensation */ Q_EXTERN float lightmapGamma Q_ASSIGN( 1.0f ); -Q_EXTERN float lightmapExposure Q_ASSIGN( 1.0f ); +Q_EXTERN float lightmapExposure Q_ASSIGN( 0.0f ); Q_EXTERN float lightmapCompensate Q_ASSIGN( 1.0f ); /* ydnar: for runtime tweaking of falloff tolerance */