From: Rudolf Polzer Date: Tue, 15 May 2012 10:03:08 +0000 (+0200) Subject: Merge remote-tracking branch 'origin/divVerent/speedup-patch' into divVerent/speedup... X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=244d8cc9222ba45435b14ca2fe70fd2a36f48775;p=xonotic%2Fnetradiant.git Merge remote-tracking branch 'origin/divVerent/speedup-patch' into divVerent/speedup-patch Conflicts: libs/mathlib.h libs/mathlib/mathlib.c tools/quake3/q3map2/light.c tools/quake3/q3map2/light_trace.c --- 244d8cc9222ba45435b14ca2fe70fd2a36f48775 diff --cc libs/mathlib.h index 64f3f6e4,02ed6fd0..fb135b8a --- a/libs/mathlib.h +++ b/libs/mathlib.h @@@ -101,16 -101,22 +101,22 @@@ void _CrossProduct( vec3_t v1, vec3_t v // I need this define in order to test some of the regression tests from time to time. // This define affect the precision of VectorNormalize() function only. #define MATHLIB_VECTOR_NORMALIZE_PRECISION_FIX 1 - vec_t VectorNormalize( const vec3_t in, vec3_t out ); -vec_t VectorAccurateNormalize (const vec3_t in, vec3_t out); -vec_t VectorFastNormalize (const vec3_t in, vec3_t out); ++vec_t VectorAccurateNormalize( const vec3_t in, vec3_t out ); ++vec_t VectorFastNormalize( const vec3_t in, vec3_t out ); + #if MATHLIB_VECTOR_NORMALIZE_PRECISION_FIX + #define VectorNormalize VectorAccurateNormalize + #else + #define VectorNormalize VectorFastNormalize + #endif vec_t ColorNormalize( const vec3_t in, vec3_t out ); -void VectorInverse (vec3_t v); -void VectorPolar(vec3_t v, float radius, float theta, float phi); +void VectorInverse( vec3_t v ); +void VectorPolar( vec3_t v, float radius, float theta, float phi ); // default snapping, to 1 -void VectorSnap(vec3_t v); +void VectorSnap( vec3_t v ); // integer snapping -void VectorISnap(vec3_t point, int snap); +void VectorISnap( vec3_t point, int snap ); // Gef: added snap to float for sub-integer grid sizes // TTimo: we still use the int version of VectorSnap when possible diff --cc libs/mathlib/mathlib.c index ce6cfdc2,41d1496d..642f9842 --- a/libs/mathlib/mathlib.c +++ b/libs/mathlib/mathlib.c @@@ -174,31 -186,35 +172,35 @@@ vec_t VectorAccurateNormalize( const ve return 0; } - out[0] = (vec_t) (x / length); - out[1] = (vec_t) (y / length); - out[2] = (vec_t) (z / length); + out[0] = (vec_t) ( x / length ); + out[1] = (vec_t) ( y / length ); + out[2] = (vec_t) ( z / length ); return (vec_t) length; + } - #else + vec_t VectorFastNormalize( const vec3_t in, vec3_t out ) { - vec_t length, ilength; + // SmileTheory: This is ioquake3's VectorNormalize2 + // for when accuracy matters less than speed - float length, ilength; - - length = in[0]*in[0] + in[1]*in[1] + in[2]*in[2]; - - if (length) - { - /* writing it this way allows gcc to recognize that rsqrt can be used */ - ilength = 1/(float)sqrt (length); - /* sqrt(length) = length * (1 / sqrt(length)) */ - length *= ilength; - out[0] = in[0]*ilength; - out[1] = in[1]*ilength; - out[2] = in[2]*ilength; - } else { - VectorClear( out ); - } ++ float length, ilength; + - length = (vec_t)sqrt( in[0] * in[0] + in[1] * in[1] + in[2] * in[2] ); - if ( length == 0 ) { ++ length = in[0] * in[0] + in[1] * in[1] + in[2] * in[2]; ++ ++ if ( length ) { ++ /* writing it this way allows gcc to recognize that rsqrt can be used */ ++ ilength = 1 / (float)sqrt( length ); ++ /* sqrt(length) = length * (1 / sqrt(length)) */ ++ length *= ilength; ++ out[0] = in[0] * ilength; ++ out[1] = in[1] * ilength; ++ out[2] = in[2] * ilength; ++ } ++ else { + VectorClear( out ); - return 0; + } - ilength = 1.0f / length; - out[0] = in[0] * ilength; - out[1] = in[1] * ilength; - out[2] = in[2] * ilength; - - return length; + return length; - - #endif - } vec_t ColorNormalize( const vec3_t in, vec3_t out ) { diff --cc tools/quake3/q3map2/light.c index ffcd832a,fe4bcf1b..f03f64c7 --- a/tools/quake3/q3map2/light.c +++ b/tools/quake3/q3map2/light.c @@@ -698,67 -679,64 +698,67 @@@ void SetEntityOrigins( void ) /* -PointToPolygonFormFactor() -calculates the area over a point/normal hemisphere a winding covers -ydnar: fixme: there has to be a faster way to calculate this -without the expensive per-vert sqrts and transcendental functions -ydnar 2002-09-30: added -faster switch because only 19% deviance > 10% -between this and the approximation -*/ + PointToPolygonFormFactor() + calculates the area over a point/normal hemisphere a winding covers + ydnar: fixme: there has to be a faster way to calculate this + without the expensive per-vert sqrts and transcendental functions + ydnar 2002-09-30: added -faster switch because only 19% deviance > 10% + between this and the approximation + */ + +#define ONE_OVER_2PI 0.159154942f //% (1.0f / (2.0f * 3.141592657f)) + +float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w ){ + vec3_t triVector, triNormal; + int i, j; + vec3_t dirs[ MAX_POINTS_ON_WINDING ]; + float total; + float dot, angle, facing; -#define ONE_OVER_2PI 0.159154942f //% (1.0f / (2.0f * 3.141592657f)) -float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w ) -{ - vec3_t triVector, triNormal; - int i, j; - vec3_t dirs[ MAX_POINTS_ON_WINDING ]; - float total; - float dot, angle, facing; - - /* this is expensive */ - for( i = 0; i < w->numpoints; i++ ) + for ( i = 0; i < w->numpoints; i++ ) { VectorSubtract( w->p[ i ], point, dirs[ i ] ); - VectorNormalize( dirs[ i ], dirs[ i ] ); + VectorFastNormalize( dirs[ i ], dirs[ i ] ); } - + /* duplicate first vertex to avoid mod operation */ VectorCopy( dirs[ 0 ], dirs[ i ] ); - + /* calculcate relative area */ total = 0.0f; - for( i = 0; i < w->numpoints; i++ ) + for ( i = 0; i < w->numpoints; i++ ) { /* get a triangle */ j = i + 1; dot = DotProduct( dirs[ i ], dirs[ j ] ); - + /* roundoff can cause slight creep, which gives an IND from acos */ - if( dot > 1.0f ) + if ( dot > 1.0f ) { dot = 1.0f; - else if( dot < -1.0f ) + } + else if ( dot < -1.0f ) { dot = -1.0f; - + } + /* get the angle */ angle = acos( dot ); - + CrossProduct( dirs[ i ], dirs[ j ], triVector ); - if ( VectorNormalize( triVector, triNormal ) < 0.0001f ) { - if( VectorFastNormalize( triVector, triNormal ) < 0.0001f ) ++ if ( VectorFastNormalize( triVector, triNormal ) < 0.0001f ) { continue; - + } + facing = DotProduct( normal, triNormal ); total += facing * angle; - + /* ydnar: this was throwing too many errors with radiosity + crappy maps. ignoring it. */ - if( total > 6.3f || total < -6.3f ) + if ( total > 6.3f || total < -6.3f ) { return 0.0f; + } } - + /* now in the range of 0 to 1 over the entire incoming hemisphere */ //% total /= (2.0f * 3.141592657f); total *= ONE_OVER_2PI; diff --cc tools/quake3/q3map2/light_trace.c index cb22bb44,e7c3b019..08606f7e --- a/tools/quake3/q3map2/light_trace.c +++ b/tools/quake3/q3map2/light_trace.c @@@ -1616,105 -1579,136 +1616,134 @@@ qboolean TraceWinding( traceWinding_t * /* -TraceLine_r() -returns qtrue if something is hit and tracing can stop + TraceLine_r() + returns qtrue if something is hit and tracing can stop + -SmileTheory: made half-iterative -*/ ++ SmileTheory: made half-iterative + */ - static qboolean TraceLine_r( int nodeNum, vec3_t origin, vec3_t end, trace_t *trace ){ + #define TRACELINE_R_HALF_ITERATIVE 1 + + #if TRACELINE_R_HALF_ITERATIVE + static qboolean TraceLine_r( int nodeNum, const vec3_t start, const vec3_t end, trace_t *trace ) + #else + static qboolean TraceLine_r( int nodeNum, const vec3_t origin, const vec3_t end, trace_t *trace ) + #endif + { - traceNode_t *node; - int side; - float front, back, frac; - vec3_t origin, mid; - qboolean r; - + traceNode_t *node; + int side; + float front, back, frac; - vec3_t mid; ++ vec3_t origin, mid; + qboolean r; + + #if TRACELINE_R_HALF_ITERATIVE + VectorCopy( start, origin ); - /* bogus node number means solid, end tracing unless testing all */ - if ( nodeNum < 0 ) { - VectorCopy( origin, trace->hit ); - trace->passSolid = qtrue; - return qtrue; - } - while( 1 ) ++ while ( 1 ) + #endif + { + /* bogus node number means solid, end tracing unless testing all */ - if( nodeNum < 0 ) - { ++ if ( nodeNum < 0 ) { + VectorCopy( origin, trace->hit ); + trace->passSolid = qtrue; + return qtrue; + } - + - /* get node */ - node = &traceNodes[ nodeNum ]; + /* get node */ + node = &traceNodes[ nodeNum ]; - + - /* solid? */ - if ( node->type == TRACE_LEAF_SOLID ) { - VectorCopy( origin, trace->hit ); - trace->passSolid = qtrue; - return qtrue; - } + /* solid? */ - if( node->type == TRACE_LEAF_SOLID ) - { ++ if ( node->type == TRACE_LEAF_SOLID ) { + VectorCopy( origin, trace->hit ); + trace->passSolid = qtrue; + return qtrue; + } - + - /* leafnode? */ - if ( node->type < 0 ) { - /* note leaf and return */ - if ( node->numItems > 0 && trace->numTestNodes < MAX_TRACE_TEST_NODES ) { - trace->testNodes[ trace->numTestNodes++ ] = nodeNum; + /* leafnode? */ - if( node->type < 0 ) - { - /* note leaf and return */ - if( node->numItems > 0 && trace->numTestNodes < MAX_TRACE_TEST_NODES ) ++ if ( node->type < 0 ) { ++ /* note leaf and return */ ++ if ( node->numItems > 0 && trace->numTestNodes < MAX_TRACE_TEST_NODES ) { + trace->testNodes[ trace->numTestNodes++ ] = nodeNum; ++ } + return qfalse; } - return qfalse; - } - + - /* ydnar 2003-09-07: don't test branches of the bsp with nothing in them when testall is enabled */ - if ( trace->testAll && node->numItems == 0 ) { - return qfalse; - } + /* ydnar 2003-09-07: don't test branches of the bsp with nothing in them when testall is enabled */ - if( trace->testAll && node->numItems == 0 ) ++ if ( trace->testAll && node->numItems == 0 ) { + return qfalse; - ++ } + - /* classify beginning and end points */ - switch ( node->type ) - { - case PLANE_X: - front = origin[ 0 ] - node->plane[ 3 ]; - back = end[ 0 ] - node->plane[ 3 ]; - break; + /* classify beginning and end points */ - switch( node->type ) ++ switch ( node->type ) + { - case PLANE_X: - front = origin[ 0 ] - node->plane[ 3 ]; - back = end[ 0 ] - node->plane[ 3 ]; - break; - - case PLANE_Y: - front = origin[ 1 ] - node->plane[ 3 ]; - back = end[ 1 ] - node->plane[ 3 ]; - break; - - case PLANE_Z: - front = origin[ 2 ] - node->plane[ 3 ]; - back = end[ 2 ] - node->plane[ 3 ]; - break; - - default: - front = DotProduct( origin, node->plane ) - node->plane[ 3 ]; - back = DotProduct( end, node->plane ) - node->plane[ 3 ]; - break; ++ case PLANE_X: ++ front = origin[ 0 ] - node->plane[ 3 ]; ++ back = end[ 0 ] - node->plane[ 3 ]; ++ break; + - case PLANE_Y: - front = origin[ 1 ] - node->plane[ 3 ]; - back = end[ 1 ] - node->plane[ 3 ]; - break; ++ case PLANE_Y: ++ front = origin[ 1 ] - node->plane[ 3 ]; ++ back = end[ 1 ] - node->plane[ 3 ]; ++ break; + - case PLANE_Z: - front = origin[ 2 ] - node->plane[ 3 ]; - back = end[ 2 ] - node->plane[ 3 ]; - break; ++ case PLANE_Z: ++ front = origin[ 2 ] - node->plane[ 3 ]; ++ back = end[ 2 ] - node->plane[ 3 ]; ++ break; + - default: - front = DotProduct( origin, node->plane ) - node->plane[ 3 ]; - back = DotProduct( end, node->plane ) - node->plane[ 3 ]; - break; - } ++ default: ++ front = DotProduct( origin, node->plane ) - node->plane[ 3 ]; ++ back = DotProduct( end, node->plane ) - node->plane[ 3 ]; ++ break; + } - + - /* entirely in front side? */ - if ( front >= -TRACE_ON_EPSILON && back >= -TRACE_ON_EPSILON ) { - return TraceLine_r( node->children[ 0 ], origin, end, trace ); - } + /* entirely in front side? */ - if( front >= -TRACE_ON_EPSILON && back >= -TRACE_ON_EPSILON ) - { ++ if ( front >= -TRACE_ON_EPSILON && back >= -TRACE_ON_EPSILON ) { + #if TRACELINE_R_HALF_ITERATIVE + nodeNum = node->children[ 0 ]; + continue; + #else + return TraceLine_r( node->children[ 0 ], origin, end, trace ); + #endif + } - + - /* entirely on back side? */ - if ( front < TRACE_ON_EPSILON && back < TRACE_ON_EPSILON ) { - return TraceLine_r( node->children[ 1 ], origin, end, trace ); - } + /* entirely on back side? */ - if( front < TRACE_ON_EPSILON && back < TRACE_ON_EPSILON ) - { ++ if ( front < TRACE_ON_EPSILON && back < TRACE_ON_EPSILON ) { + #if TRACELINE_R_HALF_ITERATIVE + nodeNum = node->children[ 1 ]; + continue; + #else + return TraceLine_r( node->children[ 1 ], origin, end, trace ); + #endif + } - + - /* select side */ - side = front < 0; + /* select side */ + side = front < 0; - + - /* calculate intercept point */ - frac = front / ( front - back ); - mid[ 0 ] = origin[ 0 ] + ( end[ 0 ] - origin[ 0 ] ) * frac; - mid[ 1 ] = origin[ 1 ] + ( end[ 1 ] - origin[ 1 ] ) * frac; - mid[ 2 ] = origin[ 2 ] + ( end[ 2 ] - origin[ 2 ] ) * frac; + /* calculate intercept point */ - frac = front / (front - back); - mid[ 0 ] = origin[ 0 ] + (end[ 0 ] - origin[ 0 ]) * frac; - mid[ 1 ] = origin[ 1 ] + (end[ 1 ] - origin[ 1 ]) * frac; - mid[ 2 ] = origin[ 2 ] + (end[ 2 ] - origin[ 2 ]) * frac; - ++ frac = front / ( front - back ); ++ mid[ 0 ] = origin[ 0 ] + ( end[ 0 ] - origin[ 0 ] ) * frac; ++ mid[ 1 ] = origin[ 1 ] + ( end[ 1 ] - origin[ 1 ] ) * frac; ++ mid[ 2 ] = origin[ 2 ] + ( end[ 2 ] - origin[ 2 ] ) * frac; + - /* fixme: check inhibit radius, then solid nodes and ignore */ + /* fixme: check inhibit radius, then solid nodes and ignore */ - + - /* set trace hit here */ - //% VectorCopy( mid, trace->hit ); + /* set trace hit here */ + //% VectorCopy( mid, trace->hit ); - + - /* trace first side */ - r = TraceLine_r( node->children[ side ], origin, mid, trace ); - if ( r ) { - return r; - } + /* trace first side */ - if( TraceLine_r( node->children[ side ], origin, mid, trace ) ) ++ if ( TraceLine_r( node->children[ side ], origin, mid, trace ) ) { + return qtrue; - ++ } + - /* trace other side */ - return TraceLine_r( node->children[ !side ], mid, end, trace ); + /* trace other side */ + #if TRACELINE_R_HALF_ITERATIVE + nodeNum = node->children[ !side ]; + VectorCopy( mid, origin ); + #else + return TraceLine_r( node->children[ !side ], mid, end, trace ); + #endif + } } @@@ -1785,13 -1779,14 +1814,13 @@@ void TraceLine( trace_t *trace ) /* -SetupTrace() - ydnar -sets up certain trace values -*/ + SetupTrace() - ydnar + sets up certain trace values + */ -float SetupTrace( trace_t *trace ) -{ +float SetupTrace( trace_t *trace ){ VectorSubtract( trace->end, trace->origin, trace->displacement ); - trace->distance = VectorNormalize( trace->displacement, trace->direction ); + trace->distance = VectorFastNormalize( trace->displacement, trace->direction ); VectorCopy( trace->origin, trace->hit ); return trace->distance; }