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

tr_light.c File Reference

#include "tr_local.h"

Include dependency graph for tr_light.c:

Include dependency graph

Go to the source code of this file.

Defines

#define DLIGHT_AT_RADIUS   16
#define DLIGHT_MINIMUM_RADIUS   16

Functions

void LogLight (trRefEntity_t *ent)
void R_DlightBmodel (bmodel_t *bmodel)
int R_LightForPoint (vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir)
void R_SetupEntityLighting (const trRefdef_t *refdef, trRefEntity_t *ent)
void R_SetupEntityLightingGrid (trRefEntity_t *ent)
void R_TransformDlights (int count, dlight_t *dl, orientationr_t *or)

Variables

cvar_tr_ambientScale
cvar_tr_debugLight
cvar_tr_directedScale


Define Documentation

#define DLIGHT_AT_RADIUS   16
 

Definition at line 26 of file tr_light.c.

Referenced by R_SetupEntityLighting().

#define DLIGHT_MINIMUM_RADIUS   16
 

Definition at line 29 of file tr_light.c.


Function Documentation

void LogLight trRefEntity_t ent  )  [static]
 

Definition at line 250 of file tr_light.c.

References trRefEntity_t::ambientLight, trRefEntity_t::directedLight, trRefEntity_t::e, PRINT_ALL, refEntity_t::renderfx, and ri.

Referenced by R_SetupEntityLighting().

00250                                            {
00251     int max1, max2;
00252 
00253     if ( !(ent->e.renderfx & RF_FIRST_PERSON ) ) {
00254         return;
00255     }
00256 
00257     max1 = ent->ambientLight[0];
00258     if ( ent->ambientLight[1] > max1 ) {
00259         max1 = ent->ambientLight[1];
00260     } else if ( ent->ambientLight[2] > max1 ) {
00261         max1 = ent->ambientLight[2];
00262     }
00263 
00264     max2 = ent->directedLight[0];
00265     if ( ent->directedLight[1] > max2 ) {
00266         max2 = ent->directedLight[1];
00267     } else if ( ent->directedLight[2] > max2 ) {
00268         max2 = ent->directedLight[2];
00269     }
00270 
00271     ri.Printf( PRINT_ALL, "amb:%i  dir:%i\n", max1, max2 );
00272 }

void R_DlightBmodel bmodel_t bmodel  ) 
 

Definition at line 61 of file tr_light.c.

References bmodel_t::bounds, trGlobals_t::currentEntity, msurface_s::data, dlight_t, trRefdef_t::dlights, bmodel_t::firstSurface, i, j, mask, msurface_t, trRefEntity_t::needDlights, trRefdef_t::num_dlights, bmodel_t::numSurfaces, trGlobals_t::or, R_TransformDlights(), dlight_s::radius, trGlobals_t::refdef, trGlobals_t::smpFrame, srfGridMesh_t, tr, and dlight_s::transformed.

Referenced by R_AddBrushModelSurfaces().

00061                                         {
00062     int         i, j;
00063     dlight_t    *dl;
00064     int         mask;
00065     msurface_t  *surf;
00066 
00067     // transform all the lights
00068     R_TransformDlights( tr.refdef.num_dlights, tr.refdef.dlights, &tr.or );
00069 
00070     mask = 0;
00071     for ( i=0 ; i<tr.refdef.num_dlights ; i++ ) {
00072         dl = &tr.refdef.dlights[i];
00073 
00074         // see if the point is close enough to the bounds to matter
00075         for ( j = 0 ; j < 3 ; j++ ) {
00076             if ( dl->transformed[j] - bmodel->bounds[1][j] > dl->radius ) {
00077                 break;
00078             }
00079             if ( bmodel->bounds[0][j] - dl->transformed[j] > dl->radius ) {
00080                 break;
00081             }
00082         }
00083         if ( j < 3 ) {
00084             continue;
00085         }
00086 
00087         // we need to check this light
00088         mask |= 1 << i;
00089     }
00090 
00091     tr.currentEntity->needDlights = (mask != 0);
00092 
00093     // set the dlight bits in all the surfaces
00094     for ( i = 0 ; i < bmodel->numSurfaces ; i++ ) {
00095         surf = bmodel->firstSurface + i;
00096 
00097         if ( *surf->data == SF_FACE ) {
00098             ((srfSurfaceFace_t *)surf->data)->dlightBits[ tr.smpFrame ] = mask;
00099         } else if ( *surf->data == SF_GRID ) {
00100             ((srfGridMesh_t *)surf->data)->dlightBits[ tr.smpFrame ] = mask;
00101         } else if ( *surf->data == SF_TRIANGLES ) {
00102             ((srfTriangles_t *)surf->data)->dlightBits[ tr.smpFrame ] = mask;
00103         }
00104     }
00105 }

Here is the call graph for this function:

int R_LightForPoint vec3_t  point,
vec3_t  ambientLight,
vec3_t  directedLight,
vec3_t  lightDir
 

Definition at line 379 of file tr_light.c.

References Com_Memset(), world_t::lightGridData, point, R_SetupEntityLightingGrid(), tr, VectorCopy, and trGlobals_t::world.

00380 {
00381     trRefEntity_t ent;
00382     
00383     // bk010103 - this segfaults with -nolight maps
00384     if ( tr.world->lightGridData == NULL )
00385       return qfalse;
00386 
00387     Com_Memset(&ent, 0, sizeof(ent));
00388     VectorCopy( point, ent.e.origin );
00389     R_SetupEntityLightingGrid( &ent );
00390     VectorCopy(ent.ambientLight, ambientLight);
00391     VectorCopy(ent.directedLight, directedLight);
00392     VectorCopy(ent.lightDir, lightDir);
00393 
00394     return qtrue;
00395 }

Here is the call graph for this function:

void R_SetupEntityLighting const trRefdef_t refdef,
trRefEntity_t ent
 

Definition at line 282 of file tr_light.c.

References trRefEntity_t::ambientLight, trRefEntity_t::ambientLightInt, refEntity_t::axis, byte, dlight_s::color, d, trRefEntity_t::directedLight, DLIGHT_AT_RADIUS, dlight_t, trRefdef_t::dlights, DotProduct, trRefEntity_t::e, i, trGlobals_t::identityLight, trGlobals_t::identityLightByte, cvar_s::integer, trRefEntity_t::lightDir, world_t::lightGridData, trRefEntity_t::lightingCalculated, refEntity_t::lightingOrigin, lightOrigin, LogLight(), myftol, trRefdef_t::num_dlights, refEntity_t::origin, dlight_s::origin, r_debugLight, R_SetupEntityLightingGrid(), dlight_s::radius, trRefdef_t::rdflags, refEntity_t::renderfx, trGlobals_t::sunDirection, tr, vec3_t, VectorCopy, VectorLength(), VectorMA, VectorNormalize(), VectorScale, VectorSubtract, and trGlobals_t::world.

Referenced by R_AddMD3Surfaces().

00282                                                                            {
00283     int             i;
00284     dlight_t        *dl;
00285     float           power;
00286     vec3_t          dir;
00287     float           d;
00288     vec3_t          lightDir;
00289     vec3_t          lightOrigin;
00290 
00291     // lighting calculations 
00292     if ( ent->lightingCalculated ) {
00293         return;
00294     }
00295     ent->lightingCalculated = qtrue;
00296 
00297     //
00298     // trace a sample point down to find ambient light
00299     //
00300     if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
00301         // seperate lightOrigins are needed so an object that is
00302         // sinking into the ground can still be lit, and so
00303         // multi-part models can be lit identically
00304         VectorCopy( ent->e.lightingOrigin, lightOrigin );
00305     } else {
00306         VectorCopy( ent->e.origin, lightOrigin );
00307     }
00308 
00309     // if NOWORLDMODEL, only use dynamic lights (menu system, etc)
00310     if ( !(refdef->rdflags & RDF_NOWORLDMODEL ) 
00311         && tr.world->lightGridData ) {
00312         R_SetupEntityLightingGrid( ent );
00313     } else {
00314         ent->ambientLight[0] = ent->ambientLight[1] = 
00315             ent->ambientLight[2] = tr.identityLight * 150;
00316         ent->directedLight[0] = ent->directedLight[1] = 
00317             ent->directedLight[2] = tr.identityLight * 150;
00318         VectorCopy( tr.sunDirection, ent->lightDir );
00319     }
00320 
00321     // bonus items and view weapons have a fixed minimum add
00322     if ( 1 /* ent->e.renderfx & RF_MINLIGHT */ ) {
00323         // give everything a minimum light add
00324         ent->ambientLight[0] += tr.identityLight * 32;
00325         ent->ambientLight[1] += tr.identityLight * 32;
00326         ent->ambientLight[2] += tr.identityLight * 32;
00327     }
00328 
00329     //
00330     // modify the light by dynamic lights
00331     //
00332     d = VectorLength( ent->directedLight );
00333     VectorScale( ent->lightDir, d, lightDir );
00334 
00335     for ( i = 0 ; i < refdef->num_dlights ; i++ ) {
00336         dl = &refdef->dlights[i];
00337         VectorSubtract( dl->origin, lightOrigin, dir );
00338         d = VectorNormalize( dir );
00339 
00340         power = DLIGHT_AT_RADIUS * ( dl->radius * dl->radius );
00341         if ( d < DLIGHT_MINIMUM_RADIUS ) {
00342             d = DLIGHT_MINIMUM_RADIUS;
00343         }
00344         d = power / ( d * d );
00345 
00346         VectorMA( ent->directedLight, d, dl->color, ent->directedLight );
00347         VectorMA( lightDir, d, dir, lightDir );
00348     }
00349 
00350     // clamp ambient
00351     for ( i = 0 ; i < 3 ; i++ ) {
00352         if ( ent->ambientLight[i] > tr.identityLightByte ) {
00353             ent->ambientLight[i] = tr.identityLightByte;
00354         }
00355     }
00356 
00357     if ( r_debugLight->integer ) {
00358         LogLight( ent );
00359     }
00360 
00361     // save out the byte packet version
00362     ((byte *)&ent->ambientLightInt)[0] = myftol( ent->ambientLight[0] );
00363     ((byte *)&ent->ambientLightInt)[1] = myftol( ent->ambientLight[1] );
00364     ((byte *)&ent->ambientLightInt)[2] = myftol( ent->ambientLight[2] );
00365     ((byte *)&ent->ambientLightInt)[3] = 0xff;
00366     
00367     // transform the direction to local space
00368     VectorNormalize( lightDir );
00369     ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] );
00370     ent->lightDir[1] = DotProduct( lightDir, ent->e.axis[1] );
00371     ent->lightDir[2] = DotProduct( lightDir, ent->e.axis[2] );
00372 }

Here is the call graph for this function:

void R_SetupEntityLightingGrid trRefEntity_t ent  )  [static]
 

Definition at line 126 of file tr_light.c.

References trRefEntity_t::ambientLight, assert, byte, data, trRefEntity_t::directedLight, trRefEntity_t::e, floor(), FUNCTABLE_SIZE, gridData, i, j, trRefEntity_t::lightDir, world_t::lightGridBounds, world_t::lightGridData, world_t::lightGridInverseSize, world_t::lightGridOrigin, refEntity_t::lightingOrigin, lightOrigin, refEntity_t::origin, r_ambientScale, r_directedScale, refEntity_t::renderfx, trGlobals_t::sinTable, tr, v, cvar_s::value, vec3_t, VectorClear, VectorCopy, VectorMA, VectorNormalize2(), VectorScale, VectorSubtract, and trGlobals_t::world.

Referenced by R_LightForPoint(), and R_SetupEntityLighting().

00126                                                             {
00127     vec3_t  lightOrigin;
00128     int     pos[3];
00129     int     i, j;
00130     byte    *gridData;
00131     float   frac[3];
00132     int     gridStep[3];
00133     vec3_t  direction;
00134     float   totalFactor;
00135 
00136     if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
00137         // seperate lightOrigins are needed so an object that is
00138         // sinking into the ground can still be lit, and so
00139         // multi-part models can be lit identically
00140         VectorCopy( ent->e.lightingOrigin, lightOrigin );
00141     } else {
00142         VectorCopy( ent->e.origin, lightOrigin );
00143     }
00144 
00145     VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
00146     for ( i = 0 ; i < 3 ; i++ ) {
00147         float   v;
00148 
00149         v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
00150         pos[i] = floor( v );
00151         frac[i] = v - pos[i];
00152         if ( pos[i] < 0 ) {
00153             pos[i] = 0;
00154         } else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) {
00155             pos[i] = tr.world->lightGridBounds[i] - 1;
00156         }
00157     }
00158 
00159     VectorClear( ent->ambientLight );
00160     VectorClear( ent->directedLight );
00161     VectorClear( direction );
00162 
00163     assert( tr.world->lightGridData ); // bk010103 - NULL with -nolight maps
00164 
00165     // trilerp the light value
00166     gridStep[0] = 8;
00167     gridStep[1] = 8 * tr.world->lightGridBounds[0];
00168     gridStep[2] = 8 * tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1];
00169     gridData = tr.world->lightGridData + pos[0] * gridStep[0]
00170         + pos[1] * gridStep[1] + pos[2] * gridStep[2];
00171 
00172     totalFactor = 0;
00173     for ( i = 0 ; i < 8 ; i++ ) {
00174         float   factor;
00175         byte    *data;
00176         int     lat, lng;
00177         vec3_t  normal;
00178         #if idppc
00179         float d0, d1, d2, d3, d4, d5;
00180         #endif
00181         factor = 1.0;
00182         data = gridData;
00183         for ( j = 0 ; j < 3 ; j++ ) {
00184             if ( i & (1<<j) ) {
00185                 factor *= frac[j];
00186                 data += gridStep[j];
00187             } else {
00188                 factor *= (1.0f - frac[j]);
00189             }
00190         }
00191 
00192         if ( !(data[0]+data[1]+data[2]) ) {
00193             continue;   // ignore samples in walls
00194         }
00195         totalFactor += factor;
00196         #if idppc
00197         d0 = data[0]; d1 = data[1]; d2 = data[2];
00198         d3 = data[3]; d4 = data[4]; d5 = data[5];
00199 
00200         ent->ambientLight[0] += factor * d0;
00201         ent->ambientLight[1] += factor * d1;
00202         ent->ambientLight[2] += factor * d2;
00203 
00204         ent->directedLight[0] += factor * d3;
00205         ent->directedLight[1] += factor * d4;
00206         ent->directedLight[2] += factor * d5;
00207         #else
00208         ent->ambientLight[0] += factor * data[0];
00209         ent->ambientLight[1] += factor * data[1];
00210         ent->ambientLight[2] += factor * data[2];
00211 
00212         ent->directedLight[0] += factor * data[3];
00213         ent->directedLight[1] += factor * data[4];
00214         ent->directedLight[2] += factor * data[5];
00215         #endif
00216         lat = data[7];
00217         lng = data[6];
00218         lat *= (FUNCTABLE_SIZE/256);
00219         lng *= (FUNCTABLE_SIZE/256);
00220 
00221         // decode X as cos( lat ) * sin( long )
00222         // decode Y as sin( lat ) * sin( long )
00223         // decode Z as cos( long )
00224 
00225         normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
00226         normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
00227         normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
00228 
00229         VectorMA( direction, factor, normal, direction );
00230     }
00231 
00232     if ( totalFactor > 0 && totalFactor < 0.99 ) {
00233         totalFactor = 1.0f / totalFactor;
00234         VectorScale( ent->ambientLight, totalFactor, ent->ambientLight );
00235         VectorScale( ent->directedLight, totalFactor, ent->directedLight );
00236     }
00237 
00238     VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight );
00239     VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight );
00240 
00241     VectorNormalize2( direction, ent->lightDir );
00242 }

Here is the call graph for this function:

void R_TransformDlights int  count,
dlight_t dl,
orientationr_t or
 

Definition at line 42 of file tr_light.c.

References orientationr_t::axis, dlight_t, DotProduct, i, dlight_s::origin, orientationr_t::origin, dlight_s::transformed, vec3_t, and VectorSubtract.

Referenced by R_DlightBmodel(), and RB_RenderDrawSurfList().

00042                                                                       {
00043     int     i;
00044     vec3_t  temp;
00045 
00046     for ( i = 0 ; i < count ; i++, dl++ ) {
00047         VectorSubtract( dl->origin, or->origin, temp );
00048         dl->transformed[0] = DotProduct( temp, or->axis[0] );
00049         dl->transformed[1] = DotProduct( temp, or->axis[1] );
00050         dl->transformed[2] = DotProduct( temp, or->axis[2] );
00051     }
00052 }


Variable Documentation

cvar_t* r_ambientScale
 

Definition at line 139 of file tr_init.c.

Referenced by R_Register(), and R_SetupEntityLightingGrid().

cvar_t* r_debugLight
 

Definition at line 141 of file tr_init.c.

Referenced by R_Register(), and R_SetupEntityLighting().

cvar_t* r_directedScale
 

Definition at line 140 of file tr_init.c.

Referenced by R_Register(), and R_SetupEntityLightingGrid().


Generated on Thu Aug 25 15:07:37 2005 for Quake III Arena by  doxygen 1.3.9.1