From 3ece673e687e2be4f0d037583bbff069b2a6fe91 Mon Sep 17 00:00:00 2001 From: div0 Date: Tue, 29 Jul 2008 16:44:36 +0000 Subject: [PATCH] don't need the old-q3map2 patches any more git-svn-id: svn://svn.icculus.org/nexuiz/trunk@3979 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- misc/gtkradiant/singlepatches/both-obj.diff | 103 --- .../singlepatches/q3map2-UTavgcolorfix.diff | 20 - .../singlepatches/q3map2-UTfloodlight.diff | 625 ------------------ .../singlepatches/q3map2-UTtrianglecheck.diff | 280 -------- .../singlepatches/q3map2-decomptexcoords.diff | 264 -------- .../singlepatches/q3map2-snapplane.diff | 287 -------- 6 files changed, 1579 deletions(-) delete mode 100644 misc/gtkradiant/singlepatches/both-obj.diff delete mode 100644 misc/gtkradiant/singlepatches/q3map2-UTavgcolorfix.diff delete mode 100644 misc/gtkradiant/singlepatches/q3map2-UTfloodlight.diff delete mode 100644 misc/gtkradiant/singlepatches/q3map2-UTtrianglecheck.diff delete mode 100644 misc/gtkradiant/singlepatches/q3map2-decomptexcoords.diff delete mode 100644 misc/gtkradiant/singlepatches/q3map2-snapplane.diff diff --git a/misc/gtkradiant/singlepatches/both-obj.diff b/misc/gtkradiant/singlepatches/both-obj.diff deleted file mode 100644 index 77e03a9a0..000000000 --- a/misc/gtkradiant/singlepatches/both-obj.diff +++ /dev/null @@ -1,103 +0,0 @@ -Index: libs/picomodel/pm_obj.c -=================================================================== ---- libs/picomodel/pm_obj.c (revision 290) -+++ libs/picomodel/pm_obj.c (working copy) -@@ -215,10 +215,9 @@ - } - } - --#if 0 - static int _obj_mtl_load( picoModel_t *model ) - { -- //picoShader_t *curShader = NULL; -+ picoShader_t *curShader = NULL; - picoParser_t *p; - picoByte_t *mtlBuffer; - int mtlBufSize; -@@ -266,7 +265,7 @@ - /* get next token in material file */ - if (_pico_parse( p,1 ) == NULL) - break; --#if 0 -+#if 1 - - /* skip empty lines */ - if (p->token == NULL || !strlen( p->token )) -@@ -308,6 +307,7 @@ - else if (!_pico_stricmp(p->token,"map_kd")) - { - char *mapName; -+ picoShader_t *shader; - - /* pointer to current shader must be valid */ - if (curShader == NULL) -@@ -322,6 +322,10 @@ - _pico_printf( PICO_ERROR,"Missing material map name in MTL, line %d.",p->curLine); - _obj_mtl_error_return; - } -+ /* create a new pico shader */ -+ shader = PicoNewShader( model ); -+ if (shader == NULL) -+ _obj_mtl_error_return; - /* set shader map name */ - PicoSetShaderMapName( shader,mapName ); - } -@@ -478,7 +482,6 @@ - /* return with success */ - return 1; - } --#endif - - /* _obj_load: - * loads a wavefront obj model file. -@@ -523,7 +526,7 @@ - PicoSetModelFileName( model,fileName ); - - /* try loading the materials; we don't handle the result */ --#if 0 -+#if 1 - _obj_mtl_load( model ); - #endif - -@@ -832,6 +835,41 @@ - curVertex += max; - } - } -+ else if (!_pico_stricmp(p->token,"usemtl")) -+ { -+ picoShader_t *shader; -+ char *name; -+ -+ /* get material name */ -+ name = _pico_parse( p,0 ); -+ -+ /* validate material name */ -+ if (name == NULL || !strlen(name)) -+ { -+ _pico_printf( PICO_ERROR,"Missing material name in OBJ, line %d.",p->curLine); -+ } -+ else -+ { -+ shader = PicoFindShader( model, name, 1 ); -+ if (shader == NULL) -+ { -+ _pico_printf( PICO_ERROR,"Undefined material name in OBJ, line %d. Making a default shader.",p->curLine); -+ -+ /* create a new pico shader */ -+ shader = PicoNewShader( model ); -+ if (shader != NULL) -+ { -+ PicoSetShaderName( shader,name ); -+ PicoSetShaderMapName( shader,name ); -+ PicoSetSurfaceShader( curSurface, shader ); -+ } -+ } -+ else -+ { -+ PicoSetSurfaceShader( curSurface, shader ); -+ } -+ } -+ } - /* skip unparsed rest of line and continue */ - _pico_parse_skip_rest( p ); - } diff --git a/misc/gtkradiant/singlepatches/q3map2-UTavgcolorfix.diff b/misc/gtkradiant/singlepatches/q3map2-UTavgcolorfix.diff deleted file mode 100644 index f920c78f9..000000000 --- a/misc/gtkradiant/singlepatches/q3map2-UTavgcolorfix.diff +++ /dev/null @@ -1,20 +0,0 @@ -Index: tools/quake3/q3map2/shaders.c -=================================================================== ---- tools/quake3/q3map2/shaders.c (revision 290) -+++ tools/quake3/q3map2/shaders.c (working copy) -@@ -747,8 +747,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 ); -+ } - } - - diff --git a/misc/gtkradiant/singlepatches/q3map2-UTfloodlight.diff b/misc/gtkradiant/singlepatches/q3map2-UTfloodlight.diff deleted file mode 100644 index 1b579f1b0..000000000 --- a/misc/gtkradiant/singlepatches/q3map2-UTfloodlight.diff +++ /dev/null @@ -1,625 +0,0 @@ -Index: tools/quake3/q3map2/light_ydnar.c -=================================================================== ---- tools/quake3/q3map2/light_ydnar.c (revision 290) -+++ tools/quake3/q3map2/light_ydnar.c (working copy) -@@ -1449,6 +1449,8 @@ - vec3_t color, averageColor, averageDir, total, temp, temp2; - float tests[ 4 ][ 2 ] = { { 0.0f, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } }; - trace_t trace; -+ vec3_t flood; -+ float *floodlight; - - - /* bail if this number exceeds the number of raw lightmaps */ -@@ -1871,6 +1873,78 @@ - /* 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; -+ } -+ } -+ } -+ } -+ - /* ----------------------------------------------------------------- - filter pass - ----------------------------------------------------------------- */ -@@ -3123,7 +3197,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 290) -+++ tools/quake3/q3map2/light.c (working copy) -@@ -1363,6 +1363,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 ); - -@@ -1544,6 +1594,12 @@ - qboolean minVertex, minGrid; - const char *value; - -+ /* floodlight them up */ -+ if( floodlighty ) -+ { -+ Sys_Printf( "--- FloodlightRawLightmap ---\n" ); -+ RunThreadsOnIndividual( numRawLightmaps, qtrue, FloodLightRawLightmap ); -+ } - - /* ydnar: smooth normals */ - if( shade ) -@@ -1675,6 +1731,7 @@ - /* flag bouncing */ - bouncing = qtrue; - VectorClear( ambientColor ); -+ floodlighty = qfalse; - - /* generate diffuse lights */ - RadFreeLights(); -@@ -2114,6 +2171,21 @@ - loMem = qtrue; - Sys_Printf( "Enabling low-memory (potentially slower) lighting mode\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" ); -+ } - - else - Sys_Printf( "WARNING: Unknown option \"%s\"\n", argv[ i ] ); -@@ -2156,6 +2228,7 @@ - - /* ydnar: set up optimization */ - SetupBrushes(); -+ SetupFloodLight(); - SetupSurfaceLightmaps(); - - /* initialize the surface facet tracing */ -Index: tools/quake3/q3map2/lightmaps_ydnar.c -=================================================================== ---- tools/quake3/q3map2/lightmaps_ydnar.c (revision 290) -+++ tools/quake3/q3map2/lightmaps_ydnar.c (working copy) -@@ -413,6 +413,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/q3map2.h -=================================================================== ---- tools/quake3/q3map2/q3map2.h (revision 290) -+++ tools/quake3/q3map2/q3map2.h (working copy) -@@ -265,6 +265,7 @@ - #define SUPER_NORMAL_SIZE 3 - #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)) -@@ -273,6 +274,7 @@ - #define SUPER_LUXEL( s, x, y ) (lm->superLuxels[ s ] + ((((y) * lm->sw) + (x)) * SUPER_LUXEL_SIZE)) - #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_FLOODLIGHT( x, y ) (lm->superFloodLight + ((((y) * lm->sw) + (x)) * SUPER_FLOODLIGHT_SIZE) ) - #define SUPER_CLUSTER( x, y ) (lm->superClusters + (((y) * lm->sw) + (x))) - #define SUPER_DELUXEL( x, y ) (lm->superDeluxels + ((((y) * lm->sw) + (x)) * SUPER_DELUXEL_SIZE)) - #define BSP_DELUXEL( x, y ) (lm->bspDeluxels + ((((y) * lm->w) + (x)) * BSP_DELUXEL_SIZE)) -@@ -1364,6 +1366,7 @@ - - float *superDeluxels; /* average light direction */ - float *bspDeluxels; -+ float *superFloodLight; - } - rawLightmap_t; - -@@ -1670,6 +1673,9 @@ - void SmoothNormals( void ); - - void MapRawLightmap( int num ); -+void SetupFloodLight(); -+float FloodLightForSample( trace_t *trace ); -+void FloodLightRawLightmap( int num ); - void IlluminateRawLightmap( int num ); - void IlluminateVertexes( int num ); - -@@ -2037,6 +2043,12 @@ - Q_EXTERN qboolean sunOnly; - Q_EXTERN int approximateTolerance Q_ASSIGN( 0 ); - Q_EXTERN qboolean noCollapse; -+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 debug; - Q_EXTERN qboolean debugSurfaces; - Q_EXTERN qboolean debugUnused; -Index: tools/quake3/q3map2/q3map2.h -=================================================================== ---- tools/quake3/q3map2/q3map2.h (revision 290) -+++ tools/quake3/q3map2/q3map2.h (working copy) -@@ -1274,6 +1274,7 @@ - vec3_t color; /* starts out at full color, may be reduced if transparent surfaces are crossed */ - - /* output */ -+ vec3_t hit; - int compileFlags; /* for determining surface compile flags traced through */ - qboolean passSolid; - qboolean opaque; -Index: tools/quake3/q3map2/light_trace.c -=================================================================== ---- tools/quake3/q3map2/light_trace.c (revision 290) -+++ tools/quake3/q3map2/light_trace.c (working copy) -@@ -1596,6 +1596,7 @@ - /* bogus node number means solid, end tracing unless testing all */ - if( nodeNum < 0 ) - { -+ VectorCopy( origin, trace->hit ); - trace->passSolid = qtrue; - return qtrue; - } -@@ -1606,6 +1607,7 @@ - /* solid? */ - if( node->type == TRACE_LEAF_SOLID ) - { -+ VectorCopy( origin, trace->hit ); - trace->passSolid = qtrue; - return qtrue; - } diff --git a/misc/gtkradiant/singlepatches/q3map2-UTtrianglecheck.diff b/misc/gtkradiant/singlepatches/q3map2-UTtrianglecheck.diff deleted file mode 100644 index 724f11cdc..000000000 --- a/misc/gtkradiant/singlepatches/q3map2-UTtrianglecheck.diff +++ /dev/null @@ -1,280 +0,0 @@ -Index: tools/quake3/q3map2/light_ydnar.c -=================================================================== ---- tools/quake3/q3map2/light_ydnar.c (revision 290) -+++ tools/quake3/q3map2/light_ydnar.c (working copy) -@@ -372,7 +372,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; -@@ -380,6 +380,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 ] = - { -@@ -473,6 +479,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 ) -@@ -504,8 +555,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; -@@ -521,14 +577,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; - } - } -@@ -538,8 +594,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; - } - -@@ -585,7 +641,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; -@@ -633,7 +689,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 ); -@@ -641,12 +697,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 ); - } - - -@@ -662,6 +718,7 @@ - int i; - vec4_t plane; - vec3_t *stv, *ttv, stvStatic[ 3 ], ttvStatic[ 3 ]; -+ vec3_t worldverts[ 3 ]; - - - /* get plane if possible */ -@@ -687,16 +744,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; - } - -@@ -718,7 +779,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 ); - } - } - -@@ -780,8 +841,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 ) -@@ -866,10 +927,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 ); -@@ -1161,7 +1222,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 ); - } - } - } -@@ -1636,22 +1697,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 ) diff --git a/misc/gtkradiant/singlepatches/q3map2-decomptexcoords.diff b/misc/gtkradiant/singlepatches/q3map2-decomptexcoords.diff deleted file mode 100644 index 3f19de8a5..000000000 --- a/misc/gtkradiant/singlepatches/q3map2-decomptexcoords.diff +++ /dev/null @@ -1,264 +0,0 @@ -Index: tools/quake3/q3map2/convert_map.c -=================================================================== ---- tools/quake3/q3map2/convert_map.c (revision 290) -+++ tools/quake3/q3map2/convert_map.c (working copy) -@@ -45,6 +45,105 @@ - #define SNAP_FLOAT_TO_INT 4 - #define SNAP_INT_TO_FLOAT (1.0 / SNAP_FLOAT_TO_INT) - -+typedef vec_t vec2_t[2]; -+ -+static vec_t Det3x3(vec_t a00, vec_t a01, vec_t a02, -+ vec_t a10, vec_t a11, vec_t a12, -+ vec_t a20, vec_t a21, vec_t a22) -+{ -+ return -+ a00 * (a11 * a22 - a12 * a21) -+ - a01 * (a10 * a22 - a12 * a20) -+ + a02 * (a10 * a21 - a11 * a20); -+} -+ -+void GetBestSurfaceTriangleMatchForBrushside(side_t *buildSide, bspDrawVert_t *bestVert[3]) -+{ -+ bspDrawSurface_t *s; -+ int i; -+ int t; -+ vec_t best = 0; -+ vec_t thisarea; -+ vec3_t normdiff; -+ vec3_t v1v0, v2v0, norm; -+ bspDrawVert_t *vert[3]; -+ winding_t *polygon; -+ plane_t *buildPlane = &mapplanes[buildSide->planenum]; -+ int matches = 0; -+ -+ // first, start out with NULLs -+ bestVert[0] = bestVert[1] = bestVert[2] = NULL; -+ -+ // brute force through all surfaces -+ for(s = bspDrawSurfaces; s != bspDrawSurfaces + numBSPDrawSurfaces; ++s) -+ { -+ if(s->surfaceType != MST_PLANAR && s->surfaceType != MST_TRIANGLE_SOUP) -+ continue; -+ if(strcmp(buildSide->shaderInfo->shader, bspShaders[s->shaderNum].shader)) -+ continue; -+ for(t = 0; t + 3 <= s->numIndexes; t += 3) -+ { -+ vert[0] = &bspDrawVerts[s->firstVert + bspDrawIndexes[s->firstIndex + t + 0]]; -+ vert[1] = &bspDrawVerts[s->firstVert + bspDrawIndexes[s->firstIndex + t + 1]]; -+ vert[2] = &bspDrawVerts[s->firstVert + bspDrawIndexes[s->firstIndex + t + 2]]; -+ if(s->surfaceType == MST_PLANAR) -+ { -+ VectorSubtract(vert[0]->normal, buildPlane->normal, normdiff); if(VectorLength(normdiff) >= normalEpsilon) continue; -+ VectorSubtract(vert[1]->normal, buildPlane->normal, normdiff); if(VectorLength(normdiff) >= normalEpsilon) continue; -+ VectorSubtract(vert[2]->normal, buildPlane->normal, normdiff); if(VectorLength(normdiff) >= normalEpsilon) continue; -+ } -+ else -+ { -+ // this is more prone to roundoff errors, but with embedded -+ // models, there is no better way -+ VectorSubtract(vert[1]->xyz, vert[0]->xyz, v1v0); -+ VectorSubtract(vert[2]->xyz, vert[0]->xyz, v2v0); -+ CrossProduct(v2v0, v1v0, norm); -+ VectorNormalize(norm, norm); -+ VectorSubtract(norm, buildPlane->normal, normdiff); if(VectorLength(normdiff) >= normalEpsilon) continue; -+ } -+ if(abs(DotProduct(vert[0]->xyz, buildPlane->normal) - buildPlane->dist) >= distanceEpsilon) continue; -+ if(abs(DotProduct(vert[1]->xyz, buildPlane->normal) - buildPlane->dist) >= distanceEpsilon) continue; -+ if(abs(DotProduct(vert[2]->xyz, buildPlane->normal) - buildPlane->dist) >= distanceEpsilon) continue; -+ // Okay. Correct surface type, correct shader, correct plane. Let's start with the business... -+ polygon = CopyWinding(buildSide->winding); -+ for(i = 0; i < 3; ++i) -+ { -+ // 0: 1, 2 -+ // 1: 2, 0 -+ // 2; 0, 1 -+ vec3_t *v1 = &vert[(i+1)%3]->xyz; -+ vec3_t *v2 = &vert[(i+2)%3]->xyz; -+ vec3_t triNormal; -+ vec_t triDist; -+ vec3_t sideDirection; -+ // we now need to generate triNormal and triDist so that they represent the plane spanned by normal and (v2 - v1). -+ VectorSubtract(*v2, *v1, sideDirection); -+ CrossProduct(sideDirection, buildPlane->normal, triNormal); -+ triDist = DotProduct(*v1, triNormal); -+ ChopWindingInPlace(&polygon, triNormal, triDist, distanceEpsilon); -+ if(!polygon) -+ goto exwinding; -+ } -+ thisarea = WindingArea(polygon); -+ if(thisarea > 0) -+ ++matches; -+ if(thisarea > best) -+ { -+ best = thisarea; -+ bestVert[0] = vert[0]; -+ bestVert[1] = vert[1]; -+ bestVert[2] = vert[2]; -+ } -+ FreeWinding(polygon); -+exwinding: -+ ; -+ } -+ } -+ //if(strncmp(buildSide->shaderInfo->shader, "textures/common/", 16)) -+ // fprintf(stderr, "brushside with %s: %d matches (%f area)\n", buildSide->shaderInfo->shader, matches, best); -+} -+ - static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin ) - { - int i, j; -@@ -53,12 +152,17 @@ - bspShader_t *shader; - char *texture; - bspPlane_t *plane; -+ plane_t *buildPlane; - vec3_t pts[ 3 ]; -+ bspDrawVert_t *vert[3]; -+ int valid; - - - /* start brush */ - fprintf( f, "\t// brush %d\n", num ); - fprintf( f, "\t{\n" ); -+ fprintf( f, "\tbrushDef\n" ); -+ fprintf( f, "\t{\n" ); - - /* clear out build brush */ - for( i = 0; i < buildBrush->numsides; i++ ) -@@ -108,9 +212,88 @@ - /* get build side */ - buildSide = &buildBrush->sides[ i ]; - -+ /* get plane */ -+ buildPlane = &mapplanes[ buildSide->planenum ]; -+ - /* dummy check */ - if( buildSide->shaderInfo == NULL || buildSide->winding == NULL ) - continue; -+ -+ // st-texcoords -> texMat block -+ // start out with dummy -+ VectorSet(buildSide->texMat[0], 1/32.0, 0, 0); -+ VectorSet(buildSide->texMat[1], 0, 1/32.0, 0); -+ -+ // find surface for this side (by brute force) -+ // surface format: -+ // - meshverts point in pairs of three into verts -+ // - (triangles) -+ // - find the triangle that has most in common with our side -+ GetBestSurfaceTriangleMatchForBrushside(buildSide, vert); -+ valid = 0; -+ -+ if(vert[0] && vert[1] && vert[2]) -+ { -+ int i; -+ vec3_t texX, texY; -+ vec3_t xy1I, xy1J, xy1K; -+ vec2_t stI, stJ, stK; -+ vec_t D, D0, D1, D2; -+ -+ ComputeAxisBase(buildPlane->normal, texX, texY); -+ -+ VectorSet(xy1I, DotProduct(vert[0]->xyz, texX), DotProduct(vert[0]->xyz, texY), 1); -+ VectorSet(xy1J, DotProduct(vert[1]->xyz, texX), DotProduct(vert[1]->xyz, texY), 1); -+ VectorSet(xy1K, DotProduct(vert[2]->xyz, texX), DotProduct(vert[2]->xyz, texY), 1); -+ stI[0] = vert[0]->st[0]; stI[1] = vert[0]->st[1]; -+ stJ[0] = vert[1]->st[0]; stJ[1] = vert[1]->st[1]; -+ stK[0] = vert[2]->st[0]; stK[1] = vert[2]->st[1]; -+ -+ // - solve linear equations: -+ // - (x, y) := xyz . (texX, texY) -+ // - st[i] = texMat[i][0]*x + texMat[i][1]*y + texMat[i][2] -+ // (for three vertices) -+ D = Det3x3( -+ xy1I[0], xy1I[1], 1, -+ xy1J[0], xy1J[1], 1, -+ xy1K[0], xy1K[1], 1 -+ ); -+ if(D != 0) -+ { -+ for(i = 0; i < 2; ++i) -+ { -+ D0 = Det3x3( -+ stI[i], xy1I[1], 1, -+ stJ[i], xy1J[1], 1, -+ stK[i], xy1K[1], 1 -+ ); -+ D1 = Det3x3( -+ xy1I[0], stI[i], 1, -+ xy1J[0], stJ[i], 1, -+ xy1K[0], stK[i], 1 -+ ); -+ D2 = Det3x3( -+ xy1I[0], xy1I[1], stI[i], -+ xy1J[0], xy1J[1], stJ[i], -+ xy1K[0], xy1K[1], stK[i] -+ ); -+ VectorSet(buildSide->texMat[i], D0 / D, D1 / D, D2 / D); -+ valid = 1; -+ } -+ } -+ else -+ fprintf(stderr, "degenerate triangle found when solving texMat equations for\n(%f %f %f) (%f %f %f) (%f %f %f)\n( %f %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n", -+ buildPlane->normal[0], buildPlane->normal[1], buildPlane->normal[2], -+ vert[0]->normal[0], vert[0]->normal[1], vert[0]->normal[2], -+ texX[0], texX[1], texX[2], texY[0], texY[1], texY[2], -+ vert[0]->xyz[0], vert[0]->xyz[1], vert[0]->xyz[2], xy1I[0], xy1I[1], -+ vert[1]->xyz[0], vert[1]->xyz[1], vert[1]->xyz[2], xy1J[0], xy1J[1], -+ vert[2]->xyz[0], vert[2]->xyz[1], vert[2]->xyz[2], xy1K[0], xy1K[1] -+ ); -+ } -+ else -+ if(strncmp(buildSide->shaderInfo->shader, "textures/common/", 16)) -+ fprintf(stderr, "no matching triangle for brushside using %s (hopefully nobody can see this side anyway)\n", buildSide->shaderInfo->shader); - - /* get texture name */ - if( !Q_strncasecmp( buildSide->shaderInfo->shader, "textures/", 9 ) ) -@@ -129,14 +312,21 @@ - - /* print brush side */ - /* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk 0 48 0 0.500000 0.500000 0 0 0 */ -- fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) %s 0 0 0 0.5 0.5 0 0 0\n", -+ fprintf( f, "\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n", - pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ], - pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ], - pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ], -- texture ); -+ buildSide->texMat[0][0], buildSide->texMat[0][1], buildSide->texMat[0][2], -+ buildSide->texMat[1][0], buildSide->texMat[1][1], buildSide->texMat[1][2], -+ texture, -+ // DEBUG: valid ? 0 : C_DETAIL -+ 0 -+ ); -+ // TODO write brush primitives format here - } - - /* end brush */ -+ fprintf( f, "\t}\n" ); - fprintf( f, "\t}\n\n" ); - } - -Index: tools/quake3/q3map2/main.c -=================================================================== ---- tools/quake3/q3map2/main.c (revision 290) -+++ tools/quake3/q3map2/main.c (working copy) -@@ -276,6 +276,18 @@ - else - Sys_Printf( "Unknown conversion format \"%s\". Defaulting to ASE.\n", argv[ i ] ); - } -+ else if( !strcmp( argv[ i ], "-ne" ) ) -+ { -+ normalEpsilon = atof( argv[ i + 1 ] ); -+ i++; -+ Sys_Printf( "Normal epsilon set to %f\n", normalEpsilon ); -+ } -+ else if( !strcmp( argv[ i ], "-de" ) ) -+ { -+ distanceEpsilon = atof( argv[ i + 1 ] ); -+ i++; -+ Sys_Printf( "Distance epsilon set to %f\n", distanceEpsilon ); -+ } - } - - /* clean up map name */ diff --git a/misc/gtkradiant/singlepatches/q3map2-snapplane.diff b/misc/gtkradiant/singlepatches/q3map2-snapplane.diff deleted file mode 100644 index 56fe516e7..000000000 --- a/misc/gtkradiant/singlepatches/q3map2-snapplane.diff +++ /dev/null @@ -1,287 +0,0 @@ -Index: tools/quake3/q3map2/model.c -=================================================================== ---- tools/quake3/q3map2/model.c (revision 290) -+++ tools/quake3/q3map2/model.c (working copy) -@@ -221,6 +221,8 @@ - byte *color; - picoIndex_t *indexes; - remap_t *rm, *glob; -+ double normalEpsilon_save; -+ double distanceEpsilon_save; - - - /* get model */ -@@ -399,9 +401,8 @@ - /* 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 */ -@@ -437,90 +438,141 @@ - /* 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; - } - } - } -+ -+ 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( fabs( plane[ k ] ) > fabs( plane[ (k + 1) % 3 ] ) && -- fabs( plane[ k ] ) > fabs( plane[ (k + 2) % 3 ] ) ) -- { -- 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 ] ) ) -+ 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[ 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 ); - } - } - } -Index: tools/quake3/q3map2/map.c -=================================================================== ---- tools/quake3/q3map2/map.c (revision 290) -+++ tools/quake3/q3map2/map.c (working copy) -@@ -183,9 +183,15 @@ - 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 ) - { -- SnapNormal( normal ); -+ // 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); - - if( fabs( *dist - Q_rint( *dist ) ) < distanceEpsilon ) - *dist = Q_rint( *dist ); -@@ -199,7 +205,7 @@ - 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 - -@@ -207,10 +213,14 @@ - 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); - -- - /* hash the plane */ -- SnapPlane( normal, &dist ); -+ SnapPlane( normal, &dist, centerofweight ); - hash = (PLANE_HASHES - 1) & (int) fabs( dist ); - - /* search the border bins as well */ -@@ -251,7 +261,13 @@ - plane_t *p; - - -- 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 ); - for( i = 0, p = mapplanes; i < nummapplanes; i++, p++ ) - { - if( PlaneEqual( p, normal, dist ) ) -- 2.39.2