Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

light_trace.c File Reference

#include "light.h"

Include dependency graph for light_trace.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  tnode_s

Defines

#define CURVE_FACET_ERROR   8
#define MAX_TNODES   (MAX_MAP_NODES*4)
#define PLANAR_EPSILON   0.1
#define TRACE_ON_EPSILON   0.1

Typedefs

typedef tnode_s tnode_t

Functions

void CM_GenerateBoundaryForPoints (float boundary[4], float plane[4], vec3_t a, vec3_t b)
qboolean CM_GenerateFacetFor3Points (cFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c)
qboolean CM_GenerateFacetFor4Points (cFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c, drawVert_t *d)
void FacetsForPatch (dsurface_t *dsurf, shaderInfo_t *si, surfaceTest_t *test)
void FacetsForTriangleSurface (dsurface_t *dsurf, shaderInfo_t *si, surfaceTest_t *test)
void GenerateBoundaryForPoints (float boundary[4], float plane[4], vec3_t a, vec3_t b)
void InitSurfacesForTesting (void)
void InitTrace (void)
void MakeTnode (int nodenum)
qboolean PointInSolid (vec3_t start)
qboolean PointInSolid_r (vec3_t start, int node)
void SetFacetFilter (traceWork_t *tr, shaderInfo_t *shader, cFacet_t *facet, vec3_t point)
qboolean SphereCull (vec3_t start, vec3_t stop, vec3_t origin, float radius)
void SphereFromBounds (vec3_t mins, vec3_t maxs, vec3_t origin, float *radius)
void TextureMatrixFromPoints (cFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c)
void TraceAgainstFacet (traceWork_t *tr, shaderInfo_t *shader, cFacet_t *facet)
void TraceAgainstSurface (traceWork_t *tw, surfaceTest_t *surf)
void TraceLine (const vec3_t start, const vec3_t stop, trace_t *trace, qboolean testAll, traceWork_t *tw)
int TraceLine_r (int node, const vec3_t start, const vec3_t stop, traceWork_t *tw)

Variables

int c_cullTrace
int c_testFacets
int c_testTrace
int c_totalTrace
qboolean patchshadows
surfaceTest_tsurfaceTest [MAX_MAP_DRAW_SURFS]
tnode_ttnode_p
tnode_ttnodes


Define Documentation

#define CURVE_FACET_ERROR   8
 

Definition at line 26 of file light_trace.c.

#define MAX_TNODES   (MAX_MAP_NODES*4)
 

Definition at line 570 of file light_trace.c.

Referenced by InitTrace().

#define PLANAR_EPSILON   0.1
 

Definition at line 193 of file light_trace.c.

#define TRACE_ON_EPSILON   0.1
 

Definition at line 559 of file light_trace.c.

Referenced by TraceLine_r().


Typedef Documentation

typedef struct tnode_s tnode_t
 

Referenced by InitTrace(), MakeTnode(), PointInSolid_r(), and TraceLine_r().


Function Documentation

void CM_GenerateBoundaryForPoints float  boundary[4],
float  plane[4],
vec3_t  a,
vec3_t  b
 

Definition at line 39 of file light_trace.c.

References a, b, CrossProduct(), DotProduct, vec3_t, VectorNormalize(), and VectorSubtract.

Referenced by CM_GenerateFacetFor3Points(), and CM_GenerateFacetFor4Points().

00039                                                                                            {
00040     vec3_t  d1;
00041 
00042     // amke a perpendicular vector to the edge and the surface
00043     VectorSubtract( b, a, d1 );
00044     CrossProduct( plane, d1, boundary );
00045     VectorNormalize( boundary, boundary );
00046     boundary[3] = DotProduct( a, boundary );
00047 }

Here is the call graph for this function:

qboolean CM_GenerateFacetFor3Points cFacet_t f,
drawVert_t a,
drawVert_t b,
drawVert_t c
 

Definition at line 163 of file light_trace.c.

References a, b, cFacet_s::boundaries, c, cFacet_t, CM_GenerateBoundaryForPoints(), f, cFacet_s::numBoundaries, PlaneFromPoints(), cFacet_s::points, qboolean, cFacet_s::surface, TextureMatrixFromPoints(), VectorCopy, and drawVert_t::xyz.

Referenced by FacetsForPatch(), and FacetsForTriangleSurface().

00163                                                                                                 {
00164     // if we can't generate a valid plane for the points, ignore the facet
00165     if ( !PlaneFromPoints( f->surface, a->xyz, b->xyz, c->xyz ) ) {
00166         f->numBoundaries = 0;
00167         return qfalse;
00168     }
00169 
00170     // make boundaries
00171     f->numBoundaries = 3;
00172 
00173     CM_GenerateBoundaryForPoints( f->boundaries[0], f->surface, a->xyz, b->xyz );
00174     CM_GenerateBoundaryForPoints( f->boundaries[1], f->surface, b->xyz, c->xyz );
00175     CM_GenerateBoundaryForPoints( f->boundaries[2], f->surface, c->xyz, a->xyz );
00176 
00177     VectorCopy( a->xyz, f->points[0] );
00178     VectorCopy( b->xyz, f->points[1] );
00179     VectorCopy( c->xyz, f->points[2] );
00180 
00181     TextureMatrixFromPoints( f, a, b, c );
00182 
00183     return qtrue;
00184 }

Here is the call graph for this function:

qboolean CM_GenerateFacetFor4Points cFacet_t f,
drawVert_t a,
drawVert_t b,
drawVert_t c,
drawVert_t d
 

Definition at line 194 of file light_trace.c.

References a, b, cFacet_s::boundaries, c, cFacet_t, CM_GenerateBoundaryForPoints(), d, DotProduct, f, fabs(), i, cFacet_s::numBoundaries, PlaneFromPoints(), cFacet_s::points, qboolean, cFacet_s::surface, TextureMatrixFromPoints(), VectorCopy, and drawVert_t::xyz.

Referenced by FacetsForPatch(), and FacetsForTriangleSurface().

00194                                                                                                                {
00195     float   dist;
00196     int     i;
00197     vec4_t  plane;
00198 
00199     // if we can't generate a valid plane for the points, ignore the facet
00200     if ( !PlaneFromPoints( f->surface, a->xyz, b->xyz, c->xyz ) ) {
00201         f->numBoundaries = 0;
00202         return qfalse;
00203     }
00204 
00205     // if the fourth point is also on the plane, we can make a quad facet
00206     dist = DotProduct( d->xyz, f->surface ) - f->surface[3];
00207     if ( fabs( dist ) > PLANAR_EPSILON ) {
00208         f->numBoundaries = 0;
00209         return qfalse;
00210     }
00211 
00212     // make boundaries
00213     f->numBoundaries = 4;
00214 
00215     CM_GenerateBoundaryForPoints( f->boundaries[0], f->surface, a->xyz, b->xyz );
00216     CM_GenerateBoundaryForPoints( f->boundaries[1], f->surface, b->xyz, c->xyz );
00217     CM_GenerateBoundaryForPoints( f->boundaries[2], f->surface, c->xyz, d->xyz );
00218     CM_GenerateBoundaryForPoints( f->boundaries[3], f->surface, d->xyz, a->xyz );
00219 
00220     VectorCopy( a->xyz, f->points[0] );
00221     VectorCopy( b->xyz, f->points[1] );
00222     VectorCopy( c->xyz, f->points[2] );
00223     VectorCopy( d->xyz, f->points[3] );
00224 
00225     for (i = 1; i < 4; i++)
00226     {
00227         if ( !PlaneFromPoints( plane, f->points[i], f->points[(i+1) % 4], f->points[(i+2) % 4]) ) {
00228             f->numBoundaries = 0;
00229             return qfalse;
00230         }
00231 
00232         if (DotProduct(f->surface, plane) < 0.9) {
00233             f->numBoundaries = 0;
00234             return qfalse;
00235         }
00236     }
00237 
00238     TextureMatrixFromPoints( f, a, b, c );
00239 
00240     return qtrue;
00241 }

Here is the call graph for this function:

void FacetsForPatch dsurface_t dsurf,
shaderInfo_t si,
surfaceTest_t test
 

Definition at line 315 of file light_trace.c.

References CM_GenerateFacetFor3Points(), CM_GenerateFacetFor4Points(), count, drawVerts, surfaceTest_t::facets, dsurface_t::firstVert, FreeMesh(), mesh_t::height, i, j, MakeMeshNormals(), malloc(), surfaceTest_t::numFacets, surfaceTest_t::patch, dsurface_t::patchHeight, dsurface_t::patchWidth, PutMeshOnCurve(), RemoveLinearMeshColumnsRows(), surfaceTest_t::shader, shaderInfo_t, SubdivideMesh(), test(), v1, v2, mesh_t::verts, and mesh_t::width.

Referenced by InitSurfacesForTesting().

00315                                                                                 {
00316     int         i, j;
00317     drawVert_t  *v1, *v2, *v3, *v4;
00318     int         count;
00319     mesh_t      srcMesh, *subdivided, *mesh;
00320 
00321     srcMesh.width = dsurf->patchWidth;
00322     srcMesh.height = dsurf->patchHeight;
00323     srcMesh.verts = &drawVerts[ dsurf->firstVert ];
00324 
00325     //subdivided = SubdivideMesh( mesh, CURVE_FACET_ERROR, 9999 );
00326     mesh = SubdivideMesh( srcMesh, 8, 999 );
00327     PutMeshOnCurve( *mesh );
00328     MakeMeshNormals( *mesh );
00329 
00330     subdivided = RemoveLinearMeshColumnsRows( mesh );
00331     FreeMesh(mesh);
00332 
00333     test->patch = qtrue;
00334     test->numFacets = ( subdivided->width - 1 ) * ( subdivided->height - 1 ) * 2;
00335     test->facets = malloc( sizeof( test->facets[0] ) * test->numFacets );
00336     test->shader = si;
00337 
00338     count = 0;
00339     for ( i = 0 ; i < subdivided->width - 1 ; i++ ) {
00340         for ( j = 0 ; j < subdivided->height - 1 ; j++ ) {
00341 
00342             v1 = subdivided->verts + j * subdivided->width + i;
00343             v2 = v1 + 1;
00344             v3 = v1 + subdivided->width + 1;
00345             v4 = v1 + subdivided->width;
00346 
00347             if ( CM_GenerateFacetFor4Points( &test->facets[count], v1, v4, v3, v2 ) ) {
00348                 count++;
00349             } else {
00350                 if (CM_GenerateFacetFor3Points( &test->facets[count], v1, v4, v3 ))
00351                     count++;
00352                 if (CM_GenerateFacetFor3Points( &test->facets[count], v1, v3, v2 ))
00353                     count++;
00354             }
00355         }
00356     }
00357     test->numFacets = count;
00358     FreeMesh(subdivided);
00359 }

Here is the call graph for this function:

void FacetsForTriangleSurface dsurface_t dsurf,
shaderInfo_t si,
surfaceTest_t test
 

Definition at line 266 of file light_trace.c.

References CM_GenerateFacetFor3Points(), CM_GenerateFacetFor4Points(), count, drawIndexes, drawVerts, surfaceTest_t::facets, dsurface_t::firstIndex, dsurface_t::firstVert, i, i1, i2, malloc(), surfaceTest_t::numFacets, dsurface_t::numIndexes, surfaceTest_t::patch, surfaceTest_t::shader, shaderInfo_t, test(), v1, and v2.

Referenced by InitSurfacesForTesting().

00266                                                                                           {
00267     int         i;
00268     drawVert_t  *v1, *v2, *v3, *v4;
00269     int         count;
00270     int         i1, i2, i3, i4, i5, i6;
00271 
00272     test->patch = qfalse;
00273     test->numFacets = dsurf->numIndexes / 3;
00274     test->facets = malloc( sizeof( test->facets[0] ) * test->numFacets );
00275     test->shader = si;
00276 
00277     count = 0;
00278     for ( i = 0 ; i < test->numFacets ; i++ ) {
00279         i1 = drawIndexes[ dsurf->firstIndex + i*3 ];
00280         i2 = drawIndexes[ dsurf->firstIndex + i*3 + 1 ];
00281         i3 = drawIndexes[ dsurf->firstIndex + i*3 + 2 ];
00282 
00283         v1 = &drawVerts[ dsurf->firstVert + i1 ];
00284         v2 = &drawVerts[ dsurf->firstVert + i2 ];
00285         v3 = &drawVerts[ dsurf->firstVert + i3 ];
00286 
00287         // try and make a quad out of two triangles
00288         if ( i != test->numFacets - 1 ) {
00289             i4 = drawIndexes[ dsurf->firstIndex + i*3 + 3 ];
00290             i5 = drawIndexes[ dsurf->firstIndex + i*3 + 4 ];
00291             i6 = drawIndexes[ dsurf->firstIndex + i*3 + 5 ];
00292             if ( i4 == i3 && i5 == i2 ) {
00293                 v4 = &drawVerts[ dsurf->firstVert + i6 ];
00294                 if ( CM_GenerateFacetFor4Points( &test->facets[count], v1, v2, v4, v3 ) ) {
00295                     count++;
00296                     i++;        // skip next tri
00297                     continue;
00298                 }
00299             }
00300         }
00301 
00302         if (CM_GenerateFacetFor3Points( &test->facets[count], v1, v2, v3 ))
00303             count++;
00304     }       
00305 
00306     // we may have turned some pairs into quads
00307     test->numFacets = count;
00308 }

Here is the call graph for this function:

void GenerateBoundaryForPoints float  boundary[4],
float  plane[4],
vec3_t  a,
vec3_t  b
 

Definition at line 415 of file light_trace.c.

References a, b, CrossProduct(), DotProduct, vec3_t, VectorNormalize(), and VectorSubtract.

00415                                                                                         {
00416     vec3_t  d1;
00417 
00418     // amke a perpendicular vector to the edge and the surface
00419     VectorSubtract( b, a, d1 );
00420     CrossProduct( plane, d1, boundary );
00421     VectorNormalize( boundary, boundary );
00422     boundary[3] = DotProduct( a, boundary );
00423 }

Here is the call graph for this function:

void InitSurfacesForTesting void   ) 
 

Definition at line 369 of file light_trace.c.

References AddPointToBounds(), ClearBounds(), shaderInfo_s::contents, drawSurfaces, drawVerts, dshaders, FacetsForPatch(), FacetsForTriangleSurface(), dsurface_t::firstVert, i, j, malloc(), MST_TRIANGLE_SOUP, dsurface_t::numIndexes, dsurface_t::numVerts, dsurface_t::patchWidth, shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, SphereFromBounds(), shaderInfo_s::surfaceFlags, surfaceTest, dsurface_t::surfaceType, test(), and drawVert_t::xyz.

Referenced by InitTrace().

00369                                     {
00370 
00371     int             i, j;
00372     dsurface_t      *dsurf;
00373     surfaceTest_t   *test;
00374     drawVert_t      *dvert;
00375     shaderInfo_t    *si;
00376 
00377     for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
00378         dsurf = &drawSurfaces[ i ];
00379         if ( !dsurf->numIndexes && !dsurf->patchWidth ) {
00380             continue;
00381         }
00382 
00383         // don't make surfaces for transparent objects
00384         // because we want light to pass through them
00385         si = ShaderInfoForShader( dshaders[ dsurf->shaderNum].shader );
00386         if ( (si->contents & CONTENTS_TRANSLUCENT) && !(si->surfaceFlags & SURF_ALPHASHADOW) ) {
00387             continue;
00388         }
00389 
00390         test = malloc( sizeof( *test ) );
00391         surfaceTest[i] = test;
00392         ClearBounds( test->mins, test->maxs );
00393 
00394         dvert = &drawVerts[ dsurf->firstVert ];
00395         for ( j = 0 ; j < dsurf->numVerts ; j++, dvert++ ) {
00396             AddPointToBounds( dvert->xyz, test->mins, test->maxs );
00397         }
00398 
00399         SphereFromBounds( test->mins, test->maxs, test->origin, &test->radius );
00400 
00401         if ( dsurf->surfaceType == MST_TRIANGLE_SOUP || dsurf->surfaceType == MST_PLANAR ) {
00402             FacetsForTriangleSurface( dsurf, si, test );
00403         } else if ( dsurf->surfaceType == MST_PATCH ) {
00404             FacetsForPatch( dsurf, si, test );
00405         }
00406     }
00407 }

Here is the call graph for this function:

void InitTrace void   ) 
 

Definition at line 623 of file light_trace.c.

References InitSurfacesForTesting(), MakeTnode(), malloc(), MAX_TNODES, tnode_p, tnode_t, and tnodes.

Referenced by GridAndVertexLighting(), and LightMain().

00623                        {
00624     // 32 byte align the structs
00625     tnodes = malloc( (MAX_TNODES+1) * sizeof(tnode_t));
00626     tnodes = (tnode_t *)(((int)tnodes + 31)&~31);
00627     tnode_p = tnodes;
00628 
00629     MakeTnode (0);
00630 
00631     InitSurfacesForTesting();
00632 }

Here is the call graph for this function:

void MakeTnode int  nodenum  ) 
 

Definition at line 580 of file light_trace.c.

References tnode_s::children, dnode_t::children, dleaf_t::cluster, dplane_t::dist, tnode_s::dist, dleafs, dnodes, dplanes, i, tnode_s::normal, dplane_t::normal, tnode_s::planeNum, dnode_t::planeNum, PlaneTypeForNormal, t, tnode_p, tnode_t, tnode_s::type, and VectorCopy.

Referenced by InitTrace().

00581 {
00582     tnode_t         *t;
00583     dplane_t        *plane;
00584     int             i;
00585     dnode_t         *node;
00586     int             leafNum;
00587 
00588     t = tnode_p++;
00589 
00590     node = dnodes + nodenum;
00591     plane = dplanes + node->planeNum;
00592 
00593     t->planeNum = node->planeNum;
00594     t->type = PlaneTypeForNormal( plane->normal );
00595     VectorCopy (plane->normal, t->normal);
00596     t->dist = plane->dist;
00597     
00598     for (i=0 ; i<2 ; i++)
00599     {
00600         if (node->children[i] < 0) {
00601             leafNum = -node->children[i] - 1;
00602             if ( dleafs[leafNum].cluster == -1  ) {
00603                 // solid
00604                 t->children[i] = leafNum | ( 1 << 31 ) | ( 1 << 30 );
00605             } else {
00606                 t->children[i] = leafNum | ( 1 << 31 );
00607             }
00608         } else {
00609             t->children[i] = tnode_p - tnodes;
00610             MakeTnode (node->children[i]);
00611         }
00612     }
00613             
00614 }

qboolean PointInSolid vec3_t  start  ) 
 

Definition at line 686 of file light_trace.c.

References PointInSolid_r(), and qboolean.

Referenced by RemoveLightsInSolid(), TraceGrid(), and TraceLtm().

00686                                       {
00687     return PointInSolid_r( start, 0 );
00688 }

Here is the call graph for this function:

qboolean PointInSolid_r vec3_t  start,
int  node
 

Definition at line 640 of file light_trace.c.

References tnode_s::children, tnode_s::dist, tnode_s::normal, PLANE_X, PLANE_Y, PLANE_Z, qboolean, tnode_t, tnodes, and tnode_s::type.

Referenced by PointInSolid().

00640                                                   {
00641     tnode_t *tnode;
00642     float   front;
00643 
00644     while ( !(node & (1<<31) ) ) {
00645         tnode = &tnodes[node];
00646         switch (tnode->type) {
00647         case PLANE_X:
00648             front = start[0] - tnode->dist;
00649             break;
00650         case PLANE_Y:
00651             front = start[1] - tnode->dist;
00652             break;
00653         case PLANE_Z:
00654             front = start[2] - tnode->dist;
00655             break;
00656         default:
00657             front = (start[0]*tnode->normal[0] + start[1]*tnode->normal[1] + start[2]*tnode->normal[2]) - tnode->dist;
00658             break;
00659         }
00660 
00661         if ( front == 0 ) {
00662             // exactly on node, must check both sides
00663             return (qboolean) ( PointInSolid_r( start, tnode->children[0] ) 
00664                 | PointInSolid_r( start, tnode->children[1] ) );
00665         }
00666 
00667         if ( front > 0 ) {
00668             node = tnode->children[0];
00669         } else {
00670             node = tnode->children[1];
00671         }
00672     }
00673 
00674     if ( node & ( 1 << 30 ) ) {
00675         return qtrue;
00676     }
00677     return qfalse;
00678 }

void SetFacetFilter traceWork_t tr,
shaderInfo_t shader,
cFacet_t facet,
vec3_t  point
 

Definition at line 434 of file light_trace.c.

References b, byte, cFacet_t, DotProduct, floor(), shaderInfo_s::height, shaderInfo_s::pixels, point, s, shaderInfo_t, shaderInfo_s::surfaceFlags, t, cFacet_s::textureMatrix, tr, VectorClear, and shaderInfo_s::width.

Referenced by TraceAgainstFacet().

00434                                                                                             {
00435     float   s, t;
00436     int     is, it;
00437     byte    *image;
00438     int     b;
00439 
00440     // most surfaces are completely opaque
00441     if ( !(shader->surfaceFlags & SURF_ALPHASHADOW) ) {
00442         VectorClear( tr->trace->filter );
00443         return;
00444     }
00445 
00446     s = DotProduct( point, facet->textureMatrix[0] ) + facet->textureMatrix[0][3];
00447     t = DotProduct( point, facet->textureMatrix[1] ) + facet->textureMatrix[1][3];
00448 
00449     if ( !shader->pixels ) {
00450         // assume completely solid
00451         VectorClear( point );
00452         return;
00453     }
00454 
00455     s = s - floor( s );
00456     t = t - floor( t );
00457 
00458     is = s * shader->width;
00459     it = t * shader->height;
00460 
00461     image = shader->pixels + 4 * ( it * shader->width + is );
00462 
00463     // alpha filter
00464     b = image[3];
00465 
00466     // alpha test makes this a binary option
00467     b = b < 128 ? 0 : 255;
00468 
00469     tr->trace->filter[0] = tr->trace->filter[0] * (255-b) / 255;
00470     tr->trace->filter[1] = tr->trace->filter[1] * (255-b) / 255;
00471     tr->trace->filter[2] = tr->trace->filter[2] * (255-b) / 255;
00472 }

Here is the call graph for this function:

qboolean SphereCull vec3_t  start,
vec3_t  stop,
vec3_t  origin,
float  radius
 

Definition at line 776 of file light_trace.c.

References d, DotProduct, qboolean, v, vec3_t, VectorLength(), VectorMA, VectorNormalize(), and VectorSubtract.

Referenced by TraceAgainstSurface().

00776                                                                                  {
00777     vec3_t      v;
00778     float       d;
00779     vec3_t      dir;
00780     float       len;
00781     vec3_t      on;
00782 
00783     VectorSubtract( stop, start, dir );
00784     len = VectorNormalize( dir, dir );
00785 
00786     VectorSubtract( origin, start, v );
00787     d = DotProduct( v, dir );
00788     if ( d > len + radius ) {
00789         return qtrue;       // too far ahead
00790     }
00791     if ( d < -radius ) {
00792         return qtrue;       // too far behind
00793     }
00794     VectorMA( start, d, dir, on );
00795     
00796     VectorSubtract( on, origin, v );
00797 
00798     len = VectorLength( v );
00799 
00800     if ( len > radius ) {
00801         return qtrue;       // too far to the side
00802     }
00803 
00804     return qfalse;      // must be traced against
00805 }

Here is the call graph for this function:

void SphereFromBounds vec3_t  mins,
vec3_t  maxs,
vec3_t  origin,
float *  radius
 

Definition at line 251 of file light_trace.c.

References vec3_t, VectorAdd, VectorLength(), VectorScale, and VectorSubtract.

Referenced by InitSurfacesForTesting().

00251                                                                                 {
00252     vec3_t      temp;
00253 
00254     VectorAdd( mins, maxs, origin );
00255     VectorScale( origin, 0.5, origin );
00256     VectorSubtract( maxs, origin, temp );
00257     *radius = VectorLength( temp );
00258 }

Here is the call graph for this function:

void TextureMatrixFromPoints cFacet_t f,
drawVert_t a,
drawVert_t b,
drawVert_t c
 

Definition at line 54 of file light_trace.c.

References a, b, c, cFacet_t, f, fabs(), i, j, m, s, drawVert_t::st, t, cFacet_s::textureMatrix, and drawVert_t::xyz.

Referenced by CM_GenerateFacetFor3Points(), and CM_GenerateFacetFor4Points().

00054                                                                                          {
00055     int         i, j;
00056     float       t;
00057     float       m[3][4];
00058     float       s;
00059 
00060     // This is an incredibly stupid way of solving a three variable equation
00061     for ( i = 0 ; i < 2 ; i++ ) {
00062 
00063         m[0][0] = a->xyz[0];
00064         m[0][1] = a->xyz[1];
00065         m[0][2] = a->xyz[2];
00066         m[0][3] = a->st[i];
00067 
00068         m[1][0] = b->xyz[0];
00069         m[1][1] = b->xyz[1];
00070         m[1][2] = b->xyz[2];
00071         m[1][3] = b->st[i];
00072 
00073         m[2][0] = c->xyz[0];
00074         m[2][1] = c->xyz[1];
00075         m[2][2] = c->xyz[2];
00076         m[2][3] = c->st[i];
00077 
00078         if ( fabs(m[1][0]) > fabs(m[0][0]) && fabs(m[1][0]) > fabs(m[2][0]) ) {
00079             for ( j = 0 ; j < 4 ; j ++ ) {
00080                 t = m[0][j];
00081                 m[0][j] = m[1][j];
00082                 m[1][j] = t;
00083             }
00084         } else if ( fabs(m[2][0]) > fabs(m[0][0]) && fabs(m[2][0]) > fabs(m[1][0]) ) {
00085             for ( j = 0 ; j < 4 ; j ++ ) {
00086                 t = m[0][j];
00087                 m[0][j] = m[2][j];
00088                 m[2][j] = t;
00089             }
00090         }
00091 
00092         s = 1.0 / m[0][0];
00093         m[0][0] *= s;
00094         m[0][1] *= s;
00095         m[0][2] *= s;
00096         m[0][3] *= s;
00097 
00098         s = m[1][0];
00099         m[1][0] -= m[0][0] * s;
00100         m[1][1] -= m[0][1] * s;
00101         m[1][2] -= m[0][2] * s;
00102         m[1][3] -= m[0][3] * s;
00103 
00104         s = m[2][0];
00105         m[2][0] -= m[0][0] * s;
00106         m[2][1] -= m[0][1] * s;
00107         m[2][2] -= m[0][2] * s;
00108         m[2][3] -= m[0][3] * s;
00109 
00110         if ( fabs(m[2][1]) > fabs(m[1][1]) ) {
00111             for ( j = 0 ; j < 4 ; j ++ ) {
00112                 t = m[1][j];
00113                 m[1][j] = m[2][j];
00114                 m[2][j] = t;
00115             }
00116         }
00117 
00118         s = 1.0 / m[1][1];
00119         m[1][0] *= s;
00120         m[1][1] *= s;
00121         m[1][2] *= s;
00122         m[1][3] *= s;
00123 
00124         s = m[2][1];
00125         m[2][0] -= m[1][0] * s;
00126         m[2][1] -= m[1][1] * s;
00127         m[2][2] -= m[1][2] * s;
00128         m[2][3] -= m[1][3] * s;
00129 
00130         s = 1.0 / m[2][2];
00131         m[2][0] *= s;
00132         m[2][1] *= s;
00133         m[2][2] *= s;
00134         m[2][3] *= s;
00135 
00136         f->textureMatrix[i][2] = m[2][3];
00137         f->textureMatrix[i][1] = m[1][3] - f->textureMatrix[i][2] * m[1][2];
00138         f->textureMatrix[i][0] = m[0][3] - f->textureMatrix[i][2] * m[0][2] - f->textureMatrix[i][1] * m[0][1];
00139 
00140         f->textureMatrix[i][3] = 0;
00141 /*
00142         s = fabs( DotProduct( a->xyz, f->textureMatrix[i] ) - a->st[i] );
00143         if ( s > 0.01 ) {
00144             Error( "Bad textureMatrix" );
00145         }
00146         s = fabs( DotProduct( b->xyz, f->textureMatrix[i] ) - b->st[i] );
00147         if ( s > 0.01 ) {
00148             Error( "Bad textureMatrix" );
00149         }
00150         s = fabs( DotProduct( c->xyz, f->textureMatrix[i] ) - c->st[i] );
00151         if ( s > 0.01 ) {
00152             Error( "Bad textureMatrix" );
00153         }
00154 */
00155     }
00156 }

Here is the call graph for this function:

void TraceAgainstFacet traceWork_t tr,
shaderInfo_t shader,
cFacet_t facet
 

Definition at line 482 of file light_trace.c.

References cFacet_s::boundaries, cFacet_t, d, DotProduct, f, j, cFacet_s::numBoundaries, point, SetFacetFilter(), shaderInfo_t, cFacet_s::surface, shaderInfo_s::surfaceFlags, tr, vec3_t, and VectorClear.

Referenced by TraceAgainstSurface().

00482                                                                                  {
00483     int         j;
00484     float       d1, d2, d, f;
00485     vec3_t      point;
00486     float       dist;
00487 
00488     // ignore degenerate facets
00489     if ( facet->numBoundaries < 3 ) {
00490         return;
00491     }
00492 
00493     dist = facet->surface[3];
00494 
00495     // compare the trace endpoints against the facet plane
00496     d1 = DotProduct( tr->start, facet->surface ) - dist;
00497     if ( d1 > -1 && d1 < 1 ) {
00498         return;     // don't self intersect
00499     }
00500     d2 = DotProduct( tr->end, facet->surface ) - dist;
00501     if ( d2 > -1 && d2 < 1 ) {
00502         return;     // don't self intersect
00503     }
00504 
00505     // calculate the intersection fraction
00506     f = ( d1 - ON_EPSILON ) / ( d1 - d2 );
00507     if ( f <= 0 ) {
00508         return;
00509     }
00510     if ( f >= tr->trace->hitFraction ) {
00511         return;         // we have hit something earlier
00512     }
00513 
00514     // calculate the intersection point
00515     for ( j = 0 ; j < 3 ; j++ ) {
00516         point[j] = tr->start[j] + f * ( tr->end[j] - tr->start[j] );
00517     }
00518 
00519     // check the point against the facet boundaries
00520     for ( j = 0 ; j < facet->numBoundaries ; j++ ) {
00521         // adjust the plane distance apropriately for mins/maxs
00522         dist = facet->boundaries[j][3];
00523 
00524         d = DotProduct( point, facet->boundaries[j] );
00525         if ( d > dist + ON_EPSILON ) {
00526             break;      // outside the bounds
00527         }
00528     }
00529 
00530     if ( j != facet->numBoundaries ) {
00531         return;         // we are outside the bounds of the facet
00532     }
00533 
00534     // we hit this facet
00535 
00536     // if this is a transparent surface, calculate filter value
00537     if ( shader->surfaceFlags & SURF_ALPHASHADOW ) {
00538         SetFacetFilter( tr, shader, facet, point );
00539     } else {
00540         // completely opaque
00541         VectorClear( tr->trace->filter );
00542         tr->trace->hitFraction = f;
00543     }
00544 
00545 //  VectorCopy( facet->surface, tr->trace->plane.normal );
00546 //  tr->trace->plane.dist = facet->surface[3];
00547 }

Here is the call graph for this function:

void TraceAgainstSurface traceWork_t tw,
surfaceTest_t surf
 

Definition at line 812 of file light_trace.c.

References c_cullTrace, c_testFacets, c_testTrace, traceWork_t::end, surfaceTest_t::facets, i, surfaceTest_t::numFacets, numthreads, surfaceTest_t::origin, surfaceTest_t::radius, surfaceTest_t::shader, SphereCull(), traceWork_t::start, and TraceAgainstFacet().

Referenced by TraceLine().

00812                                                                     {
00813     int     i;
00814 
00815     // if surfaces are trans
00816     if ( SphereCull( tw->start, tw->end, surf->origin, surf->radius ) ) {
00817         if ( numthreads == 1 ) {
00818             c_cullTrace++;
00819         }
00820         return;
00821     }
00822 
00823     if ( numthreads == 1 ) {
00824         c_testTrace++;
00825         c_testFacets += surf->numFacets;
00826     }
00827 
00828     /*
00829     // MrE: backface culling
00830     if (!surf->patch && surf->numFacets) {
00831         // if the surface does not cast an alpha shadow
00832         if ( !(surf->shader->surfaceFlags & SURF_ALPHASHADOW) ) {
00833             vec3_t vec;
00834             VectorSubtract(tw->end, tw->start, vec);
00835             if (DotProduct(vec, surf->facets->surface) > 0)
00836                 return;
00837         }
00838     }
00839     */
00840 
00841     // test against each facet
00842     for ( i = 0 ; i < surf->numFacets ; i++ ) {
00843         TraceAgainstFacet( tw, surf->shader, surf->facets + i );
00844     }
00845 }

Here is the call graph for this function:

void TraceLine const vec3_t  start,
const vec3_t  stop,
trace_t trace,
qboolean  testAll,
traceWork_t tw
 

Definition at line 866 of file light_trace.c.

References byte, c_totalTrace, dleafs, dleafsurfaces, traceWork_t::end, trace_t::filter, dleaf_t::firstLeafSurface, trace_t::hit, trace_t::hitFraction, i, j, MAX_MAP_DRAW_SURFS, memset(), numDrawSurfaces, dleaf_t::numLeafSurfaces, traceWork_t::numOpenLeafs, numthreads, traceWork_t::openLeafNumbers, trace_t::passSolid, surfaceTest_t::patch, traceWork_t::patchshadows, r, traceWork_t::start, surfaceTest, test(), traceWork_t::trace, TraceAgainstSurface(), TraceLine_r(), and VectorCopy.

Referenced by LightContributionToPoint(), LightingAtSample(), and SunToPoint().

00866                                                                                                            {
00867     int             r;
00868     int             i, j;
00869     dleaf_t         *leaf;
00870     float           oldHitFrac;
00871     surfaceTest_t   *test;
00872     int             surfaceNum;
00873     byte            surfaceTested[MAX_MAP_DRAW_SURFS/8];
00874     ;
00875 
00876     if ( numthreads == 1 ) {
00877         c_totalTrace++;
00878     }
00879 
00880     // assume all light gets through, unless the ray crosses
00881     // a translucent surface
00882     trace->filter[0] = 1.0;
00883     trace->filter[1] = 1.0;
00884     trace->filter[2] = 1.0;
00885 
00886     VectorCopy( start, tw->start );
00887     VectorCopy( stop, tw->end );
00888     tw->trace = trace;
00889 
00890     tw->numOpenLeafs = 0;
00891 
00892     trace->passSolid = qfalse;
00893     trace->hitFraction = 1.0;
00894 
00895     r = TraceLine_r( 0, start, stop, tw );
00896 
00897     // if we hit a solid leaf, stop without testing the leaf
00898     // surfaces.  Note that the plane and endpoint might not
00899     // be the first solid intersection along the ray.
00900     if ( r && !testAll ) {
00901         return;
00902     }
00903 
00904     if ( noSurfaces ) {
00905         return;
00906     }
00907 
00908     memset( surfaceTested, 0, (numDrawSurfaces+7)/8 );
00909     oldHitFrac = trace->hitFraction;
00910 
00911     for ( i = 0 ; i < tw->numOpenLeafs ; i++ ) {
00912         leaf = &dleafs[ tw->openLeafNumbers[ i ] ];
00913         for ( j = 0 ; j < leaf->numLeafSurfaces ; j++ ) {
00914             surfaceNum = dleafsurfaces[ leaf->firstLeafSurface + j ];
00915 
00916             // make sure we don't test the same ray against a surface more than once
00917             if ( surfaceTested[ surfaceNum>>3 ] & ( 1 << ( surfaceNum & 7) ) ) {
00918                 continue;
00919             }
00920             surfaceTested[ surfaceNum>>3 ] |= ( 1 << ( surfaceNum & 7 ) );
00921 
00922             test = surfaceTest[ surfaceNum ];
00923             if ( !test ) {
00924                 continue;
00925             }
00926             //
00927             if ( !tw->patchshadows && test->patch ) {
00928                 continue;
00929             }
00930             TraceAgainstSurface( tw, test );
00931         }
00932 
00933         // if the trace is now solid, we can't possibly hit anything closer
00934         if ( trace->hitFraction < oldHitFrac ) {
00935             trace->passSolid = qtrue;
00936             break;
00937         }
00938     }
00939     
00940     for ( i = 0 ; i < 3 ; i++ ) {
00941         trace->hit[i] = start[i] + ( stop[i] - start[i] ) * trace->hitFraction;
00942     }
00943 }

Here is the call graph for this function:

int TraceLine_r int  node,
const vec3_t  start,
const vec3_t  stop,
traceWork_t tw
 

Definition at line 698 of file light_trace.c.

References tnode_s::children, tnode_s::dist, trace_t::hit, tnode_s::normal, traceWork_t::numOpenLeafs, traceWork_t::openLeafNumbers, trace_t::passSolid, PLANE_X, PLANE_Y, PLANE_Z, r, tnode_t, tnodes, traceWork_t::trace, TRACE_ON_EPSILON, tnode_s::type, vec3_t, and VectorCopy.

Referenced by TraceLine().

00698                                                                                     {
00699     tnode_t *tnode;
00700     float   front, back;
00701     vec3_t  mid;
00702     float   frac;
00703     int     side;
00704     int     r;
00705 
00706     if (node & (1<<31)) {
00707         if (node & ( 1 << 30 ) ) {
00708             VectorCopy (start, tw->trace->hit);
00709             tw->trace->passSolid = qtrue;
00710             return qtrue;
00711         } else {
00712             // save the node off for more exact testing
00713             if ( tw->numOpenLeafs == MAX_MAP_LEAFS ) {
00714                 return qfalse;
00715             }
00716             tw->openLeafNumbers[ tw->numOpenLeafs ] = node & ~(3 << 30);
00717             tw->numOpenLeafs++;
00718             return qfalse;
00719         }
00720     }
00721 
00722     tnode = &tnodes[node];
00723     switch (tnode->type) {
00724     case PLANE_X:
00725         front = start[0] - tnode->dist;
00726         back = stop[0] - tnode->dist;
00727         break;
00728     case PLANE_Y:
00729         front = start[1] - tnode->dist;
00730         back = stop[1] - tnode->dist;
00731         break;
00732     case PLANE_Z:
00733         front = start[2] - tnode->dist;
00734         back = stop[2] - tnode->dist;
00735         break;
00736     default:
00737         front = (start[0]*tnode->normal[0] + start[1]*tnode->normal[1] + start[2]*tnode->normal[2]) - tnode->dist;
00738         back = (stop[0]*tnode->normal[0] + stop[1]*tnode->normal[1] + stop[2]*tnode->normal[2]) - tnode->dist;
00739         break;
00740     }
00741 
00742     if (front >= -TRACE_ON_EPSILON && back >= -TRACE_ON_EPSILON) {
00743         return TraceLine_r (tnode->children[0], start, stop, tw);
00744     }
00745     
00746     if (front < TRACE_ON_EPSILON && back < TRACE_ON_EPSILON) {
00747         return TraceLine_r (tnode->children[1], start, stop, tw);
00748     }
00749 
00750     side = front < 0;
00751     
00752     frac = front / (front-back);
00753 
00754     mid[0] = start[0] + (stop[0] - start[0])*frac;
00755     mid[1] = start[1] + (stop[1] - start[1])*frac;
00756     mid[2] = start[2] + (stop[2] - start[2])*frac;
00757 
00758     r = TraceLine_r (tnode->children[side], start, mid, tw);
00759 
00760     if (r) {
00761         return r;
00762     }
00763 
00764 //  trace->planeNum = tnode->planeNum;
00765     return TraceLine_r (tnode->children[!side], mid, stop, tw);
00766 }


Variable Documentation

int c_cullTrace
 

Definition at line 29 of file light_trace.c.

Referenced by TraceAgainstSurface().

int c_testFacets
 

Definition at line 30 of file light_trace.c.

Referenced by TraceAgainstSurface().

int c_testTrace
 

Definition at line 29 of file light_trace.c.

Referenced by TraceAgainstSurface().

int c_totalTrace
 

Definition at line 28 of file light_trace.c.

Referenced by TraceLine().

qboolean patchshadows
 

Definition at line 50 of file light.c.

surfaceTest_t* surfaceTest[MAX_MAP_DRAW_SURFS]
 

Definition at line 32 of file light_trace.c.

Referenced by CreateSurfaceLights(), InitSurfacesForTesting(), and TraceLine().

tnode_t * tnode_p
 

Definition at line 571 of file light_trace.c.

Referenced by InitTrace(), and MakeTnode().

tnode_t* tnodes
 

Definition at line 571 of file light_trace.c.

Referenced by InitTrace(), PointInSolid_r(), and TraceLine_r().


Generated on Thu Aug 25 16:50:08 2005 for Quake III Arena by  doxygen 1.3.9.1