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
This commit is contained in:
Rudolf Polzer
2012-05-15 12:03:08 +02:00
4 changed files with 141 additions and 104 deletions
+7 -1
View File
@@ -101,7 +101,13 @@ void _CrossProduct( vec3_t v1, vec3_t v2, vec3_t cross );
// 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 );
#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 );
+18 -16
View File
@@ -153,9 +153,7 @@ void _VectorCopy( vec3_t in, vec3_t out ){
out[2] = in[2];
}
vec_t VectorNormalize( const vec3_t in, vec3_t out ) {
#if MATHLIB_VECTOR_NORMALIZE_PRECISION_FIX
vec_t VectorAccurateNormalize( const vec3_t in, vec3_t out ) {
// The sqrt() function takes double as an input and returns double as an
// output according the the man pages on Debian and on FreeBSD. Therefore,
@@ -179,26 +177,30 @@ vec_t VectorNormalize( const vec3_t in, vec3_t out ) {
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 = (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;
#endif
}
vec_t ColorNormalize( const vec3_t in, vec3_t out ) {
+2 -2
View File
@@ -720,7 +720,7 @@ float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const w
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 */
@@ -746,7 +746,7 @@ float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const w
angle = acos( dot );
CrossProduct( dirs[ i ], dirs[ j ], triVector );
if ( VectorNormalize( triVector, triNormal ) < 0.0001f ) {
if ( VectorFastNormalize( triVector, triNormal ) < 0.0001f ) {
continue;
}
+114 -85
View File
@@ -1618,103 +1618,132 @@ qboolean TraceWinding( traceWinding_t *tw, trace_t *trace ){
/*
TraceLine_r()
returns qtrue if something is hit and tracing can stop
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 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;
}
/* get node */
node = &traceNodes[ nodeNum ];
/* 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;
}
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;
}
/* classify beginning and end points */
switch ( node->type )
while ( 1 )
#endif
{
case PLANE_X:
front = origin[ 0 ] - node->plane[ 3 ];
back = end[ 0 ] - node->plane[ 3 ];
break;
/* bogus node number means solid, end tracing unless testing all */
if ( nodeNum < 0 ) {
VectorCopy( origin, trace->hit );
trace->passSolid = qtrue;
return qtrue;
}
case PLANE_Y:
front = origin[ 1 ] - node->plane[ 3 ];
back = end[ 1 ] - node->plane[ 3 ];
break;
/* get node */
node = &traceNodes[ nodeNum ];
case PLANE_Z:
front = origin[ 2 ] - node->plane[ 3 ];
back = end[ 2 ] - node->plane[ 3 ];
break;
/* solid? */
if ( node->type == TRACE_LEAF_SOLID ) {
VectorCopy( origin, trace->hit );
trace->passSolid = qtrue;
return qtrue;
}
default:
front = DotProduct( origin, node->plane ) - node->plane[ 3 ];
back = DotProduct( end, node->plane ) - node->plane[ 3 ];
break;
/* leafnode? */
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;
}
/* 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;
}
/* classify beginning and end points */
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;
}
/* entirely in front side? */
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 ) {
#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;
/* 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;
/* fixme: check inhibit radius, then solid nodes and ignore */
/* set trace hit here */
//% VectorCopy( mid, trace->hit );
/* trace first side */
if ( TraceLine_r( node->children[ side ], origin, mid, trace ) ) {
return qtrue;
}
/* 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
}
/* entirely in front side? */
if ( front >= -TRACE_ON_EPSILON && back >= -TRACE_ON_EPSILON ) {
return TraceLine_r( node->children[ 0 ], origin, end, trace );
}
/* entirely on back side? */
if ( front < TRACE_ON_EPSILON && back < TRACE_ON_EPSILON ) {
return TraceLine_r( node->children[ 1 ], origin, end, trace );
}
/* 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;
/* fixme: check inhibit radius, then solid nodes and ignore */
/* 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 other side */
return TraceLine_r( node->children[ !side ], mid, end, trace );
}
@@ -1791,7 +1820,7 @@ void TraceLine( 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;
}