#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
#include "imagelib.h"
#include "threads.h"
#include "mutex.h"
#include "scriplib.h"
#include "shaders.h"
#include "mesh.h"
Include dependency graph for soundv.c:

Go to the source code of this file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 251 of file l_poly.c. References AllocWinding(), BOGUS_RANGE, CrossProduct(), DotProduct, Error(), fabs(), i, max, MAX_WORLD_COORD, winding_t::numpoints, winding_t::p, v, vec3_origin, vec3_t, vec_t, VectorAdd, VectorCopy, VectorMA, VectorNormalize(), VectorScale, VectorSubtract, vright, vup, w, and x. Referenced by AAS_CreateCurveBrushes(), AAS_FixMapBrush(), AAS_MakeBrushWindings(), AAS_SplitWinding(), BaseWindingForNode(), BSPBrushWindings(), CM_AddFacetBevels(), CM_DrawDebugSurface(), CM_ValidateFacet(), CreateBrushWindings(), HL_SplitBrush(), MakeBrushWindings(), MakeHeadnodePortals(), Q1_SplitBrush(), Q2_BrushSideWinding(), Q3_BrushSideWinding(), Sin_BrushSideWinding(), SplitBrush(), TestExpandBrushes(), VL_WindingForBrushSide(), VS_WindingForBrushSide(), WriteBspBrushMap(), WriteMapBrush(), and WriteOriginBrush(). 00252 {
00253 int i, x;
00254 vec_t max, v;
00255 vec3_t org, vright, vup;
00256 winding_t *w;
00257
00258 // find the major axis
00259
00260 max = -BOGUS_RANGE;
00261 x = -1;
00262 for (i=0 ; i<3; i++)
00263 {
00264 v = fabs(normal[i]);
00265 if (v > max)
00266 {
00267 x = i;
00268 max = v;
00269 }
00270 }
00271 if (x==-1)
00272 Error ("BaseWindingForPlane: no axis found");
00273
00274 VectorCopy (vec3_origin, vup);
00275 switch (x)
00276 {
00277 case 0:
00278 case 1:
00279 vup[2] = 1;
00280 break;
00281 case 2:
00282 vup[0] = 1;
00283 break;
00284 }
00285
00286 v = DotProduct (vup, normal);
00287 VectorMA (vup, -v, normal, vup);
00288 VectorNormalize (vup);
00289
00290 VectorScale (normal, dist, org);
00291
00292 CrossProduct (vup, normal, vright);
00293
00294 VectorScale (vup, BOGUS_RANGE, vup);
00295 VectorScale (vright, BOGUS_RANGE, vright);
00296
00297 // project a really big axis aligned box onto the plane
00298 w = AllocWinding (4);
00299
00300 VectorSubtract (org, vright, w->p[0]);
00301 VectorAdd (w->p[0], vup, w->p[0]);
00302
00303 VectorAdd (org, vright, w->p[1]);
00304 VectorAdd (w->p[1], vup, w->p[1]);
00305
00306 VectorAdd (org, vright, w->p[2]);
00307 VectorSubtract (w->p[2], vup, w->p[2]);
00308
00309 VectorSubtract (org, vright, w->p[3]);
00310 VectorSubtract (w->p[3], vup, w->p[3]);
00311
00312 w->numpoints = 4;
00313
00314 return w;
00315 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 358 of file l_poly.c. References AllocWinding(), b, CopyWinding(), DotProduct, Error(), f, i, in, j, MAX_POINTS_ON_WINDING, winding_t::numpoints, winding_t::p, p2, SIDE_ON, vec3_t, vec_t, and VectorCopy. Referenced by AAS_SplitFace(), BuildFaceTree_r(), ChopFaceByBrush(), ChopWinding(), ClipSideIntoTree_r(), FilterMapDrawSurfIntoTree_r(), FilterSideIntoTree_r(), HL_SplitBrush(), Q1_SplitBrush(), SplitBrush(), SplitNodePortals(), SubdivideAreaLight(), SubdivideDrawSurf(), SubdivideFace(), VL_SubdivideAreaLight(), and VS_SubdivideAreaLight(). 00360 {
00361 vec_t dists[MAX_POINTS_ON_WINDING+4];
00362 int sides[MAX_POINTS_ON_WINDING+4];
00363 int counts[3];
00364 //MrElusive: DOH can't use statics when unsing multithreading!!!
00365 vec_t dot; // VC 4.2 optimizer bug if not static
00366 int i, j;
00367 vec_t *p1, *p2;
00368 vec3_t mid;
00369 winding_t *f, *b;
00370 int maxpts;
00371
00372 counts[0] = counts[1] = counts[2] = 0;
00373
00374 // determine sides for each point
00375 for (i=0 ; i<in->numpoints ; i++)
00376 {
00377 dot = DotProduct (in->p[i], normal);
00378 dot -= dist;
00379 dists[i] = dot;
00380 if (dot > epsilon)
00381 sides[i] = SIDE_FRONT;
00382 else if (dot < -epsilon)
00383 sides[i] = SIDE_BACK;
00384 else
00385 {
00386 sides[i] = SIDE_ON;
00387 }
00388 counts[sides[i]]++;
00389 }
00390 sides[i] = sides[0];
00391 dists[i] = dists[0];
00392
00393 *front = *back = NULL;
00394
00395 if (!counts[0])
00396 {
00397 *back = CopyWinding (in);
00398 return;
00399 }
00400 if (!counts[1])
00401 {
00402 *front = CopyWinding (in);
00403 return;
00404 }
00405
00406 maxpts = in->numpoints+4; // cant use counts[0]+2 because
00407 // of fp grouping errors
00408
00409 *front = f = AllocWinding (maxpts);
00410 *back = b = AllocWinding (maxpts);
00411
00412 for (i=0 ; i<in->numpoints ; i++)
00413 {
00414 p1 = in->p[i];
00415
00416 if (sides[i] == SIDE_ON)
00417 {
00418 VectorCopy (p1, f->p[f->numpoints]);
00419 f->numpoints++;
00420 VectorCopy (p1, b->p[b->numpoints]);
00421 b->numpoints++;
00422 continue;
00423 }
00424
00425 if (sides[i] == SIDE_FRONT)
00426 {
00427 VectorCopy (p1, f->p[f->numpoints]);
00428 f->numpoints++;
00429 }
00430 if (sides[i] == SIDE_BACK)
00431 {
00432 VectorCopy (p1, b->p[b->numpoints]);
00433 b->numpoints++;
00434 }
00435
00436 if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
00437 continue;
00438
00439 // generate a split point
00440 p2 = in->p[(i+1)%in->numpoints];
00441
00442 dot = dists[i] / (dists[i]-dists[i+1]);
00443 for (j=0 ; j<3 ; j++)
00444 { // avoid round off error when possible
00445 if (normal[j] == 1)
00446 mid[j] = dist;
00447 else if (normal[j] == -1)
00448 mid[j] = -dist;
00449 else
00450 mid[j] = p1[j] + dot*(p2[j]-p1[j]);
00451 }
00452
00453 VectorCopy (mid, f->p[f->numpoints]);
00454 f->numpoints++;
00455 VectorCopy (mid, b->p[b->numpoints]);
00456 b->numpoints++;
00457 }
00458
00459 if (f->numpoints > maxpts || b->numpoints > maxpts)
00460 Error ("ClipWinding: points exceeded estimate");
00461 if (f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING)
00462 Error ("ClipWinding: MAX_POINTS_ON_WINDING");
00463 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1167 of file light.c. References byte, max, vec3_t, VectorCopy, and VectorScale. Referenced by TraceGrid(), TraceLtm(), VL_StoreLightmap(), and VS_StoreLightmap(). 01167 {
01168 float max;
01169 vec3_t sample;
01170
01171 VectorCopy( color, sample );
01172
01173 // clamp with color normalization
01174 max = sample[0];
01175 if ( sample[1] > max ) {
01176 max = sample[1];
01177 }
01178 if ( sample[2] > max ) {
01179 max = sample[2];
01180 }
01181 if ( max > 255 ) {
01182 VectorScale( sample, 255/max, sample );
01183 }
01184 colorBytes[ 0 ] = sample[0];
01185 colorBytes[ 1 ] = sample[1];
01186 colorBytes[ 2 ] = sample[2];
01187 }
|
|
|
Definition at line 225 of file light.c. References count, drawSurfaces, Error(), i, LIGHTMAP_HEIGHT, LIGHTMAP_WIDTH, dsurface_t::lightmapNum, numDrawSurfaces, numLightBytes, and qprintf(). Referenced by LightMain(), VLightMain(), and VSoundMain(). 00225 {
00226 int count;
00227 int i;
00228 dsurface_t *ds;
00229
00230 qprintf ("--- CountLightmaps ---\n");
00231 count = 0;
00232 for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
00233 // see if this surface is light emiting
00234 ds = &drawSurfaces[i];
00235 if ( ds->lightmapNum > count ) {
00236 count = ds->lightmapNum;
00237 }
00238 }
00239
00240 count++;
00241 numLightBytes = count * LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT * 3;
00242 if ( numLightBytes > MAX_MAP_LIGHTING ) {
00243 Error("MAX_MAP_LIGHTING exceeded");
00244 }
00245
00246 qprintf( "%5i drawSurfaces\n", numDrawSurfaces );
00247 qprintf( "%5i lightmaps\n", count );
00248 }
|
Here is the call graph for this function:

|
|
Definition at line 443 of file light.c. References entities, i, n, strcmp(), and ValueForKey(). Referenced by CreateEntityLights(), VL_CreateEntityLights(), and VS_CreateEntitySpeakers(). 00443 {
00444 int i;
00445 const char *n;
00446
00447 for ( i = 0 ; i < num_entities ; i++ ) {
00448 n = ValueForKey (&entities[i], "targetname");
00449 if ( !strcmp (n, target) ) {
00450 return &entities[i];
00451 }
00452 }
00453
00454 return NULL;
00455 }
|
Here is the call graph for this function:

|
|
Definition at line 92 of file l_poly.c. 00093 {
00094 if (*(unsigned *)w == 0xdeaddead)
00095 Error ("FreeWinding: freed a freed winding");
00096
00097 if (numthreads == 1)
00098 {
00099 c_active_windings--;
00100 c_windingmemory -= MemorySize(w);
00101 } //end if
00102
00103 *(unsigned *)w = 0xdeaddead;
00104
00105 FreeMemory(w);
00106 } //end of the function FreeWinding
|
|
|
Definition at line 1989 of file light.c. References _printf(), CreateEntityLights(), CreateFilters(), CreateSurfaceLights(), FindSkyBrushes(), InitTrace(), numDrawSurfaces, numGridPoints, qtrue, RunThreadsOnIndividual(), SetupGrid(), TraceGrid(), TriSoupLightingThread(), and VertexLightingThread(). Referenced by VLightMain(), and VSoundMain(). 01989 {
01990 SetupGrid();
01991
01992 FindSkyBrushes();
01993 CreateFilters();
01994 InitTrace();
01995 CreateEntityLights ();
01996 CreateSurfaceLights();
01997
01998 if (!nogridlighting) {
01999 _printf ("--- TraceGrid ---\n");
02000 RunThreadsOnIndividual( numGridPoints, qtrue, TraceGrid );
02001 }
02002
02003 if (!novertexlighting) {
02004 _printf ("--- Vertex Lighting ---\n");
02005 RunThreadsOnIndividual( numDrawSurfaces, qtrue, VertexLightingThread );
02006 }
02007
02008 _printf("--- Model Lighting ---\n");
02009 RunThreadsOnIndividual( numDrawSurfaces, qtrue, TriSoupLightingThread );
02010 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1139 of file soundv.c. References a, b, plane_t::dist, fabs(), plane_t::normal, NORMAL_EPSILON, and vec3_t. 01140 {
01141 vec3_t normal;
01142 float dist;
01143
01144 if (flip) {
01145 normal[0] = - b->normal[0];
01146 normal[1] = - b->normal[1];
01147 normal[2] = - b->normal[2];
01148 dist = - b->dist;
01149 }
01150 else {
01151 normal[0] = b->normal[0];
01152 normal[1] = b->normal[1];
01153 normal[2] = b->normal[2];
01154 dist = b->dist;
01155 }
01156 if (
01157 fabs(a->normal[0] - normal[0]) < NORMAL_EPSILON
01158 && fabs(a->normal[1] - normal[1]) < NORMAL_EPSILON
01159 && fabs(a->normal[2] - normal[2]) < NORMAL_EPSILON
01160 && fabs(a->dist - dist) < DIST_EPSILON )
01161 return qtrue;
01162 return qfalse;
01163 }
|
Here is the call graph for this function:

|
|
Definition at line 2664 of file soundv.c. References dnode_t::children, dplane_t::dist, dnodes, DotProduct, dplanes, dplane_t::normal, dnode_t::planeNum, point, and vec_t. 02665 {
02666 int nodenum;
02667 vec_t dist;
02668 dnode_t *node;
02669 dplane_t *plane;
02670
02671 nodenum = 0;
02672 while (nodenum >= 0)
02673 {
02674 node = &dnodes[nodenum];
02675 plane = &dplanes[node->planeNum];
02676 dist = DotProduct (point, plane->normal) - plane->dist;
02677 if (dist > 0)
02678 nodenum = node->children[0];
02679 else
02680 nodenum = node->children[1];
02681 }
02682
02683 return -nodenum - 1;
02684 }
|
|
||||||||||||||||
|
Definition at line 610 of file light.c. References _printf(), acos(), CrossProduct(), dirs, DotProduct, i, j, winding_t::numpoints, winding_t::p, point, printed(), qboolean, vec3_t, VectorCopy, VectorNormalize(), VectorSubtract, and w. Referenced by LightContributionToPoint(), LightingAtSample(), VL_LightSurfaceWithVolume(), and VS_LightSurfaceWithVolume(). 00610 {
00611 vec3_t triVector, triNormal;
00612 int i, j;
00613 vec3_t dirs[MAX_POINTS_ON_WINDING];
00614 float total;
00615 float dot, angle, facing;
00616
00617 for ( i = 0 ; i < w->numpoints ; i++ ) {
00618 VectorSubtract( w->p[i], point, dirs[i] );
00619 VectorNormalize( dirs[i], dirs[i] );
00620 }
00621
00622 // duplicate first vertex to avoid mod operation
00623 VectorCopy( dirs[0], dirs[i] );
00624
00625 total = 0;
00626 for ( i = 0 ; i < w->numpoints ; i++ ) {
00627 j = i+1;
00628 dot = DotProduct( dirs[i], dirs[j] );
00629
00630 // roundoff can cause slight creep, which gives an IND from acos
00631 if ( dot > 1.0 ) {
00632 dot = 1.0;
00633 } else if ( dot < -1.0 ) {
00634 dot = -1.0;
00635 }
00636
00637 angle = acos( dot );
00638 CrossProduct( dirs[i], dirs[j], triVector );
00639 if ( VectorNormalize( triVector, triNormal ) < 0.0001 ) {
00640 continue;
00641 }
00642 facing = DotProduct( normal, triNormal );
00643 total += facing * angle;
00644
00645 if ( total > 6.3 || total < -6.3 ) {
00646 static qboolean printed;
00647
00648 if ( !printed ) {
00649 printed = qtrue;
00650 _printf( "WARNING: bad PointToPolygonFormFactor: %f at %1.1f %1.1f %1.1f from %1.1f %1.1f %1.1f\n", total,
00651 w->p[i][0], w->p[i][1], w->p[i][2], point[0], point[1], point[2]);
00652 }
00653 return 0;
00654 }
00655
00656 }
00657
00658 total /= 2*3.141592657; // now in the range of 0 to 1 over the entire incoming hemisphere
00659
00660 return total;
00661 }
|
Here is the call graph for this function:

|
|
Definition at line 338 of file l_poly.c. References AllocWinding(), c, i, winding_t::numpoints, winding_t::p, VectorCopy, and w. Referenced by AAS_CheckFaceWindingPlane(), AAS_CreateArea(), AAS_FlipFace(), AAS_StoreArea(), ClipSidesIntoTree(), CreateSurfaceLights(), FaceFromPortal(), OutputPortal(), VL_CreateFakeSurfaceLights(), and VS_CreateFakeSurfaceLights(). 00339 {
00340 int i;
00341 winding_t *c;
00342
00343 c = AllocWinding (w->numpoints);
00344 for (i=0 ; i<w->numpoints ; i++)
00345 {
00346 VectorCopy (w->p[w->numpoints-1-i], c->p[i]);
00347 }
00348 c->numpoints = w->numpoints;
00349 return c;
00350 }
|
Here is the call graph for this function:

|
|
Definition at line 560 of file light.c. References atoi, dmodels, e, entities, entitySurface, dmodel_t::firstSurface, GetVectorForKey(), i, j, dmodel_t::numSurfaces, surfaceOrigin, ValueForKey(), vec3_t, and VectorCopy. Referenced by LightMain(), VLightMain(), and VSoundMain(). 00560 {
00561 int i, j;
00562 entity_t *e;
00563 vec3_t origin;
00564 const char *key;
00565 int modelnum;
00566 dmodel_t *dm;
00567
00568 for ( i=0 ; i < num_entities ; i++ ) {
00569 e = &entities[i];
00570 key = ValueForKey (e, "model");
00571 if ( key[0] != '*' ) {
00572 continue;
00573 }
00574 modelnum = atoi( key + 1 );
00575 dm = &dmodels[ modelnum ];
00576
00577 // set entity surface to true for all surfaces for this model
00578 for ( j = 0 ; j < dm->numSurfaces ; j++ ) {
00579 entitySurface[ dm->firstSurface + j ] = qtrue;
00580 }
00581
00582 key = ValueForKey (e, "origin");
00583 if ( !key[0] ) {
00584 continue;
00585 }
00586 GetVectorForKey ( e, "origin", origin );
00587
00588 // set origin for all surfaces for this model
00589 for ( j = 0 ; j < dm->numSurfaces ; j++ ) {
00590 VectorCopy( origin, surfaceOrigin[ dm->firstSurface + j ] );
00591 }
00592 }
00593 }
|
Here is the call graph for this function:

|
|
Definition at line 1196 of file light.c. References byte, c_occluded, c_visible, ColorToBytes(), count, drawSurfaces, drawVerts, dshaders, Error(), dsurface_t::firstVert, shaderInfo_s::forceSunLight, FreeMesh(), mesh_t::height, i, j, k, lightBytes, LightingAtSample(), LIGHTMAP_HEIGHT, LIGHTMAP_WIDTH, dsurface_t::lightmapHeight, dsurface_t::lightmapNum, dsurface_t::lightmapOrigin, shaderInfo_s::lightmapSampleSize, dsurface_t::lightmapVecs, dsurface_t::lightmapWidth, dsurface_t::lightmapX, dsurface_t::lightmapY, LinearSubdivideMesh(), MakeMeshNormals(), MakeNormalVectors(), memset(), shaderInfo_s::noVertexShadows, numthreads, dsurface_t::patchHeight, traceWork_t::patchshadows, shaderInfo_s::patchShadows, dsurface_t::patchWidth, PointInSolid(), PrintOccluded(), PutMeshOnCurve(), qfalse, qtrue, RemoveLinearMeshColumnsRows(), shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, SubdivideMesh(), SubdivideMeshQuads(), surfaceOrigin, dsurface_t::surfaceType, TransposeMesh(), value, vec3_t, VectorAdd, VectorClear, VectorCopy, VectorMA, VectorScale, VertexLighting(), shaderInfo_s::vertexScale, shaderInfo_s::vertexShadows, mesh_t::verts, mesh_t::width, x, and y. Referenced by LightWorld(), VL_DoForcedTraceLight(), and VS_DoForcedTraceLight(). 01196 {
01197 dsurface_t *ds;
01198 int i, j, k;
01199 int x, y;
01200 int position, numPositions;
01201 vec3_t base, origin, normal;
01202 byte occluded[LIGHTMAP_WIDTH*EXTRASCALE][LIGHTMAP_HEIGHT*EXTRASCALE];
01203 vec3_t color[LIGHTMAP_WIDTH*EXTRASCALE][LIGHTMAP_HEIGHT*EXTRASCALE];
01204 traceWork_t tw;
01205 vec3_t average;
01206 int count;
01207 mesh_t srcMesh, *mesh, *subdivided;
01208 shaderInfo_t *si;
01209 static float nudge[2][9] = {
01210 { 0, -1, 0, 1, -1, 1, -1, 0, 1 },
01211 { 0, -1, -1, -1, 0, 0, 1, 1, 1 }
01212 };
01213 int sampleWidth, sampleHeight, ssize;
01214 vec3_t lightmapOrigin, lightmapVecs[2];
01215 int widthtable[LIGHTMAP_WIDTH], heighttable[LIGHTMAP_WIDTH];
01216
01217 ds = &drawSurfaces[num];
01218 si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
01219
01220 // vertex-lit triangle model
01221 if ( ds->surfaceType == MST_TRIANGLE_SOUP ) {
01222 VertexLighting( ds, !si->noVertexShadows, si->forceSunLight, 1.0, &tw );
01223 return;
01224 }
01225
01226 if ( ds->lightmapNum == -1 ) {
01227 return; // doesn't need lighting at all
01228 }
01229
01230 if (!novertexlighting) {
01231 // calculate the vertex lighting for gouraud shade mode
01232 VertexLighting( ds, si->vertexShadows, si->forceSunLight, si->vertexScale, &tw );
01233 }
01234
01235 if ( ds->lightmapNum < 0 ) {
01236 return; // doesn't need lightmap lighting
01237 }
01238
01239 si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
01240 ssize = samplesize;
01241 if (si->lightmapSampleSize)
01242 ssize = si->lightmapSampleSize;
01243
01244 if (si->patchShadows)
01245 tw.patchshadows = qtrue;
01246 else
01247 tw.patchshadows = patchshadows;
01248
01249 if ( ds->surfaceType == MST_PATCH ) {
01250 srcMesh.width = ds->patchWidth;
01251 srcMesh.height = ds->patchHeight;
01252 srcMesh.verts = drawVerts + ds->firstVert;
01253 mesh = SubdivideMesh( srcMesh, 8, 999 );
01254 PutMeshOnCurve( *mesh );
01255 MakeMeshNormals( *mesh );
01256
01257 subdivided = RemoveLinearMeshColumnsRows( mesh );
01258 FreeMesh(mesh);
01259
01260 mesh = SubdivideMeshQuads( subdivided, ssize, LIGHTMAP_WIDTH, widthtable, heighttable);
01261 if ( mesh->width != ds->lightmapWidth || mesh->height != ds->lightmapHeight ) {
01262 Error( "Mesh lightmap miscount");
01263 }
01264
01265 if ( extra ) {
01266 mesh_t *mp;
01267
01268 // chop it up for more light samples (leaking memory...)
01269 mp = mesh;//CopyMesh( mesh );
01270 mp = LinearSubdivideMesh( mp );
01271 mp = TransposeMesh( mp );
01272 mp = LinearSubdivideMesh( mp );
01273 mp = TransposeMesh( mp );
01274
01275 mesh = mp;
01276 }
01277 } else {
01278 VectorCopy( ds->lightmapVecs[2], normal );
01279
01280 if ( !extra ) {
01281 VectorCopy( ds->lightmapOrigin, lightmapOrigin );
01282 VectorCopy( ds->lightmapVecs[0], lightmapVecs[0] );
01283 VectorCopy( ds->lightmapVecs[1], lightmapVecs[1] );
01284 } else {
01285 // sample at a closer spacing for antialiasing
01286 VectorCopy( ds->lightmapOrigin, lightmapOrigin );
01287 VectorScale( ds->lightmapVecs[0], 0.5, lightmapVecs[0] );
01288 VectorScale( ds->lightmapVecs[1], 0.5, lightmapVecs[1] );
01289 VectorMA( lightmapOrigin, -0.5, lightmapVecs[0], lightmapOrigin );
01290 VectorMA( lightmapOrigin, -0.5, lightmapVecs[1], lightmapOrigin );
01291 }
01292 }
01293
01294 if ( extra ) {
01295 sampleWidth = ds->lightmapWidth * 2;
01296 sampleHeight = ds->lightmapHeight * 2;
01297 } else {
01298 sampleWidth = ds->lightmapWidth;
01299 sampleHeight = ds->lightmapHeight;
01300 }
01301
01302 memset ( color, 0, sizeof( color ) );
01303
01304 // determine which samples are occluded
01305 memset ( occluded, 0, sizeof( occluded ) );
01306 for ( i = 0 ; i < sampleWidth ; i++ ) {
01307 for ( j = 0 ; j < sampleHeight ; j++ ) {
01308
01309 if ( ds->patchWidth ) {
01310 numPositions = 9;
01311 VectorCopy( mesh->verts[j*mesh->width+i].normal, normal );
01312 // VectorNormalize( normal, normal );
01313 // push off of the curve a bit
01314 VectorMA( mesh->verts[j*mesh->width+i].xyz, 1, normal, base );
01315
01316 MakeNormalVectors( normal, lightmapVecs[0], lightmapVecs[1] );
01317 } else {
01318 numPositions = 9;
01319 for ( k = 0 ; k < 3 ; k++ ) {
01320 base[k] = lightmapOrigin[k] + normal[k]
01321 + i * lightmapVecs[0][k]
01322 + j * lightmapVecs[1][k];
01323 }
01324 }
01325 VectorAdd( base, surfaceOrigin[ num ], base );
01326
01327 // we may need to slightly nudge the sample point
01328 // if directly on a wall
01329 for ( position = 0 ; position < numPositions ; position++ ) {
01330 // calculate lightmap sample position
01331 for ( k = 0 ; k < 3 ; k++ ) {
01332 origin[k] = base[k] +
01333 + ( nudge[0][position]/16 ) * lightmapVecs[0][k]
01334 + ( nudge[1][position]/16 ) * lightmapVecs[1][k];
01335 }
01336
01337 if ( notrace ) {
01338 break;
01339 }
01340 if ( !PointInSolid( origin ) ) {
01341 break;
01342 }
01343 }
01344
01345 // if none of the nudges worked, this sample is occluded
01346 if ( position == numPositions ) {
01347 occluded[i][j] = qtrue;
01348 if ( numthreads == 1 ) {
01349 c_occluded++;
01350 }
01351 continue;
01352 }
01353
01354 if ( numthreads == 1 ) {
01355 c_visible++;
01356 }
01357 occluded[i][j] = qfalse;
01358 LightingAtSample( origin, normal, color[i][j], qtrue, qfalse, &tw );
01359 }
01360 }
01361
01362 if ( dump ) {
01363 PrintOccluded( occluded, sampleWidth, sampleHeight );
01364 }
01365
01366 // calculate average values for occluded samples
01367 for ( i = 0 ; i < sampleWidth ; i++ ) {
01368 for ( j = 0 ; j < sampleHeight ; j++ ) {
01369 if ( !occluded[i][j] ) {
01370 continue;
01371 }
01372 // scan all surrounding samples
01373 count = 0;
01374 VectorClear( average );
01375 for ( x = -1 ; x <= 1; x++ ) {
01376 for ( y = -1 ; y <= 1 ; y++ ) {
01377 if ( i + x < 0 || i + x >= sampleWidth ) {
01378 continue;
01379 }
01380 if ( j + y < 0 || j + y >= sampleHeight ) {
01381 continue;
01382 }
01383 if ( occluded[i+x][j+y] ) {
01384 continue;
01385 }
01386 count++;
01387 VectorAdd( color[i+x][j+y], average, average );
01388 }
01389 }
01390 if ( count ) {
01391 VectorScale( average, 1.0/count, color[i][j] );
01392 }
01393 }
01394 }
01395
01396 // average together the values if we are extra sampling
01397 if ( ds->lightmapWidth != sampleWidth ) {
01398 for ( i = 0 ; i < ds->lightmapWidth ; i++ ) {
01399 for ( j = 0 ; j < ds->lightmapHeight ; j++ ) {
01400 for ( k = 0 ; k < 3 ; k++ ) {
01401 float value, coverage;
01402
01403 value = color[i*2][j*2][k] + color[i*2][j*2+1][k] +
01404 color[i*2+1][j*2][k] + color[i*2+1][j*2+1][k];
01405 coverage = 4;
01406 if ( extraWide ) {
01407 // wider than box filter
01408 if ( i > 0 ) {
01409 value += color[i*2-1][j*2][k] + color[i*2-1][j*2+1][k];
01410 value += color[i*2-2][j*2][k] + color[i*2-2][j*2+1][k];
01411 coverage += 4;
01412 }
01413 if ( i < ds->lightmapWidth - 1 ) {
01414 value += color[i*2+2][j*2][k] + color[i*2+2][j*2+1][k];
01415 value += color[i*2+3][j*2][k] + color[i*2+3][j*2+1][k];
01416 coverage += 4;
01417 }
01418 if ( j > 0 ) {
01419 value += color[i*2][j*2-1][k] + color[i*2+1][j*2-1][k];
01420 value += color[i*2][j*2-2][k] + color[i*2+1][j*2-2][k];
01421 coverage += 4;
01422 }
01423 if ( j < ds->lightmapHeight - 1 ) {
01424 value += color[i*2][j*2+2][k] + color[i*2+1][j*2+2][k];
01425 value += color[i*2][j*2+3][k] + color[i*2+1][j*2+3][k];
01426 coverage += 2;
01427 }
01428 }
01429
01430 color[i][j][k] = value / coverage;
01431 }
01432 }
01433 }
01434 }
01435
01436 // optionally create a debugging border around the lightmap
01437 if ( lightmapBorder ) {
01438 for ( i = 0 ; i < ds->lightmapWidth ; i++ ) {
01439 color[i][0][0] = 255;
01440 color[i][0][1] = 0;
01441 color[i][0][2] = 0;
01442
01443 color[i][ds->lightmapHeight-1][0] = 255;
01444 color[i][ds->lightmapHeight-1][1] = 0;
01445 color[i][ds->lightmapHeight-1][2] = 0;
01446 }
01447 for ( i = 0 ; i < ds->lightmapHeight ; i++ ) {
01448 color[0][i][0] = 255;
01449 color[0][i][1] = 0;
01450 color[0][i][2] = 0;
01451
01452 color[ds->lightmapWidth-1][i][0] = 255;
01453 color[ds->lightmapWidth-1][i][1] = 0;
01454 color[ds->lightmapWidth-1][i][2] = 0;
01455 }
01456 }
01457
01458 // clamp the colors to bytes and store off
01459 for ( i = 0 ; i < ds->lightmapWidth ; i++ ) {
01460 for ( j = 0 ; j < ds->lightmapHeight ; j++ ) {
01461 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + j)
01462 * LIGHTMAP_WIDTH + ds->lightmapX + i;
01463
01464 ColorToBytes( color[i][j], lightBytes + k*3 );
01465 }
01466 }
01467
01468 if (ds->surfaceType == MST_PATCH)
01469 {
01470 FreeMesh(mesh);
01471 }
01472 }
|
Here is the call graph for this function:

|
|
Definition at line 5457 of file soundv.c. References Error(), malloc(), memset(), winding_t::points, points, and w. Referenced by VS_LoadPortals(). 05458 {
05459 winding_t *w;
05460 int size;
05461
05462 if (points > MAX_POINTS_ON_WINDING)
05463 Error ("NewWinding: %i points", points);
05464
05465 size = (int)((winding_t *)0)->points[points];
05466 w = malloc (size);
05467 memset (w, 0, size);
05468
05469 return w;
05470 }
|
Here is the call graph for this function:

|
|
Definition at line 1859 of file soundv.c. References _printf(), lsurfaceTest_s::detailMesh, drawSurfaces, lsurfaceTest_s::facets, i, j, k, LIGHTMAP_HEIGHT, LIGHTMAP_PIXELSHIFT, LIGHTMAP_WIDTH, dsurface_t::lightmapHeight, dsurface_t::lightmapNum, dsurface_t::lightmapOrigin, lightmappixelarea, dsurface_t::lightmapVecs, dsurface_t::lightmapWidth, dsurface_t::lightmapX, dsurface_t::lightmapY, lsurfaceTest, lsurfaceTest_t, memcpy(), lsurfaceTest_s::numFacets, winding_t::numpoints, winding_t::points, dsurface_t::surfaceType, test(), VectorCopy, VectorMA, mesh_t::verts, VS_ChopWindingWithFacet(), VS_WindingAreaOutsideSolid(), w, mesh_t::width, WindingArea(), x, and y. Referenced by VSoundMain(). 01860 {
01861 int i, j, x, y, k;
01862 dsurface_t *ds;
01863 lsurfaceTest_t *test;
01864 mesh_t *mesh;
01865 winding_t w, tmpw;
01866 float area;
01867
01868 _printf("calculating visible lightmap pixel area...\n");
01869 for ( i = 0 ; i < numDrawSurfaces ; i++ )
01870 {
01871 test = lsurfaceTest[ i ];
01872 if (!test)
01873 continue;
01874 ds = &drawSurfaces[ i ];
01875
01876 if ( ds->lightmapNum < 0 )
01877 continue;
01878
01879 for (y = 0; y < ds->lightmapHeight; y++)
01880 {
01881 for (x = 0; x < ds->lightmapWidth; x++)
01882 {
01883 if (ds->surfaceType == MST_PATCH)
01884 {
01885 if (y == ds->lightmapHeight-1)
01886 continue;
01887 if (x == ds->lightmapWidth-1)
01888 continue;
01889 mesh = lsurfaceTest[i]->detailMesh;
01890 VectorCopy( mesh->verts[y*mesh->width+x].xyz, w.points[0]);
01891 VectorCopy( mesh->verts[(y+1)*mesh->width+x].xyz, w.points[1]);
01892 VectorCopy( mesh->verts[(y+1)*mesh->width+x+1].xyz, w.points[2]);
01893 VectorCopy( mesh->verts[y*mesh->width+x+1].xyz, w.points[3]);
01894 w.numpoints = 4;
01895 if (nostitching)
01896 area = WindingArea(&w);
01897 else
01898 area = VS_WindingAreaOutsideSolid(&w, mesh->verts[y*mesh->width+x].normal);
01899 }
01900 else
01901 {
01902 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[0], w.points[0]);
01903 VectorMA(w.points[0], (float) y - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[1], w.points[0]);
01904 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[0], w.points[3]);
01905 VectorMA(w.points[3], (float) y - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[1], w.points[3]);
01906 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[0], w.points[2]);
01907 VectorMA(w.points[2], (float) y - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[1], w.points[2]);
01908 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1, ds->lightmapVecs[0], w.points[1]);
01909 VectorMA(w.points[1], (float) y - LIGHTMAP_PIXELSHIFT, ds->lightmapVecs[1], w.points[1]);
01910 w.numpoints = 4;
01911 area = 0;
01912 for (j = 0; j < test->numFacets; j++)
01913 {
01914 memcpy(&tmpw, &w, sizeof(winding_t));
01915 area += VS_ChopWindingWithFacet(&tmpw, &test->facets[j]);
01916 }
01917 }
01918 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
01919 * LIGHTMAP_WIDTH + ds->lightmapX + x;
01920 lightmappixelarea[k] = area;
01921 }
01922 }
01923 }
01924 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1556 of file soundv.c. References _printf(), plane_t::dist, DotProduct, i, in, j, memcpy(), plane_t::normal, winding_t::numpoints, p2, winding_t::points, SIDE_ON, vec3_t, vec_t, and VectorCopy. Referenced by VS_ChopWindingWithFacet(), VS_LightSurfaceWithVolume(), VS_R_FloodLight(), and VS_WindingForBrushSide(). 01557 {
01558 vec_t dists[128];
01559 int sides[128];
01560 int counts[3];
01561 vec_t dot;
01562 int i, j;
01563 vec_t *p1, *p2;
01564 vec3_t mid;
01565 winding_t out;
01566 winding_t *neww;
01567
01568 counts[0] = counts[1] = counts[2] = 0;
01569
01570 // determine sides for each point
01571 for (i=0 ; i<in->numpoints ; i++)
01572 {
01573 dot = DotProduct (in->points[i], split->normal);
01574 dot -= split->dist;
01575 dists[i] = dot;
01576 if (dot > epsilon)
01577 sides[i] = SIDE_FRONT;
01578 else if (dot < -epsilon)
01579 sides[i] = SIDE_BACK;
01580 else
01581 {
01582 sides[i] = SIDE_ON;
01583 }
01584 counts[sides[i]]++;
01585 }
01586
01587 if (!counts[SIDE_BACK])
01588 {
01589 if (!counts[SIDE_FRONT])
01590 return SIDE_ON;
01591 else
01592 return SIDE_FRONT;
01593 }
01594
01595 if (!counts[SIDE_FRONT])
01596 {
01597 return SIDE_BACK;
01598 }
01599
01600 sides[i] = sides[0];
01601 dists[i] = dists[0];
01602
01603 neww = &out;
01604
01605 neww->numpoints = 0;
01606
01607 for (i=0 ; i<in->numpoints ; i++)
01608 {
01609 p1 = in->points[i];
01610
01611 if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
01612 {
01613 _printf("WARNING: VS_ChopWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
01614 return SIDE_FRONT; // can't chop -- fall back to original
01615 }
01616
01617 if (sides[i] == SIDE_ON)
01618 {
01619 VectorCopy (p1, neww->points[neww->numpoints]);
01620 neww->numpoints++;
01621 continue;
01622 }
01623
01624 if (sides[i] == SIDE_FRONT)
01625 {
01626 VectorCopy (p1, neww->points[neww->numpoints]);
01627 neww->numpoints++;
01628 }
01629
01630 if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
01631 continue;
01632
01633 if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
01634 {
01635 _printf("WARNING: VS_ChopWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
01636 return SIDE_FRONT; // can't chop -- fall back to original
01637 }
01638
01639 // generate a split point
01640 p2 = in->points[(i+1)%in->numpoints];
01641
01642 dot = dists[i] / (dists[i]-dists[i+1]);
01643 for (j=0 ; j<3 ; j++)
01644 { // avoid round off error when possible
01645 if (split->normal[j] == 1)
01646 mid[j] = split->dist;
01647 else if (split->normal[j] == -1)
01648 mid[j] = -split->dist;
01649 else
01650 mid[j] = p1[j] + dot*(p2[j]-p1[j]);
01651 }
01652
01653 VectorCopy (mid, neww->points[neww->numpoints]);
01654 neww->numpoints++;
01655 }
01656 memcpy(in, &out, sizeof(winding_t));
01657
01658 return SIDE_CROSS;
01659 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1668 of file soundv.c. References _printf(), dbrushsides, dplane_t::dist, plane_t::dist, dplanes, dbrush_t::firstSide, i, memcpy(), plane_t::normal, winding_t::numpoints, dbrush_t::numSides, dbrushside_t::planeNum, points, winding_t::points, SIDE_BACK, vec3_t, VectorCopy, VectorInverse(), VS_SplitWinding(), and w. Referenced by VS_WindingAreaOutsideBrushes(). 01669 {
01670 int i, res, numout;
01671 winding_t front, back;
01672 plane_t plane;
01673
01674 numout = 0;
01675 memcpy(front.points, w->points, w->numpoints * sizeof(vec3_t));
01676 front.numpoints = w->numpoints;
01677 for (i = 0; i < brush->numSides; i++)
01678 {
01679 VectorCopy(dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].normal, plane.normal);
01680 VectorInverse(plane.normal);
01681 plane.dist = -dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].dist;
01682 res = VS_SplitWinding(&front, &back, &plane, 0.1);
01683 if (res == SIDE_BACK || res == SIDE_ON)
01684 {
01685 memcpy(outwindings[0].points, w->points, w->numpoints * sizeof(vec3_t));
01686 outwindings[0].numpoints = w->numpoints;
01687 return 1; //did not intersect
01688 }
01689 if (res != SIDE_FRONT)
01690 {
01691 if (numout >= maxout)
01692 {
01693 _printf("WARNING: VS_ChopWindingWithBrush: more than %d windings\n", maxout);
01694 return 0;
01695 }
01696 memcpy(outwindings[numout].points, back.points, back.numpoints * sizeof(vec3_t));
01697 outwindings[numout].numpoints = back.numpoints;
01698 numout++;
01699 }
01700 }
01701 return numout;
01702 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1837 of file soundv.c. References lFacet_s::boundaries, i, lFacet_t, plane_t::normal, lFacet_s::numpoints, lFacet_s::plane, VS_ChopWinding(), VS_WindingAreaOutsideSolid(), w, and WindingArea(). Referenced by VS_CalcVisibleLightmapPixelArea(). 01838 {
01839 int i;
01840
01841 for (i = 0; i < facet->numpoints; i++)
01842 {
01843 if (VS_ChopWinding(w, &facet->boundaries[i], 0) == SIDE_BACK)
01844 return 0;
01845 }
01846 if (nostitching)
01847 return WindingArea(w);
01848 else
01849 return VS_WindingAreaOutsideSolid(w, facet->plane.normal);
01850 }
|
Here is the call graph for this function:

|
|
Definition at line 4989 of file soundv.c. References _printf(), vsound_s::atten_anglescale, vsound_s::atten_angletype, vsound_s::atten_distscale, vsound_s::atten_disttype, vsound_s::color, ColorNormalize(), e, entities, FindTargetEntity(), FloatForKey(), GetVectorForKey(), i, malloc(), memset(), name, numvsounds, entity_t::origin, vsound_s::photons, sscanf(), strncmp(), vsound_s::style, vsound_s::type, ValueForKey(), vec3_t, VectorNormalize(), VectorSubtract, vsound_t, and vsounds. Referenced by VSoundMain(). 04990 {
04991 int i, c_entityLights;
04992 vsound_t *dl;
04993 entity_t *e, *e2;
04994 const char *name;
04995 const char *target;
04996 vec3_t dest;
04997 const char *_color;
04998 float intensity;
04999 int spawnflags;
05000
05001 //
05002 c_entityLights = 0;
05003 _printf("Creating entity lights...\n");
05004 //
05005 for ( i = 0 ; i < num_entities ; i++ ) {
05006 e = &entities[i];
05007 name = ValueForKey (e, "classname");
05008 if (strncmp (name, "speaker", 7))
05009 continue;
05010
05011 dl = malloc(sizeof(*dl));
05012 memset (dl, 0, sizeof(*dl));
05013
05014 spawnflags = FloatForKey (e, "spawnflags");
05015 if ( spawnflags & 1 ) {
05016 dl->atten_disttype = LDAT_LINEAR;
05017 }
05018 if ( spawnflags & 2 ) {
05019 dl->atten_disttype = LDAT_NOSCALE;
05020 }
05021 if ( spawnflags & 4 ) {
05022 dl->atten_angletype = LAAT_QUADRATIC;
05023 }
05024 if ( spawnflags & 8 ) {
05025 dl->atten_angletype = LAAT_DOUBLEQUADRATIC;
05026 }
05027
05028 dl->atten_distscale = FloatForKey(e, "atten_distscale");
05029 dl->atten_anglescale = FloatForKey(e, "atten_anglescale");
05030
05031 GetVectorForKey (e, "origin", dl->origin);
05032 dl->style = FloatForKey (e, "_style");
05033 if (!dl->style)
05034 dl->style = FloatForKey (e, "style");
05035 if (dl->style < 0)
05036 dl->style = 0;
05037
05038 intensity = FloatForKey (e, "light");
05039 if (!intensity)
05040 intensity = FloatForKey (e, "_light");
05041 if (!intensity)
05042 intensity = 300;
05043 _color = ValueForKey (e, "_color");
05044 if (_color && _color[0])
05045 {
05046 sscanf (_color, "%f %f %f", &dl->color[0],&dl->color[1],&dl->color[2]);
05047 ColorNormalize (dl->color, dl->color);
05048 }
05049 else
05050 dl->color[0] = dl->color[1] = dl->color[2] = 1.0;
05051
05052 intensity = intensity * lightPointScale;
05053 dl->photons = intensity;
05054
05055 dl->type = LIGHT_POINTRADIAL;
05056
05057 // lights with a target will be spotlights
05058 target = ValueForKey (e, "target");
05059
05060 if ( target[0] ) {
05061 float radius;
05062 float dist;
05063
05064 e2 = FindTargetEntity (target);
05065 if (!e2) {
05066 _printf ("WARNING: light at (%i %i %i) has missing target\n",
05067 (int)dl->origin[0], (int)dl->origin[1], (int)dl->origin[2]);
05068 } else {
05069 GetVectorForKey (e2, "origin", dest);
05070 VectorSubtract (dest, dl->origin, dl->normal);
05071 dist = VectorNormalize (dl->normal, dl->normal);
05072 radius = FloatForKey (e, "radius");
05073 if ( !radius ) {
05074 radius = 64;
05075 }
05076 if ( !dist ) {
05077 dist = 64;
05078 }
05079 dl->radiusByDist = (radius + 16) / dist;
05080 dl->type = LIGHT_POINTSPOT;
05081 }
05082 }
05083 vsounds[numvsounds++] = dl;
05084 c_entityLights++;
05085 }
05086 _printf("%7i entity lights\n", c_entityLights);
05087 }
|
Here is the call graph for this function:

|
|
Definition at line 5185 of file soundv.c. References _printf(), AllocWinding(), shaderInfo_s::autosprite, shaderInfo_s::color, drawSurfaces, drawVerts, dshaders, f, lsurfaceTest_s::facets, dsurface_t::firstVert, FreeWinding(), i, j, lFacet_t, dsurface_t::lightmapVecs, shaderInfo_s::lightSubdivide, lsurfaceTest, malloc(), memcpy(), memset(), plane_t::normal, lsurfaceTest_s::numFacets, winding_t::numpoints, lFacet_s::numpoints, dsurface_t::numVerts, numvsounds, vsound_s::photons, lFacet_s::plane, winding_t::points, lFacet_s::points, qtrue, ReverseWinding(), shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, t, shaderInfo_s::twoSided, shaderInfo_s::value, vec3_origin, vec3_t, VectorAdd, VectorCopy, VectorScale, VectorSubtract, VS_SubdivideAreaLight(), vsound_t, vsounds, w, and drawVert_t::xyz. Referenced by VSoundMain(). 05185 {
05186 int i, j, side;
05187 dsurface_t *ds;
05188 shaderInfo_t *ls;
05189 winding_t *w;
05190 lFacet_t *f;
05191 vsound_t *dl;
05192 vec3_t origin;
05193 drawVert_t *dv;
05194 int c_surfaceLights;
05195 float lightSubdivide;
05196 vec3_t normal;
05197
05198
05199 c_surfaceLights = 0;
05200 _printf ("Creating surface lights...\n");
05201
05202 for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
05203 // see if this surface is light emiting
05204 ds = &drawSurfaces[i];
05205
05206 ls = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
05207 if ( ls->value == 0 ) {
05208 continue;
05209 }
05210
05211 // determine how much we need to chop up the surface
05212 if ( ls->lightSubdivide ) {
05213 lightSubdivide = ls->lightSubdivide;
05214 } else {
05215 lightSubdivide = lightDefaultSubdivide;
05216 }
05217
05218 c_surfaceLights++;
05219
05220 // an autosprite shader will become
05221 // a point light instead of an area light
05222 if ( ls->autosprite ) {
05223 // autosprite geometry should only have four vertexes
05224 if ( lsurfaceTest[i] ) {
05225 // curve or misc_model
05226 f = lsurfaceTest[i]->facets;
05227 if ( lsurfaceTest[i]->numFacets != 1 || f->numpoints != 4 ) {
05228 _printf( "WARNING: surface at (%i %i %i) has autosprite shader but isn't a quad\n",
05229 (int)f->points[0], (int)f->points[1], (int)f->points[2] );
05230 }
05231 VectorAdd( f->points[0], f->points[1], origin );
05232 VectorAdd( f->points[2], origin, origin );
05233 VectorAdd( f->points[3], origin, origin );
05234 VectorScale( origin, 0.25, origin );
05235 } else {
05236 // normal polygon
05237 dv = &drawVerts[ ds->firstVert ];
05238 if ( ds->numVerts != 4 ) {
05239 _printf( "WARNING: surface at (%i %i %i) has autosprite shader but %i verts\n",
05240 (int)dv->xyz[0], (int)dv->xyz[1], (int)dv->xyz[2] );
05241 continue;
05242 }
05243
05244 VectorAdd( dv[0].xyz, dv[1].xyz, origin );
05245 VectorAdd( dv[2].xyz, origin, origin );
05246 VectorAdd( dv[3].xyz, origin, origin );
05247 VectorScale( origin, 0.25, origin );
05248 }
05249
05250 dl = malloc(sizeof(*dl));
05251 memset (dl, 0, sizeof(*dl));
05252 VectorCopy( origin, dl->origin );
05253 VectorCopy( ls->color, dl->color );
05254 dl->photons = ls->value * lightPointScale;
05255 dl->type = LIGHT_POINTRADIAL;
05256 vsounds[numvsounds++] = dl;
05257 continue;
05258 }
05259
05260 // possibly create for both sides of the polygon
05261 for ( side = 0 ; side <= ls->twoSided ; side++ ) {
05262 // create area lights
05263 if ( lsurfaceTest[i] ) {
05264 // curve or misc_model
05265 for ( j = 0 ; j < lsurfaceTest[i]->numFacets ; j++ ) {
05266 f = lsurfaceTest[i]->facets + j;
05267 w = AllocWinding( f->numpoints );
05268 w->numpoints = f->numpoints;
05269 memcpy( w->points, f->points, f->numpoints * 12 );
05270
05271 VectorCopy( f->plane.normal, normal );
05272 if ( side ) {
05273 winding_t *t;
05274
05275 t = w;
05276 w = ReverseWinding( t );
05277 FreeWinding( t );
05278 VectorSubtract( vec3_origin, normal, normal );
05279 }
05280 VS_SubdivideAreaLight( ls, w, normal, lightSubdivide, qtrue );
05281 }
05282 } else {
05283 // normal polygon
05284
05285 w = AllocWinding( ds->numVerts );
05286 w->numpoints = ds->numVerts;
05287 for ( j = 0 ; j < ds->numVerts ; j++ ) {
05288 VectorCopy( drawVerts[ds->firstVert+j].xyz, w->points[j] );
05289 }
05290 VectorCopy( ds->lightmapVecs[2], normal );
05291 if ( side ) {
05292 winding_t *t;
05293
05294 t = w;
05295 w = ReverseWinding( t );
05296 FreeWinding( t );
05297 VectorSubtract( vec3_origin, normal, normal );
05298 }
05299 VS_SubdivideAreaLight( ls, w, normal, lightSubdivide, qtrue );
05300 }
05301 }
05302 }
05303
05304 _printf( "%7i light emitting surfaces\n", c_surfaceLights );
05305 }
|
Here is the call graph for this function:

|
|
Definition at line 5345 of file soundv.c. References _printf(), b, d, dbrushes, dbrushsides, dplane_t::dist, DotProduct, dplanes, drawSurfaces, dshaders, dbrush_t::firstSide, i, j, malloc(), memset(), dbrush_t::numSides, numvsounds, vsound_s::plane, dbrushside_t::planeNum, s, shaderInfo_t, ShaderInfoForShader(), dbrushside_t::shaderNum, shaderInfo_s::sunDirection, shaderInfo_s::sunLight, dshader_t::surfaceFlags, shaderInfo_s::surfaceFlags, dplane_t::type, vec3_t, VectorCopy, VectorInverse(), VectorNormalize(), VS_WindingForBrushSide(), vsound_t, and vsounds. Referenced by VSoundMain(). 05346 {
05347 int i, j, c_skyLights;
05348 dbrush_t *b;
05349 shaderInfo_t *si;
05350 dbrushside_t *s;
05351 vsound_t *dl;
05352 vec3_t sunColor, sunDir = { 0.45, 0.3, 0.9 };
05353 float d;
05354
05355 VectorNormalize(sunDir, sunDir);
05356 VectorInverse(sunDir);
05357
05358 c_skyLights = 0;
05359 _printf("Creating sky lights...\n");
05360 // find the sky shader
05361 for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
05362 si = ShaderInfoForShader( dshaders[ drawSurfaces[i].shaderNum ].shader );
05363 if ( si->surfaceFlags & SURF_SKY ) {
05364 VectorCopy( si->sunLight, sunColor );
05365 VectorCopy( si->sunDirection, sunDir );
05366 VectorInverse(sunDir);
05367 break;
05368 }
05369 }
05370
05371 // find the brushes
05372 for ( i = 0 ; i < numbrushes ; i++ ) {
05373 b = &dbrushes[i];
05374 for ( j = 0 ; j < b->numSides ; j++ ) {
05375 s = &dbrushsides[ b->firstSide + j ];
05376 if ( dshaders[ s->shaderNum ].surfaceFlags & SURF_SKY ) {
05377 //if this surface doesn't face in the same direction as the sun
05378 d = DotProduct(dplanes[ s->planeNum ].normal, sunDir);
05379 if (d <= 0)
05380 continue;
05381 //
05382 dl = malloc(sizeof(*dl));
05383 memset (dl, 0, sizeof(*dl));
05384 VectorCopy(sunColor, dl->color);
05385 VectorCopy(sunDir, dl->normal);
05386 VectorCopy(dplanes[ s->planeNum ].normal, dl->plane);
05387 dl->plane[3] = dplanes[ s->planeNum ].dist;
05388 dl->type = LIGHT_SURFACEDIRECTED;
05389 dl->atten_disttype = LDAT_NOSCALE;
05390 VS_WindingForBrushSide(b, j, &dl->w);
05391 // DebugNet_DrawWinding(&dl->w, 2);
05392 //
05393 vsounds[numvsounds++] = dl;
05394 c_skyLights++;
05395 }
05396 }
05397 }
05398 _printf("%7i light emitting sky surfaces\n", c_skyLights);
05399 }
|
Here is the call graph for this function:

|
|
Definition at line 4790 of file soundv.c. References drawSurfaces, dshaders, entitySurface, shaderInfo_s::forceTraceLight, shaderInfo_s::forceVLight, dsurface_t::lightmapNum, shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, dsurface_t::surfaceType, and TraceLtm(). Referenced by VS_DoForcedTraceLightSurfaces(). 04791 {
04792 dsurface_t *ds;
04793 shaderInfo_t *si;
04794
04795 ds = &drawSurfaces[num];
04796
04797 if ( ds->surfaceType == MST_TRIANGLE_SOUP )
04798 return;
04799
04800 if ( ds->lightmapNum < 0 )
04801 return;
04802
04803 // always light entity surfaces with the old light algorithm
04804 if ( !entitySurface[num] )
04805 {
04806 si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
04807
04808 if (defaulttracelight)
04809 {
04810 if (si->forceVLight)
04811 return;
04812 }
04813 else
04814 {
04815 if (!si->forceTraceLight)
04816 return;
04817 }
04818 }
04819
04820 TraceLtm(num);
04821 }
|
Here is the call graph for this function:

|
|
Definition at line 4828 of file soundv.c. References _printf(), numDrawSurfaces, qtrue, RunThreadsOnIndividual(), and VS_DoForcedTraceLight(). Referenced by VS_LightWorld(). 04829 {
04830 _printf( "forced trace light\n" );
04831 RunThreadsOnIndividual( numDrawSurfaces, qtrue, VS_DoForcedTraceLight );
04832 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1395 of file soundv.c. References count, lsurfaceTest_s::detailMesh, drawVerts, Error(), lsurfaceTest_s::facets, dsurface_t::firstVert, FreeMesh(), lFacet_s::height, mesh_t::height, i, j, LIGHTMAP_SIZE, dsurface_t::lightmapHeight, dsurface_t::lightmapNum, shaderInfo_s::lightmapSampleSize, dsurface_t::lightmapWidth, lsurfaceTest_t, MakeMeshNormals(), malloc(), memset(), lsurfaceTest_s::numFacets, lsurfaceTest_s::patch, dsurface_t::patchHeight, dsurface_t::patchWidth, PutMeshOnCurve(), RemoveLinearMeshColumnsRows(), lsurfaceTest_s::shader, shaderInfo_t, SubdivideMesh(), SubdivideMeshQuads(), test(), lsurfaceTest_s::trisoup, v1, v2, mesh_t::verts, VS_GenerateFacetFor3Points(), VS_GenerateFacetFor4Points(), lFacet_s::width, mesh_t::width, lFacet_s::x, x, lFacet_s::y, and y. Referenced by VS_InitSurfacesForTesting(). 01395 {
01396 int i, j, x, y;
01397 drawVert_t *v1, *v2, *v3, *v4;
01398 int count, ssize;
01399 mesh_t mesh;
01400 mesh_t *subdivided, *detailmesh, *newmesh;
01401 int widthtable[LIGHTMAP_SIZE], heighttable[LIGHTMAP_SIZE];
01402
01403 mesh.width = dsurf->patchWidth;
01404 mesh.height = dsurf->patchHeight;
01405 mesh.verts = &drawVerts[ dsurf->firstVert ];
01406
01407 newmesh = SubdivideMesh( mesh, 8, 999 );
01408 PutMeshOnCurve( *newmesh );
01409 MakeMeshNormals( *newmesh );
01410
01411 subdivided = RemoveLinearMeshColumnsRows( newmesh );
01412 FreeMesh(newmesh);
01413
01414 // DebugNet_RemoveAllPolys();
01415 // DebugNet_DrawMesh(subdivided);
01416
01417 ssize = samplesize;
01418 if (si->lightmapSampleSize)
01419 ssize = si->lightmapSampleSize;
01420
01421 if ( dsurf->lightmapNum >= 0 ) {
01422
01423 detailmesh = SubdivideMeshQuads( subdivided, ssize, LIGHTMAP_SIZE, widthtable, heighttable);
01424 test->detailMesh = detailmesh;
01425
01426 // DebugNet_RemoveAllPolys();
01427 // DebugNet_DrawMesh(detailmesh);
01428
01429 if ( detailmesh->width != dsurf->lightmapWidth || detailmesh->height != dsurf->lightmapHeight ) {
01430 Error( "Mesh lightmap miscount");
01431 }
01432 }
01433 else {
01434 test->detailMesh = NULL;
01435 memset(widthtable, 0, sizeof(widthtable));
01436 memset(heighttable, 0, sizeof(heighttable));
01437 }
01438
01439 test->patch = qtrue;
01440 test->trisoup = qfalse;
01441 test->numFacets = ( subdivided->width - 1 ) * ( subdivided->height - 1 ) * 2;
01442 test->facets = malloc( sizeof( test->facets[0] ) * test->numFacets );
01443 test->shader = si;
01444
01445 count = 0;
01446 x = 0;
01447 for ( i = 0 ; i < subdivided->width - 1 ; i++ ) {
01448 y = 0;
01449 for ( j = 0 ; j < subdivided->height - 1 ; j++ ) {
01450
01451 v1 = subdivided->verts + j * subdivided->width + i;
01452 v2 = v1 + 1;
01453 v3 = v1 + subdivided->width + 1;
01454 v4 = v1 + subdivided->width;
01455
01456 if ( VS_GenerateFacetFor4Points( dsurf, si, &test->facets[count], v1, v4, v3, v2 ) ) {
01457 test->facets[count].x = x;
01458 test->facets[count].y = y;
01459 test->facets[count].width = widthtable[i];
01460 test->facets[count].height = heighttable[j];
01461 count++;
01462 } else {
01463 if (VS_GenerateFacetFor3Points( dsurf, si, &test->facets[count], v1, v4, v3 )) {
01464 test->facets[count].x = x;
01465 test->facets[count].y = y;
01466 test->facets[count].width = widthtable[i];
01467 test->facets[count].height = heighttable[j];
01468 count++;
01469 }
01470 if (VS_GenerateFacetFor3Points( dsurf, si, &test->facets[count], v1, v3, v2 )) {
01471 test->facets[count].x = x;
01472 test->facets[count].y = y;
01473 test->facets[count].width = widthtable[i];
01474 test->facets[count].height = heighttable[j];
01475 count++;
01476 }
01477 }
01478 y += heighttable[j];
01479 }
01480 x += widthtable[i];
01481 }
01482 test->numFacets = count;
01483
01484 FreeMesh(subdivided);
01485 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1341 of file soundv.c. References count, drawIndexes, drawVerts, lsurfaceTest_s::facets, dsurface_t::firstIndex, dsurface_t::firstVert, i, i1, i2, lsurfaceTest_t, malloc(), lsurfaceTest_s::numFacets, dsurface_t::numIndexes, lsurfaceTest_s::patch, lsurfaceTest_s::shader, shaderInfo_t, dsurface_t::surfaceType, test(), lsurfaceTest_s::trisoup, v1, v2, VS_GenerateFacetFor3Points(), and VS_GenerateFacetFor4Points(). Referenced by VS_InitSurfacesForTesting(). 01341 {
01342 int i;
01343 drawVert_t *v1, *v2, *v3, *v4;
01344 int count;
01345 int i1, i2, i3, i4, i5, i6;
01346
01347 test->patch = qfalse;
01348 if (dsurf->surfaceType == MST_TRIANGLE_SOUP)
01349 test->trisoup = qtrue;
01350 else
01351 test->trisoup = qfalse;
01352 test->numFacets = dsurf->numIndexes / 3;
01353 test->facets = malloc( sizeof( test->facets[0] ) * test->numFacets );
01354 test->shader = si;
01355
01356 count = 0;
01357 for ( i = 0 ; i < test->numFacets ; i++ ) {
01358 i1 = drawIndexes[ dsurf->firstIndex + i*3 ];
01359 i2 = drawIndexes[ dsurf->firstIndex + i*3 + 1 ];
01360 i3 = drawIndexes[ dsurf->firstIndex + i*3 + 2 ];
01361
01362 v1 = &drawVerts[ dsurf->firstVert + i1 ];
01363 v2 = &drawVerts[ dsurf->firstVert + i2 ];
01364 v3 = &drawVerts[ dsurf->firstVert + i3 ];
01365
01366 // try and make a quad out of two triangles
01367 if ( i != test->numFacets - 1 ) {
01368 i4 = drawIndexes[ dsurf->firstIndex + i*3 + 3 ];
01369 i5 = drawIndexes[ dsurf->firstIndex + i*3 + 4 ];
01370 i6 = drawIndexes[ dsurf->firstIndex + i*3 + 5 ];
01371 if ( i4 == i3 && i5 == i2 ) {
01372 v4 = &drawVerts[ dsurf->firstVert + i6 ];
01373 if ( VS_GenerateFacetFor4Points( dsurf, si, &test->facets[count], v1, v2, v4, v3 ) ) {
01374 count++;
01375 i++; // skip next tri
01376 continue;
01377 }
01378 }
01379 }
01380
01381 if (VS_GenerateFacetFor3Points( dsurf, si, &test->facets[count], v1, v2, v3 )) {
01382 count++;
01383 }
01384 }
01385
01386 // we may have turned some pairs into quads
01387 test->numFacets = count;
01388 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||
|
Definition at line 1931 of file soundv.c. References DotProduct, drawSurfaces, fabs(), lsurfaceTest_s::facets, i, j, k, lFacet_t, dsurface_t::lightmapNum, lsurfaceTest, lsurfaceTest_t, plane_t::normal, lsurfaceTest_s::numFacets, lFacet_s::numpoints, lsurfaceTest_s::origin, p2, lsurfaceTest_s::patch, lFacet_s::plane, point, lFacet_s::points, lsurfaceTest_s::radius, test(), lsurfaceTest_s::trisoup, vec3_t, and VectorSubtract. Referenced by VS_SmoothenLightmapEdges(). 01932 {
01933 int i, j, k;
01934 lsurfaceTest_t *test;
01935 lFacet_t *facet;
01936 dsurface_t *ds;
01937 float *fp1, *fp2;
01938 vec3_t dir;
01939 plane_t *facetplane;
01940 // winding_t w;
01941
01942 facetplane = &lsurfaceTest[surfaceNum]->facets[facetNum].plane;
01943 // DebugNet_RemoveAllPolys();
01944 // memcpy(w.points, lsurfaceTest[surfaceNum]->facets[facetNum].points,
01945 // lsurfaceTest[surfaceNum]->facets[facetNum].numpoints * sizeof(vec3_t));
01946 // w.numpoints = lsurfaceTest[surfaceNum]->facets[facetNum].numpoints;
01947 // DebugNet_DrawWinding(&w, 2);
01948 for ( i = 0 ; i < numDrawSurfaces ; i++ )
01949 {
01950 if (i == surfaceNum)
01951 continue;
01952 test = lsurfaceTest[ i ];
01953 if (!test)
01954 continue;
01955 if (test->trisoup)// || test->patch)
01956 continue;
01957 ds = &drawSurfaces[i];
01958 if ( ds->lightmapNum < 0 )
01959 continue;
01960 //if this surface is not even near the edge
01961 VectorSubtract(p1, test->origin, dir);
01962 if (fabs(dir[0]) > test->radius ||
01963 fabs(dir[1]) > test->radius ||
01964 fabs(dir[1]) > test->radius)
01965 {
01966 VectorSubtract(p2, test->origin, dir);
01967 if (fabs(dir[0]) > test->radius ||
01968 fabs(dir[1]) > test->radius ||
01969 fabs(dir[1]) > test->radius)
01970 {
01971 continue;
01972 }
01973 }
01974 //
01975 for (j = 0; j < test->numFacets; j++)
01976 {
01977 facet = &test->facets[j];
01978 //
01979 //if (!Plane_Equal(&facet->plane, facetplane, qfalse))
01980 if (DotProduct(facet->plane.normal, facetplane->normal) < 0.9)
01981 {
01982 if (!test->trisoup && !test->patch)
01983 break;
01984 continue;
01985 }
01986 //
01987 for (k = 0; k < facet->numpoints; k++)
01988 {
01989 fp1 = facet->points[k];
01990 if (fabs(p2[0] - fp1[0]) < 0.1 &&
01991 fabs(p2[1] - fp1[1]) < 0.1 &&
01992 fabs(p2[2] - fp1[2]) < 0.1)
01993 {
01994 fp2 = facet->points[(k+1) % facet->numpoints];
01995 if (fabs(p1[0] - fp2[0]) < 0.1 &&
01996 fabs(p1[1] - fp2[1]) < 0.1 &&
01997 fabs(p1[2] - fp2[2]) < 0.1)
01998 {
01999 // memcpy(w.points, facet->points, facet->numpoints * sizeof(vec3_t));
02000 // w.numpoints = facet->numpoints;
02001 // DebugNet_DrawWinding(&w, 1);
02002 *sNum = i;
02003 *fNum = j;
02004 *point = k;
02005 return qtrue;
02006 }
02007 }
02008 /*
02009 else if (fabs(p1[0] - fp1[0]) < 0.1 &&
02010 fabs(p1[1] - fp1[1]) < 0.1 &&
02011 fabs(p1[2] - fp1[2]) < 0.1)
02012 {
02013 fp2 = facet->points[(k+1) % facet->numpoints];
02014 if (fabs(p2[0] - fp2[0]) < 0.1 &&
02015 fabs(p2[1] - fp2[1]) < 0.1 &&
02016 fabs(p2[2] - fp2[2]) < 0.1)
02017 {
02018 // memcpy(w.points, facet->points, facet->numpoints * sizeof(vec3_t));
02019 // w.numpoints = facet->numpoints;
02020 // DebugNet_DrawWinding(&w, 1);
02021 *sNum = i;
02022 *fNum = j;
02023 *point = k;
02024 return qtrue;
02025 }
02026 }
02027 //*/
02028 }
02029 }
02030 }
02031 return qfalse;
02032 }
|
Here is the call graph for this function:

|
|
Definition at line 2208 of file soundv.c. References bottom, byte, drawSurfaces, height, i, j, k, lightFloats, LIGHTMAP_HEIGHT, LIGHTMAP_SIZE, LIGHTMAP_WIDTH, dsurface_t::lightmapHeight, dsurface_t::lightmapNum, lightmappixelarea, dsurface_t::lightmapWidth, dsurface_t::lightmapX, dsurface_t::lightmapY, lsurfaceTest, lsurfaceTest_t, memset(), ptr(), dsurface_t::surfaceType, test(), top, VS_SmoothenLightmapEdges(), width, x, and y. Referenced by VS_StoreLightmap(). 02209 {
02210 int i, j, x, y, k, foundvalue, height, width, index;
02211 int pos, top, bottom;
02212 dsurface_t *ds;
02213 lsurfaceTest_t *test;
02214 float color[3];
02215 float *ptr;
02216 byte filled[(LIGHTMAP_SIZE+1) * (LIGHTMAP_SIZE+1) / 8];
02217 float lightmap_edge_epsilon;
02218
02219 lightmap_edge_epsilon = 0.1 * samplesize;
02220 for ( i = 0 ; i < numDrawSurfaces ; i++ )
02221 {
02222 test = lsurfaceTest[ i ];
02223 if (!test)
02224 continue;
02225 ds = &drawSurfaces[ i ];
02226
02227 if ( ds->lightmapNum < 0 )
02228 continue;
02229 if (ds->surfaceType == MST_PATCH)
02230 {
02231 height = ds->lightmapHeight - 1;
02232 width = ds->lightmapWidth - 1;
02233 }
02234 else
02235 {
02236 height = ds->lightmapHeight;
02237 width = ds->lightmapWidth;
02238 }
02239 memset(filled, 0, sizeof(filled));
02240 // printf("\n");
02241 for (x = 0; x < width; x++)
02242 {
02243 for (y = 0; y < height; y++)
02244 {
02245 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02246 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02247 if (lightmappixelarea[k] > lightmap_edge_epsilon)
02248 {
02249 index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
02250 filled[index >> 3] |= 1 << (index & 7);
02251 // printf("*");
02252 }
02253 // else
02254 // printf("_");
02255 }
02256 // printf("\n");
02257 }
02258 for (y = 0; y < height; y++)
02259 {
02260 pos = -2;
02261 for (x = 0; x < width; x++)
02262 {
02263 index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
02264 if (pos == -2)
02265 {
02266 if (filled[index >> 3] & (1 << (index & 7)))
02267 pos = -1;
02268 }
02269 else if (pos == -1)
02270 {
02271 if (!(filled[index >> 3] & (1 << (index & 7))))
02272 pos = x - 1;
02273 }
02274 else
02275 {
02276 if (filled[index >> 3] & (1 << (index & 7)))
02277 {
02278 bottom = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02279 * LIGHTMAP_WIDTH + ds->lightmapX + pos;
02280 top = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02281 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02282 for (j = 0; j < (x - pos + 1) / 2; j++)
02283 {
02284 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02285 * LIGHTMAP_WIDTH + ds->lightmapX + pos + j + 1;
02286 index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + pos + j + 1;
02287 filled[index >> 3] |= 1 << (index & 7);
02288 (lightFloats + k*3)[0] = (lightFloats + top*3)[0];
02289 (lightFloats + k*3)[1] = (lightFloats + top*3)[1];
02290 (lightFloats + k*3)[2] = (lightFloats + top*3)[2];
02291 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02292 * LIGHTMAP_WIDTH + ds->lightmapX + x - j - 1;
02293 index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x - j - 1;
02294 filled[index >> 3] |= 1 << (index & 7);
02295 (lightFloats + k*3)[0] = (lightFloats + bottom*3)[0];
02296 (lightFloats + k*3)[1] = (lightFloats + bottom*3)[1];
02297 (lightFloats + k*3)[2] = (lightFloats + bottom*3)[2];
02298 }
02299 pos = -1;
02300 }
02301 }
02302 }
02303 }
02304 for (x = 0; x < width; x++)
02305 {
02306 pos = -2;
02307 for (y = 0; y < height; y++)
02308 {
02309 index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
02310 if (pos == -2)
02311 {
02312 if (filled[index >> 3] & (1 << (index & 7)))
02313 pos = -1;
02314 }
02315 else if (pos == -1)
02316 {
02317 if (!(filled[index >> 3] & (1 << (index & 7))))
02318 pos = y - 1;
02319 }
02320 else
02321 {
02322 if (filled[index >> 3] & (1 << (index & 7)))
02323 {
02324 bottom = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + pos)
02325 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02326 top = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02327 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02328 for (j = 0; j < (y - pos + 1) / 2; j++)
02329 {
02330 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + pos + j + 1)
02331 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02332 index = (ds->lightmapY + pos + j + 1) * LIGHTMAP_WIDTH + ds->lightmapX + x;
02333 filled[index >> 3] |= 1 << (index & 7);
02334 (lightFloats + k*3)[0] = (lightFloats + top*3)[0];
02335 (lightFloats + k*3)[1] = (lightFloats + top*3)[1];
02336 (lightFloats + k*3)[2] = (lightFloats + top*3)[2];
02337 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y - j - 1)
02338 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02339 index = (ds->lightmapY + y - j - 1) * LIGHTMAP_WIDTH + ds->lightmapX + x;
02340 filled[index >> 3] |= 1 << (index & 7);
02341 (lightFloats + k*3)[0] = (lightFloats + bottom*3)[0];
02342 (lightFloats + k*3)[1] = (lightFloats + bottom*3)[1];
02343 (lightFloats + k*3)[2] = (lightFloats + bottom*3)[2];
02344 }
02345 pos = -1;
02346 }
02347 }
02348 }
02349 }
02350 for (y = 0; y < height; y++)
02351 {
02352 foundvalue = qfalse;
02353 for (x = 0; x < width; x++)
02354 {
02355 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02356 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02357 index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
02358 if (foundvalue)
02359 {
02360 if (filled[index >> 3] & (1 << (index & 7)))
02361 {
02362 ptr = lightFloats + k*3;
02363 color[0] = ptr[0];
02364 color[1] = ptr[1];
02365 color[2] = ptr[2];
02366 }
02367 else
02368 {
02369 ptr = lightFloats + k*3;
02370 ptr[0] = color[0];
02371 ptr[1] = color[1];
02372 ptr[2] = color[2];
02373 filled[index >> 3] |= 1 << (index & 7);
02374 }
02375 }
02376 else
02377 {
02378 if (filled[index >> 3] & (1 << (index & 7)))
02379 {
02380 ptr = lightFloats + k*3;
02381 color[0] = ptr[0];
02382 color[1] = ptr[1];
02383 color[2] = ptr[2];
02384 foundvalue = qtrue;
02385 }
02386 }
02387 }
02388 foundvalue = qfalse;
02389 for (x = width-1; x >= 0; x--)
02390 {
02391 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02392 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02393 index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
02394 if (foundvalue)
02395 {
02396 if (filled[index >> 3] & (1 << (index & 7)))
02397 {
02398 ptr = lightFloats + k*3;
02399 color[0] = ptr[0];
02400 color[1] = ptr[1];
02401 color[2] = ptr[2];
02402 }
02403 else
02404 {
02405 ptr = lightFloats + k*3;
02406 ptr[0] = color[0];
02407 ptr[1] = color[1];
02408 ptr[2] = color[2];
02409 filled[index >> 3] |= 1 << (index & 7);
02410 }
02411 }
02412 else
02413 {
02414 if (filled[index >> 3] & (1 << (index & 7)))
02415 {
02416 ptr = lightFloats + k*3;
02417 color[0] = ptr[0];
02418 color[1] = ptr[1];
02419 color[2] = ptr[2];
02420 foundvalue = qtrue;
02421 }
02422 }
02423 }
02424 }
02425 for (x = 0; x < width; x++)
02426 {
02427 foundvalue = qfalse;
02428 for (y = 0; y < height; y++)
02429 {
02430 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02431 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02432 index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
02433 if (foundvalue)
02434 {
02435 if (filled[index >> 3] & (1 << (index & 7)))
02436 {
02437 ptr = lightFloats + k*3;
02438 color[0] = ptr[0];
02439 color[1] = ptr[1];
02440 color[2] = ptr[2];
02441 }
02442 else
02443 {
02444 ptr = lightFloats + k*3;
02445 ptr[0] = color[0];
02446 ptr[1] = color[1];
02447 ptr[2] = color[2];
02448 filled[index >> 3] |= 1 << (index & 7);
02449 }
02450 }
02451 else
02452 {
02453 if (filled[index >> 3] & (1 << (index & 7)))
02454 {
02455 ptr = lightFloats + k*3;
02456 color[0] = ptr[0];
02457 color[1] = ptr[1];
02458 color[2] = ptr[2];
02459 foundvalue = qtrue;
02460 }
02461 }
02462 }
02463 foundvalue = qfalse;
02464 for (y = height-1; y >= 0; y--)
02465 {
02466 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02467 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02468 index = (ds->lightmapY + y) * LIGHTMAP_WIDTH + ds->lightmapX + x;
02469 if (foundvalue)
02470 {
02471 if (filled[index >> 3] & (1 << (index & 7)))
02472 {
02473 ptr = lightFloats + k*3;
02474 color[0] = ptr[0];
02475 color[1] = ptr[1];
02476 color[2] = ptr[2];
02477 }
02478 else
02479 {
02480 ptr = lightFloats + k*3;
02481 ptr[0] = color[0];
02482 ptr[1] = color[1];
02483 ptr[2] = color[2];
02484 filled[index >> 3] |= 1 << (index & 7);
02485 }
02486 }
02487 else
02488 {
02489 if (filled[index >> 3] & (1 << (index & 7)))
02490 {
02491 ptr = lightFloats + k*3;
02492 color[0] = ptr[0];
02493 color[1] = ptr[1];
02494 color[2] = ptr[2];
02495 foundvalue = qtrue;
02496 }
02497 }
02498 }
02499 }
02500 if (ds->surfaceType == MST_PATCH)
02501 {
02502 x = ds->lightmapWidth-1;
02503 for (y = 0; y < ds->lightmapHeight; y++)
02504 {
02505 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02506 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02507 ptr = lightFloats + k*3;
02508 ptr[0] = (lightFloats + (k-1)*3)[0];
02509 ptr[1] = (lightFloats + (k-1)*3)[1];
02510 ptr[2] = (lightFloats + (k-1)*3)[2];
02511 }
02512 y = ds->lightmapHeight-1;
02513 for (x = 0; x < ds->lightmapWidth; x++)
02514 {
02515 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02516 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02517 ptr = lightFloats + k*3;
02518 ptr[0] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[0];
02519 ptr[1] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[1];
02520 ptr[2] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[2];
02521 }
02522 }
02523 /*
02524 //colored debug edges
02525 if (ds->surfaceType == MST_PATCH)
02526 {
02527 x = ds->lightmapWidth-1;
02528 for (y = 0; y < ds->lightmapHeight; y++)
02529 {
02530 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02531 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02532 ptr = lightFloats + k*3;
02533 ptr[0] = 255;
02534 ptr[1] = 0;
02535 ptr[2] = 0;
02536 }
02537 y = ds->lightmapHeight-1;
02538 for (x = 0; x < ds->lightmapWidth; x++)
02539 {
02540 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02541 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02542 ptr = lightFloats + k*3;
02543 ptr[0] = 0;
02544 ptr[1] = 255;
02545 ptr[2] = 0;
02546 }
02547 }
02548 //*/
02549 }
02550 //
02551 VS_SmoothenLightmapEdges();
02552 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 4267 of file soundv.c. References vsound_t. Referenced by VS_R_SubdivideAreaSpotLight(). 04268 {
04269 }
|
|
||||||||||||||||
|
Definition at line 4383 of file soundv.c. References vsound_s::atten_disttype, dleaf_t::cluster, lightvolume_s::cluster, CrossProduct(), plane_t::dist, dleafs, DotProduct, lightvolume_s::endplane, lightvolume_s::farplane, i, lightvolume_t, memset(), plane_t::normal, vsound_s::normal, lightvolume_s::numplanes, winding_t::numpoints, vsound_s::photons, lightvolume_s::planes, lightvolume_s::points, winding_t::points, sqrt(), lightvolume_s::surfaceNum, lightvolume_s::type, vec3_t, VectorCopy, VectorInverse(), VectorMA, VectorNormalize(), VectorSubtract, VS_R_CastLightAtSurface(), VS_R_FloodLight(), vsound_t, and w. Referenced by VS_R_SubdivideDirectedAreaLight(). 04384 {
04385 int i;
04386 float dist;
04387 lightvolume_t volume;
04388 vec3_t dir;
04389
04390 if (light->atten_disttype == LDAT_NOSCALE)
04391 {
04392 // light travels without decrease in intensity over distance
04393 dist = MAX_WORLD_COORD;
04394 }
04395 else
04396 {
04397 if ( light->atten_disttype == LDAT_LINEAR )
04398 dist = light->photons * lightLinearScale;
04399 else
04400 dist = sqrt(light->photons);
04401 }
04402
04403 memset(&volume, 0, sizeof(lightvolume_t));
04404 for (i = 0; i < w->numpoints; i++)
04405 {
04406 VectorMA(w->points[i], dist, light->normal, volume.points[i]);
04407 VectorSubtract(w->points[(i+1)%w->numpoints], w->points[i], dir);
04408 CrossProduct(light->normal, dir, volume.planes[i].normal);
04409 VectorNormalize(volume.planes[i].normal, volume.planes[i].normal);
04410 volume.planes[i].dist = DotProduct(volume.planes[i].normal, w->points[i]);
04411 }
04412 volume.numplanes = w->numpoints;
04413 VectorCopy(light->normal, volume.endplane.normal);
04414 VectorInverse(volume.endplane.normal);
04415 volume.endplane.dist = DotProduct(volume.endplane.normal, volume.points[0]);
04416 volume.farplane = volume.endplane;
04417 volume.surfaceNum = -1;
04418 volume.type = VOLUME_DIRECTED;
04419 volume.cluster = dleafs[leafnum].cluster;
04420 VS_R_FloodLight(light, &volume, volume.cluster, 0);
04421 if (volume.surfaceNum >= 0)
04422 {
04423 VS_R_CastLightAtSurface(light, &volume);
04424 }
04425 }
|
Here is the call graph for this function:

|
|
Definition at line 4481 of file soundv.c. References a, vsound_s::atten_disttype, lightvolume_s::cluster, dleaf_t::cluster, lightvolume_s::clusterTested, CrossProduct(), plane_t::dist, dleafs, DotProduct, lightvolume_s::endplane, fabs(), lightvolume_s::facetTested, lightvolume_s::farplane, i, vsound_s::insolid, j, k, LIGHT_POINTFAKESURFACE, LIGHT_POINTRADIAL, LIGHT_POINTSPOT, LIGHT_SURFACEDIRECTED, LIGHT_SURFACERADIAL, LIGHT_SURFACESPOT, lightvolume_t, memcpy(), memset(), n, vsound_s::normal, plane_t::normal, lightvolume_s::numplanes, vsound_s::origin, p, vsound_s::photons, lightvolume_s::planes, lightvolume_s::points, r, vsound_s::radiusByDist, RotatePointAroundVector(), sqrt(), lightvolume_s::surfaceNum, lightvolume_s::type, vsound_s::type, v, value, vec3_t, vecs, VectorAdd, VectorClear, VectorCopy, VectorInverse(), VectorMA, VectorScale, VS_LightLeafnum(), VS_PlaneFromPoints(), VS_R_CastLightAtSurface(), VS_R_FloodLight(), VS_R_SubdivideAreaSpotLight(), VS_R_SubdivideDirectedAreaLight(), VS_R_SubdivideRadialAreaLight(), vsound_t, and vsound_s::w. Referenced by VS_FloodLightThread(), and VS_SurfaceRadiosity(). 04482 {
04483 lightvolume_t volume;
04484 dleaf_t *leaf;
04485 int leafnum, i, j, k, dir[2][4] = {{1, 1, -1, -1}, {1, -1, -1, 1}};
04486 float a, step, dist, radius, windingdist;
04487 vec3_t vec, r, p, temp;
04488 winding_t winding;
04489
04490 switch(light->type)
04491 {
04492 case LIGHT_POINTRADIAL:
04493 {
04494 // source is a point
04495 // light radiates in all directions
04496 // creates sharp shadows
04497 //
04498 // create 6 volumes shining in the axis directions
04499 // what about: 4 tetrahedrons instead?
04500 //
04501 if ( light->atten_disttype == LDAT_LINEAR )
04502 dist = light->photons * lightLinearScale;
04503 else
04504 dist = sqrt(light->photons);
04505 //always put the winding at a large distance to avoid epsilon issues
04506 windingdist = MAX_WORLD_COORD;
04507 if (dist > windingdist)
04508 windingdist = dist;
04509 //
04510 leafnum = VS_LightLeafnum(light->origin);
04511 leaf = &dleafs[leafnum];
04512 if (leaf->cluster == -1)
04513 {
04514 light->insolid = qtrue;
04515 break;
04516 }
04517 // for each axis
04518 for (i = 0; i < 3; i++)
04519 {
04520 // for both directions on the axis
04521 for (j = -1; j <= 1; j += 2)
04522 {
04523 memset(&volume, 0, sizeof(lightvolume_t));
04524 volume.numplanes = 0;
04525 for (k = 0; k < 4; k ++)
04526 {
04527 volume.points[volume.numplanes][i] = light->origin[i] + j * windingdist;
04528 volume.points[volume.numplanes][(i+1)%3] = light->origin[(i+1)%3] + dir[0][k] * windingdist;
04529 volume.points[volume.numplanes][(i+2)%3] = light->origin[(i+2)%3] + dir[1][k] * windingdist;
04530 volume.numplanes++;
04531 }
04532 if (j >= 0)
04533 {
04534 VectorCopy(volume.points[0], temp);
04535 VectorCopy(volume.points[2], volume.points[0]);
04536 VectorCopy(temp, volume.points[2]);
04537 }
04538 for (k = 0; k < volume.numplanes; k++)
04539 {
04540 VS_PlaneFromPoints(&volume.planes[k], light->origin, volume.points[(k+1)%volume.numplanes], volume.points[k]);
04541 }
04542 VectorCopy(light->origin, temp);
04543 temp[i] += (float) j * dist;
04544 VectorClear(volume.endplane.normal);
04545 volume.endplane.normal[i] = -j;
04546 volume.endplane.dist = DotProduct(volume.endplane.normal, temp); //DotProduct(volume.endplane.normal, volume.points[0]);
04547 volume.farplane = volume.endplane;
04548 volume.cluster = leaf->cluster;
04549 volume.surfaceNum = -1;
04550 volume.type = VOLUME_NORMAL;
04551 //
04552 memset(volume.facetTested, 0, sizeof(volume.facetTested));
04553 memset(volume.clusterTested, 0, sizeof(volume.clusterTested));
04554 VS_R_FloodLight(light, &volume, leaf->cluster, 0);
04555 if (volume.surfaceNum >= 0)
04556 {
04557 VS_R_CastLightAtSurface(light, &volume);
04558 }
04559 }
04560 }
04561 break;
04562 }
04563 case LIGHT_POINTSPOT:
04564 {
04565 // source is a point
04566 // light is targetted
04567 // creates sharp shadows
04568 //
04569 // what about using brushes to shape spot lights? that'd be pretty cool
04570 //
04571 if ( light->atten_disttype == LDAT_LINEAR )
04572 dist = light->photons * lightLinearScale;
04573 else
04574 dist = sqrt(light->photons);
04575 dist *= 2;
04576 //
04577 windingdist = 4096;
04578 if (dist > windingdist)
04579 windingdist = dist;
04580 //take 8 times the cone radius because the spotlight also lights outside the cone
04581 radius = 8 * windingdist * light->radiusByDist;
04582 //
04583 memset(&volume, 0, sizeof(lightvolume_t));
04584 leafnum = VS_LightLeafnum(light->origin);
04585 leaf = &dleafs[leafnum];
04586 if (leaf->cluster == -1)
04587 {
04588 light->insolid = qtrue;
04589 break;
04590 }
04591 //
04592 VectorClear(vec);
04593 for (i = 0; i < 3; i++)
04594 {
04595 if (light->normal[i] > -0.9 && light->normal[i] < 0.9)
04596 {
04597 vec[i] = 1;
04598 break;
04599 }
04600 }
04601 CrossProduct(light->normal, vec, r);
04602 VectorScale(r, radius, p);
04603 volume.numplanes = 0;
04604 step = 45;
04605 for (a = step / 2; a < 360 + step / 2; a += step)
04606 {
04607 RotatePointAroundVector(volume.points[volume.numplanes], light->normal, p, a);
04608 VectorAdd(light->origin, volume.points[volume.numplanes], volume.points[volume.numplanes]);
04609 VectorMA(volume.points[volume.numplanes], windingdist, light->normal, volume.points[volume.numplanes]);
04610 volume.numplanes++;
04611 }
04612 for (i = 0; i < volume.numplanes; i++)
04613 {
04614 VS_PlaneFromPoints(&volume.planes[i], light->origin, volume.points[(i+1)%volume.numplanes], volume.points[i]);
04615 }
04616 VectorMA(light->origin, dist, light->normal, temp);
04617 VectorCopy(light->normal, volume.endplane.normal);
04618 VectorInverse(volume.endplane.normal);
04619 volume.endplane.dist = DotProduct(volume.endplane.normal, temp);//DotProduct(volume.endplane.normal, volume.points[0]);
04620 volume.farplane = volume.endplane;
04621 volume.cluster = leaf->cluster;
04622 volume.surfaceNum = -1;
04623 volume.type = VOLUME_NORMAL;
04624 //
04625 memset(volume.facetTested, 0, sizeof(volume.facetTested));
04626 memset(volume.clusterTested, 0, sizeof(volume.clusterTested));
04627 VS_R_FloodLight(light, &volume, leaf->cluster, 0);
04628 if (volume.surfaceNum >= 0)
04629 {
04630 VS_R_CastLightAtSurface(light, &volume);
04631 }
04632 break;
04633 }
04634 case LIGHT_POINTFAKESURFACE:
04635 {
04636 float value;
04637 int n, axis;
04638 vec3_t v, vecs[2];
04639
04640 if ( light->atten_disttype == LDAT_LINEAR )
04641 dist = light->photons * lightLinearScale;
04642 else
04643 dist = sqrt(light->photons);
04644 //always put the winding at a large distance to avoid epsilon issues
04645 windingdist = 4096;
04646 if (dist > windingdist)
04647 windingdist = dist;
04648 //
04649 VectorMA(light->origin, 0.1, light->normal, light->origin);
04650 //
04651 leafnum = VS_LightLeafnum(light->origin);
04652 leaf = &dleafs[leafnum];
04653 if (leaf->cluster == -1)
04654 {
04655 light->insolid = qtrue;
04656 break;
04657 }
04658 value = 0;
04659 for (i = 0; i < 3; i++)
04660 {
04661 if (fabs(light->normal[i]) > value)
04662 {
04663 value = fabs(light->normal[i]);
04664 axis = i;
04665 }
04666 }
04667 for (i = 0; i < 2; i++)
04668 {
04669 VectorClear(v);
04670 v[(axis + 1 + i) % 3] = 1;
04671 CrossProduct(light->normal, v, vecs[i]);
04672 }
04673 //cast 4 volumes at the front of the surface
04674 for (i = -1; i <= 1; i += 2)
04675 {
04676 for (j = -1; j <= 1; j += 2)
04677 {
04678 for (n = 0; n < 2; n++)
04679 {
04680 memset(&volume, 0, sizeof(lightvolume_t));
04681 volume.numplanes = 3;
04682 VectorMA(light->origin, i * windingdist, vecs[0], volume.points[(i == j) == n]);
04683 VectorMA(light->origin, j * windingdist, vecs[1], volume.points[(i != j) == n]);
04684 VectorMA(light->origin, windingdist, light->normal, volume.points[2]);
04685 for (k = 0; k < volume.numplanes; k++)
04686 {
04687 VS_PlaneFromPoints(&volume.planes[k], light->origin, volume.points[(k+1)%volume.numplanes], volume.points[k]);
04688 }
04689 VS_PlaneFromPoints(&volume.endplane, volume.points[0], volume.points[1], volume.points[2]);
04690 VectorMA(light->origin, dist, light->normal, temp);
04691 volume.endplane.dist = DotProduct(volume.endplane.normal, temp);
04692 if (DotProduct(light->origin, volume.endplane.normal) - volume.endplane.dist > 0)
04693 break;
04694 }
04695 volume.farplane = volume.endplane;
04696 volume.cluster = leaf->cluster;
04697 volume.surfaceNum = -1;
04698 volume.type = VOLUME_NORMAL;
04699 //
04700 memset(volume.facetTested, 0, sizeof(volume.facetTested));
04701 memset(volume.clusterTested, 0, sizeof(volume.clusterTested));
04702
04703 VS_R_FloodLight(light, &volume, leaf->cluster, 0);
04704 if (volume.surfaceNum >= 0)
04705 {
04706 VS_R_CastLightAtSurface(light, &volume);
04707 }
04708 }
04709 }
04710 break;
04711 }
04712 case LIGHT_SURFACEDIRECTED:
04713 {
04714 // source is an area defined by a winding
04715 // the light is unidirectional
04716 // creates sharp shadows
04717 // for instance sun light or laser light
04718 //
04719 memcpy(&winding, &light->w, sizeof(winding_t));
04720 VS_R_SubdivideDirectedAreaLight(light, 0, &winding);
04721 break;
04722 }
04723 case LIGHT_SURFACERADIAL:
04724 {
04725 // source is an area defined by a winding
04726 // the light radiates in all directions at the front of the winding plane
04727 //
04728 memcpy(&winding, &light->w, sizeof(winding_t));
04729 VS_R_SubdivideRadialAreaLight(light, 0, &winding);
04730 break;
04731 }
04732 case LIGHT_SURFACESPOT:
04733 {
04734 // source is an area defined by a winding
04735 // light is targetted but not unidirectional
04736 //
04737 memcpy(&winding, &light->w, sizeof(winding_t));
04738 VS_R_SubdivideAreaSpotLight(light, 0, &winding);
04739 break;
04740 }
04741 }
04742 }
|
Here is the call graph for this function:

|
|
Definition at line 4749 of file soundv.c. References VS_FloodLight(), and vsounds. Referenced by VS_LightWorld(). 04750 {
04751 VS_FloodLight(vsounds[num]);
04752 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 4325 of file soundv.c. References vsound_t. Referenced by VS_R_SubdivideRadialAreaLight(). 04326 {
04327 }
|
|
||||||||||||||||||||
|
Definition at line 1189 of file soundv.c. References a, b, CrossProduct(), plane_t::dist, DotProduct, plane_t::normal, vec3_t, VectorNormalize(), and VectorSubtract. Referenced by VS_GenerateFacetFor3Points(), and VS_GenerateFacetFor4Points(). 01189 {
01190 vec3_t d1;
01191
01192 // make a perpendicular vector to the edge and the surface
01193 VectorSubtract( a, b, d1 );
01194 CrossProduct( plane->normal, d1, boundary->normal );
01195 VectorNormalize( boundary->normal, boundary->normal );
01196 boundary->dist = DotProduct( a, boundary->normal );
01197 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 1204 of file soundv.c. References a, b, lFacet_s::boundaries, c, drawSurfaces, f, i, lFacet_t, drawVert_t::lightmap, lFacet_s::lightmapCoords, lFacet_s::num, numfacets, lFacet_s::numpoints, lFacet_s::plane, lFacet_s::points, qboolean, shaderInfo_t, surfaceOrigin, vec3_t, VectorAdd, VectorLength(), VectorSubtract, VS_GenerateBoundaryForPoints(), VS_LightmapMatrixFromPoints(), VS_PlaneFromPoints(), VS_TextureMatrixFromPoints(), and drawVert_t::xyz. Referenced by VS_FacetsForPatch(), and VS_FacetsForTriangleSurface(). 01204 {
01205 //
01206 vec3_t dir;
01207 int i;
01208
01209 // if we can't generate a valid plane for the points, ignore the facet
01210 if ( !VS_PlaneFromPoints( &f->plane, a->xyz, b->xyz, c->xyz ) ) {
01211 f->numpoints = 0;
01212 return qfalse;
01213 }
01214
01215 f->num = numfacets++;
01216
01217 VectorAdd( a->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[0] );
01218 VectorAdd( b->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[1] );
01219 VectorAdd( c->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[2] );
01220
01221 f->lightmapCoords[0][0] = a->lightmap[0];
01222 f->lightmapCoords[0][1] = a->lightmap[1];
01223 f->lightmapCoords[1][0] = b->lightmap[0];
01224 f->lightmapCoords[1][1] = b->lightmap[1];
01225 f->lightmapCoords[2][0] = c->lightmap[0];
01226 f->lightmapCoords[2][1] = c->lightmap[1];
01227
01228 VS_GenerateBoundaryForPoints( &f->boundaries[0], &f->plane, f->points[0], f->points[1] );
01229 VS_GenerateBoundaryForPoints( &f->boundaries[1], &f->plane, f->points[1], f->points[2] );
01230 VS_GenerateBoundaryForPoints( &f->boundaries[2], &f->plane, f->points[2], f->points[0] );
01231
01232 for (i = 0; i < 3; i++)
01233 {
01234 VectorSubtract(f->points[(i+1)%3], f->points[i], dir);
01235 if (VectorLength(dir) < 0.1)
01236 return qfalse;
01237 }
01238
01239 VS_TextureMatrixFromPoints( f, a, b, c );
01240 VS_LightmapMatrixFromPoints( dsurf, si, f, a, b, c );
01241
01242 f->numpoints = 3;
01243
01244 return qtrue;
01245 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||
|
Definition at line 1255 of file soundv.c. References a, b, lFacet_s::boundaries, c, d, plane_t::dist, DotProduct, drawSurfaces, f, fabs(), i, lFacet_t, drawVert_t::lightmap, lFacet_s::lightmapCoords, plane_t::normal, lFacet_s::num, numfacets, lFacet_s::numpoints, lFacet_s::plane, Plane_Equal(), lFacet_s::points, qboolean, qfalse, shaderInfo_t, surfaceOrigin, vec3_t, VectorAdd, VectorLength(), VectorSubtract, VS_GenerateBoundaryForPoints(), VS_LightmapMatrixFromPoints(), VS_PlaneFromPoints(), VS_TextureMatrixFromPoints(), and drawVert_t::xyz. Referenced by VS_FacetsForPatch(), and VS_FacetsForTriangleSurface(). 01255 {
01256 float dist;
01257 vec3_t dir;
01258 int i;
01259 plane_t plane;
01260
01261 // if we can't generate a valid plane for the points, ignore the facet
01262 if ( !VS_PlaneFromPoints( &f->plane, a->xyz, b->xyz, c->xyz ) ) {
01263 f->numpoints = 0;
01264 return qfalse;
01265 }
01266
01267 // if the fourth point is also on the plane, we can make a quad facet
01268 dist = DotProduct( d->xyz, f->plane.normal ) - f->plane.dist;
01269 if ( fabs( dist ) > PLANAR_EPSILON ) {
01270 f->numpoints = 0;
01271 return qfalse;
01272 }
01273
01274 VectorAdd( a->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[0] );
01275 VectorAdd( b->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[1] );
01276 VectorAdd( c->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[2] );
01277 VectorAdd( d->xyz, surfaceOrigin[dsurf - drawSurfaces], f->points[3] );
01278
01279 for (i = 1; i < 4; i++)
01280 {
01281 if ( !VS_PlaneFromPoints( &plane, f->points[i], f->points[(i+1) % 4], f->points[(i+2) % 4]) ) {
01282 f->numpoints = 0;
01283 return qfalse;
01284 }
01285
01286 if (!Plane_Equal(&f->plane, &plane, qfalse)) {
01287 f->numpoints = 0;
01288 return qfalse;
01289 }
01290 }
01291
01292 f->lightmapCoords[0][0] = a->lightmap[0];
01293 f->lightmapCoords[0][1] = a->lightmap[1];
01294 f->lightmapCoords[1][0] = b->lightmap[0];
01295 f->lightmapCoords[1][1] = b->lightmap[1];
01296 f->lightmapCoords[2][0] = c->lightmap[0];
01297 f->lightmapCoords[2][1] = c->lightmap[1];
01298 f->lightmapCoords[3][0] = d->lightmap[0];
01299 f->lightmapCoords[3][1] = d->lightmap[1];
01300
01301 VS_GenerateBoundaryForPoints( &f->boundaries[0], &f->plane, f->points[0], f->points[1] );
01302 VS_GenerateBoundaryForPoints( &f->boundaries[1], &f->plane, f->points[1], f->points[2] );
01303 VS_GenerateBoundaryForPoints( &f->boundaries[2], &f->plane, f->points[2], f->points[3] );
01304 VS_GenerateBoundaryForPoints( &f->boundaries[3], &f->plane, f->points[3], f->points[0] );
01305
01306 for (i = 0; i < 4; i++)
01307 {
01308 VectorSubtract(f->points[(i+1)%4], f->points[i], dir);
01309 if (VectorLength(dir) < 0.1)
01310 return qfalse;
01311 }
01312
01313 VS_TextureMatrixFromPoints( f, a, b, c );
01314 VS_LightmapMatrixFromPoints( dsurf, si, f, a, b, c );
01315
01316 f->num = numfacets++;
01317 f->numpoints = 4;
01318
01319 return qtrue;
01320 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 2952 of file soundv.c. References b, byte, d, plane_t::dist, DotProduct, lsurfaceTest_s::facets, floor(), shaderInfo_s::height, i, j, lFacet_t, lightvolume_t, lsurfaceTest, lsurfaceTest_t, plane_t::normal, shaderInfo_s::pixels, lFacet_s::plane, point, s, lsurfaceTest_s::shader, shaderInfo_s::surfaceFlags, t, test(), lFacet_s::textureMatrix, v, vec3_t, VectorClear, VectorCopy, VectorMA, VectorSet, vsound_t, shaderInfo_s::width, x, and y. Referenced by VS_LightSurfaceWithVolume(). 02953 {
02954 lFacet_t *facet;
02955 lsurfaceTest_t *test;
02956 float d, d1, d2, frac, s, t, ns;
02957 int i, j, is, it, b;
02958 int x, y, u, v, numsamples, radius, color[4], largest;
02959 byte *image;
02960 vec3_t point, origin, total;
02961
02962 VectorSet(filter, 1, 1, 1);
02963
02964 if (noalphashading)
02965 return;
02966
02967 if (volume->numtransFacets <= 0)
02968 return;
02969
02970 if (light->type == LIGHT_SURFACEDIRECTED)
02971 {
02972 // project the light map pixel origin onto the area light source plane
02973 d = DotProduct(lmp, light->normal) - DotProduct(light->normal, light->w.points[0]);
02974 VectorMA(lmp, -d, light->normal, origin);
02975 }
02976 else
02977 {
02978 VectorCopy(light->origin, origin);
02979 }
02980 for (i = 0; i < volume->numtransFacets; i++)
02981 {
02982 test = lsurfaceTest[ volume->transSurfaces[i] ];
02983 facet = &test->facets[ volume->transFacets[i] ];
02984 // if this surface does not cast an alpha shadow
02985 if ( !(test->shader->surfaceFlags & SURF_ALPHASHADOW) )
02986 continue;
02987 // if there are no texture pixel available
02988 if ( !test->shader->pixels ) {
02989 continue;
02990 }
02991 //
02992 d1 = DotProduct( origin, facet->plane.normal) - facet->plane.dist;
02993 d2 = DotProduct( lmp, facet->plane.normal ) - facet->plane.dist;
02994 // this should never happen because the light volume went through the facet
02995 if ( ( d1 < 0 ) == ( d2 < 0 ) ) {
02996 continue;
02997 }
02998 // calculate the crossing point
02999 frac = d1 / ( d1 - d2 );
03000
03001 for ( j = 0 ; j < 3 ; j++ ) {
03002 point[j] = origin[j] + frac * ( lmp[j] - origin[j] );
03003 }
03004
03005 s = DotProduct( point, facet->textureMatrix[0] ) + facet->textureMatrix[0][3];
03006 t = DotProduct( point, facet->textureMatrix[1] ) + facet->textureMatrix[1][3];
03007 if (s < 0)
03008 s = 0;
03009 if (t < 0)
03010 t = 0;
03011
03012 s = s - floor( s );
03013 t = t - floor( t );
03014
03015 is = s * test->shader->width;
03016 it = t * test->shader->height;
03017
03018 //if old style alpha shading
03019 if (nocolorshading) {
03020 image = test->shader->pixels + 4 * ( it * test->shader->width + is );
03021
03022 // alpha filter
03023 b = image[3];
03024
03025 // alpha test makes this a binary option
03026 b = b < 128 ? 0 : 255;
03027
03028 filter[0] = filter[0] * (255-b) / 255;
03029 filter[1] = filter[1] * (255-b) / 255;
03030 filter[2] = filter[2] * (255-b) / 255;
03031 }
03032 else {
03033 VectorClear(total);
03034 numsamples = 0;
03035 radius = 2;
03036 for ( u = -radius; u <= radius; u++ )
03037 {
03038 x = is + u;
03039 if ( x < 0 || x >= test->shader->width)
03040 continue;
03041 for ( v = -radius; v <= radius; v++ )
03042 {
03043 y = it + v;
03044 if ( y < 0 || y >= test->shader->height)
03045 continue;
03046
03047 image = test->shader->pixels + 4 * ( y * test->shader->width + x );
03048 color[0] = image[0];
03049 color[1] = image[1];
03050 color[2] = image[2];
03051 largest = 0;
03052 for (j = 0; j < 3; j++)
03053 if (image[j] > largest)
03054 largest = image[j];
03055 if (largest <= 0 || image[3] == 0) {
03056 color[0] = 255;
03057 color[1] = 255;
03058 color[2] = 255;
03059 largest = 255;
03060 }
03061 total[0] += ((float) color[0]/largest) * (255-image[3]) / 255.0;
03062 total[1] += ((float) color[1]/largest) * (255-image[3]) / 255.0;
03063 total[2] += ((float) color[2]/largest) * (255-image[3]) / 255.0;
03064 numsamples++;
03065 }
03066 }
03067 ns = numsamples;
03068 //
03069 filter[0] *= total[0] / ns;
03070 filter[1] *= total[1] / ns;
03071 filter[2] *= total[2] / ns;
03072 }
03073 }
03074 }
|
Here is the call graph for this function:

|
|
Definition at line 1492 of file soundv.c. References _printf(), AddPointToBounds(), lsurfaceTest_s::always_tracelight, lsurfaceTest_s::always_vsound, ClearBounds(), shaderInfo_s::contents, drawSurfaces, dshaders, entitySurface, Error(), shaderInfo_s::forceTraceLight, shaderInfo_s::forceVLight, i, j, k, lFacet_t, dsurface_t::lightmapNum, lsurfaceTest, lsurfaceTest_t, malloc(), MAX_FACETS, memset(), lFacet_s::mins, MST_TRIANGLE_SOUP, lsurfaceTest_s::mutex, MutexAlloc(), numfacets, dsurface_t::numIndexes, lFacet_s::numpoints, lsurfaceTest_s::numvolumes, dsurface_t::patchWidth, lFacet_s::points, shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, shaderInfo_s::surfaceFlags, dsurface_t::surfaceType, test(), VS_FacetsForPatch(), VS_FacetsForTriangleSurface(), VS_LinkSurfaces(), and VS_SphereFromBounds(). Referenced by VSoundMain(). 01492 {
01493
01494 int i, j, k;
01495 dsurface_t *dsurf;
01496 lsurfaceTest_t *test;
01497 shaderInfo_t *si;
01498 lFacet_t *facet;
01499
01500 for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
01501 // don't light the entity surfaces with vsound
01502 if ( entitySurface[i] )
01503 continue;
01504 //
01505 dsurf = &drawSurfaces[ i ];
01506 if ( !dsurf->numIndexes && !dsurf->patchWidth ) {
01507 continue;
01508 }
01509
01510 si = ShaderInfoForShader( dshaders[ dsurf->shaderNum].shader );
01511 // if the surface is translucent and does not cast an alpha shadow
01512 if ( (si->contents & CONTENTS_TRANSLUCENT) && !(si->surfaceFlags & SURF_ALPHASHADOW) ) {
01513 // if the surface has no lightmap
01514 if ( dsurf->lightmapNum < 0 )
01515 continue;
01516 }
01517
01518 test = malloc( sizeof( *test ) );
01519 memset(test, 0, sizeof( *test ));
01520 test->mutex = MutexAlloc();
01521 test->numvolumes = 0;
01522 if (si->forceTraceLight)
01523 test->always_tracelight = qtrue;
01524 else if (si->forceVLight)
01525 test->always_vsound = qtrue;
01526 lsurfaceTest[i] = test;
01527
01528 if ( dsurf->surfaceType == MST_TRIANGLE_SOUP || dsurf->surfaceType == MST_PLANAR ) {
01529 VS_FacetsForTriangleSurface( dsurf, si, test );
01530 } else if ( dsurf->surfaceType == MST_PATCH ) {
01531 VS_FacetsForPatch( dsurf, i, si, test );
01532 }
01533 if (numfacets >= MAX_FACETS)
01534 Error("numfacets >= MAX_FACETS (%d)", MAX_FACETS);
01535
01536 ClearBounds( test->mins, test->maxs );
01537 for (j = 0; j < test->numFacets; j++)
01538 {
01539 facet = &test->facets[j];
01540 for ( k = 0 ; k < facet->numpoints; k++) {
01541 AddPointToBounds( facet->points[k], test->mins, test->maxs );
01542 }
01543 }
01544 VS_SphereFromBounds( test->mins, test->maxs, test->origin, &test->radius );
01545 }
01546 _printf("%6d facets\n", numfacets);
01547 _printf("linking surfaces...\n");
01548 VS_LinkSurfaces();
01549 }
|
Here is the call graph for this function:

|
|
Definition at line 2739 of file soundv.c. References point, and VS_PointInLeafnum(). Referenced by VS_FloodLight(), and VS_TestLightLeafs(). 02740 {
02741 /*
02742 int leafnum;
02743 dleaf_t *leaf;
02744 float x, y, z;
02745 vec3_t test;
02746
02747 leafnum = VS_PointInLeafnum(point);
02748 leaf = &dleafs[leafnum];
02749 if (leaf->cluster != -1)
02750 return leafnum;
02751 for (z = 1; z >= -1; z -= 1)
02752 {
02753 for (x = 1; x >= -1; x -= 1)
02754 {
02755 for (y = 1; y >= -1; y -= 1)
02756 {
02757 VectorCopy(point, test);
02758 test[0] += x;
02759 test[1] += y;
02760 test[2] += z;
02761 leafnum = VS_PointInLeafnum(test);
02762 leaf = &dleafs[leafnum];
02763 if (leaf->cluster != -1)
02764 {
02765 VectorCopy(test, point);
02766 return leafnum;
02767 }
02768 }
02769 }
02770 }
02771 return leafnum;
02772 */
02773 return VS_PointInLeafnum(point);
02774 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 900 of file soundv.c. References _printf(), a, AddPointToBounds(), b, c, ceil(), cl, ClearBounds(), DotProduct, drawSurfaces, drawVerts, f, fabs(), dsurface_t::firstVert, floor(), h(), i, j, lFacet_t, drawVert_t::lightmap, LIGHTMAP_SIZE, lFacet_s::lightmapMatrix, dsurface_t::lightmapNum, shaderInfo_s::lightmapSampleSize, dsurface_t::lightmapVecs, dsurface_t::lightmapX, dsurface_t::lightmapY, m, lFacet_s::mins, dsurface_t::numVerts, s, shaderInfo_t, surfaceOrigin, dsurface_t::surfaceType, t, vec3_t, VectorAdd, VectorClear, VectorScale, VectorSubtract, w, and drawVert_t::xyz. Referenced by VS_GenerateFacetFor3Points(), and VS_GenerateFacetFor4Points(). 00900 {
00901 int i, j;
00902 float t;
00903 float m[3][4], al, bl, cl;
00904 float s;
00905 int h, w, ssize;
00906 vec3_t mins, maxs, delta, size, planeNormal;
00907 drawVert_t *verts;
00908 static int message;
00909
00910 // vertex-lit triangle model
00911 if ( dsurf->surfaceType == MST_TRIANGLE_SOUP ) {
00912 return;
00913 }
00914
00915 if ( dsurf->lightmapNum < 0 ) {
00916 return; // doesn't need lighting
00917 }
00918
00919 VectorClear(f->mins);
00920 if (dsurf->surfaceType != MST_PATCH)
00921 {
00922 ssize = samplesize;
00923 if (si->lightmapSampleSize)
00924 ssize = si->lightmapSampleSize;
00925 ClearBounds( mins, maxs );
00926 verts = &drawVerts[dsurf->firstVert];
00927 for ( i = 0 ; i < dsurf->numVerts ; i++ ) {
00928 AddPointToBounds( verts[i].xyz, mins, maxs );
00929 }
00930 // round to the lightmap resolution
00931 for ( i = 0 ; i < 3 ; i++ ) {
00932 mins[i] = ssize * floor( mins[i] / ssize );
00933 maxs[i] = ssize * ceil( maxs[i] / ssize );
00934 f->mins[i] = mins[i];
00935 size[i] = (maxs[i] - mins[i]) / ssize + 1;
00936 }
00937 // the two largest axis will be the lightmap size
00938 VectorClear(f->lightmapMatrix[0]);
00939 f->lightmapMatrix[0][3] = 0;
00940 VectorClear(f->lightmapMatrix[1]);
00941 f->lightmapMatrix[1][3] = 0;
00942
00943 planeNormal[0] = fabs( dsurf->lightmapVecs[2][0] );
00944 planeNormal[1] = fabs( dsurf->lightmapVecs[2][1] );
00945 planeNormal[2] = fabs( dsurf->lightmapVecs[2][2] );
00946
00947 if ( planeNormal[0] >= planeNormal[1] && planeNormal[0] >= planeNormal[2] ) {
00948 w = size[1];
00949 h = size[2];
00950 f->lightmapMatrix[0][1] = 1.0 / ssize;
00951 f->lightmapMatrix[1][2] = 1.0 / ssize;
00952 } else if ( planeNormal[1] >= planeNormal[0] && planeNormal[1] >= planeNormal[2] ) {
00953 w = size[0];
00954 h = size[2];
00955 f->lightmapMatrix[0][0] = 1.0 / ssize;
00956 f->lightmapMatrix[1][2] = 1.0 / ssize;
00957 } else {
00958 w = size[0];
00959 h = size[1];
00960 f->lightmapMatrix[0][0] = 1.0 / ssize;
00961 f->lightmapMatrix[1][1] = 1.0 / ssize;
00962 }
00963 if ( w > LIGHTMAP_WIDTH ) {
00964 VectorScale ( f->lightmapMatrix[0], (float)LIGHTMAP_SIZE/w, f->lightmapMatrix[0] );
00965 }
00966
00967 if ( h > LIGHTMAP_HEIGHT ) {
00968 VectorScale ( f->lightmapMatrix[1], (float)LIGHTMAP_SIZE/h, f->lightmapMatrix[1] );
00969 }
00970 VectorSubtract(a->xyz, f->mins, delta);
00971 s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
00972 if ( fabs(s - a->lightmap[0]) > 0.01 ) {
00973 _printf( "Bad lightmapMatrix" );
00974 }
00975 t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
00976 if ( fabs(t - a->lightmap[1]) > 0.01 ) {
00977 _printf( "Bad lightmapMatrix" );
00978 }
00979 VectorSubtract(b->xyz, f->mins, delta);
00980 s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
00981 if ( fabs(s - b->lightmap[0]) > 0.01 ) {
00982 _printf( "Bad lightmapMatrix" );
00983 }
00984 t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
00985 if ( fabs(t - b->lightmap[1]) > 0.01 ) {
00986 _printf( "Bad lightmapMatrix" );
00987 }
00988 VectorSubtract(c->xyz, f->mins, delta);
00989 s = (DotProduct( delta, f->lightmapMatrix[0] ) + dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
00990 if ( fabs(s - c->lightmap[0]) > 0.01 ) {
00991 _printf( "Bad lightmapMatrix" );
00992 }
00993 t = (DotProduct( delta, f->lightmapMatrix[1] ) + dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
00994 if ( fabs(t - c->lightmap[1]) > 0.01 ) {
00995 _printf( "Bad lightmapMatrix" );
00996 }
00997 VectorAdd(f->mins, surfaceOrigin[dsurf - drawSurfaces], f->mins);
00998 return;
00999 }
01000 // This is an incredibly stupid way of solving a three variable equation
01001 for ( i = 0 ; i < 2 ; i++ ) {
01002
01003 if (i)
01004 al = a->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
01005 else
01006 al = a->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
01007
01008 m[0][0] = a->xyz[0] - f->mins[0];
01009 m[0][1] = a->xyz[1] - f->mins[1];
01010 m[0][2] = a->xyz[2] - f->mins[2];
01011 m[0][3] = al;
01012
01013 if (i)
01014 bl = b->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
01015 else
01016 bl = b->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
01017
01018 m[1][0] = b->xyz[0] - f->mins[0];
01019 m[1][1] = b->xyz[1] - f->mins[1];
01020 m[1][2] = b->xyz[2] - f->mins[2];
01021 m[1][3] = bl;
01022
01023 if (i)
01024 cl = c->lightmap[i] - ((float) dsurf->lightmapY + 0.5) / LIGHTMAP_SIZE;
01025 else
01026 cl = c->lightmap[i] - ((float) dsurf->lightmapX + 0.5) / LIGHTMAP_SIZE;
01027
01028 m[2][0] = c->xyz[0] - f->mins[0];
01029 m[2][1] = c->xyz[1] - f->mins[1];
01030 m[2][2] = c->xyz[2] - f->mins[2];
01031 m[2][3] = cl;
01032
01033 if ( fabs(m[1][0]) > fabs(m[0][0]) && fabs(m[1][0]) >= fabs(m[2][0]) ) {
01034 for ( j = 0 ; j < 4 ; j ++ ) {
01035 t = m[0][j];
01036 m[0][j] = m[1][j];
01037 m[1][j] = t;
01038 }
01039 } else if ( fabs(m[2][0]) > fabs(m[0][0]) && fabs(m[2][0]) >= fabs(m[1][0]) ) {
01040 for ( j = 0 ; j < 4 ; j ++ ) {
01041 t = m[0][j];
01042 m[0][j] = m[2][j];
01043 m[2][j] = t;
01044 }
01045 }
01046
01047 if (m[0][0])
01048 {
01049 s = 1.0 / m[0][0];
01050 m[0][0] *= s;
01051 m[0][1] *= s;
01052 m[0][2] *= s;
01053 m[0][3] *= s;
01054
01055 s = m[1][0];
01056 m[1][0] -= m[0][0] * s;
01057 m[1][1] -= m[0][1] * s;
01058 m[1][2] -= m[0][2] * s;
01059 m[1][3] -= m[0][3] * s;
01060
01061 s = m[2][0];
01062 m[2][0] -= m[0][0] * s;
01063 m[2][1] -= m[0][1] * s;
01064 m[2][2] -= m[0][2] * s;
01065 m[2][3] -= m[0][3] * s;
01066 }
01067
01068 if ( fabs(m[2][1]) > fabs(m[1][1]) ) {
01069 for ( j = 0 ; j < 4 ; j ++ ) {
01070 t = m[1][j];
01071 m[1][j] = m[2][j];
01072 m[2][j] = t;
01073 }
01074 }
01075
01076 if (m[1][1])
01077 {
01078 s = 1.0 / m[1][1];
01079 m[1][0] *= s;
01080 m[1][1] *= s;
01081 m[1][2] *= s;
01082 m[1][3] *= s;
01083
01084 s = m[2][1];
01085 m[2][0] -= m[1][0] * s;
01086 m[2][1] -= m[1][1] * s;
01087 m[2][2] -= m[1][2] * s;
01088 m[2][3] -= m[1][3] * s;
01089 }
01090
01091 if (m[2][2])
01092 {
01093 s = 1.0 / m[2][2];
01094 m[2][0] *= s;
01095 m[2][1] *= s;
01096 m[2][2] *= s;
01097 m[2][3] *= s;
01098 }
01099
01100 f->lightmapMatrix[i][2] = m[2][3];
01101 f->lightmapMatrix[i][1] = m[1][3] - f->lightmapMatrix[i][2] * m[1][2];
01102 f->lightmapMatrix[i][0] = m[0][3] - f->lightmapMatrix[i][2] * m[0][2] - f->lightmapMatrix[i][1] * m[0][1];
01103
01104 f->lightmapMatrix[i][3] = 0;
01105
01106 VectorSubtract(a->xyz, f->mins, delta);
01107 s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - al );
01108 if ( s > 0.01 ) {
01109 if (!message)
01110 _printf( "Bad lightmapMatrix\n" );
01111 message = qtrue;
01112 }
01113 VectorSubtract(b->xyz, f->mins, delta);
01114 s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - bl );
01115 if ( s > 0.01 ) {
01116 if (!message)
01117 _printf( "Bad lightmapMatrix\n" );
01118 message = qtrue;
01119 }
01120 VectorSubtract(c->xyz, f->mins, delta);
01121 s = fabs( DotProduct( delta, f->lightmapMatrix[i] ) - cl );
01122 if ( s > 0.01 ) {
01123 if (!message)
01124 _printf( "Bad lightmapMatrix\n" );
01125 message = qtrue;
01126 }
01127 VectorAdd(f->mins, surfaceOrigin[dsurf - drawSurfaces], f->mins);
01128 }
01129 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 3081 of file soundv.c. References _printf(), add, lsurfaceTest_s::always_tracelight, lsurfaceTest_s::always_vsound, vsound_s::atten_anglescale, vsound_s::atten_angletype, vsound_s::atten_distscale, vsound_s::atten_disttype, byte, vsound_s::color, d, defaulttracelight, lsurfaceTest_s::detailMesh, DotProduct, drawSurfaces, fabs(), lsurfaceTest_s::facets, floor(), mesh_t::height, lFacet_s::height, i, k, lFacet_t, lightFloats, lightLinearScale, LIGHTMAP_HEIGHT, LIGHTMAP_PIXELSHIFT, LIGHTMAP_SIZE, LIGHTMAP_WIDTH, lFacet_s::lightmapMatrix, dsurface_t::lightmapNum, dsurface_t::lightmapOrigin, lightmappixelarea, dsurface_t::lightmapVecs, dsurface_t::lightmapX, dsurface_t::lightmapY, lightvolume_t, lsurfaceTest, lsurfaceTest_t, MAX_POINTS_ON_WINDING, memcpy(), memset(), lFacet_s::mins, lsurfaceTest_s::mutex, MutexLock(), MutexUnlock(), n, vsound_s::normal, plane_t::normal, lightvolume_s::numplanes, winding_t::numpoints, lFacet_s::numpoints, lsurfaceTest_s::numvolumes, vsound_s::origin, vsound_s::photons, lFacet_s::plane, lightvolume_s::planes, lFacet_s::points, winding_t::points, PointToPolygonFormFactor(), vsound_s::radiusByDist, s, SIDE_BACK, dsurface_t::surfaceType, t, test(), vsound_s::twosided, vsound_s::type, vec3_t, VectorCopy, VectorLength(), VectorMA, VectorNormalize(), VectorSubtract, mesh_t::verts, VS_ChopWinding(), VS_GetFilter(), vsound_t, vsound_s::w, w, mesh_t::width, lFacet_s::width, WindingArea(), x, lFacet_s::x, y, and lFacet_s::y. Referenced by VS_R_CastLightAtSurface(). 03082 {
03083 int i;
03084 dsurface_t *ds;
03085 lFacet_t *facet;
03086 lsurfaceTest_t *test;
03087 winding_t w;
03088 vec3_t base, dir, delta, normal, filter, origin;
03089 int min_x[LIGHTMAP_SIZE+2], max_x[LIGHTMAP_SIZE+2];
03090 int min_y, max_y, k, x, y, n;
03091 float *color, distscale;
03092 float d, add, angle, dist, area, insidearea, coords[MAX_POINTS_ON_WINDING+1][2];
03093 mesh_t *mesh;
03094 byte polygonedges[(LIGHTMAP_SIZE+1) * (LIGHTMAP_SIZE+1) / 8];
03095
03096
03097 ds = &drawSurfaces[surfaceNum];
03098
03099 // vertex-lit triangle model
03100 if ( ds->surfaceType == MST_TRIANGLE_SOUP ) {
03101 return;
03102 }
03103
03104 if ( ds->lightmapNum < 0 ) {
03105 return; // doesn't need lighting
03106 }
03107
03108 test = lsurfaceTest[ surfaceNum ];
03109 facet = &test->facets[ facetNum ];
03110
03111 if (defaulttracelight && !test->always_vsound)
03112 return;
03113 if (test->always_tracelight)
03114 return;
03115
03116 memcpy(w.points, facet->points, sizeof(vec3_t) * facet->numpoints);
03117 w.numpoints = facet->numpoints;
03118
03119 for (i = 0; i < volume->numplanes; i++)
03120 {
03121 //if totally on the back
03122 if (VS_ChopWinding(&w, &volume->planes[i], 0.01) == SIDE_BACK)
03123 return;
03124 }
03125
03126 // only one thread at a time may write to the lightmap of this surface
03127 MutexLock(test->mutex);
03128
03129 test->numvolumes++;
03130
03131 if (ds->surfaceType == MST_PATCH)
03132 {
03133 // FIXME: reduce size and don't mark all as edge
03134 min_y = ds->lightmapY + facet->y;
03135 max_y = ds->lightmapY + facet->y + facet->height - 1;
03136 for (y = min_y; y <= max_y; y++)
03137 {
03138 min_x[y] = ds->lightmapX + facet->x;
03139 max_x[y] = ds->lightmapX + facet->x + facet->width - 1;
03140 for (x = min_x[y]; x <= max_x[y]; x++)
03141 {
03142 n = y * LIGHTMAP_SIZE + x;
03143 polygonedges[n >> 3] |= 1 << (n & 7);
03144 }
03145 }
03146 }
03147 else
03148 {
03149 for (i = 0; i < w.numpoints; i++)
03150 {
03151 float s, t;
03152
03153 if (i >= MAX_POINTS_ON_WINDING)
03154 _printf("coords overflow\n");
03155 if (ds->surfaceType != MST_PATCH)
03156 {
03157 VectorSubtract(w.points[i], facet->mins, delta);
03158 s = DotProduct( delta, facet->lightmapMatrix[0] ) + ds->lightmapX + 0.5;
03159 t = DotProduct( delta, facet->lightmapMatrix[1] ) + ds->lightmapY + 0.5;
03160 if (s >= LIGHTMAP_SIZE)
03161 s = LIGHTMAP_SIZE - 0.5;
03162 if (s < 0)
03163 s = 0;
03164 if (t >= LIGHTMAP_SIZE)
03165 t = LIGHTMAP_SIZE - 0.5;
03166 if (t < 0)
03167 t = 0;
03168 coords[i][0] = s;
03169 coords[i][1] = t;
03170 }
03171 else
03172 {
03173 s = DotProduct( w.points[i], facet->lightmapMatrix[0] ) + facet->lightmapMatrix[0][3];
03174 t = DotProduct( w.points[i], facet->lightmapMatrix[1] ) + facet->lightmapMatrix[1][3];
03175
03176 s = s - floor( s );
03177 t = t - floor( t );
03178
03179 coords[i][0] = ds->lightmapX + s * LIGHTMAP_SIZE;// + 0.5;
03180 coords[i][1] = ds->lightmapY + t * LIGHTMAP_SIZE;// + 0.5;
03181
03182 if (coords[i][0] >= LIGHTMAP_SIZE)
03183 coords[i][0] -= LIGHTMAP_SIZE;
03184 if (coords[i][1] >= LIGHTMAP_SIZE)
03185 coords[i][1] -= LIGHTMAP_SIZE;
03186 if (coords[i][0] < ds->lightmapX)
03187 coords[i][0] = ds->lightmapX;
03188 if (coords[i][1] < ds->lightmapY)
03189 coords[i][1] = ds->lightmapY;
03190 }
03191 x = coords[i][0];
03192 y = coords[i][1];
03193 if (x < ds->lightmapX || x >= LIGHTMAP_SIZE)
03194 _printf("VS_LightSurfaceWithVolume: x outside lightmap\n");
03195 if (y < ds->lightmapY || y >= LIGHTMAP_SIZE)
03196 _printf("VS_LightSurfaceWithVolume: y outside lightmap\n");
03197 }
03198 coords[i][0] = coords[0][0];
03199 coords[i][1] = coords[0][1];
03200
03201 //
03202 min_y = LIGHTMAP_SIZE;
03203 max_y = 0;
03204 for (i = 0; i < LIGHTMAP_SIZE; i++)
03205 {
03206 min_x[i] = LIGHTMAP_SIZE;
03207 max_x[i] = 0;
03208 }
03209 memset(polygonedges, 0, sizeof(polygonedges));
03210 // scan convert the polygon onto the lightmap
03211 // for each edge it marks *every* lightmap pixel the edge goes through
03212 // so no brasenham and no scan conversion used for texture mapping but
03213 // more something like ray casting
03214 // this is necesary because we need all lightmap pixels totally or partly
03215 // inside the light volume. these lightmap pixels are only lit for the part
03216 // that they are inside the light volume.
03217 for (i = 0; i < w.numpoints; i++)
03218 {
03219 float xf, yf, dx, dy, xstep, ystep, xfrac, yfrac;
03220 int xinc, yinc;
03221
03222 xf = coords[i][0];
03223 yf = coords[i][1];
03224 dx = coords[i+1][0] - xf;
03225 dy = coords[i+1][1] - yf;
03226 //
03227 x = (int) xf;
03228 y = (int) yf;
03229 //
03230 if (y < min_y)
03231 min_y = y;
03232 if (y > max_y)
03233 max_y = y;
03234 //
03235 if (fabs(dx) > fabs(dy))
03236 {
03237 if (dx > 0)
03238 {
03239 // y fraction at integer x below fractional x
03240 yfrac = yf + (floor(xf) - xf) * dy / dx;
03241 xinc = 1;
03242 }
03243 else if (dx < 0)
03244 {
03245 // y fraction at integer x above fractional x
03246 yfrac = yf + (floor(xf) + 1 - xf) * dy / dx;
03247 xinc = -1;
03248 }
03249 else
03250 {
03251 yfrac = yf;
03252 xinc = 0;
03253 }
03254 // step in y direction per 1 unit in x direction
03255 if (dx)
03256 ystep = dy / fabs(dx);
03257 else
03258 ystep = 0;
03259 while(1)
03260 {
03261 if (x < ds->lightmapX || x >= LIGHTMAP_SIZE)
03262 _printf("VS_LightSurfaceWithVolume: x outside lightmap\n");
03263 if (y < ds->lightmapY || y >= LIGHTMAP_SIZE)
03264 _printf("VS_LightSurfaceWithVolume: y outside lightmap\n");
03265 //
03266 n = y * LIGHTMAP_SIZE + x;
03267 polygonedges[n >> 3] |= 1 << (n & 7);
03268 if (x < min_x[y])
03269 min_x[y] = x;
03270 if (x > max_x[y])
03271 max_x[y] = x;
03272 if (x == (int) coords[i+1][0])
03273 break;
03274 yfrac += ystep;
03275 if (dy > 0)
03276 {
03277 if (yfrac > (float) y + 1)
03278 {
03279 y += 1;
03280 //
03281 n = y * LIGHTMAP_SIZE + x;
03282 polygonedges[n >> 3] |= 1 << (n & 7);
03283 if (x < min_x[y])
03284 min_x[y] = x;
03285 if (x > max_x[y])
03286 max_x[y] = x;
03287 }
03288 }
03289 else
03290 {
03291 if (yfrac < (float) y)
03292 {
03293 y -= 1;
03294 //
03295 n = y * LIGHTMAP_SIZE + x;
03296 polygonedges[n >> 3] |= 1 << (n & 7);
03297 if (x < min_x[y])
03298 min_x[y] = x;
03299 if (x > max_x[y])
03300 max_x[y] = x;
03301 }
03302 }
03303 x += xinc;
03304 }
03305 }
03306 else
03307 {
03308 if (dy > 0)
03309 {
03310 //x fraction at integer y below fractional y
03311 xfrac = xf + (floor(yf) - yf) * dx / dy;
03312 yinc = 1;
03313 }
03314 else if (dy < 0)
03315 {
03316 //x fraction at integer y above fractional y
03317 xfrac = xf + (floor(yf) + 1 - yf) * dx / dy;
03318 yinc = -1;
03319 }
03320 else
03321 {
03322 xfrac = xf;
03323 yinc = 0;
03324 }
03325 // step in x direction per 1 unit in y direction
03326 if (dy)
03327 xstep = dx / fabs(dy);
03328 else
03329 xstep = 0;
03330 while(1)
03331 {
03332 if (x < ds->lightmapX || x >= LIGHTMAP_SIZE)
03333 _printf("VS_LightSurfaceWithVolume: x outside lightmap\n");
03334 if (y < ds->lightmapY || y >= LIGHTMAP_SIZE)
03335 _printf("VS_LightSurfaceWithVolume: y outside lightmap\n");
03336 //
03337 n = y * LIGHTMAP_SIZE + x;
03338 polygonedges[n >> 3] |= 1 << (n & 7);
03339 if (x < min_x[y])
03340 min_x[y] = x;
03341 if (x > max_x[y])
03342 max_x[y] = x;
03343 if (y == (int) coords[i+1][1])
03344 break;
03345 xfrac += xstep;
03346 if (dx > 0)
03347 {
03348 if (xfrac > (float) x + 1)
03349 {
03350 x += 1;
03351 //
03352 n = y * LIGHTMAP_SIZE + x;
03353 polygonedges[n >> 3] |= 1 << (n & 7);
03354 if (x < min_x[y])
03355 min_x[y] = x;
03356 if (x > max_x[y])
03357 max_x[y] = x;
03358 }
03359 }
03360 else
03361 {
03362 if (xfrac < (float) x)
03363 {
03364 x -= 1;
03365 //
03366 n = y * LIGHTMAP_SIZE + x;
03367 polygonedges[n >> 3] |= 1 << (n & 7);
03368 if (x < min_x[y])
03369 min_x[y] = x;
03370 if (x > max_x[y])
03371 max_x[y] = x;
03372 }
03373 }
03374 y += yinc;
03375 }
03376 }
03377 }
03378 }
03379 // map light onto the lightmap
03380 for (y = min_y; y <= max_y; y++)
03381 {
03382 for (x = min_x[y]; x <= max_x[y]; x++)
03383 {
03384 if (ds->surfaceType == MST_PATCH)
03385 {
03386 mesh = test->detailMesh;
03387 VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, base);
03388 VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x-ds->lightmapX].normal, normal);
03389 //VectorCopy(facet->plane.normal, normal);
03390 }
03391 else
03392 {
03393 VectorMA(ds->lightmapOrigin, (float) x - ds->lightmapX, ds->lightmapVecs[0], base);
03394 VectorMA(base, (float) y - ds->lightmapY, ds->lightmapVecs[1], base);
03395 VectorCopy(facet->plane.normal, normal);
03396 }
03397 if (light->type == LIGHT_POINTSPOT)
03398 {
03399 float distByNormal;
03400 vec3_t pointAtDist;
03401 float radiusAtDist;
03402 float sampleRadius;
03403 vec3_t distToSample;
03404 float coneScale;
03405
03406 VectorSubtract( light->origin, base, dir );
03407
03408 distByNormal = -DotProduct( dir, light->normal );
03409 if ( distByNormal < 0 ) {
03410 continue;
03411 }
03412 VectorMA( light->origin, distByNormal, light->normal, pointAtDist );
03413 radiusAtDist = light->radiusByDist * distByNormal;
03414
03415 VectorSubtract( base, pointAtDist, distToSample );
03416 sampleRadius = VectorLength( distToSample );
03417
03418 if ( sampleRadius >= radiusAtDist ) {
03419 continue; // outside the cone
03420 }
03421 if ( sampleRadius <= radiusAtDist - 32 ) {
03422 coneScale = 1.0; // fully inside
03423 } else {
03424 coneScale = ( radiusAtDist - sampleRadius ) / 32.0;
03425 }
03426
03427 dist = VectorNormalize( dir, dir );
03428 // clamp the distance to prevent super hot spots
03429 if ( dist < 16 ) {
03430 dist = 16;
03431 }
03432 angle = DotProduct( normal, dir );
03433 if (angle > 1)
03434 angle = 1;
03435 if (angle > 0) {
03436 if ( light->atten_angletype == LAAT_QUADRATIC ) {
03437 angle = 1 - angle;
03438 angle *= angle;
03439 angle = 1 - angle;
03440 }
03441 else if ( light->atten_angletype == LAAT_DOUBLEQUADRATIC ) {
03442 angle = 1 - angle;
03443 angle *= angle * angle;
03444 angle = 1 - angle;
03445 }
03446 }
03447 if (light->atten_anglescale > 0) {
03448 angle /= light->atten_anglescale;
03449 if (angle > 1)
03450 angle = 1;
03451 }
03452 if (light->atten_distscale > 0) {
03453 distscale = light->atten_distscale;
03454 }
03455 else {
03456 distscale = 1;
03457 }
03458 //
03459 if ( light->atten_disttype == LDAT_NOSCALE ) {
03460 add = angle * coneScale;
03461 }
03462 else if ( light->atten_disttype == LDAT_LINEAR ) {
03463 add = angle * light->photons * lightLinearScale * coneScale - dist * distscale;
03464 if ( add < 0 ) {
03465 add = 0;
03466 }
03467 }
03468 else {
03469 add = light->photons / ( dist * dist * distscale) * angle * coneScale;
03470 }
03471 if (add <= 1.0)
03472 continue;
03473 }
03474 else if (light->type == LIGHT_POINTFAKESURFACE)
03475 {
03476 // calculate the contribution
03477 add = PointToPolygonFormFactor( base, normal, &light->w );
03478 if ( add <= 0 ) {
03479 if ( light->twosided ) {
03480 add = -add;
03481 } else {
03482 continue;
03483 }
03484 }
03485 }
03486 else if (light->type == LIGHT_SURFACEDIRECTED)
03487 {
03488 //VectorCopy(light->normal, dir);
03489 //VectorInverse(dir);
03490 // project the light map pixel origin onto the area light source plane
03491 d = DotProduct(base, light->normal) - DotProduct(light->normal, light->w.points[0]);
03492 VectorMA(base, -d, light->normal, origin);
03493 VectorSubtract(origin, base, dir);
03494 dist = VectorNormalize(dir, dir);
03495 if ( dist < 16 ) {
03496 dist = 16;
03497 }
03498 //
03499 angle = DotProduct( normal, dir );
03500 if (angle > 1)
03501 angle = 1;
03502 if (angle > 0) {
03503 if ( light->atten_angletype == LAAT_QUADRATIC ) {
03504 angle = 1 - angle;
03505 angle *= angle;
03506 angle = 1 - angle;
03507 }
03508 else if ( light->atten_angletype == LAAT_DOUBLEQUADRATIC ) {
03509 angle = 1 - angle;
03510 angle *= angle * angle;
03511 angle = 1 - angle;
03512 }
03513 }
03514 if (light->atten_anglescale > 0) {
03515 angle /= light->atten_anglescale;
03516 if (angle > 1)
03517 angle = 1;
03518 }
03519 if (light->atten_distscale > 0) {
03520 distscale = light->atten_distscale;
03521 }
03522 else {
03523 distscale = 1;
03524 }
03525 if ( light->atten_disttype == LDAT_NOSCALE ) {
03526 add = angle;
03527 }
03528 else if ( light->atten_disttype == LDAT_LINEAR ) {
03529 add = angle * light->photons * lightLinearScale - dist * distscale;
03530 if ( add < 0 ) {
03531 add = 0;
03532 }
03533 } else { //default quadratic
03534 add = light->photons / ( dist * dist * distscale) * angle;
03535 }
03536 if (add <= 0)
03537 continue;
03538 }
03539 else //normal radial point light
03540 {
03541 VectorSubtract(light->origin, base, dir);
03542 dist = VectorNormalize(dir, dir);
03543 if ( dist < 16 ) {
03544 dist = 16;
03545 }
03546 angle = DotProduct( normal, dir );
03547 if (angle > 1)
03548 angle = 1;
03549 if (angle > 0) {
03550 if ( light->atten_angletype == LAAT_QUADRATIC ) {
03551 angle = 1 - angle;
03552 angle *= angle;
03553 angle = 1 - angle;
03554 }
03555 else if ( light->atten_angletype == LAAT_DOUBLEQUADRATIC ) {
03556 angle = 1 - angle;
03557 angle *= angle * angle;
03558 angle = 1 - angle;
03559 }
03560 }
03561 if (light->atten_anglescale > 0) {
03562 angle /= light->atten_anglescale;
03563 if (angle > 1)
03564 angle = 1;
03565 }
03566 if (light->atten_distscale > 0) {
03567 distscale = light->atten_distscale;
03568 }
03569 else {
03570 distscale = 1;
03571 }
03572 if ( light->atten_disttype == LDAT_NOSCALE ) {
03573 add = angle;
03574 }
03575 else if ( light->atten_disttype == LDAT_LINEAR ) {
03576 add = angle * light->photons * lightLinearScale - dist * distscale;
03577 if ( add < 0 ) {
03578 add = 0;
03579 }
03580 } else {
03581 add = light->photons / ( dist * dist * distscale) * angle;
03582 }
03583 if (add <= 1.0)
03584 continue;
03585 }
03586 //
03587 k = (ds->lightmapNum * LIGHTMAP_HEIGHT + y) * LIGHTMAP_WIDTH + x;
03588 //if on one of the edges
03589 n = y * LIGHTMAP_SIZE + x;
03590 if ((polygonedges[n >> 3] & (1 << (n & 7)) ))
03591 {
03592 // multiply 'add' by the relative area being lit of the total visible lightmap pixel area
03593 //
03594 // first create a winding for the lightmap pixel
03595 if (ds->surfaceType == MST_PATCH)
03596 {
03597 mesh = test->detailMesh;
03598 if (y-ds->lightmapY >= mesh->height-1)
03599 _printf("y outside mesh\n");
03600 if (x-ds->lightmapX >= mesh->width-1)
03601 _printf("x outside mesh\n");
03602 VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, w.points[0]);
03603 VectorCopy( mesh->verts[(y+1-ds->lightmapY)*mesh->width+x-ds->lightmapX].xyz, w.points[1]);
03604 VectorCopy( mesh->verts[(y+1-ds->lightmapY)*mesh->width+x+1-ds->lightmapX].xyz, w.points[2]);
03605 VectorCopy( mesh->verts[(y-ds->lightmapY)*mesh->width+x+1-ds->lightmapX].xyz, w.points[3]);
03606 w.numpoints = 4;
03607 }
03608 else
03609 {
03610 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[0]);
03611 VectorMA(w.points[0], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[0]);
03612 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT - ds->lightmapX, ds->lightmapVecs[0], w.points[1]);
03613 VectorMA(w.points[1], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[1]);
03614 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[2]);
03615 VectorMA(w.points[2], (float) y - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapY, ds->lightmapVecs[1], w.points[2]);
03616 VectorMA(ds->lightmapOrigin, (float) x - LIGHTMAP_PIXELSHIFT + 1 - ds->lightmapX, ds->lightmapVecs[0], w.points[3]);
03617 VectorMA(w.points[3], (float) y - LIGHTMAP_PIXELSHIFT - ds->lightmapY, ds->lightmapVecs[1], w.points[3]);
03618 w.numpoints = 4;
03619 }
03620 //
03621 // take the visible area of the lightmap pixel into account
03622 //
03623 //area = WindingArea(&w);
03624 area = lightmappixelarea[k];
03625 if (area <= 0)
03626 continue;
03627 // chop the lightmap pixel winding with the light volume
03628 for (i = 0; i < volume->numplanes; i++)
03629 {
03630 //if totally on the back
03631 if (VS_ChopWinding(&w, &volume->planes[i], 0) == SIDE_BACK)
03632 break;
03633 }
03634 // if the lightmap pixel is partly inside the light volume
03635 if (i >= volume->numplanes)
03636 {
03637 insidearea = WindingArea(&w);
03638 if (insidearea <= 0)
03639 i = 0;
03640 add = add * insidearea / area;
03641 }
03642 else
03643 {
03644 //DebugNet_DrawWinding(&w, 2);
03645 continue; // this shouldn't happen
03646 }
03647 }
03648 // get the light filter from all the translucent surfaces the light volume went through
03649 VS_GetFilter(light, volume, base, filter);
03650 //
03651 color = &lightFloats[k*3];
03652 color[0] += add * light->color[0] * filter[0];
03653 color[1] += add * light->color[1] * filter[1];
03654 color[2] += add * light->color[2] * filter[2];
03655 }
03656 }
03657
03658 MutexUnlock(test->mutex);
03659 }
|
Here is the call graph for this function:

|
|
Definition at line 4936 of file soundv.c. References _printf(), entities, f, FloatForKey(), GetVectorForKey(), i, vsound_s::insolid, lightAmbientColor, lsurfaceTest, lsurfaceTest_s::numvolumes, numvsounds, qtrue, radiosity_scale, RunThreadsOnIndividual(), VectorScale, VS_DoForcedTraceLightSurfaces(), VS_FloodLightThread(), VS_Radiosity(), VS_StoreLightmap(), and vsounds. Referenced by VSoundMain(). 04937 {
04938 int i, numcastedvolumes, numvsoundsinsolid;
04939 float f;
04940
04941 // find the optional world ambient
04942 GetVectorForKey( &entities[0], "_color", lightAmbientColor );
04943 f = FloatForKey( &entities[0], "ambient" );
04944 VectorScale( lightAmbientColor, f, lightAmbientColor );
04945 /*
04946 _printf("\r%6d lights out of %d", 0, numvsounds);
04947 for (i = 0; i < numvsounds; i++)
04948 {
04949 _printf("\r%6d", i);
04950 VS_FloodLight(vsounds[i]);
04951 }
04952 _printf("\r%6d lights out of %d\n", i, numvsounds);
04953 */
04954 _printf("%7i lights\n", numvsounds);
04955 RunThreadsOnIndividual( numvsounds, qtrue, VS_FloodLightThread );
04956
04957 numcastedvolumes = 0;
04958 for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
04959 if (lsurfaceTest[i])
04960 numcastedvolumes += lsurfaceTest[i]->numvolumes;
04961 }
04962 _printf("%7i light volumes casted\n", numcastedvolumes);
04963 numvsoundsinsolid = 0;
04964 for (i = 0; i < numvsounds; i++)
04965 {
04966 if (vsounds[i]->insolid)
04967 numvsoundsinsolid++;
04968 }
04969 _printf("%7i lights in solid\n", numvsoundsinsolid);
04970 //
04971 radiosity_scale = 1;
04972 for (i = 0; i < radiosity; i++) {
04973 VS_Radiosity();
04974 radiosity_scale <<= 1;
04975 }
04976 //
04977 VS_StoreLightmap();
04978 // redo surfaces with the old light algorithm when needed
04979 VS_DoForcedTraceLightSurfaces();
04980 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 679 of file soundv.c. References clustersurfaces, Error(), lleaf_s::firstSurface, i, leafs, lleaf_t, numclustersurfaces, and lleaf_s::numSurfaces. Referenced by VS_R_LinkSurface(). 00680 {
00681 lleaf_t *leaf;
00682 int i;
00683
00684 leaf = &leafs[cluster];
00685
00686 for (i = 0; i < leaf->numSurfaces; i++)
00687 {
00688 if (clustersurfaces[leaf->firstSurface + i] == surfaceNum)
00689 return;
00690 }
00691 for (i = numclustersurfaces; i > leaf->firstSurface + leaf->numSurfaces; i--)
00692 clustersurfaces[i] = clustersurfaces[i-1];
00693 for (i = 0; i < portalclusters; i++)
00694 {
00695 if (i == cluster)
00696 continue;
00697 if (leafs[i].firstSurface >= leaf->firstSurface + leaf->numSurfaces)
00698 leafs[i].firstSurface++;
00699 }
00700 clustersurfaces[leaf->firstSurface + leaf->numSurfaces] = surfaceNum;
00701 leaf->numSurfaces++;
00702 numclustersurfaces++;
00703 if (numclustersurfaces >= MAX_MAP_LEAFFACES)
00704 Error("MAX_MAP_LEAFFACES");
00705 }
|
Here is the call graph for this function:

|
|
Definition at line 764 of file soundv.c. References lsurfaceTest_s::facets, i, j, lFacet_t, lsurfaceTest, lsurfaceTest_t, memcpy(), lsurfaceTest_s::numFacets, winding_t::numpoints, lFacet_s::numpoints, lFacet_s::points, winding_t::points, test(), vec3_t, and VS_R_LinkSurface(). Referenced by VS_InitSurfacesForTesting(). 00765 {
00766 int i, j;
00767 lsurfaceTest_t *test;
00768 lFacet_t *facet;
00769 winding_t winding;
00770
00771 for ( i = 0 ; i < numDrawSurfaces ; i++ )
00772 {
00773 test = lsurfaceTest[ i ];
00774 if (!test)
00775 continue;
00776 for (j = 0; j < test->numFacets; j++)
00777 {
00778 facet = &test->facets[j];
00779 memcpy(winding.points, facet->points, facet->numpoints * sizeof(vec3_t));
00780 winding.numpoints = facet->numpoints;
00781 VS_R_LinkSurface(0, i, &winding);
00782 }
00783 }
00784 }
|
Here is the call graph for this function:

|
|
Definition at line 5477 of file soundv.c. References _printf(), plane_t::dist, Error(), f, fclose(), fopen(), fscanf(), i, j, k, l, lportal_t::leaf, leafs, lleaf_t, malloc(), MAX_CLUSTERS, memset(), name, plane_t::normal, numfaces, winding_t::numpoints, lleaf_s::numportals, numportals, p, lportal_t::plane, winding_t::points, portalclusters, PORTALFILE, lleaf_s::portals, portals, strcmp(), v, vec3_origin, VectorCopy, VectorSubtract, VS_AllocWinding(), VS_PlaneFromWinding(), VS_SetPortalSphere(), w, and lportal_t::winding. Referenced by VSoundMain(). 05478 {
05479 int i, j, hint;
05480 lportal_t *p;
05481 lleaf_t *l;
05482 char magic[80];
05483 FILE *f;
05484 int numpoints;
05485 winding_t *w;
05486 int leafnums[2];
05487 plane_t plane;
05488 //
05489
05490 if (!strcmp(name,"-"))
05491 f = stdin;
05492 else
05493 {
05494 f = fopen(name, "r");
05495 if (!f)
05496 Error ("LoadPortals: couldn't read %s\n",name);
05497 }
05498
05499 if (fscanf (f,"%79s\n%i\n%i\n%i\n",magic, &portalclusters, &numportals, &numfaces) != 4)
05500 Error ("LoadPortals: failed to read header");
05501 if (strcmp(magic, PORTALFILE))
05502 Error ("LoadPortals: not a portal file");
05503
05504 _printf ("%6i portalclusters\n", portalclusters);
05505 _printf ("%6i numportals\n", numportals);
05506 _printf ("%6i numfaces\n", numfaces);
05507
05508 if (portalclusters >= MAX_CLUSTERS)
05509 Error ("more than %d clusters in portal file\n", MAX_CLUSTERS);
05510
05511 // each file portal is split into two memory portals
05512 portals = malloc(2*numportals*sizeof(lportal_t));
05513 memset (portals, 0, 2*numportals*sizeof(lportal_t));
05514
05515 leafs = malloc(portalclusters*sizeof(lleaf_t));
05516 memset (leafs, 0, portalclusters*sizeof(lleaf_t));
05517
05518 for (i=0, p=portals ; i<numportals ; i++)
05519 {
05520 if (fscanf (f, "%i %i %i ", &numpoints, &leafnums[0], &leafnums[1]) != 3)
05521 Error ("LoadPortals: reading portal %i", i);
05522 if (numpoints > MAX_POINTS_ON_WINDING)
05523 Error ("LoadPortals: portal %i has too many points", i);
05524 if ( (unsigned)leafnums[0] > portalclusters
05525 || (unsigned)leafnums[1] > portalclusters)
05526 Error ("LoadPortals: reading portal %i", i);
05527 if (fscanf (f, "%i ", &hint) != 1)
05528 Error ("LoadPortals: reading hint state");
05529
05530 w = p->winding = VS_AllocWinding (numpoints);
05531 w->numpoints = numpoints;
05532
05533 for (j=0 ; j<numpoints ; j++)
05534 {
05535 double v[3];
05536 int k;
05537
05538 // scanf into double, then assign to vec_t
05539 // so we don't care what size vec_t is
05540 if (fscanf (f, "(%lf %lf %lf ) "
05541 , &v[0], &v[1], &v[2]) != 3)
05542 Error ("LoadPortals: reading portal %i", i);
05543 for (k=0 ; k<3 ; k++)
05544 w->points[j][k] = v[k];
05545 }
05546 fscanf (f, "\n");
05547
05548 // calc plane
05549 VS_PlaneFromWinding (w, &plane);
05550
05551 // create forward portal
05552 l = &leafs[leafnums[0]];
05553 if (l->numportals == MAX_PORTALS_ON_LEAF)
05554 Error ("Leaf with too many portals");
05555 l->portals[l->numportals] = p;
05556 l->numportals++;
05557
05558 p->winding = w;
05559 VectorSubtract (vec3_origin, plane.normal, p->plane.normal);
05560 p->plane.dist = -plane.dist;
05561 p->leaf = leafnums[1];
05562 VS_SetPortalSphere (p);
05563 p++;
05564
05565 // create backwards portal
05566 l = &leafs[leafnums[1]];
05567 if (l->numportals == MAX_PORTALS_ON_LEAF)
05568 Error ("Leaf with too many portals");
05569 l->portals[l->numportals] = p;
05570 l->numportals++;
05571
05572 p->winding = VS_AllocWinding(w->numpoints);
05573 p->winding->numpoints = w->numpoints;
05574 for (j=0 ; j<w->numpoints ; j++)
05575 {
05576 VectorCopy (w->points[w->numpoints-1-j], p->winding->points[j]);
05577 }
05578
05579 p->plane = plane;
05580 p->leaf = leafnums[0];
05581 VS_SetPortalSphere (p);
05582 p++;
05583
05584 }
05585
05586 fclose (f);
05587 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 3826 of file soundv.c. References d, plane_t::dist, DotProduct, i, j, length(), plane_t::normal, winding_t::numpoints, p2, winding_t::points, sqrt(), v1, v2, vec3_t, VectorSubtract, and w. 03827 {
03828 int i, j;
03829 float length, d;
03830 vec3_t v1, v2;
03831
03832 VectorSubtract(p2, p1, v1);
03833 for (i = 0; i < w->numpoints; i++)
03834 {
03835 VectorSubtract (w->points[i], p1, v2);
03836
03837 plane->normal[0] = v1[1]*v2[2] - v1[2]*v2[1];
03838 plane->normal[1] = v1[2]*v2[0] - v1[0]*v2[2];
03839 plane->normal[2] = v1[0]*v2[1] - v1[1]*v2[0];
03840
03841 // if points don't make a valid plane, skip it
03842 length = plane->normal[0] * plane->normal[0]
03843 + plane->normal[1] * plane->normal[1]
03844 + plane->normal[2] * plane->normal[2];
03845
03846 if (length < ON_EPSILON)
03847 continue;
03848
03849 length = 1/sqrt(length);
03850
03851 plane->normal[0] *= length;
03852 plane->normal[1] *= length;
03853 plane->normal[2] *= length;
03854
03855 plane->dist = DotProduct (w->points[i], plane->normal);
03856 //
03857 for (j = 0; j < w->numpoints; j++)
03858 {
03859 if (j == i)
03860 continue;
03861 d = DotProduct(w->points[j], plane->normal) - plane->dist;
03862 if (windingonfront)
03863 {
03864 if (d < -ON_EPSILON)
03865 break;
03866 }
03867 else
03868 {
03869 if (d > ON_EPSILON)
03870 break;
03871 }
03872 }
03873 if (j >= w->numpoints)
03874 return;
03875 }
03876 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1170 of file soundv.c. References a, b, c, CrossProduct(), plane_t::dist, DotProduct, plane_t::normal, qboolean, vec3_t, VectorNormalize(), and VectorSubtract. Referenced by VS_FloodLight(), VS_GenerateFacetFor3Points(), and VS_GenerateFacetFor4Points(). 01170 {
01171 vec3_t d1, d2;
01172
01173 VectorSubtract( b, a, d1 );
01174 VectorSubtract( c, a, d2 );
01175 CrossProduct( d2, d1, plane->normal );
01176 if ( VectorNormalize( plane->normal, plane->normal ) == 0 ) {
01177 return qfalse;
01178 }
01179
01180 plane->dist = DotProduct( a, plane->normal );
01181 return qtrue;
01182 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 5440 of file soundv.c. References CrossProduct(), plane_t::dist, DotProduct, plane_t::normal, winding_t::points, v1, v2, vec3_t, VectorNormalize(), VectorSubtract, and w. Referenced by VS_LoadPortals(). 05441 {
05442 vec3_t v1, v2;
05443
05444 //calc plane
05445 VectorSubtract (w->points[2], w->points[1], v1);
05446 VectorSubtract (w->points[0], w->points[1], v2);
05447 CrossProduct (v2, v1, plane->normal);
05448 VectorNormalize (plane->normal, plane->normal);
05449 plane->dist = DotProduct (w->points[0], plane->normal);
05450 }
|
Here is the call graph for this function:

|
|
Definition at line 2729 of file soundv.c. References point, and VS_PointInLeafnum_r(). Referenced by VS_LightLeafnum(). 02730 {
02731 return VS_PointInLeafnum_r(point, 0);
02732 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 2691 of file soundv.c. References dnode_t::children, dleaf_t::cluster, dplane_t::dist, dleafs, dnodes, DotProduct, dplanes, dplane_t::normal, dnode_t::planeNum, point, and vec_t. Referenced by VS_PointInLeafnum(). 02692 {
02693 int leafnum;
02694 vec_t dist;
02695 dnode_t *node;
02696 dplane_t *plane;
02697
02698 while (nodenum >= 0)
02699 {
02700 node = &dnodes[nodenum];
02701 plane = &dplanes[node->planeNum];
02702 dist = DotProduct (point, plane->normal) - plane->dist;
02703 if (dist > 0.1)
02704 {
02705 nodenum = node->children[0];
02706 }
02707 else if (dist < -0.1)
02708 {
02709 nodenum = node->children[1];
02710 }
02711 else
02712 {
02713 leafnum = VS_PointInLeafnum_r(point, node->children[0]);
02714 if (dleafs[leafnum].cluster != -1)
02715 return leafnum;
02716 nodenum = node->children[1];
02717 }
02718 }
02719
02720 leafnum = -nodenum - 1;
02721 return leafnum;
02722 }
|
|
||||||||||||
|
Definition at line 3885 of file soundv.c. References lightvolume_s::cluster, lightvolume_s::clusterTested, shaderInfo_s::contents, lightvolume_s::endplane, Error(), lightvolume_s::facetNum, lsurfaceTest_s::facets, lightvolume_s::facetTested, lightvolume_s::farplane, i, lightvolume_t, lsurfaceTest, lsurfaceTest_t, MAX_TRANSLUCENTFACETS, memset(), n, lFacet_s::num, lightvolume_s::numtransFacets, lsurfaceTest_s::shader, shaderInfo_s::surfaceFlags, lightvolume_s::surfaceNum, test(), lightvolume_s::transFacets, lightvolume_s::transSurfaces, VS_LightSurfaceWithVolume(), VS_R_FloodLight(), and vsound_t. Referenced by VS_FloodDirectedLight(), VS_FloodLight(), and VS_R_SplitLightVolume(). 03886 {
03887 lsurfaceTest_t *test;
03888 int i, n;
03889
03890 // light the surface with this volume
03891 VS_LightSurfaceWithVolume(volume->surfaceNum, volume->facetNum, light, volume);
03892 //
03893 test = lsurfaceTest[ volume->surfaceNum ];
03894 // if this is not a translucent surface
03895 if ( !(test->shader->surfaceFlags & SURF_ALPHASHADOW) && !(test->shader->contents & CONTENTS_TRANSLUCENT))
03896 return;
03897 //
03898 if (volume->numtransFacets >= MAX_TRANSLUCENTFACETS)
03899 Error("a light valume went through more than %d translucent facets", MAX_TRANSLUCENTFACETS);
03900 //add this translucent surface to the list
03901 volume->transSurfaces[volume->numtransFacets] = volume->surfaceNum;
03902 volume->transFacets[volume->numtransFacets] = volume->facetNum;
03903 volume->numtransFacets++;
03904 //clear the tested facets except the translucent ones
03905 memset(volume->facetTested, 0, sizeof(volume->facetTested));
03906 for (i = 0; i < volume->numtransFacets; i++)
03907 {
03908 test = lsurfaceTest[ volume->transSurfaces[i] ];
03909 n = test->facets[volume->transFacets[i]].num;
03910 volume->facetTested[n >> 3] |= 1 << (n & 7);
03911 }
03912 memset(volume->clusterTested, 0, sizeof(volume->clusterTested));
03913 volume->endplane = volume->farplane;
03914 volume->surfaceNum = -1;
03915 volume->facetNum = 0;
03916 VS_R_FloodLight(light, volume, volume->cluster, 0);
03917 if (volume->surfaceNum >= 0)
03918 {
03919 VS_R_CastLightAtSurface(light, volume);
03920 }
03921 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 3972 of file soundv.c. References clustersurfaces, CrossProduct(), d, plane_t::dist, DotProduct, lightvolume_s::endplane, lightvolume_s::facetNum, lsurfaceTest_s::facets, lightvolume_s::facetTested, lleaf_s::firstSurface, i, j, k, leafs, lFacet_t, lightvolume_t, lleaf_t, lsurfaceTest, lsurfaceTest_t, memcpy(), nobackfaceculling, vsound_s::normal, plane_t::normal, lFacet_s::num, lsurfaceTest_s::numFacets, numplanes, lightvolume_s::numplanes, winding_t::numpoints, lFacet_s::numpoints, lleaf_s::numSurfaces, lsurfaceTest_s::origin, vsound_s::origin, lsurfaceTest_s::patch, lFacet_s::plane, lightvolume_s::planes, winding_t::points, lFacet_s::points, lsurfaceTest_s::radius, lsurfaceTest_s::shader, SIDE_BACK, SIDE_ON, lightvolume_s::surfaceNum, test(), lsurfaceTest_s::trisoup, shaderInfo_s::twoSided, lightvolume_s::type, vec3_t, VectorCopy, VectorInverse(), VectorNormalize(), VectorSubtract, VOLUME_DIRECTED, VS_ChopWinding(), VS_R_SplitLightVolume(), and vsound_t. Referenced by VS_FloodDirectedLight(), VS_FloodLight(), VS_R_CastLightAtSurface(), and VS_R_SplitLightVolume(). 03973 {
03974 int i, j, k, res, surfaceNum, backfaceculled, testculled;
03975 float d;
03976 winding_t winding, tmpwinding;
03977 lleaf_t *leaf;
03978 lportal_t *p;
03979 lsurfaceTest_t *test;
03980 lFacet_t *facet;
03981 vec3_t dir1, dir2;
03982 plane_t plane;
03983
03984 // DebugNet_RemoveAllPolys();
03985 // VS_DrawLightVolume(light, volume);
03986
03987 // if the first portal is not zero then we've checked all occluders in this leaf already
03988 if (firstportal == 0)
03989 {
03990 // check all potential occluders in this leaf
03991 for (i = 0; i < leafs[cluster].numSurfaces; i++)
03992 {
03993 surfaceNum = clustersurfaces[leafs[cluster].firstSurface + i];
03994 //
03995 test = lsurfaceTest[ surfaceNum ];
03996 if ( !test )
03997 continue;
03998 //
03999 testculled = qfalse;
04000 // use surface as an occluder
04001 for (j = 0; j < test->numFacets; j++)
04002 {
04003 // use each facet as an occluder
04004 facet = &test->facets[j];
04005 //
04006 // memcpy(winding.points, facet->points, sizeof(vec3_t) * facet->numpoints);
04007 // winding.numpoints = facet->numpoints;
04008 // DebugNet_DrawWinding(&winding, 5);
04009 //
04010 // if the facet was tested already
04011 if ( volume->facetTested[facet->num >> 3] & (1 << (facet->num & 7)) )
04012 continue;
04013 volume->facetTested[facet->num >> 3] |= 1 << (facet->num & 7);
04014 // backface culling for planar surfaces
04015 backfaceculled = qfalse;
04016 if (!test->patch && !test->trisoup)
04017 {
04018 if (volume->type == VOLUME_NORMAL)
04019 {
04020 // facet backface culling
04021 d = DotProduct(light->origin, facet->plane.normal) - facet->plane.dist;
04022 if (d < 0)
04023 {
04024 // NOTE: this doesn't work too great because of sometimes very bad tesselation
04025 // of surfaces that are supposed to be flat
04026 // FIXME: to work around this problem we should make sure that all facets
04027 // created from planar surfaces use the lightmapVecs normal vector
04028 /*
04029 if ( !test->shader->twoSided )
04030 {
04031 // skip all other facets of this surface as well because they are in the same plane
04032 for (k = 0; k < test->numFacets; k++)
04033 {
04034 facet = &test->facets[k];
04035 volume->facetTested[facet->num >> 3] |= 1 << (facet->num & 7);
04036 }
04037 }*/
04038 backfaceculled = qtrue;
04039 }
04040 }
04041 else
04042 {
04043 // FIXME: if all light source winding points are at the back of the facet
04044 // plane then backfaceculled = qtrue
04045 }
04046 }
04047 else // backface culling per facet for patches and triangle soups
04048 {
04049 if (volume->type == VOLUME_NORMAL)
04050 {
04051 // facet backface culling
04052 d = DotProduct(light->origin, facet->plane.normal) - facet->plane.dist;
04053 if (d < 0)
04054 backfaceculled = qtrue;
04055 }
04056 else
04057 {
04058 // FIXME: if all light source winding points are at the back of the facet
04059 // plane then backfaceculled = qtrue
04060 }
04061 }
04062 /* chopping does this already
04063 // check if this facet is totally or partly in front of the volume end plane
04064 for (k = 0; k < facet->numpoints; k++)
04065 {
04066 d = DotProduct(volume->endplane.normal, facet->points[k]) - volume->endplane.dist;
04067 if (d > ON_EPSILON)
04068 break;
04069 }
04070 // if this facet is outside the light volume
04071 if (k >= facet->numpoints)
04072 continue;
04073 */
04074 //
04075 if (backfaceculled)
04076 {
04077 // if the facet is not two sided
04078 if ( !nobackfaceculling && !test->shader->twoSided )
04079 continue;
04080 // flip the winding
04081 for (k = 0; k < facet->numpoints; k++)
04082 VectorCopy(facet->points[k], winding.points[facet->numpoints - k - 1]);
04083 winding.numpoints = facet->numpoints;
04084 }
04085 else
04086 {
04087 memcpy(winding.points, facet->points, sizeof(vec3_t) * facet->numpoints);
04088 winding.numpoints = facet->numpoints;
04089 }
04090 //
04091 if (!testculled)
04092 {
04093 testculled = qtrue;
04094 // fast check if the surface sphere is totally behind the volume end plane
04095 d = DotProduct(volume->endplane.normal, test->origin) - volume->endplane.dist;
04096 if (d < -test->radius)
04097 {
04098 for (k = 0; k < test->numFacets; k++)
04099 {
04100 facet = &test->facets[k];
04101 volume->facetTested[facet->num >> 3] |= 1 << (facet->num & 7);
04102 }
04103 break;
04104 }
04105 for (k = 0; k < volume->numplanes; k++)
04106 {
04107 d = DotProduct(volume->planes[k].normal, test->origin) - volume->planes[k].dist;
04108 if (d < - test->radius)
04109 {
04110 for (k = 0; k < test->numFacets; k++)
04111 {
04112 facet = &test->facets[k];
04113 volume->facetTested[facet->num >> 3] |= 1 << (facet->num & 7);
04114 }
04115 break;
04116 }
04117 }
04118 if (k < volume->numplanes)
04119 break;
04120 }
04121 //NOTE: we have to chop the facet winding with the volume end plane because
04122 // the faces in Q3 are not stitched together nicely
04123 res = VS_ChopWinding(&winding, &volume->endplane, 0.01);
04124 // if the facet is on or at the back of the volume end plane
04125 if (res == SIDE_BACK || res == SIDE_ON)
04126 continue;
04127 // check if the facet winding is totally or partly inside the light volume
04128 memcpy(&tmpwinding, &winding, sizeof(winding_t));
04129 for (k = 0; k < volume->numplanes; k++)
04130 {
04131 res = VS_ChopWinding(&tmpwinding, &volume->planes[k], 0.01);
04132 if (res == SIDE_BACK || res == SIDE_ON)
04133 break;
04134 }
04135 // if no part of the light volume is occluded by this facet
04136 if (k < volume->numplanes)
04137 continue;
04138 //
04139 for (k = 0; k < winding.numpoints; k++)
04140 {
04141 if (volume->type == VOLUME_DIRECTED)
04142 {
04143 VectorSubtract(winding.points[(k+1) % winding.numpoints], winding.points[k], dir1);
04144 CrossProduct(light->normal, dir1, plane.normal);
04145 VectorNormalize(plane.normal, plane.normal);
04146 plane.dist = DotProduct(plane.normal, winding.points[k]);
04147 }
04148 else
04149 {
04150 VectorSubtract(winding.points[(k+1) % winding.numpoints], winding.points[k], dir1);
04151 VectorSubtract(light->origin, winding.points[k], dir2);
04152 CrossProduct(dir1, dir2, plane.normal);
04153 VectorNormalize(plane.normal, plane.normal);
04154 plane.dist = DotProduct(plane.normal, winding.points[k]);
04155 }
04156 res = VS_R_SplitLightVolume(light, volume, &plane, cluster, 0);
04157 if (res == 1)
04158 break; //the facet wasn't really inside the volume
04159 }
04160 if (k >= winding.numpoints)
04161 {
04162 volume->endplane = facet->plane;
04163 if (backfaceculled)
04164 {
04165 VectorInverse(volume->endplane.normal);
04166 volume->endplane.dist = -volume->endplane.dist;
04167 }
04168 volume->surfaceNum = surfaceNum;
04169 volume->facetNum = j;
04170 }
04171 }
04172 }
04173 }
04174 // we've tested all occluders in this cluster
04175 volume->clusterTested[cluster >> 3] |= 1 << (cluster & 7);
04176 // flood light through the portals of the current leaf
04177 leaf = &leafs[cluster];
04178 for (i = firstportal; i < leaf->numportals; i++)
04179 {
04180 p = leaf->portals[i];
04181 //
04182 // memcpy(&winding, p->winding, sizeof(winding_t));
04183 // DebugNet_DrawWinding(&winding, 5);
04184 // if already flooded into the cluster this portal leads to
04185 if ( volume->clusterTested[p->leaf >> 3] & (1 << (p->leaf & 7)) )
04186 continue;
04187 //
04188 if (volume->type == VOLUME_NORMAL)
04189 {
04190 // portal backface culling
04191 d = DotProduct(light->origin, p->plane.normal) - p->plane.dist;
04192 if (d > 0) // portal plane normal points into neighbour cluster
04193 continue;
04194 }
04195 else
04196 {
04197 // FIXME: if all light source winding points are at the back of this portal
04198 // plane then there's no need to flood through
04199 }
04200 // check if this portal is totally or partly in front of the volume end plane
04201 // fast check with portal sphere
04202 d = DotProduct(volume->endplane.normal, p->origin) - volume->endplane.dist;
04203 if (d < -p->radius)
04204 continue;
04205 for (j = 0; j < p->winding->numpoints; j++)
04206 {
04207 d = DotProduct(volume->endplane.normal, p->winding->points[j]) - volume->endplane.dist;
04208 if (d > -0.01)
04209 break;
04210 }
04211 // if this portal is totally behind the light volume end plane
04212 if (j >= p->winding->numpoints)
04213 continue;
04214 //distance from point light to portal
04215 d = DotProduct(p->plane.normal, light->origin) - p->plane.dist;
04216 // only check if a point light is Not *on* the portal
04217 if (volume->type != VOLUME_NORMAL || fabs(d) > 0.1)
04218 {
04219 // check if the portal is partly or totally inside the light volume
04220 memcpy(&winding, p->winding, sizeof(winding_t));
04221 for (j = 0; j < volume->numplanes; j++)
04222 {
04223 res = VS_ChopWinding(&winding, &volume->planes[j], 0.01);
04224 if (res == SIDE_BACK || res == SIDE_ON)
04225 break;
04226 }
04227 // if the light volume does not go through this portal at all
04228 if (j < volume->numplanes)
04229 continue;
04230 }
04231 // chop the light volume with the portal
04232 for (k = 0; k < p->winding->numpoints; k++)
04233 {
04234 if (volume->type == VOLUME_DIRECTED)
04235 {
04236 VectorSubtract(p->winding->points[(k+1) % p->winding->numpoints], p->winding->points[k], dir1);
04237 CrossProduct(light->normal, dir1, plane.normal);
04238 VectorNormalize(plane.normal, plane.normal);
04239 plane.dist = DotProduct(plane.normal, p->winding->points[k]);
04240 }
04241 else
04242 {
04243 VectorSubtract(p->winding->points[(k+1) % p->winding->numpoints], p->winding->points[k], dir1);
04244 VectorSubtract(light->origin, p->winding->points[k], dir2);
04245 CrossProduct(dir1, dir2, plane.normal);
04246 VectorNormalize(plane.normal, plane.normal);
04247 plane.dist = DotProduct(plane.normal, p->winding->points[k]);
04248 }
04249 res = VS_R_SplitLightVolume(light, volume, &plane, cluster, i+1);
04250 if (res == 1)
04251 break; //volume didn't really go through the portal
04252 }
04253 // if the light volume went through the portal
04254 if (k >= p->winding->numpoints)
04255 {
04256 // flood through the portal
04257 VS_R_FloodLight(light, volume, p->leaf, 0);
04258 }
04259 }
04260 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 712 of file soundv.c. References dnode_t::children, dleaf_t::cluster, dplane_t::dist, plane_t::dist, dleafs, dnodes, dplanes, memcpy(), plane_t::normal, dplane_t::normal, dnode_t::planeNum, VectorCopy, VS_LinkSurfaceIntoCluster(), VS_SplitWinding(), and w. Referenced by VS_LinkSurfaces(). 00713 {
00714 int leafnum, cluster, res;
00715 dnode_t *node;
00716 dplane_t *plane;
00717 winding_t back;
00718 plane_t split;
00719
00720 while(nodenum >= 0)
00721 {
00722 node = &dnodes[nodenum];
00723 plane = &dplanes[node->planeNum];
00724
00725 VectorCopy(plane->normal, split.normal);
00726 split.dist = plane->dist;
00727 res = VS_SplitWinding (w, &back, &split, 0.1);
00728
00729 if (res == SIDE_FRONT)
00730 {
00731 nodenum = node->children[0];
00732 }
00733 else if (res == SIDE_BACK)
00734 {
00735 nodenum = node->children[1];
00736 }
00737 else if (res == SIDE_ON)
00738 {
00739 memcpy(&back, w, sizeof(winding_t));
00740 VS_R_LinkSurface(node->children[1], surfaceNum, &back);
00741 nodenum = node->children[0];
00742 }
00743 else
00744 {
00745 VS_R_LinkSurface(node->children[1], surfaceNum, &back);
00746 nodenum = node->children[0];
00747 }
00748 }
00749 leafnum = -nodenum - 1;
00750 cluster = dleafs[leafnum].cluster;
00751 if (cluster != -1)
00752 {
00753 VS_LinkSurfaceIntoCluster(cluster, surfaceNum);
00754 }
00755 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 3930 of file soundv.c. References lightvolume_s::cluster, lightvolume_s::clusterTested, lightvolume_s::endplane, lightvolume_s::facetNum, lightvolume_s::facetTested, lightvolume_s::farplane, lightvolume_t, memcpy(), lightvolume_s::num, lightvolume_s::numtransFacets, numvolumes, lightvolume_s::surfaceNum, lightvolume_s::transFacets, lightvolume_s::transSurfaces, lightvolume_s::type, VS_R_CastLightAtSurface(), VS_R_FloodLight(), VS_SplitLightVolume(), and vsound_t. Referenced by VS_R_FloodLight(). 03931 {
03932 lightvolume_t back;
03933 int res;
03934
03935 //
03936 res = VS_SplitLightVolume(volume, &back, split, 0.1);
03937 // if the volume was split
03938 if (res == 2)
03939 {
03940 memcpy(back.clusterTested, volume->clusterTested, sizeof(back.clusterTested));
03941 memcpy(back.facetTested, volume->facetTested, sizeof(back.facetTested));
03942 back.num = numvolumes++;
03943 back.endplane = volume->endplane;
03944 back.surfaceNum = volume->surfaceNum;
03945 back.facetNum = volume->facetNum;
03946 back.type = volume->type;
03947 back.cluster = volume->cluster;
03948 back.farplane = volume->farplane;
03949 if (volume->numtransFacets > 0)
03950 {
03951 memcpy(back.transFacets, volume->transFacets, sizeof(back.transFacets));
03952 memcpy(back.transSurfaces, volume->transSurfaces, sizeof(back.transSurfaces));
03953 }
03954 back.numtransFacets = volume->numtransFacets;
03955 //
03956 // flood the volume at the back of the split plane
03957 VS_R_FloodLight(light, &back, cluster, firstportal);
03958 // if the back volume hit a surface
03959 if (back.surfaceNum >= 0)
03960 {
03961 VS_R_CastLightAtSurface(light, &back);
03962 }
03963 }
03964 return res;
03965 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 4276 of file soundv.c. References dnode_t::children, dleaf_t::cluster, dplane_t::dist, plane_t::dist, dleafs, dnodes, dplanes, memcpy(), plane_t::normal, dplane_t::normal, dnode_t::planeNum, VectorCopy, VS_FloodAreaSpotLight(), VS_SplitWinding(), vsound_t, and w. Referenced by VS_FloodLight(). 04277 {
04278 int leafnum, res;
04279 dnode_t *node;
04280 dplane_t *plane;
04281 winding_t back;
04282 plane_t split;
04283
04284 while(nodenum >= 0)
04285 {
04286 node = &dnodes[nodenum];
04287 plane = &dplanes[node->planeNum];
04288
04289 VectorCopy(plane->normal, split.normal);
04290 split.dist = plane->dist;
04291 res = VS_SplitWinding (w, &back, &split, 0.1);
04292
04293 if (res == SIDE_FRONT)
04294 {
04295 nodenum = node->children[0];
04296 }
04297 else if (res == SIDE_BACK)
04298 {
04299 nodenum = node->children[1];
04300 }
04301 else if (res == SIDE_ON)
04302 {
04303 memcpy(&back, w, sizeof(winding_t));
04304 VS_R_SubdivideAreaSpotLight(light, node->children[1], &back);
04305 nodenum = node->children[0];
04306 }
04307 else
04308 {
04309 VS_R_SubdivideAreaSpotLight(light, node->children[1], &back);
04310 nodenum = node->children[0];
04311 }
04312 }
04313 leafnum = -nodenum - 1;
04314 if (dleafs[leafnum].cluster != -1)
04315 {
04316 VS_FloodAreaSpotLight(light, w, leafnum);
04317 }
04318 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 4432 of file soundv.c. References dnode_t::children, dleaf_t::cluster, dplane_t::dist, plane_t::dist, dleafs, dnodes, dplanes, memcpy(), plane_t::normal, dplane_t::normal, dnode_t::planeNum, VectorCopy, VS_FloodDirectedLight(), VS_SplitWinding(), vsound_t, and w. Referenced by VS_FloodLight(). 04433 {
04434 int leafnum, res;
04435 dnode_t *node;
04436 dplane_t *plane;
04437 winding_t back;
04438 plane_t split;
04439
04440 while(nodenum >= 0)
04441 {
04442 node = &dnodes[nodenum];
04443 plane = &dplanes[node->planeNum];
04444
04445 VectorCopy(plane->normal, split.normal);
04446 split.dist = plane->dist;
04447 res = VS_SplitWinding (w, &back, &split, 0.1);
04448
04449 if (res == SIDE_FRONT)
04450 {
04451 nodenum = node->children[0];
04452 }
04453 else if (res == SIDE_BACK)
04454 {
04455 nodenum = node->children[1];
04456 }
04457 else if (res == SIDE_ON)
04458 {
04459 memcpy(&back, w, sizeof(winding_t));
04460 VS_R_SubdivideDirectedAreaLight(light, node->children[1], &back);
04461 nodenum = node->children[0];
04462 }
04463 else
04464 {
04465 VS_R_SubdivideDirectedAreaLight(light, node->children[1], &back);
04466 nodenum = node->children[0];
04467 }
04468 }
04469 leafnum = -nodenum - 1;
04470 if (dleafs[leafnum].cluster != -1)
04471 {
04472 VS_FloodDirectedLight(light, w, leafnum);
04473 }
04474 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 4334 of file soundv.c. References dnode_t::children, dleaf_t::cluster, dplane_t::dist, plane_t::dist, dleafs, dnodes, dplanes, memcpy(), plane_t::normal, dplane_t::normal, dnode_t::planeNum, VectorCopy, VS_FloodRadialAreaLight(), VS_SplitWinding(), vsound_t, and w. Referenced by VS_FloodLight(). 04335 {
04336 int leafnum, res;
04337 dnode_t *node;
04338 dplane_t *plane;
04339 winding_t back;
04340 plane_t split;
04341
04342 while(nodenum >= 0)
04343 {
04344 node = &dnodes[nodenum];
04345 plane = &dplanes[node->planeNum];
04346
04347 VectorCopy(plane->normal, split.normal);
04348 split.dist = plane->dist;
04349 res = VS_SplitWinding (w, &back, &split, 0.1);
04350
04351 if (res == SIDE_FRONT)
04352 {
04353 nodenum = node->children[0];
04354 }
04355 else if (res == SIDE_BACK)
04356 {
04357 nodenum = node->children[1];
04358 }
04359 else if (res == SIDE_ON)
04360 {
04361 memcpy(&back, w, sizeof(winding_t));
04362 VS_R_SubdivideRadialAreaLight(light, node->children[1], &back);
04363 nodenum = node->children[0];
04364 }
04365 else
04366 {
04367 VS_R_SubdivideRadialAreaLight(light, node->children[1], &back);
04368 nodenum = node->children[0];
04369 }
04370 }
04371 leafnum = -nodenum - 1;
04372 if (dleafs[leafnum].cluster != -1)
04373 {
04374 VS_FloodRadialAreaLight(light, w, leafnum);
04375 }
04376 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1772 of file soundv.c. References dnode_t::children, dleaf_t::cluster, dplane_t::dist, plane_t::dist, dleafbrushes, dleafs, dnodes, DotProduct, dplanes, dleaf_t::firstLeafBrush, plane_t::normal, dplane_t::normal, dleaf_t::numLeafBrushes, dnode_t::planeNum, VectorCopy, VS_SplitWinding(), VS_WindingAreaOutsideBrushes(), and w. Referenced by VS_WindingAreaOutsideSolid(). 01773 {
01774 int leafnum, res;
01775 float area;
01776 dnode_t *node;
01777 dleaf_t *leaf;
01778 dplane_t *plane;
01779 winding_t back;
01780 plane_t split;
01781
01782 area = 0;
01783 while(nodenum >= 0)
01784 {
01785 node = &dnodes[nodenum];
01786 plane = &dplanes[node->planeNum];
01787
01788 VectorCopy(plane->normal, split.normal);
01789 split.dist = plane->dist;
01790 res = VS_SplitWinding (w, &back, &split, 0.1);
01791
01792 if (res == SIDE_FRONT)
01793 {
01794 nodenum = node->children[0];
01795 }
01796 else if (res == SIDE_BACK)
01797 {
01798 nodenum = node->children[1];
01799 }
01800 else if (res == SIDE_ON)
01801 {
01802 if (DotProduct(normal, plane->normal) > 0)
01803 nodenum = node->children[0];
01804 else
01805 nodenum = node->children[1];
01806 }
01807 else
01808 {
01809 area += VS_R_WindingAreaOutsideSolid(&back, normal, node->children[1]);
01810 nodenum = node->children[0];
01811 }
01812 }
01813 leafnum = -nodenum - 1;
01814 leaf = &dleafs[leafnum];
01815 if (leaf->cluster != -1)
01816 {
01817 area += VS_WindingAreaOutsideBrushes(w, &dleafbrushes[leaf->firstLeafBrush], leaf->numLeafBrushes);
01818 }
01819 return area;
01820 }
|
Here is the call graph for this function:

|
|
Definition at line 4921 of file soundv.c. References _printf(), free(), lightFloats, malloc(), memcpy(), numDrawSurfaces, numLightBytes, oldLightFloats, qtrue, RunThreadsOnIndividual(), and VS_SurfaceRadiosity(). Referenced by VS_LightWorld(). 04921 {
04922
04923 oldLightFloats = lightFloats;
04924 lightFloats = (float *) malloc(numLightBytes * sizeof(float));
04925 memcpy(lightFloats, oldLightFloats, numLightBytes * sizeof(float));
04926 _printf("%7i surfaces\n", numDrawSurfaces);
04927 RunThreadsOnIndividual( numDrawSurfaces, qtrue, VS_SurfaceRadiosity );
04928 free(oldLightFloats);
04929 }
|
Here is the call graph for this function:

|
|
Definition at line 5406 of file soundv.c. References i, winding_t::numpoints, lportal_t::origin, p, winding_t::points, r, lportal_t::radius, vec3_origin, vec3_t, VectorAdd, VectorCopy, VectorLength(), VectorSubtract, w, and lportal_t::winding. Referenced by VS_LoadPortals(). 05407 {
05408 int i;
05409 vec3_t total, dist;
05410 winding_t *w;
05411 float r, bestr;
05412
05413 w = p->winding;
05414 VectorCopy (vec3_origin, total);
05415 for (i=0 ; i<w->numpoints ; i++)
05416 {
05417 VectorAdd (total, w->points[i], total);
05418 }
05419
05420 for (i=0 ; i<3 ; i++)
05421 total[i] /= w->numpoints;
05422
05423 bestr = 0;
05424 for (i=0 ; i<w->numpoints ; i++)
05425 {
05426 VectorSubtract (w->points[i], total, dist);
05427 r = VectorLength (dist);
05428 if (r > bestr)
05429 bestr = r;
05430 }
05431 VectorCopy (total, p->origin);
05432 p->radius = bestr;
05433 }
|
Here is the call graph for this function:

|
|
Definition at line 2559 of file soundv.c. References drawSurfaces, drawVerts, dsurface_t::firstVert, i, j, k, lightFloats, drawVert_t::lightmap, LIGHTMAP_HEIGHT, LIGHTMAP_WIDTH, dsurface_t::lightmapHeight, dsurface_t::lightmapNum, dsurface_t::lightmapWidth, dsurface_t::lightmapX, dsurface_t::lightmapY, lsurfaceTest, lsurfaceTest_t, dsurface_t::patchHeight, dsurface_t::patchWidth, ptr(), dsurface_t::surfaceType, test(), x, and y. Referenced by VS_StoreLightmap(). 02560 {
02561 int i, j, x, y, k;
02562 drawVert_t *verts;
02563 dsurface_t *ds;
02564 lsurfaceTest_t *test;
02565 float *ptr;
02566
02567 for ( i = 0 ; i < numDrawSurfaces ; i++ )
02568 {
02569 test = lsurfaceTest[ i ];
02570 if (!test)
02571 continue;
02572 ds = &drawSurfaces[ i ];
02573
02574 if ( ds->lightmapNum < 0 )
02575 continue;
02576 if (ds->surfaceType != MST_PATCH)
02577 continue;
02578 for (x = ds->lightmapWidth; x > 0; x--)
02579 {
02580 for (y = 0; y <= ds->lightmapHeight; y++)
02581 {
02582 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02583 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02584 ptr = lightFloats + k*3;
02585 ptr[0] = (lightFloats + (k-1)*3)[0];
02586 ptr[1] = (lightFloats + (k-1)*3)[1];
02587 ptr[2] = (lightFloats + (k-1)*3)[2];
02588 }
02589 }
02590 for (y = ds->lightmapHeight; y > 0; y--)
02591 {
02592 for (x = 0; x <= ds->lightmapWidth; x++)
02593 {
02594 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02595 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02596 ptr = lightFloats + k*3;
02597 ptr[0] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[0];
02598 ptr[1] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[1];
02599 ptr[2] = (lightFloats + (k-LIGHTMAP_WIDTH)*3)[2];
02600 }
02601 }
02602 verts = &drawVerts[ ds->firstVert ];
02603 for ( j = 0 ; j < ds->patchHeight * ds->patchWidth; j++ )
02604 {
02605 verts[j].lightmap[0] += 0.5 / LIGHTMAP_WIDTH;
02606 verts[j].lightmap[1] += 0.5 / LIGHTMAP_HEIGHT;
02607 }
02608 ds->lightmapHeight++;
02609 ds->lightmapWidth++;
02610 }
02611 }
|
Here is the call graph for this function:

|
|
Definition at line 2041 of file soundv.c. References CrossProduct(), DotProduct, drawSurfaces, fabs(), lsurfaceTest_s::facets, i, j, k, length(), lFacet_t, lightFloats, LIGHTMAP_HEIGHT, LIGHTMAP_SIZE, LIGHTMAP_WIDTH, lFacet_s::lightmapCoords, dsurface_t::lightmapHeight, lFacet_s::lightmapMatrix, dsurface_t::lightmapNum, lightmappixelarea, dsurface_t::lightmapWidth, dsurface_t::lightmapX, dsurface_t::lightmapY, lsurfaceTest, lsurfaceTest_t, plane_t::normal, lsurfaceTest_s::numFacets, lFacet_s::numpoints, p, lFacet_s::plane, point, lFacet_s::points, s, t, test(), lsurfaceTest_s::trisoup, vec3_t, VectorNormalize(), VectorSubtract, VS_FindAdjacentSurface(), x2, y1, and y2. Referenced by VS_FixLightmapEdges(). 02042 {
02043 int i, j, k, coords1[2][2];
02044 float coords2[2][2];
02045 int x1, y1, xinc1, yinc1, k1, k2;
02046 float x2, y2, xinc2, yinc2, length;
02047 int surfaceNum, facetNum, point;
02048 lsurfaceTest_t *test;
02049 lFacet_t *facet1, *facet2;
02050 dsurface_t *ds1, *ds2;
02051 float *p[2], s, t, *color1, *color2;
02052 vec3_t dir, cross;
02053
02054 for ( i = 0 ; i < numDrawSurfaces ; i++ )
02055 {
02056 test = lsurfaceTest[ i ];
02057 if (!test)
02058 continue;
02059 if (test->trisoup)// || test->patch)
02060 continue;
02061 ds1 = &drawSurfaces[i];
02062 if ( ds1->lightmapNum < 0 )
02063 continue;
02064 for (j = 0; j < test->numFacets; j++)
02065 {
02066 facet1 = &test->facets[j];
02067 //
02068 for (k = 0; k < facet1->numpoints; k++)
02069 {
02070 p[0] = facet1->points[k];
02071 p[1] = facet1->points[(k+1)%facet1->numpoints];
02072 //
02073 coords1[0][0] = facet1->lightmapCoords[k][0] * LIGHTMAP_SIZE;
02074 coords1[0][1] = facet1->lightmapCoords[k][1] * LIGHTMAP_SIZE;
02075 coords1[1][0] = facet1->lightmapCoords[(k+1)%facet1->numpoints][0] * LIGHTMAP_SIZE;
02076 coords1[1][1] = facet1->lightmapCoords[(k+1)%facet1->numpoints][1] * LIGHTMAP_SIZE;
02077 if (coords1[0][0] >= LIGHTMAP_SIZE)
02078 coords1[0][0] = LIGHTMAP_SIZE-1;
02079 if (coords1[0][1] >= LIGHTMAP_SIZE)
02080 coords1[0][1] = LIGHTMAP_SIZE-1;
02081 if (coords1[1][0] >= LIGHTMAP_SIZE)
02082 coords1[1][0] = LIGHTMAP_SIZE-1;
02083 if (coords1[1][1] >= LIGHTMAP_SIZE)
02084 coords1[1][1] = LIGHTMAP_SIZE-1;
02085 // try one row or column further because on flat faces the lightmap can
02086 // extend beyond the edge
02087 VectorSubtract(p[1], p[0], dir);
02088 VectorNormalize(dir, dir);
02089 CrossProduct(dir, facet1->plane.normal, cross);
02090 //
02091 if (coords1[0][0] - coords1[1][0] == 0)
02092 {
02093 s = DotProduct( cross, facet1->lightmapMatrix[0] );
02094 coords1[0][0] += s < 0 ? 1 : -1;
02095 coords1[1][0] += s < 0 ? 1 : -1;
02096 if (coords1[0][0] < ds1->lightmapX || coords1[0][0] >= ds1->lightmapX + ds1->lightmapWidth)
02097 {
02098 coords1[0][0] += s < 0 ? -1 : 1;
02099 coords1[1][0] += s < 0 ? -1 : 1;
02100 }
02101 length = fabs(coords1[1][1] - coords1[0][1]);
02102 }
02103 else if (coords1[0][1] - coords1[1][1] == 0)
02104 {
02105 t = DotProduct( cross, facet1->lightmapMatrix[1] );
02106 coords1[0][1] += t < 0 ? 1 : -1;
02107 coords1[1][1] += t < 0 ? 1 : -1;
02108 if (coords1[0][1] < ds1->lightmapY || coords1[0][1] >= ds1->lightmapY + ds1->lightmapHeight)
02109 {
02110 coords1[0][1] += t < 0 ? -1 : 1;
02111 coords1[1][1] += t < 0 ? -1 : 1;
02112 }
02113 length = fabs(coords1[1][0] - coords1[0][0]);
02114 }
02115 else
02116 {
02117 //the edge is not parallell to one of the lightmap axis
02118 continue;
02119 }
02120 //
02121 x1 = coords1[0][0];
02122 y1 = coords1[0][1];
02123 xinc1 = coords1[1][0] - coords1[0][0];
02124 if (xinc1 < 0) xinc1 = -1;
02125 if (xinc1 > 0) xinc1 = 1;
02126 yinc1 = coords1[1][1] - coords1[0][1];
02127 if (yinc1 < 0) yinc1 = -1;
02128 if (yinc1 > 0) yinc1 = 1;
02129 // the edge should be parallell to one of the lightmap axis
02130 if (xinc1 != 0 && yinc1 != 0)
02131 continue;
02132 //
02133 if (!VS_FindAdjacentSurface(i, j, p[0], p[1], &surfaceNum, &facetNum, &point))
02134 continue;
02135 //
02136 ds2 = &drawSurfaces[surfaceNum];
02137 facet2 = &lsurfaceTest[surfaceNum]->facets[facetNum];
02138 coords2[0][0] = facet2->lightmapCoords[(point+1)%facet2->numpoints][0] * LIGHTMAP_SIZE;
02139 coords2[0][1] = facet2->lightmapCoords[(point+1)%facet2->numpoints][1] * LIGHTMAP_SIZE;
02140 coords2[1][0] = facet2->lightmapCoords[point][0] * LIGHTMAP_SIZE;
02141 coords2[1][1] = facet2->lightmapCoords[point][1] * LIGHTMAP_SIZE;
02142 if (coords2[0][0] >= LIGHTMAP_SIZE)
02143 coords2[0][0] = LIGHTMAP_SIZE-1;
02144 if (coords2[0][1] >= LIGHTMAP_SIZE)
02145 coords2[0][1] = LIGHTMAP_SIZE-1;
02146 if (coords2[1][0] >= LIGHTMAP_SIZE)
02147 coords2[1][0] = LIGHTMAP_SIZE-1;
02148 if (coords2[1][1] >= LIGHTMAP_SIZE)
02149 coords2[1][1] = LIGHTMAP_SIZE-1;
02150 //
02151 x2 = coords2[0][0];
02152 y2 = coords2[0][1];
02153 xinc2 = coords2[1][0] - coords2[0][0];
02154 if (length)
02155 xinc2 = xinc2 / length;
02156 yinc2 = coords2[1][1] - coords2[0][1];
02157 if (length)
02158 yinc2 = yinc2 / length;
02159 // the edge should be parallell to one of the lightmap axis
02160 if ((int) xinc2 != 0 && (int) yinc2 != 0)
02161 continue;
02162 //
02163 while(1)
02164 {
02165 k1 = ( ds1->lightmapNum * LIGHTMAP_HEIGHT + y1) * LIGHTMAP_WIDTH + x1;
02166 k2 = ( ds2->lightmapNum * LIGHTMAP_HEIGHT + ((int) y2)) * LIGHTMAP_WIDTH + ((int) x2);
02167 color1 = lightFloats + k1*3;
02168 color2 = lightFloats + k2*3;
02169 if (lightmappixelarea[k1] < 0.01)
02170 {
02171 color1[0] = color2[0];
02172 color1[1] = color2[1];
02173 color1[2] = color2[2];
02174 }
02175 else
02176 {
02177 color1[0] = (float) color2[0] * 0.7 + (float) color1[0] * 0.3;
02178 color1[1] = (float) color2[1] * 0.7 + (float) color1[1] * 0.3;
02179 color1[2] = (float) color2[2] * 0.7 + (float) color1[2] * 0.3;
02180 }
02181 //
02182 if (x1 == coords1[1][0] &&
02183 y1 == coords1[1][1])
02184 break;
02185 x1 += xinc1;
02186 y1 += yinc1;
02187 x2 += xinc2;
02188 y2 += yinc2;
02189 if (x2 < ds2->lightmapX)
02190 x2 = ds2->lightmapX;
02191 if (x2 >= ds2->lightmapX + ds2->lightmapWidth)
02192 x2 = ds2->lightmapX + ds2->lightmapWidth-1;
02193 if (y2 < ds2->lightmapY)
02194 y2 = ds2->lightmapY;
02195 if (y2 >= ds2->lightmapY + ds2->lightmapHeight)
02196 y2 = ds2->lightmapY + ds2->lightmapHeight-1;
02197 }
02198 }
02199 }
02200 }
02201 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1327 of file soundv.c. References vec3_t, VectorAdd, VectorLength(), VectorScale, and VectorSubtract. Referenced by VS_InitSurfacesForTesting(). 01327 {
01328 vec3_t temp;
01329
01330 VectorAdd( mins, maxs, origin );
01331 VectorScale( origin, 0.5, origin );
01332 VectorSubtract( maxs, origin, temp );
01333 *radius = VectorLength( temp );
01334 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 3668 of file soundv.c. References _printf(), b, plane_t::dist, DotProduct, f, i, j, lightvolume_t, memcpy(), plane_t::normal, lightvolume_s::numplanes, p2, plane_t, lightvolume_s::planes, lightvolume_s::points, SIDE_ON, vec3_t, vec_t, VectorCopy, and VectorInverse(). Referenced by VS_R_SplitLightVolume(). 03669 {
03670 lightvolume_t f, b;
03671 vec_t dists[128];
03672 int sides[128];
03673 int counts[3];
03674 vec_t dot;
03675 int i, j;
03676 vec_t *p1, *p2;
03677 vec3_t mid;
03678
03679 counts[0] = counts[1] = counts[2] = 0;
03680
03681 // determine sides for each point
03682 for (i = 0; i < volume->numplanes; i++)
03683 {
03684 dot = DotProduct (volume->points[i], split->normal);
03685 dot -= split->dist;
03686 dists[i] = dot;
03687 if (dot > epsilon)
03688 sides[i] = SIDE_FRONT;
03689 else if (dot < -epsilon)
03690 sides[i] = SIDE_BACK;
03691 else
03692 {
03693 sides[i] = SIDE_ON;
03694 }
03695 counts[sides[i]]++;
03696 }
03697
03698 if (!counts[1])
03699 return 0; // completely on front side
03700
03701 if (!counts[0])
03702 return 1; // completely on back side
03703
03704 sides[i] = sides[0];
03705 dists[i] = dists[0];
03706
03707 f.numplanes = 0;
03708 b.numplanes = 0;
03709
03710 for (i = 0; i < volume->numplanes; i++)
03711 {
03712 p1 = volume->points[i];
03713
03714 if (f.numplanes >= MAX_POINTS_ON_FIXED_WINDING)
03715 {
03716 _printf("WARNING: VS_SplitLightVolume -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
03717 return 0; // can't chop -- fall back to original
03718 }
03719 if (b.numplanes >= MAX_POINTS_ON_FIXED_WINDING)
03720 {
03721 _printf("WARNING: VS_SplitLightVolume -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
03722 return 0; // can't chop -- fall back to original
03723 }
03724
03725 if (sides[i] == SIDE_ON)
03726 {
03727 VectorCopy(p1, f.points[f.numplanes]);
03728 VectorCopy(p1, b.points[b.numplanes]);
03729 if (sides[i+1] == SIDE_BACK)
03730 {
03731 f.planes[f.numplanes] = *split;
03732 b.planes[b.numplanes] = volume->planes[i];
03733 }
03734 else if (sides[i+1] == SIDE_FRONT)
03735 {
03736 f.planes[f.numplanes] = volume->planes[i];
03737 b.planes[b.numplanes] = *split;
03738 VectorInverse(b.planes[b.numplanes].normal);
03739 b.planes[b.numplanes].dist = -b.planes[b.numplanes].dist;
03740 }
03741 else //this shouldn't happen
03742 {
03743 f.planes[f.numplanes] = *split;
03744 b.planes[b.numplanes] = *split;
03745 VectorInverse(b.planes[b.numplanes].normal);
03746 b.planes[b.numplanes].dist = -b.planes[b.numplanes].dist;
03747 }
03748 f.numplanes++;
03749 b.numplanes++;
03750 continue;
03751 }
03752
03753 if (sides[i] == SIDE_FRONT)
03754 {
03755 VectorCopy (p1, f.points[f.numplanes]);
03756 f.planes[f.numplanes] = volume->planes[i];
03757 f.numplanes++;
03758 }
03759 if (sides[i] == SIDE_BACK)
03760 {
03761 VectorCopy (p1, b.points[b.numplanes]);
03762 b.planes[b.numplanes] = volume->planes[i];
03763 b.numplanes++;
03764 }
03765
03766 if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
03767 continue;
03768
03769 if (f.numplanes >= MAX_POINTS_ON_FIXED_WINDING)
03770 {
03771 _printf("WARNING: VS_SplitLightVolume -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
03772 return 0; // can't chop -- fall back to original
03773 }
03774 if (b.numplanes >= MAX_POINTS_ON_FIXED_WINDING)
03775 {
03776 _printf("WARNING: VS_SplitLightVolume -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
03777 return 0; // can't chop -- fall back to original
03778 }
03779
03780 // generate a split point
03781 p2 = volume->points[(i+1)%volume->numplanes];
03782
03783 dot = dists[i] / (dists[i]-dists[i+1]);
03784 for (j=0 ; j<3 ; j++)
03785 { // avoid round off error when possible
03786 if (split->normal[j] == 1)
03787 mid[j] = split->dist;
03788 else if (split->normal[j] == -1)
03789 mid[j] = -split->dist;
03790 else
03791 mid[j] = p1[j] + dot*(p2[j]-p1[j]);
03792 }
03793
03794 VectorCopy (mid, f.points[f.numplanes]);
03795 VectorCopy(mid, b.points[b.numplanes]);
03796 if (sides[i+1] == SIDE_BACK)
03797 {
03798 f.planes[f.numplanes] = *split;
03799 b.planes[b.numplanes] = volume->planes[i];
03800 }
03801 else
03802 {
03803 f.planes[f.numplanes] = volume->planes[i];
03804 b.planes[b.numplanes] = *split;
03805 VectorInverse(b.planes[b.numplanes].normal);
03806 b.planes[b.numplanes].dist = -b.planes[b.numplanes].dist;
03807 }
03808 f.numplanes++;
03809 b.numplanes++;
03810 }
03811 memcpy(volume->points, f.points, sizeof(vec3_t) * f.numplanes);
03812 memcpy(volume->planes, f.planes, sizeof(plane_t) * f.numplanes);
03813 volume->numplanes = f.numplanes;
03814 memcpy(back->points, b.points, sizeof(vec3_t) * b.numplanes);
03815 memcpy(back->planes, b.planes, sizeof(plane_t) * b.numplanes);
03816 back->numplanes = b.numplanes;
03817
03818 return 2;
03819 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 548 of file soundv.c. References _printf(), plane_t::dist, DotProduct, i, in, j, memcpy(), plane_t::normal, winding_t::numpoints, p2, winding_t::points, SIDE_ON, vec3_t, vec_t, and VectorCopy. Referenced by VS_ChopWindingWithBrush(), VS_R_LinkSurface(), VS_R_SubdivideAreaSpotLight(), VS_R_SubdivideDirectedAreaLight(), VS_R_SubdivideRadialAreaLight(), and VS_R_WindingAreaOutsideSolid(). 00549 {
00550 vec_t dists[128];
00551 int sides[128];
00552 int counts[3];
00553 vec_t dot;
00554 int i, j;
00555 vec_t *p1, *p2;
00556 vec3_t mid;
00557 winding_t out;
00558 winding_t *neww;
00559
00560 counts[0] = counts[1] = counts[2] = 0;
00561
00562 // determine sides for each point
00563 for (i=0 ; i<in->numpoints ; i++)
00564 {
00565 dot = DotProduct (in->points[i], split->normal);
00566 dot -= split->dist;
00567 dists[i] = dot;
00568 if (dot > epsilon)
00569 sides[i] = SIDE_FRONT;
00570 else if (dot < -epsilon)
00571 sides[i] = SIDE_BACK;
00572 else
00573 {
00574 sides[i] = SIDE_ON;
00575 }
00576 counts[sides[i]]++;
00577 }
00578
00579 if (!counts[SIDE_BACK])
00580 {
00581 if (!counts[SIDE_FRONT])
00582 return SIDE_ON;
00583 else
00584 return SIDE_FRONT;
00585 }
00586
00587 if (!counts[SIDE_FRONT])
00588 {
00589 return SIDE_BACK;
00590 }
00591
00592 sides[i] = sides[0];
00593 dists[i] = dists[0];
00594
00595 neww = &out;
00596
00597 neww->numpoints = 0;
00598 back->numpoints = 0;
00599
00600 for (i=0 ; i<in->numpoints ; i++)
00601 {
00602 p1 = in->points[i];
00603
00604 if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
00605 {
00606 _printf("WARNING: VS_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
00607 return SIDE_FRONT; // can't chop -- fall back to original
00608 }
00609 if (back->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
00610 {
00611 _printf("WARNING: VS_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
00612 return SIDE_FRONT;
00613 }
00614
00615 if (sides[i] == SIDE_ON)
00616 {
00617 VectorCopy (p1, neww->points[neww->numpoints]);
00618 neww->numpoints++;
00619 VectorCopy (p1, back->points[back->numpoints]);
00620 back->numpoints++;
00621 continue;
00622 }
00623
00624 if (sides[i] == SIDE_FRONT)
00625 {
00626 VectorCopy (p1, neww->points[neww->numpoints]);
00627 neww->numpoints++;
00628 }
00629 if (sides[i] == SIDE_BACK)
00630 {
00631 VectorCopy (p1, back->points[back->numpoints]);
00632 back->numpoints++;
00633 }
00634
00635 if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
00636 continue;
00637
00638 if (neww->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
00639 {
00640 _printf("WARNING: VS_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
00641 return SIDE_FRONT; // can't chop -- fall back to original
00642 }
00643
00644 if (back->numpoints >= MAX_POINTS_ON_FIXED_WINDING)
00645 {
00646 _printf("WARNING: VS_SplitWinding -> MAX_POINTS_ON_FIXED_WINDING overflowed\n");
00647 return SIDE_FRONT; // can't chop -- fall back to original
00648 }
00649
00650 // generate a split point
00651 p2 = in->points[(i+1)%in->numpoints];
00652
00653 dot = dists[i] / (dists[i]-dists[i+1]);
00654 for (j=0 ; j<3 ; j++)
00655 { // avoid round off error when possible
00656 if (split->normal[j] == 1)
00657 mid[j] = split->dist;
00658 else if (split->normal[j] == -1)
00659 mid[j] = -split->dist;
00660 else
00661 mid[j] = p1[j] + dot*(p2[j]-p1[j]);
00662 }
00663
00664 VectorCopy (mid, neww->points[neww->numpoints]);
00665 neww->numpoints++;
00666 VectorCopy (mid, back->points[back->numpoints]);
00667 back->numpoints++;
00668 }
00669 memcpy(in, &out, sizeof(winding_t));
00670
00671 return SIDE_CROSS;
00672 }
|
Here is the call graph for this function:

|
|
Definition at line 2618 of file soundv.c. References _printf(), byte, ColorToBytes(), drawSurfaces, i, k, lightAmbientColor, lightBytes, lightFloats, LIGHTMAP_HEIGHT, LIGHTMAP_WIDTH, dsurface_t::lightmapHeight, dsurface_t::lightmapNum, dsurface_t::lightmapWidth, dsurface_t::lightmapX, dsurface_t::lightmapY, lsurfaceTest, lsurfaceTest_t, src, test(), VectorAdd, VS_FixLightmapEdges(), VS_ShiftPatchLightmaps(), x, and y. Referenced by VS_LightWorld(). 02619 {
02620 int i, x, y, k;
02621 dsurface_t *ds;
02622 lsurfaceTest_t *test;
02623 float *src;
02624 byte *dst;
02625
02626 _printf("storing lightmaps...\n");
02627 //fix lightmap edges before storing them
02628 VS_FixLightmapEdges();
02629 //
02630 #ifdef LIGHTMAP_PATCHSHIFT
02631 VS_ShiftPatchLightmaps();
02632 #endif
02633 //
02634 for ( i = 0 ; i < numDrawSurfaces ; i++ )
02635 {
02636 test = lsurfaceTest[ i ];
02637 if (!test)
02638 continue;
02639 ds = &drawSurfaces[ i ];
02640
02641 if ( ds->lightmapNum < 0 )
02642 continue;
02643
02644 for (y = 0; y < ds->lightmapHeight; y++)
02645 {
02646 for (x = 0; x < ds->lightmapWidth; x++)
02647 {
02648 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
02649 * LIGHTMAP_WIDTH + ds->lightmapX + x;
02650 VectorAdd((lightFloats + k*3), lightAmbientColor, (lightFloats + k*3));
02651 src = &lightFloats[k*3];
02652 dst = lightBytes + k*3;
02653 ColorToBytes(src, dst);
02654 }
02655 }
02656 }
02657 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 5094 of file soundv.c. References shaderInfo_s::backsplashDistance, shaderInfo_s::backsplashFraction, ClipWindingEpsilon(), shaderInfo_s::color, shaderInfo_s::contents, DotProduct, FreeWinding(), lightAreaScale, lightFormFactorValueScale, malloc(), memcpy(), memset(), winding_t::numpoints, numvsounds, ON_EPSILON, vsound_s::photons, winding_t::points, qfalse, shaderInfo_t, vsound_s::type, shaderInfo_s::value, value, vec3_t, VectorAdd, VectorClear, VectorCopy, VectorMA, VectorScale, vsound_t, vsounds, vsound_s::w, w, WindingArea(), WindingBounds(), and WindingCenter(). Referenced by VS_CreateFakeSurfaceLights(). 05095 {
05096 float area, value, intensity;
05097 vsound_t *dl, *dl2;
05098 vec3_t mins, maxs;
05099 int axis;
05100 winding_t *front, *back;
05101 vec3_t planeNormal;
05102 float planeDist;
05103
05104 if ( !w ) {
05105 return;
05106 }
05107
05108 WindingBounds( w, mins, maxs );
05109
05110 // check for subdivision
05111 for ( axis = 0 ; axis < 3 ; axis++ ) {
05112 if ( maxs[axis] - mins[axis] > areaSubdivide ) {
05113 VectorClear( planeNormal );
05114 planeNormal[axis] = 1;
05115 planeDist = ( maxs[axis] + mins[axis] ) * 0.5;
05116 ClipWindingEpsilon ( w, planeNormal, planeDist, ON_EPSILON, &front, &back );
05117 VS_SubdivideAreaLight( ls, front, normal, areaSubdivide, qfalse );
05118 VS_SubdivideAreaLight( ls, back, normal, areaSubdivide, qfalse );
05119 FreeWinding( w );
05120 return;
05121 }
05122 }
05123
05124 // create a light from this
05125 area = WindingArea (w);
05126 if ( area <= 0 || area > 20000000 ) {
05127 return;
05128 }
05129
05130 dl = malloc(sizeof(*dl));
05131 memset (dl, 0, sizeof(*dl));
05132 dl->type = LIGHT_POINTFAKESURFACE;
05133
05134 WindingCenter( w, dl->origin );
05135 memcpy(dl->w.points, w->points, sizeof(vec3_t) * w->numpoints);
05136 dl->w.numpoints = w->numpoints;
05137 VectorCopy ( normal, dl->normal);
05138 VectorCopy ( normal, dl->plane);
05139 dl->plane[3] = DotProduct( dl->origin, normal );
05140
05141 value = ls->value;
05142 intensity = value * area * lightAreaScale;
05143 VectorAdd( dl->origin, dl->normal, dl->origin );
05144
05145 VectorCopy( ls->color, dl->color );
05146
05147 dl->photons = intensity;
05148
05149 // emitColor is irrespective of the area
05150 VectorScale( ls->color, value*lightFormFactorValueScale*lightAreaScale, dl->emitColor );
05151 //
05152 VectorCopy(dl->emitColor, dl->color);
05153
05154 dl->si = ls;
05155
05156 if ( ls->contents & CONTENTS_FOG ) {
05157 dl->twosided = qtrue;
05158 }
05159
05160 vsounds[numvsounds++] = dl;
05161
05162 // optionally create a point backsplash light
05163 if ( backsplash && ls->backsplashFraction > 0 ) {
05164
05165 dl2 = malloc(sizeof(*dl));
05166 memset (dl2, 0, sizeof(*dl2));
05167 dl2->type = LIGHT_POINTRADIAL;
05168
05169 VectorMA( dl->origin, ls->backsplashDistance, normal, dl2->origin );
05170
05171 VectorCopy( ls->color, dl2->color );
05172
05173 dl2->photons = dl->photons * ls->backsplashFraction;
05174 dl2->si = ls;
05175
05176 vsounds[numvsounds++] = dl2;
05177 }
05178 }
|
Here is the call graph for this function:

|
|
Definition at line 4841 of file soundv.c. References vsound_s::color, ColorNormalize(), lsurfaceTest_s::detailMesh, drawSurfaces, dshaders, lsurfaceTest_s::facets, k, lightFloats, LIGHTMAP_HEIGHT, LIGHTMAP_WIDTH, dsurface_t::lightmapHeight, dsurface_t::lightmapNum, dsurface_t::lightmapOrigin, lightmappixelarea, dsurface_t::lightmapVecs, dsurface_t::lightmapWidth, dsurface_t::lightmapX, dsurface_t::lightmapY, lightPointScale, lsurfaceTest, lsurfaceTest_t, memset(), lsurfaceTest_s::mutex, MutexLock(), MutexUnlock(), plane_t::normal, oldLightFloats, vsound_s::origin, vsound_s::photons, lFacet_s::plane, shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, dsurface_t::surfaceType, test(), vsound_s::type, vec3_t, VectorCopy, VectorLength(), VectorMA, mesh_t::verts, VS_FloodLight(), vsound_t, mesh_t::width, x, and y. Referenced by VS_Radiosity(). 04841 {
04842 dsurface_t *ds;
04843 mesh_t *mesh;
04844 shaderInfo_t *si;
04845 lsurfaceTest_t *test;
04846 int x, y, k;
04847 vec3_t base, normal;
04848 float *color, area;
04849 vsound_t vsound;
04850
04851 ds = &drawSurfaces[num];
04852
04853 if ( ds->lightmapNum < 0 ) {
04854 return; // doesn't have a lightmap
04855 }
04856
04857 // vertex-lit triangle model
04858 if ( ds->surfaceType == MST_TRIANGLE_SOUP ) {
04859 return;
04860 }
04861
04862 si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
04863 test = lsurfaceTest[ num ];
04864
04865 if (!test) {
04866 return;
04867 }
04868
04869 for (x = 0; x < ds->lightmapWidth; x++) {
04870 for (y = 0; y < ds->lightmapHeight; y++) {
04871 //
04872 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + y)
04873 * LIGHTMAP_WIDTH + ds->lightmapX + x;
04874 area = lightmappixelarea[k];
04875 if (area <= 0)
04876 continue;
04877 //
04878 if (ds->surfaceType == MST_PATCH)
04879 {
04880 mesh = test->detailMesh;
04881 VectorCopy( mesh->verts[y*mesh->width+x].xyz, base);
04882 VectorCopy( mesh->verts[y*mesh->width+x].normal, normal);
04883 }
04884 else
04885 {
04886 VectorMA(ds->lightmapOrigin, (float) x, ds->lightmapVecs[0], base);
04887 VectorMA(base, (float) y, ds->lightmapVecs[1], base);
04888 VectorCopy(test->facets[0].plane.normal, normal);
04889 }
04890 // create ligth from base
04891 memset(&vsound, 0, sizeof(vsound_t));
04892 color = &oldLightFloats[k*3];
04893 // a few units away from the surface
04894 VectorMA(base, 5, normal, vsound.origin);
04895 ColorNormalize(color, vsound.color);
04896 // ok this is crap
04897 vsound.photons = VectorLength(color) * 0.05 * lightPointScale / (area * radiosity_scale);
04898 // what about using a front facing light only ?
04899 vsound.type = LIGHT_POINTRADIAL;
04900 // flood the light from this lightmap pixel
04901 VS_FloodLight(&vsound);
04902 // only one thread at a time may write to the lightmap of this surface
04903 MutexLock(test->mutex);
04904 // don't light the lightmap pixel itself
04905 lightFloats[k*3] = oldLightFloats[k*3];
04906 lightFloats[k*3+1] = oldLightFloats[k*3+1];
04907 lightFloats[k*3+2] = oldLightFloats[k*3+2];
04908 //
04909 MutexUnlock(test->mutex);
04910 }
04911 }
04912 }
|
Here is the call graph for this function:

|
|
Definition at line 4759 of file soundv.c. References dleaf_t::cluster, dleafs, i, LIGHT_POINTRADIAL, vsound_s::origin, qprintf(), vsound_s::type, VS_LightLeafnum(), vsound_t, and vsounds. Referenced by VSoundMain(). 04760 {
04761 int leafnum, i;
04762 vsound_t *light;
04763 dleaf_t *leaf;
04764
04765 for (i = 0; i < numvsounds; i++)
04766 {
04767 light = vsounds[i];
04768 if (light->type != LIGHT_POINTRADIAL &&
04769 light->type != LIGHT_POINTSPOT)
04770 continue;
04771 leafnum = VS_LightLeafnum(light->origin);
04772 leaf = &dleafs[leafnum];
04773 if (leaf->cluster == -1)
04774 if (light->type == LIGHT_POINTRADIAL)
04775 qprintf("light in solid at %1.1f %1.1f %1.1f\n", light->origin[0], light->origin[1], light->origin[2]);
04776 else if (light->type == LIGHT_POINTSPOT)
04777 qprintf("spot light in solid at %1.1f %1.1f %1.1f\n", light->origin[0], light->origin[1], light->origin[2]);
04778 }
04779 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 791 of file soundv.c. References a, b, c, f, fabs(), i, j, lFacet_t, m, s, drawVert_t::st, t, lFacet_s::textureMatrix, and drawVert_t::xyz. Referenced by VS_GenerateFacetFor3Points(), and VS_GenerateFacetFor4Points(). 00791 {
00792 int i, j;
00793 float t;
00794 float m[3][4];
00795 float s;
00796
00797 // This is an incredibly stupid way of solving a three variable equation
00798 for ( i = 0 ; i < 2 ; i++ ) {
00799
00800 m[0][0] = a->xyz[0];
00801 m[0][1] = a->xyz[1];
00802 m[0][2] = a->xyz[2];
00803 m[0][3] = a->st[i];
00804
00805 m[1][0] = b->xyz[0];
00806 m[1][1] = b->xyz[1];
00807 m[1][2] = b->xyz[2];
00808 m[1][3] = b->st[i];
00809
00810 m[2][0] = c->xyz[0];
00811 m[2][1] = c->xyz[1];
00812 m[2][2] = c->xyz[2];
00813 m[2][3] = c->st[i];
00814
00815 if ( fabs(m[1][0]) > fabs(m[0][0]) && fabs(m[1][0]) > fabs(m[2][0]) ) {
00816 for ( j = 0 ; j < 4 ; j ++ ) {
00817 t = m[0][j];
00818 m[0][j] = m[1][j];
00819 m[1][j] = t;
00820 }
00821 } else if ( fabs(m[2][0]) > fabs(m[0][0]) && fabs(m[2][0]) > fabs(m[1][0]) ) {
00822 for ( j = 0 ; j < 4 ; j ++ ) {
00823 t = m[0][j];
00824 m[0][j] = m[2][j];
00825 m[2][j] = t;
00826 }
00827 }
00828
00829 s = 1.0 / m[0][0];
00830 m[0][0] *= s;
00831 m[0][1] *= s;
00832 m[0][2] *= s;
00833 m[0][3] *= s;
00834
00835 s = m[1][0];
00836 m[1][0] -= m[0][0] * s;
00837 m[1][1] -= m[0][1] * s;
00838 m[1][2] -= m[0][2] * s;
00839 m[1][3] -= m[0][3] * s;
00840
00841 s = m[2][0];
00842 m[2][0] -= m[0][0] * s;
00843 m[2][1] -= m[0][1] * s;
00844 m[2][2] -= m[0][2] * s;
00845 m[2][3] -= m[0][3] * s;
00846
00847 if ( fabs(m[2][1]) > fabs(m[1][1]) ) {
00848 for ( j = 0 ; j < 4 ; j ++ ) {
00849 t = m[1][j];
00850 m[1][j] = m[2][j];
00851 m[2][j] = t;
00852 }
00853 }
00854
00855 s = 1.0 / m[1][1];
00856 m[1][0] *= s;
00857 m[1][1] *= s;
00858 m[1][2] *= s;
00859 m[1][3] *= s;
00860
00861 s = m[2][1];// / m[1][1];
00862 m[2][0] -= m[1][0] * s;
00863 m[2][1] -= m[1][1] * s;
00864 m[2][2] -= m[1][2] * s;
00865 m[2][3] -= m[1][3] * s;
00866
00867 s = 1.0 / m[2][2];
00868 m[2][0] *= s;
00869 m[2][1] *= s;
00870 m[2][2] *= s;
00871 m[2][3] *= s;
00872
00873 f->textureMatrix[i][2] = m[2][3];
00874 f->textureMatrix[i][1] = m[1][3] - f->textureMatrix[i][2] * m[1][2];
00875 f->textureMatrix[i][0] = m[0][3] - f->textureMatrix[i][2] * m[0][2] - f->textureMatrix[i][1] * m[0][1];
00876
00877 f->textureMatrix[i][3] = 0;
00878 /*
00879 s = fabs( DotProduct( a->xyz, f->textureMatrix[i] ) - a->st[i] );
00880 if ( s > 0.01 ) {
00881 Error( "Bad textureMatrix" );
00882 }
00883 s = fabs( DotProduct( b->xyz, f->textureMatrix[i] ) - b->st[i] );
00884 if ( s > 0.01 ) {
00885 Error( "Bad textureMatrix" );
00886 }
00887 s = fabs( DotProduct( c->xyz, f->textureMatrix[i] ) - c->st[i] );
00888 if ( s > 0.01 ) {
00889 Error( "Bad textureMatrix" );
00890 }
00891 */
00892 }
00893 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1709 of file soundv.c. References dshader_t::contentFlags, CONTENTS_AREAPORTAL, CONTENTS_BODY, CONTENTS_CLUSTERPORTAL, CONTENTS_CORPSE, CONTENTS_DONOTENTER, CONTENTS_FOG, CONTENTS_LAVA, CONTENTS_MONSTERCLIP, CONTENTS_PLAYERCLIP, CONTENTS_SLIME, CONTENTS_TRANSLUCENT, CONTENTS_TRIGGER, CONTENTS_WATER, dbrushes, dshaders, i, j, memcpy(), n, winding_t::numpoints, winding_t::points, points, dbrush_t::shaderNum, vec3_t, VS_ChopWindingWithBrush(), w, and WindingArea(). Referenced by VS_R_WindingAreaOutsideSolid(). 01710 {
01711 int i, j, numwindings[2], n;
01712 winding_t windingsbuf[2][64];
01713 dbrush_t *brush;
01714 float area;
01715
01716 memcpy(windingsbuf[0][0].points, w->points, w->numpoints * sizeof(vec3_t));
01717 windingsbuf[0][0].numpoints = w->numpoints;
01718 numwindings[0] = 1;
01719 for (i = 0; i < numbrushes; i++)
01720 {
01721 brush = &dbrushes[brushnums[i]];
01722 if (!(dshaders[brush->shaderNum].contentFlags & (
01723 CONTENTS_LAVA
01724 | CONTENTS_SLIME
01725 | CONTENTS_WATER
01726 | CONTENTS_FOG
01727 | CONTENTS_AREAPORTAL
01728 | CONTENTS_PLAYERCLIP
01729 | CONTENTS_MONSTERCLIP
01730 | CONTENTS_CLUSTERPORTAL
01731 | CONTENTS_DONOTENTER
01732 | CONTENTS_BODY
01733 | CONTENTS_CORPSE
01734 | CONTENTS_TRANSLUCENT
01735 | CONTENTS_TRIGGER
01736 | CONTENTS_NODROP) ) &&
01737 (dshaders[brush->shaderNum].contentFlags & CONTENTS_SOLID) )
01738 {
01739 numwindings[!(i & 1)] = 0;
01740 for (j = 0; j < numwindings[i&1]; j++)
01741 {
01742 n = VS_ChopWindingWithBrush(&windingsbuf[i&1][j], brush,
01743 &windingsbuf[!(i&1)][numwindings[!(i&1)]],
01744 64 - numwindings[!(i&1)]);
01745 numwindings[!(i&1)] += n;
01746 }
01747 if (!numwindings[!(i&1)])
01748 return 0;
01749 }
01750 else
01751 {
01752 for (j = 0; j < numwindings[i&1]; j++)
01753 {
01754 windingsbuf[!(i&1)][j] = windingsbuf[i&1][j];
01755 }
01756 numwindings[!(i&1)] = numwindings[i&1];
01757 }
01758 }
01759 area = 0;
01760 for (j = 0; j < numwindings[i&1]; j++)
01761 {
01762 area += WindingArea(&windingsbuf[i&1][j]);
01763 }
01764 return area;
01765 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 1827 of file soundv.c. References VS_R_WindingAreaOutsideSolid(), and w. Referenced by VS_CalcVisibleLightmapPixelArea(), and VS_ChopWindingWithFacet(). 01828 {
01829 return VS_R_WindingAreaOutsideSolid(w, normal, 0);
01830 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 5313 of file soundv.c. References BaseWindingForPlane(), dbrushsides, dplane_t::dist, plane_t::dist, dplanes, dbrush_t::firstSide, i, memcpy(), plane_t::normal, winding_t::numpoints, dbrush_t::numSides, dbrushside_t::planeNum, winding_t::points, vec3_t, VectorCopy, VectorInverse(), VS_ChopWinding(), and w. Referenced by VS_CreateSkyLights(). 05314 {
05315 int i, res;
05316 winding_t *tmpw;
05317 plane_t plane;
05318
05319 VectorCopy(dplanes[ dbrushsides[ brush->firstSide + side ].planeNum ].normal, plane.normal);
05320 VectorInverse(plane.normal);
05321 plane.dist = -dplanes[ dbrushsides[ brush->firstSide + side ].planeNum ].dist;
05322 tmpw = BaseWindingForPlane( plane.normal, plane.dist );
05323 memcpy(w->points, tmpw->points, sizeof(vec3_t) * tmpw->numpoints);
05324 w->numpoints = tmpw->numpoints;
05325
05326 for (i = 0; i < brush->numSides; i++)
05327 {
05328 if (i == side)
05329 continue;
05330 VectorCopy(dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].normal, plane.normal);
05331 VectorInverse(plane.normal);
05332 plane.dist = -dplanes[ dbrushsides[ brush->firstSide + i ].planeNum ].dist;
05333 res = VS_ChopWinding(w, &plane, 0.1);
05334 if (res == SIDE_BACK)
05335 return NULL;
05336 }
05337 return w;
05338 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 5594 of file soundv.c. References _printf(), argc, argv, atof(), atoi, clock(), CountLightmaps(), DefaultExtension(), defaulttracelight, entities, exit(), ExpandArg(), gamedir, GridAndVertexLighting(), gridSize, i, InitPakFile(), lightAreaScale, lightFloats, lightPointScale, LoadBSPFile(), LoadShaderInfo(), malloc(), memset(), noalphashading, nobackfaceculling, nocolorshading, nostitching, NULL, numLightBytes, numthreads, numvsounds, ParseEntities(), radiosity, samplesize, SetEntityOrigins(), SetQdirFromPath(), source, sscanf(), strcmp(), strcpy(), StripExtension(), strlen(), ThreadSetDefault(), value, ValueForKey(), verbose, VS_CalcVisibleLightmapPixelArea(), VS_CreateEntitySpeakers(), VS_CreateFakeSurfaceLights(), VS_CreateSkyLights(), VS_InitSurfacesForTesting(), VS_LightWorld(), VS_LoadPortals(), VS_TestLightLeafs(), and WriteBSPFile(). Referenced by main(). 05594 {
05595 int i;
05596 double start, end;
05597 const char *value;
05598
05599 _printf ("----- VLighting ----\n");
05600
05601 for (i=1 ; i<argc ; i++) {
05602 if (!strcmp(argv[i],"-v")) {
05603 verbose = qtrue;
05604 } else if (!strcmp(argv[i],"-threads")) {
05605 numthreads = atoi (argv[i+1]);
05606 _printf("num threads = %d\n", numthreads);
05607 i++;
05608 } else if (!strcmp(argv[i],"-area")) {
05609 lightAreaScale *= atof(argv[i+1]);
05610 _printf ("area light scaling at %f\n", lightAreaScale);
05611 i++;
05612 } else if (!strcmp(argv[i],"-point")) {
05613 lightPointScale *= atof(argv[i+1]);
05614 _printf ("point light scaling at %f\n", lightPointScale);
05615 i++;
05616 } else if (!strcmp(argv[i], "-samplesize")) {
05617 samplesize = atoi(argv[i+1]);
05618 if (samplesize < 1) samplesize = 1;
05619 i++;
05620 _printf("lightmap sample size is %dx%d units\n", samplesize, samplesize);
05621 } else if (!strcmp(argv[i], "-nostitching")) {
05622 nostitching = qtrue;
05623 _printf("no stitching = true\n");
05624 } else if (!strcmp(argv[i], "-noalphashading")) {
05625 noalphashading = qtrue;
05626 _printf("no alpha shading = true\n");
05627 } else if (!strcmp(argv[i], "-nocolorshading")) {
05628 nocolorshading = qtrue;
05629 _printf("old style alpha shading = true\n");
05630 } else if (!strcmp(argv[i], "-nobackfaceculling")) {
05631 nobackfaceculling = qtrue;
05632 _printf("no backface culling = true\n");
05633 } else if (!strcmp(argv[i], "-tracelight")) {
05634 defaulttracelight = qtrue;
05635 _printf("default trace light = true\n");
05636 } else if (!strcmp(argv[i], "-radiosity")) {
05637 radiosity = atoi(argv[i+1]);
05638 _printf("radiosity = %d\n", radiosity);
05639 i++;
05640 } else {
05641 break;
05642 }
05643 }
05644
05645 ThreadSetDefault ();
05646
05647 if (i != argc - 1) {
05648 _printf("usage: q3map -vsound [-<switch> [-<switch> ...]] <mapname>\n"
05649 "\n"
05650 "Switches:\n"
05651 " v = verbose output\n"
05652 " threads <X> = set number of threads to X\n"
05653 " area <V> = set the area light scale to V\n"
05654 " point <W> = set the point light scale to W\n"
05655 " novertex = don't calculate vertex lighting\n"
05656 " nogrid = don't calculate light grid for dynamic model lighting\n"
05657 " nostitching = no polygon stitching before lighting\n"
05658 " noalphashading = don't use alpha shading\n"
05659 " nocolorshading = don't use color alpha shading\n"
05660 " tracelight = use old light algorithm by default\n"
05661 " samplesize <N> = set the lightmap pixel size to NxN units\n");
05662 exit(0);
05663 }
05664
05665 SetQdirFromPath (argv[i]);
05666
05667 #ifdef _WIN32
05668 InitPakFile(gamedir, NULL);
05669 #endif
05670
05671 strcpy (source, ExpandArg(argv[i]));
05672 StripExtension (source);
05673 DefaultExtension (source, ".bsp");
05674
05675 LoadShaderInfo();
05676
05677 _printf ("reading %s\n", source);
05678
05679 LoadBSPFile (source);
05680 ParseEntities();
05681
05682 value = ValueForKey( &entities[0], "gridsize" );
05683 if (strlen(value)) {
05684 sscanf( value, "%f %f %f", &gridSize[0], &gridSize[1], &gridSize[2] );
05685 _printf("grid size = {%1.1f, %1.1f, %1.1f}\n", gridSize[0], gridSize[1], gridSize[2]);
05686 }
05687
05688 CountLightmaps();
05689
05690 StripExtension (source);
05691 DefaultExtension (source, ".prt");
05692
05693 VS_LoadPortals(source);
05694
05695 // set surfaceOrigin
05696 SetEntityOrigins();
05697
05698 // grid and vertex lighting
05699 GridAndVertexLighting();
05700
05701 #ifdef DEBUGNET
05702 DebugNet_Setup();
05703 #endif
05704
05705 start = clock();
05706
05707 lightFloats = (float *) malloc(numLightBytes * sizeof(float));
05708 memset(lightFloats, 0, numLightBytes * sizeof(float));
05709
05710 VS_InitSurfacesForTesting();
05711
05712 VS_CalcVisibleLightmapPixelArea();
05713
05714 numvsounds = 0;
05715 VS_CreateEntitySpeakers();
05716 VS_CreateFakeSurfaceLights();
05717 VS_CreateSkyLights();
05718
05719 VS_TestLightLeafs();
05720
05721 VS_LightWorld();
05722
05723 #ifndef LIGHTPOLYS
05724 StripExtension (source);
05725 DefaultExtension (source, ".bsp");
05726 _printf ("writing %s\n", source);
05727 WriteBSPFile (source);
05728 #endif
05729
05730 end = clock();
05731
05732 _printf ("%5.2f seconds elapsed\n", (end-start) / CLK_TCK);
05733
05734 #ifdef LIGHTPOLYS
05735 VS_DrawLightWindings();
05736 #endif
05737
05738 #ifdef DEBUGNET
05739 DebugNet_Shutdown();
05740 #endif
05741 return 0;
05742 }
|
Here is the call graph for this function:

|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 207 of file l_poly.c. References i, j, winding_t::numpoints, winding_t::p, v, vec_t, and w. Referenced by AAS_CreateCurveBrushes(), CM_AddFacetBevels(), CM_ValidateFacet(), SubdivideAreaLight(), VL_SubdivideAreaLight(), and VS_SubdivideAreaLight(). 00208 {
00209 vec_t v;
00210 int i,j;
00211
00212 mins[0] = mins[1] = mins[2] = 99999;
00213 maxs[0] = maxs[1] = maxs[2] = -99999;
00214
00215 for (i=0 ; i<w->numpoints ; i++)
00216 {
00217 for (j=0 ; j<3 ; j++)
00218 {
00219 v = w->p[i][j];
00220 if (v < mins[j])
00221 mins[j] = v;
00222 if (v > maxs[j])
00223 maxs[j] = v;
00224 }
00225 }
00226 }
|
|
||||||||||||
|
Definition at line 233 of file l_poly.c. References i, winding_t::numpoints, winding_t::p, vec3_origin, VectorAdd, VectorCopy, VectorScale, and w. Referenced by AAS_CheckArea(), AAS_FlipAreaFaces(), LeakFile(), SubdivideAreaLight(), VL_SubdivideAreaLight(), and VS_SubdivideAreaLight(). 00234 {
00235 int i;
00236 float scale;
00237
00238 VectorCopy (vec3_origin, center);
00239 for (i=0 ; i<w->numpoints ; i++)
00240 VectorAdd (w->p[i], center, center);
00241
00242 scale = 1.0/w->numpoints;
00243 VectorScale (center, scale, center);
00244 }
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 1478 of file light.c. Referenced by LightMain(), SetupGrid(), TraceGrid(), VLightMain(), and VSoundMain(). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 208 of file soundv.c. Referenced by VS_CreateEntitySpeakers(), VS_CreateFakeSurfaceLights(), VS_CreateSkyLights(), VS_LightWorld(), VS_SubdivideAreaLight(), and VSoundMain(). |
|
|
|
|
|
Definition at line 50 of file light.c. Referenced by LightMain(). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 58 of file light.c. Referenced by LightMain(), main(), VLightMain(), and VSoundMain(). |
|
|
|
|
|
Definition at line 87 of file light.c. Referenced by SetEntityOrigins(), TraceLtm(), VL_GenerateFacetFor3Points(), VL_GenerateFacetFor4Points(), VL_LightmapMatrixFromPoints(), VS_GenerateFacetFor3Points(), VS_GenerateFacetFor4Points(), and VS_LightmapMatrixFromPoints(). |
|
|
Definition at line 209 of file soundv.c. Referenced by VS_CreateEntitySpeakers(), VS_CreateFakeSurfaceLights(), VS_CreateSkyLights(), VS_FloodLightThread(), VS_LightWorld(), VS_SubdivideAreaLight(), and VS_TestLightLeafs(). |
1.3.9.1