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

soundv.c File Reference

#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:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  lFacet_s
struct  lightvolume_s
struct  lleaf_s
struct  lportal_t
struct  lsurfaceTest_s
struct  plane_t
struct  vsound_s
struct  winding_t

Defines

#define DIST_EPSILON   0.02
#define LAAT_DOUBLEQUADRATIC   2
#define LAAT_NORMAL   0
#define LAAT_QUADRATIC   1
#define LDAT_LINEAR   1
#define LDAT_NOSCALE   2
#define LDAT_QUADRATIC   0
#define LIGHT_POINTFAKESURFACE   3
#define LIGHT_POINTRADIAL   1
#define LIGHT_POINTSPOT   2
#define LIGHT_SURFACEDIRECTED   4
#define LIGHT_SURFACERADIAL   5
#define LIGHT_SURFACESPOT   6
#define LIGHTMAP_PIXELSHIFT   0.5
#define LIGHTMAP_SIZE   128
#define MAX_CLUSTERS   16384
#define MAX_FACETS   65536
#define MAX_LIGHTS   16384
#define MAX_POINTS_ON_FIXED_WINDING   48
#define MAX_POINTS_ON_WINDING   64
#define MAX_PORTALS   32768
#define MAX_PORTALS_ON_LEAF   128
#define MAX_TRANSLUCENTFACETS   32
#define NORMAL_EPSILON   0.0001
#define ON_EPSILON   0.1
#define PLANAR_EPSILON   0.1
#define PORTALFILE   "PRT1"
#define VectorSet(v, x, y, z)   v[0] = x;v[1] = y;v[2] = z;
#define VOLUME_DIRECTED   1
#define VOLUME_NORMAL   0

Typedefs

typedef lFacet_s lFacet_t
typedef lightvolume_s lightvolume_t
typedef lleaf_s lleaf_t
typedef lsurfaceTest_s lsurfaceTest_t
typedef vsound_s vsound_t

Functions

winding_tAllocWinding (int points)
winding_tBaseWindingForPlane (vec3_t normal, vec_t dist)
void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist, vec_t epsilon, winding_t **front, winding_t **back)
void ColorToBytes (const float *color, byte *colorBytes)
void CountLightmaps (void)
entity_tFindTargetEntity (const char *target)
void FreeWinding (winding_t *w)
void GridAndVertexLighting (void)
int Plane_Equal (plane_t *a, plane_t *b, int flip)
int PointInLeafnum (vec3_t point)
float PointToPolygonFormFactor (const vec3_t point, const vec3_t normal, const winding_t *w)
winding_tReverseWinding (winding_t *w)
void SetEntityOrigins (void)
void TraceLtm (int num)
winding_tVS_AllocWinding (int points)
void VS_CalcVisibleLightmapPixelArea (void)
int VS_ChopWinding (winding_t *in, plane_t *split, float epsilon)
int VS_ChopWindingWithBrush (winding_t *w, dbrush_t *brush, winding_t *outwindings, int maxout)
float VS_ChopWindingWithFacet (winding_t *w, lFacet_t *facet)
void VS_CreateEntitySpeakers (void)
void VS_CreateFakeSurfaceLights (void)
void VS_CreateSkyLights (void)
void VS_DoForcedTraceLight (int num)
void VS_DoForcedTraceLightSurfaces (void)
void VS_FacetsForPatch (dsurface_t *dsurf, int surfaceNum, shaderInfo_t *si, lsurfaceTest_t *test)
void VS_FacetsForTriangleSurface (dsurface_t *dsurf, shaderInfo_t *si, lsurfaceTest_t *test)
int VS_FindAdjacentSurface (int surfaceNum, int facetNum, vec3_t p1, vec3_t p2, int *sNum, int *fNum, int *point)
void VS_FixLightmapEdges (void)
void VS_FloodAreaSpotLight (vsound_t *light, winding_t *w, int leafnum)
void VS_FloodDirectedLight (vsound_t *light, winding_t *w, int leafnum)
void VS_FloodLight (vsound_t *light)
void VS_FloodLightThread (int num)
void VS_FloodRadialAreaLight (vsound_t *light, winding_t *w, int leafnum)
void VS_GenerateBoundaryForPoints (plane_t *boundary, plane_t *plane, vec3_t a, vec3_t b)
qboolean VS_GenerateFacetFor3Points (dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c)
qboolean VS_GenerateFacetFor4Points (dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c, drawVert_t *d)
void VS_GetFilter (vsound_t *light, lightvolume_t *volume, vec3_t lmp, vec3_t filter)
void VS_InitSurfacesForTesting (void)
int VS_LightLeafnum (vec3_t point)
void VS_LightmapMatrixFromPoints (dsurface_t *dsurf, shaderInfo_t *si, lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c)
void VS_LightSurfaceWithVolume (int surfaceNum, int facetNum, vsound_t *light, lightvolume_t *volume)
void VS_LightWorld (void)
void VS_LinkSurfaceIntoCluster (int cluster, int surfaceNum)
void VS_LinkSurfaces (void)
void VS_LoadPortals (char *name)
void VS_PlaneForEdgeToWinding (vec3_t p1, vec3_t p2, winding_t *w, int windingonfront, plane_t *plane)
qboolean VS_PlaneFromPoints (plane_t *plane, const vec3_t a, const vec3_t b, const vec3_t c)
void VS_PlaneFromWinding (winding_t *w, plane_t *plane)
int VS_PointInLeafnum (vec3_t point)
int VS_PointInLeafnum_r (vec3_t point, int nodenum)
void VS_R_CastLightAtSurface (vsound_t *light, lightvolume_t *volume)
void VS_R_FloodLight (vsound_t *light, lightvolume_t *volume, int cluster, int firstportal)
void VS_R_LinkSurface (int nodenum, int surfaceNum, winding_t *w)
int VS_R_SplitLightVolume (vsound_t *light, lightvolume_t *volume, plane_t *split, int cluster, int firstportal)
void VS_R_SubdivideAreaSpotLight (vsound_t *light, int nodenum, winding_t *w)
void VS_R_SubdivideDirectedAreaLight (vsound_t *light, int nodenum, winding_t *w)
void VS_R_SubdivideRadialAreaLight (vsound_t *light, int nodenum, winding_t *w)
float VS_R_WindingAreaOutsideSolid (winding_t *w, vec3_t normal, int nodenum)
void VS_Radiosity (void)
void VS_SetPortalSphere (lportal_t *p)
void VS_ShiftPatchLightmaps (void)
void VS_SmoothenLightmapEdges (void)
void VS_SphereFromBounds (vec3_t mins, vec3_t maxs, vec3_t origin, float *radius)
int VS_SplitLightVolume (lightvolume_t *volume, lightvolume_t *back, plane_t *split, float epsilon)
int VS_SplitWinding (winding_t *in, winding_t *back, plane_t *split, float epsilon)
void VS_StoreLightmap (void)
void VS_SubdivideAreaLight (shaderInfo_t *ls, winding_t *w, vec3_t normal, float areaSubdivide, qboolean backsplash)
void VS_SurfaceRadiosity (int num)
void VS_TestLightLeafs (void)
void VS_TextureMatrixFromPoints (lFacet_t *f, drawVert_t *a, drawVert_t *b, drawVert_t *c)
float VS_WindingAreaOutsideBrushes (winding_t *w, int *brushnums, int numbrushes)
float VS_WindingAreaOutsideSolid (winding_t *w, vec3_t normal)
winding_tVS_WindingForBrushSide (dbrush_t *brush, int side, winding_t *w)
int VSoundMain (int argc, char **argv)
vec_t WindingArea (winding_t *w)
void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs)
void WindingCenter (winding_t *w, vec3_t center)

Variables

int clustersurfaces [MAX_MAP_LEAFFACES]
int defaulttracelight = 0
int entitySurface [MAX_MAP_DRAW_SURFS]
vec3_t gridSize
lleaf_tleafs
vec3_t lightAmbientColor
float lightAreaScale = 0.25
int lightDefaultSubdivide = 999
float * lightFloats
float lightFormFactorValueScale = 3
float lightLinearScale = 1.0 / 8000
float lightmappixelarea [MAX_MAP_LIGHTING/3]
float lightPointScale = 7500
lsurfaceTest_tlsurfaceTest [MAX_MAP_DRAW_SURFS]
int noalphashading = 0
int nobackfaceculling = 0
int nocolorshading = 0
int nostitching = 0
int numclustersurfaces = 0
int numfaces
int numfacets
int numportals
int numvolumes = 0
int numvsounds = 0
float * oldLightFloats
qboolean patchshadows
int portalclusters
lportal_tportals
int radiosity = 0
int radiosity_scale
int samplesize
char source [1024]
vec3_t surfaceOrigin [MAX_MAP_DRAW_SURFS]
vsound_tvsounds [MAX_LIGHTS]


Define Documentation

#define DIST_EPSILON   0.02
 

Definition at line 1137 of file soundv.c.

#define LAAT_DOUBLEQUADRATIC   2
 

Definition at line 174 of file soundv.c.

#define LAAT_NORMAL   0
 

Definition at line 172 of file soundv.c.

#define LAAT_QUADRATIC   1
 

Definition at line 173 of file soundv.c.

#define LDAT_LINEAR   1
 

Definition at line 168 of file soundv.c.

#define LDAT_NOSCALE   2
 

Definition at line 169 of file soundv.c.

#define LDAT_QUADRATIC   0
 

Definition at line 167 of file soundv.c.

#define LIGHT_POINTFAKESURFACE   3
 

Definition at line 161 of file soundv.c.

#define LIGHT_POINTRADIAL   1
 

Definition at line 159 of file soundv.c.

#define LIGHT_POINTSPOT   2
 

Definition at line 160 of file soundv.c.

#define LIGHT_SURFACEDIRECTED   4
 

Definition at line 162 of file soundv.c.

#define LIGHT_SURFACERADIAL   5
 

Definition at line 163 of file soundv.c.

#define LIGHT_SURFACESPOT   6
 

Definition at line 164 of file soundv.c.

#define LIGHTMAP_PIXELSHIFT   0.5
 

Definition at line 53 of file soundv.c.

#define LIGHTMAP_SIZE   128
 

Definition at line 51 of file soundv.c.

#define MAX_CLUSTERS   16384
 

Definition at line 46 of file soundv.c.

#define MAX_FACETS   65536
 

Definition at line 48 of file soundv.c.

#define MAX_LIGHTS   16384
 

Definition at line 49 of file soundv.c.

#define MAX_POINTS_ON_FIXED_WINDING   48
 

Definition at line 71 of file soundv.c.

#define MAX_POINTS_ON_WINDING   64
 

Definition at line 69 of file soundv.c.

#define MAX_PORTALS   32768
 

Definition at line 47 of file soundv.c.

#define MAX_PORTALS_ON_LEAF   128
 

Definition at line 88 of file soundv.c.

#define MAX_TRANSLUCENTFACETS   32
 

Definition at line 134 of file soundv.c.

#define NORMAL_EPSILON   0.0001
 

Definition at line 1136 of file soundv.c.

#define ON_EPSILON   0.1
 

Definition at line 59 of file soundv.c.

#define PLANAR_EPSILON   0.1
 

Definition at line 1254 of file soundv.c.

#define PORTALFILE   "PRT1"
 

Definition at line 57 of file soundv.c.

#define VectorSet v,
x,
y,
z   )     v[0] = x;v[1] = y;v[2] = z;
 

Definition at line 61 of file soundv.c.

#define VOLUME_DIRECTED   1
 

Definition at line 132 of file soundv.c.

#define VOLUME_NORMAL   0
 

Definition at line 131 of file soundv.c.


Typedef Documentation

typedef struct lFacet_s lFacet_t
 

typedef struct lightvolume_s lightvolume_t
 

typedef struct lleaf_s lleaf_t
 

typedef struct lsurfaceTest_s lsurfaceTest_t
 

typedef struct vsound_s vsound_t
 

Referenced by VS_CreateEntitySpeakers(), VS_CreateFakeSurfaceLights(), VS_CreateSkyLights(), VS_FloodAreaSpotLight(), VS_FloodDirectedLight(), VS_FloodLight(), VS_FloodRadialAreaLight(), VS_GetFilter(), VS_LightSurfaceWithVolume(), VS_R_CastLightAtSurface(), VS_R_FloodLight(), VS_R_SplitLightVolume(), VS_R_SubdivideAreaSpotLight(), VS_R_SubdivideDirectedAreaLight(), VS_R_SubdivideRadialAreaLight(), VS_SubdivideAreaLight(), VS_SurfaceRadiosity(), and VS_TestLightLeafs().


Function Documentation

winding_t* AllocWinding int  points  ) 
 

Definition at line 69 of file l_poly.c.

References c_active_windings, c_peak_windingmemory, c_peak_windings, c_winding_allocs, c_winding_points, c_windingmemory, GetMemory(), malloc(), MemorySize(), memset(), numthreads, points, s, and w.

Referenced by AddWindingPoint(), AddWindingToConvexHull(), BaseWindingForPlane(), ChopWindingInPlace(), ClipWindingEpsilon(), CopyWinding(), CreateSurfaceLights(), FilterMiscModelSurfIntoTree(), FilterPatchSurfIntoTree(), MergeWindings(), ReverseWinding(), TryMergeWinding(), VL_CreateFakeSurfaceLights(), VS_CreateFakeSurfaceLights(), and WindingFromDrawSurf().

00070 {
00071     winding_t   *w;
00072     int         s;
00073 
00074     s = sizeof(vec_t)*3*points + sizeof(int);
00075     w = GetMemory(s);
00076     memset(w, 0, s);
00077 
00078     if (numthreads == 1)
00079     {
00080         c_winding_allocs++;
00081         c_winding_points += points;
00082         c_active_windings++;
00083         if (c_active_windings > c_peak_windings)
00084             c_peak_windings = c_active_windings;
00085         c_windingmemory += MemorySize(w);
00086         if (c_windingmemory > c_peak_windingmemory)
00087             c_peak_windingmemory = c_windingmemory;
00088     } //end if
00089     return w;
00090 } //end of the function AllocWinding

Here is the call graph for this function:

winding_t* BaseWindingForPlane vec3_t  normal,
vec_t  dist
 

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:

void ClipWindingEpsilon winding_t in,
vec3_t  normal,
vec_t  dist,
vec_t  epsilon,
winding_t **  front,
winding_t **  back
 

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:

void ColorToBytes const float *  color,
byte colorBytes
 

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 }

void CountLightmaps void   ) 
 

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:

entity_t* FindTargetEntity const char *  target  ) 
 

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:

void FreeWinding winding_t w  ) 
 

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

void GridAndVertexLighting void   ) 
 

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:

int Plane_Equal plane_t a,
plane_t b,
int  flip
[static]
 

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:

int PointInLeafnum vec3_t  point  )  [static]
 

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 }

float PointToPolygonFormFactor const vec3_t  point,
const vec3_t  normal,
const winding_t w
 

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:

winding_t* ReverseWinding winding_t w  ) 
 

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:

void SetEntityOrigins void   ) 
 

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:

void TraceLtm int  num  ) 
 

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:

winding_t* VS_AllocWinding int  points  ) 
 

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:

void VS_CalcVisibleLightmapPixelArea void   ) 
 

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:

int VS_ChopWinding winding_t in,
plane_t split,
float  epsilon
 

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:

int VS_ChopWindingWithBrush winding_t w,
dbrush_t brush,
winding_t outwindings,
int  maxout
 

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:

float VS_ChopWindingWithFacet winding_t w,
lFacet_t facet
 

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:

void VS_CreateEntitySpeakers void   ) 
 

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:

void VS_CreateFakeSurfaceLights void   ) 
 

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:

void VS_CreateSkyLights void   ) 
 

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:

void VS_DoForcedTraceLight int  num  ) 
 

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:

void VS_DoForcedTraceLightSurfaces void   ) 
 

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:

void VS_FacetsForPatch dsurface_t dsurf,
int  surfaceNum,
shaderInfo_t si,
lsurfaceTest_t test
 

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:

void VS_FacetsForTriangleSurface dsurface_t dsurf,
shaderInfo_t si,
lsurfaceTest_t test
 

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:

int VS_FindAdjacentSurface int  surfaceNum,
int  facetNum,
vec3_t  p1,
vec3_t  p2,
int *  sNum,
int *  fNum,
int *  point
 

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:

void VS_FixLightmapEdges void   ) 
 

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:

void VS_FloodAreaSpotLight vsound_t light,
winding_t w,
int  leafnum
 

Definition at line 4267 of file soundv.c.

References vsound_t.

Referenced by VS_R_SubdivideAreaSpotLight().

04268 {
04269 }

void VS_FloodDirectedLight vsound_t light,
winding_t w,
int  leafnum
 

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:

void VS_FloodLight vsound_t light  ) 
 

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:

void VS_FloodLightThread int  num  ) 
 

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:

void VS_FloodRadialAreaLight vsound_t light,
winding_t w,
int  leafnum
 

Definition at line 4325 of file soundv.c.

References vsound_t.

Referenced by VS_R_SubdivideRadialAreaLight().

04326 {
04327 }

void VS_GenerateBoundaryForPoints plane_t boundary,
plane_t plane,
vec3_t  a,
vec3_t  b
 

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:

qboolean VS_GenerateFacetFor3Points dsurface_t dsurf,
shaderInfo_t si,
lFacet_t f,
drawVert_t a,
drawVert_t b,
drawVert_t c
 

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:

qboolean VS_GenerateFacetFor4Points dsurface_t dsurf,
shaderInfo_t si,
lFacet_t f,
drawVert_t a,
drawVert_t b,
drawVert_t c,
drawVert_t d
 

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:

void VS_GetFilter vsound_t light,
lightvolume_t volume,
vec3_t  lmp,
vec3_t  filter
 

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:

void VS_InitSurfacesForTesting void   ) 
 

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:

int VS_LightLeafnum vec3_t  point  ) 
 

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:

void VS_LightmapMatrixFromPoints dsurface_t dsurf,
shaderInfo_t si,
lFacet_t f,
drawVert_t a,
drawVert_t b,
drawVert_t c
 

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:

void VS_LightSurfaceWithVolume int  surfaceNum,
int  facetNum,
vsound_t light,
lightvolume_t volume
 

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:

void VS_LightWorld void   ) 
 

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:

void VS_LinkSurfaceIntoCluster int  cluster,
int  surfaceNum
 

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:

void VS_LinkSurfaces void   ) 
 

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:

void VS_LoadPortals char *  name  ) 
 

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:

void VS_PlaneForEdgeToWinding vec3_t  p1,
vec3_t  p2,
winding_t w,
int  windingonfront,
plane_t plane
 

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:

qboolean VS_PlaneFromPoints plane_t plane,
const vec3_t  a,
const vec3_t  b,
const vec3_t  c
 

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:

void VS_PlaneFromWinding winding_t w,
plane_t plane
 

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:

int VS_PointInLeafnum vec3_t  point  ) 
 

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:

int VS_PointInLeafnum_r vec3_t  point,
int  nodenum
 

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 }

void VS_R_CastLightAtSurface vsound_t light,
lightvolume_t volume
 

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:

void VS_R_FloodLight vsound_t light,
lightvolume_t volume,
int  cluster,
int  firstportal
 

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:

void VS_R_LinkSurface int  nodenum,
int  surfaceNum,
winding_t w
 

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:

int VS_R_SplitLightVolume vsound_t light,
lightvolume_t volume,
plane_t split,
int  cluster,
int  firstportal
 

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:

void VS_R_SubdivideAreaSpotLight vsound_t light,
int  nodenum,
winding_t w
 

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:

void VS_R_SubdivideDirectedAreaLight vsound_t light,
int  nodenum,
winding_t w
 

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:

void VS_R_SubdivideRadialAreaLight vsound_t light,
int  nodenum,
winding_t w
 

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:

float VS_R_WindingAreaOutsideSolid winding_t w,
vec3_t  normal,
int  nodenum
 

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:

void VS_Radiosity void   ) 
 

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:

void VS_SetPortalSphere lportal_t p  ) 
 

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:

void VS_ShiftPatchLightmaps void   ) 
 

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:

void VS_SmoothenLightmapEdges void   ) 
 

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:

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

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:

int VS_SplitLightVolume lightvolume_t volume,
lightvolume_t back,
plane_t split,
float  epsilon
 

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:

int VS_SplitWinding winding_t in,
winding_t back,
plane_t split,
float  epsilon
 

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:

void VS_StoreLightmap void   ) 
 

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:

void VS_SubdivideAreaLight shaderInfo_t ls,
winding_t w,
vec3_t  normal,
float  areaSubdivide,
qboolean  backsplash
 

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:

void VS_SurfaceRadiosity int  num  ) 
 

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:

void VS_TestLightLeafs void   ) 
 

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:

void VS_TextureMatrixFromPoints lFacet_t f,
drawVert_t a,
drawVert_t b,
drawVert_t c
 

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:

float VS_WindingAreaOutsideBrushes winding_t w,
int *  brushnums,
int  numbrushes
 

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:

float VS_WindingAreaOutsideSolid winding_t w,
vec3_t  normal
 

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:

winding_t* VS_WindingForBrushSide dbrush_t brush,
int  side,
winding_t w
 

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:

int VSoundMain int  argc,
char **  argv
 

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:

vec_t WindingArea winding_t w  ) 
 

Definition at line 190 of file l_poly.c.

References CrossProduct(), i, winding_t::numpoints, winding_t::p, vec3_t, vec_t, VectorLength(), VectorSubtract, and w.

Referenced by AAS_RemoveTinyFaces(), BrushVolume(), CheckWinding(), HL_FaceOnWinding(), Q1_FaceOnWinding(), Q2_FaceOnWinding(), Q2_FixTextureReferences(), Q3_FaceOnWinding(), Q3_FindVisibleBrushSides(), Sin_FaceOnWinding(), Sin_FixTextureReferences(), SubdivideAreaLight(), VL_CalcVisibleLightmapPixelArea(), VL_ChopWindingWithFacet(), VL_LightSurfaceWithVolume(), VL_SubdivideAreaLight(), VL_WindingAreaOutsideBrushes(), VS_CalcVisibleLightmapPixelArea(), VS_ChopWindingWithFacet(), VS_LightSurfaceWithVolume(), VS_SubdivideAreaLight(), VS_WindingAreaOutsideBrushes(), WindingError(), and WindingIsTiny().

00191 {
00192     int     i;
00193     vec3_t  d1, d2, cross;
00194     vec_t   total;
00195 
00196     total = 0;
00197     for (i=2 ; i<w->numpoints ; i++)
00198     {
00199         VectorSubtract (w->p[i-1], w->p[0], d1);
00200         VectorSubtract (w->p[i], w->p[0], d2);
00201         CrossProduct (d1, d2, cross);
00202         total += 0.5 * VectorLength ( cross );
00203     }
00204     return total;
00205 }

Here is the call graph for this function:

void WindingBounds winding_t w,
vec3_t  mins,
vec3_t  maxs
 

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 }

void WindingCenter winding_t w,
vec3_t  center
 

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 }


Variable Documentation

int clustersurfaces[MAX_MAP_LEAFFACES] [static]
 

Definition at line 218 of file soundv.c.

int defaulttracelight = 0 [static]
 

Definition at line 214 of file soundv.c.

int entitySurface[MAX_MAP_DRAW_SURFS]
 

Definition at line 42 of file tr_main.c.

vec3_t gridSize
 

Definition at line 1478 of file light.c.

Referenced by LightMain(), SetupGrid(), TraceGrid(), VLightMain(), and VSoundMain().

lleaf_t* leafs [static]
 

Definition at line 206 of file soundv.c.

vec3_t lightAmbientColor [static]
 

Definition at line 203 of file soundv.c.

float lightAreaScale = 0.25 [static]
 

Definition at line 200 of file soundv.c.

int lightDefaultSubdivide = 999 [static]
 

Definition at line 202 of file soundv.c.

float* lightFloats [static]
 

Definition at line 223 of file soundv.c.

float lightFormFactorValueScale = 3 [static]
 

Definition at line 201 of file soundv.c.

float lightLinearScale = 1.0 / 8000 [static]
 

Definition at line 198 of file soundv.c.

float lightmappixelarea[MAX_MAP_LIGHTING/3] [static]
 

Definition at line 222 of file soundv.c.

float lightPointScale = 7500 [static]
 

Definition at line 199 of file soundv.c.

lsurfaceTest_t* lsurfaceTest[MAX_MAP_DRAW_SURFS] [static]
 

Definition at line 220 of file soundv.c.

int noalphashading = 0 [static]
 

Definition at line 211 of file soundv.c.

int nobackfaceculling = 0 [static]
 

Definition at line 213 of file soundv.c.

int nocolorshading = 0 [static]
 

Definition at line 212 of file soundv.c.

int nostitching = 0 [static]
 

Definition at line 210 of file soundv.c.

int numclustersurfaces = 0 [static]
 

Definition at line 219 of file soundv.c.

int numfaces [static]
 

Definition at line 205 of file soundv.c.

int numfacets [static]
 

Definition at line 221 of file soundv.c.

int numportals [static]
 

Definition at line 205 of file soundv.c.

int numvolumes = 0 [static]
 

Definition at line 3928 of file soundv.c.

int numvsounds = 0 [static]
 

Definition at line 208 of file soundv.c.

Referenced by VS_CreateEntitySpeakers(), VS_CreateFakeSurfaceLights(), VS_CreateSkyLights(), VS_LightWorld(), VS_SubdivideAreaLight(), and VSoundMain().

float* oldLightFloats
 

Definition at line 4834 of file soundv.c.

qboolean patchshadows
 

Definition at line 50 of file light.c.

Referenced by LightMain().

int portalclusters [static]
 

Definition at line 205 of file soundv.c.

lportal_t* portals [static]
 

Definition at line 207 of file soundv.c.

int radiosity = 0 [static]
 

Definition at line 215 of file soundv.c.

int radiosity_scale [static]
 

Definition at line 216 of file soundv.c.

int samplesize
 

Definition at line 58 of file light.c.

Referenced by LightMain(), main(), VLightMain(), and VSoundMain().

char source[1024]
 

Definition at line 49 of file bspc.c.

vec3_t surfaceOrigin[MAX_MAP_DRAW_SURFS]
 

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().

vsound_t* vsounds[MAX_LIGHTS] [static]
 

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().


Generated on Thu Aug 25 17:11:18 2005 for Quake III Arena by  doxygen 1.3.9.1