From f49639c6978a37745e55c8da69ea96ab41abb097 Mon Sep 17 00:00:00 2001 From: Garux Date: Tue, 3 Aug 2021 04:12:34 +0300 Subject: [PATCH] std::list lights --- tools/quake3/common/polylib.cpp | 9 ++ tools/quake3/common/polylib.h | 1 + tools/quake3/q3map2/light.cpp | 204 ++++++++++++--------------- tools/quake3/q3map2/light_bounce.cpp | 177 ++++++++++------------- tools/quake3/q3map2/light_ydnar.cpp | 75 +++------- tools/quake3/q3map2/q3map2.h | 16 +-- 6 files changed, 206 insertions(+), 276 deletions(-) diff --git a/tools/quake3/common/polylib.cpp b/tools/quake3/common/polylib.cpp index fdbbf4f1..1719571f 100644 --- a/tools/quake3/common/polylib.cpp +++ b/tools/quake3/common/polylib.cpp @@ -49,6 +49,15 @@ winding_t *AllocWinding( int points ){ return w; } +winding_t AllocWinding_( int points ){ + if ( points >= MAX_POINTS_ON_WINDING ) { + Error( "AllocWinding failed: MAX_POINTS_ON_WINDING exceeded" ); + } + winding_t w; + w.reserve( points ); + return w; +} + /* ============= FreeWinding diff --git a/tools/quake3/common/polylib.h b/tools/quake3/common/polylib.h index 30615fd9..ae1526be 100644 --- a/tools/quake3/common/polylib.h +++ b/tools/quake3/common/polylib.h @@ -41,6 +41,7 @@ enum EPlaneSide }; winding_t *AllocWinding( int points ); +winding_t AllocWinding_( int points ); float WindingArea( const winding_t& w ); Vector3 WindingCenter( const winding_t& w ); void ClipWindingEpsilon( const winding_t& in, const Plane3f& plane, diff --git a/tools/quake3/q3map2/light.cpp b/tools/quake3/q3map2/light.cpp index 3471e12e..04cf3e08 100644 --- a/tools/quake3/q3map2/light.cpp +++ b/tools/quake3/q3map2/light.cpp @@ -42,7 +42,6 @@ static void CreateSunLight( sun_t *sun ){ int i; float photons, d, angle, elevation, da, de; Vector3 direction; - light_t *light; /* dummy check */ @@ -98,28 +97,26 @@ static void CreateSunLight( sun_t *sun ){ /* create a light */ numSunLights++; - light = safe_calloc( sizeof( *light ) ); - light->next = lights; - lights = light; + light_t& light = lights.emplace_front(); /* initialize the light */ - light->flags = LightFlags::DefaultSun; - light->type = ELightType::Sun; - light->fade = 1.0f; - light->falloffTolerance = falloffTolerance; - light->filterRadius = sun->filterRadius / sun->numSamples; - light->style = noStyles ? LS_NORMAL : sun->style; + light.flags = LightFlags::DefaultSun; + light.type = ELightType::Sun; + light.fade = 1.0f; + light.falloffTolerance = falloffTolerance; + light.filterRadius = sun->filterRadius / sun->numSamples; + light.style = noStyles ? LS_NORMAL : sun->style; /* set the light's position out to infinity */ - light->origin = direction * ( MAX_WORLD_COORD * 8.0f ); /* MAX_WORLD_COORD * 2.0f */ + light.origin = direction * ( MAX_WORLD_COORD * 8.0f ); /* MAX_WORLD_COORD * 2.0f */ /* set the facing to be the inverse of the sun direction */ - light->normal = -direction; - light->dist = vector3_dot( light->origin, light->normal ); + light.normal = -direction; + light.dist = vector3_dot( light.origin, light.normal ); /* set color and photons */ - light->color = sun->color; - light->photons = photons * skyScale; + light.color = sun->color; + light.photons = photons * skyScale; } /* another sun? */ @@ -203,22 +200,17 @@ static void CreateSkyLights( const Vector3& color, float value, int iterations, */ void CreateEntityLights( void ){ - int j; - light_t *light, *light2; - const entity_t *e, *e2; - - /* go through entity list and find lights */ for ( std::size_t i = 0; i < entities.size(); ++i ) { /* get entity */ - e = &entities[ i ]; + const entity_t& e = entities[ i ]; /* ydnar: check for lightJunior */ bool junior; - if ( e->classname_is( "lightJunior" ) ) { + if ( e.classname_is( "lightJunior" ) ) { junior = true; } - else if ( e->classname_prefixed( "light" ) ) { + else if ( e.classname_prefixed( "light" ) ) { junior = false; } else{ @@ -226,18 +218,16 @@ void CreateEntityLights( void ){ } /* lights with target names (and therefore styles) are only parsed from BSP */ - if ( !strEmpty( e->valueForKey( "targetname" ) ) && i >= numBSPEntities ) { + if ( !strEmpty( e.valueForKey( "targetname" ) ) && i >= numBSPEntities ) { continue; } /* create a light */ numPointLights++; - light = safe_calloc( sizeof( *light ) ); - light->next = lights; - lights = light; + light_t& light = lights.emplace_front(); /* handle spawnflags */ - const int spawnflags = e->intForKey( "spawnflags" ); + const int spawnflags = e.intForKey( "spawnflags" ); LightFlags flags; /* ydnar: quake 3+ light behavior */ @@ -304,88 +294,88 @@ void CreateEntityLights( void ){ } /* store the flags */ - light->flags = flags; + light.flags = flags; /* ydnar: set fade key (from wolf) */ - light->fade = 1.0f; - if ( light->flags & LightFlags::AttenLinear ) { - light->fade = e->floatForKey( "fade" ); - if ( light->fade == 0.0f ) { - light->fade = 1.0f; + light.fade = 1.0f; + if ( light.flags & LightFlags::AttenLinear ) { + light.fade = e.floatForKey( "fade" ); + if ( light.fade == 0.0f ) { + light.fade = 1.0f; } } /* ydnar: set angle scaling (from vlight) */ - light->angleScale = e->floatForKey( "_anglescale" ); - if ( light->angleScale != 0.0f ) { - light->flags |= LightFlags::AttenAngle; + light.angleScale = e.floatForKey( "_anglescale" ); + if ( light.angleScale != 0.0f ) { + light.flags |= LightFlags::AttenAngle; } /* set origin */ - light->origin = e->vectorForKey( "origin" ); - e->read_keyvalue( light->style, "_style", "style" ); - if ( light->style < LS_NORMAL || light->style >= LS_NONE ) { - Error( "Invalid lightstyle (%d) on entity %zu", light->style, i ); + light.origin = e.vectorForKey( "origin" ); + e.read_keyvalue( light.style, "_style", "style" ); + if ( light.style < LS_NORMAL || light.style >= LS_NONE ) { + Error( "Invalid lightstyle (%d) on entity %zu", light.style, i ); } /* set light intensity */ float intensity = 300.f; - e->read_keyvalue( intensity, "_light", "light" ); + e.read_keyvalue( intensity, "_light", "light" ); if ( intensity == 0.0f ) { intensity = 300.0f; } { /* ydnar: set light scale (sof2) */ float scale; - if( e->read_keyvalue( scale, "scale" ) && scale != 0.f ) + if( e.read_keyvalue( scale, "scale" ) && scale != 0.f ) intensity *= scale; } /* ydnar: get deviance and samples */ - const float deviance = std::max( 0.f, e->floatForKey( "_deviance", "_deviation", "_jitter" ) ); - const int numSamples = std::max( 1, e->intForKey( "_samples" ) ); + const float deviance = std::max( 0.f, e.floatForKey( "_deviance", "_deviation", "_jitter" ) ); + const int numSamples = std::max( 1, e.intForKey( "_samples" ) ); intensity /= numSamples; { /* ydnar: get filter radius */ - light->filterRadius = std::max( 0.f, e->floatForKey( "_filterradius", "_filteradius", "_filter" ) ); + light.filterRadius = std::max( 0.f, e.floatForKey( "_filterradius", "_filteradius", "_filter" ) ); } /* set light color */ - if ( e->read_keyvalue( light->color, "_color" ) ) { + if ( e.read_keyvalue( light.color, "_color" ) ) { if ( colorsRGB ) { - light->color[0] = Image_LinearFloatFromsRGBFloat( light->color[0] ); - light->color[1] = Image_LinearFloatFromsRGBFloat( light->color[1] ); - light->color[2] = Image_LinearFloatFromsRGBFloat( light->color[2] ); + light.color[0] = Image_LinearFloatFromsRGBFloat( light.color[0] ); + light.color[1] = Image_LinearFloatFromsRGBFloat( light.color[1] ); + light.color[2] = Image_LinearFloatFromsRGBFloat( light.color[2] ); } - if ( !( light->flags & LightFlags::Unnormalized ) ) { - ColorNormalize( light->color ); + if ( !( light.flags & LightFlags::Unnormalized ) ) { + ColorNormalize( light.color ); } } else{ - light->color.set( 1 ); + light.color.set( 1 ); } - if( !e->read_keyvalue( light->extraDist, "_extradist" ) ) - light->extraDist = extraDist; + if( !e.read_keyvalue( light.extraDist, "_extradist" ) ) + light.extraDist = extraDist; - light->photons = intensity; + light.photons = intensity; - light->type = ELightType::Point; + light.type = ELightType::Point; /* set falloff threshold */ - light->falloffTolerance = falloffTolerance / numSamples; + light.falloffTolerance = falloffTolerance / numSamples; /* lights with a target will be spotlights */ const char *target; - if ( e->read_keyvalue( target, "target" ) ) { + if ( e.read_keyvalue( target, "target" ) ) { /* get target */ - e2 = FindTargetEntity( target ); + const entity_t *e2 = FindTargetEntity( target ); if ( e2 == NULL ) { Sys_Warning( "light at (%i %i %i) has missing target\n", - (int) light->origin[ 0 ], (int) light->origin[ 1 ], (int) light->origin[ 2 ] ); - light->photons *= pointScale; + (int) light.origin[ 0 ], (int) light.origin[ 1 ], (int) light.origin[ 2 ] ); + light.photons *= pointScale; } else { @@ -394,72 +384,65 @@ void CreateEntityLights( void ){ numSpotLights++; /* make a spotlight */ - light->normal = e2->vectorForKey( "origin" ) - light->origin; - float dist = VectorNormalize( light->normal ); - float radius = e->floatForKey( "radius" ); + light.normal = e2->vectorForKey( "origin" ) - light.origin; + float dist = VectorNormalize( light.normal ); + float radius = e.floatForKey( "radius" ); if ( !radius ) { radius = 64; } if ( !dist ) { dist = 64; } - light->radiusByDist = ( radius + 16 ) / dist; - light->type = ELightType::Spot; + light.radiusByDist = ( radius + 16 ) / dist; + light.type = ELightType::Spot; /* ydnar: wolf mods: spotlights always use nonlinear + angle attenuation */ - light->flags &= ~LightFlags::AttenLinear; - light->flags |= LightFlags::AttenAngle; - light->fade = 1.0f; + light.flags &= ~LightFlags::AttenLinear; + light.flags |= LightFlags::AttenAngle; + light.fade = 1.0f; /* ydnar: is this a sun? */ - if ( e->boolForKey( "_sun" ) ) { + if ( e.boolForKey( "_sun" ) ) { /* not a spot light */ numSpotLights--; - /* unlink this light */ - lights = light->next; - /* make a sun */ sun_t sun; - sun.direction = -light->normal; - sun.color = light->color; + sun.direction = -light.normal; + sun.color = light.color; sun.photons = intensity; sun.deviance = degrees_to_radians( deviance ); sun.numSamples = numSamples; - sun.style = noStyles ? LS_NORMAL : light->style; + sun.style = noStyles ? LS_NORMAL : light.style; sun.next = NULL; + /* free original light before sun insertion */ + lights.pop_front(); + /* make a sun light */ CreateSunLight( &sun ); - /* free original light */ - free( light ); - light = NULL; - /* skip the rest of this love story */ continue; } else { - light->photons *= spotScale; + light.photons *= spotScale; } } } else{ - light->photons *= pointScale; + light.photons *= pointScale; } /* jitter the light */ - for ( j = 1; j < numSamples; j++ ) + for ( int j = 1; j < numSamples; j++ ) { /* create a light */ - light2 = safe_malloc( sizeof( *light ) ); - memcpy( light2, light, sizeof( *light ) ); - light2->next = lights; - lights = light2; + light_t& light2 = lights.emplace_front( light ); /* add to counts */ - if ( light->type == ELightType::Spot ) { + if ( light.type == ELightType::Spot ) { numSpotLights++; } else{ @@ -467,9 +450,9 @@ void CreateEntityLights( void ){ } /* jitter it */ - light2->origin[ 0 ] = light->origin[ 0 ] + ( Random() * 2.0f - 1.0f ) * deviance; - light2->origin[ 1 ] = light->origin[ 1 ] + ( Random() * 2.0f - 1.0f ) * deviance; - light2->origin[ 2 ] = light->origin[ 2 ] + ( Random() * 2.0f - 1.0f ) * deviance; + light2.origin[ 0 ] = light.origin[ 0 ] + ( Random() * 2.0f - 1.0f ) * deviance; + light2.origin[ 1 ] = light.origin[ 1 ] + ( Random() * 2.0f - 1.0f ) * deviance; + light2.origin[ 2 ] = light.origin[ 2 ] + ( Random() * 2.0f - 1.0f ) * deviance; } } } @@ -488,7 +471,6 @@ void CreateSurfaceLights( void ){ bspDrawSurface_t *ds; surfaceInfo_t *info; shaderInfo_t *si; - light_t *light; float subdivide; clipWork_t cw; @@ -526,20 +508,18 @@ void CreateSurfaceLights( void ){ /* autosprite shaders become point lights */ if ( si->autosprite ) { /* create a light */ - light = safe_calloc( sizeof( *light ) ); - light->next = lights; - lights = light; + light_t& light = lights.emplace_front(); /* set it up */ - light->flags = LightFlags::DefaultQ3A; - light->type = ELightType::Point; - light->photons = si->value * pointScale; - light->fade = 1.0f; - light->si = si; - light->origin = info->minmax.origin(); - light->color = si->color; - light->falloffTolerance = falloffTolerance; - light->style = si->lightStyle; + light.flags = LightFlags::DefaultQ3A; + light.type = ELightType::Point; + light.photons = si->value * pointScale; + light.fade = 1.0f; + light.si = si; + light.origin = info->minmax.origin(); + light.color = si->color; + light.falloffTolerance = falloffTolerance; + light.style = si->lightStyle; /* add to point light count and continue */ numPointLights++; @@ -693,7 +673,6 @@ float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, con */ int LightContributionToSample( trace_t *trace ){ - light_t *light; float angle; float add; float dist; @@ -703,7 +682,7 @@ int LightContributionToSample( trace_t *trace ){ bool doAddDeluxe = true; /* get light */ - light = trace->light; + const light_t *light = trace->light; /* clear color */ trace->forceSubsampling = 0.0f; /* to make sure */ @@ -811,7 +790,7 @@ int LightContributionToSample( trace_t *trace ){ else { /* calculate the contribution */ - factor = PointToPolygonFormFactor( pushedOrigin, trace->normal, *light->w ); + factor = PointToPolygonFormFactor( pushedOrigin, trace->normal, light->w ); if ( factor == 0.0f ) { return 0; } @@ -1176,12 +1155,10 @@ void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&c */ bool LightContributionToPoint( trace_t *trace ){ - light_t *light; float add, dist; - /* get light */ - light = trace->light; + const light_t *light = trace->light; /* clear color */ trace->color.set( 0 ); @@ -1258,7 +1235,7 @@ bool LightContributionToPoint( trace_t *trace ){ } /* calculate the contribution (ydnar 2002-10-21: [bug 642] bad normal calc) */ - factor = PointToPolygonFormFactor( pushedOrigin, trace->direction, *light->w ); + factor = PointToPolygonFormFactor( pushedOrigin, trace->direction, light->w ); if ( factor == 0.0f ) { return false; } @@ -1447,8 +1424,9 @@ void TraceGrid( int num ){ /* trace to all the lights, find the major light direction, and divide the total light between that along the direction and the remaining in the ambient */ - for ( trace.light = lights; trace.light != NULL; trace.light = trace.light->next ) + for ( const light_t& light : lights ) { + trace.light = &light; float addSize; diff --git a/tools/quake3/q3map2/light_bounce.cpp b/tools/quake3/q3map2/light_bounce.cpp index d143258a..5c9f37a9 100644 --- a/tools/quake3/q3map2/light_bounce.cpp +++ b/tools/quake3/q3map2/light_bounce.cpp @@ -41,20 +41,8 @@ */ void RadFreeLights( void ){ - light_t *light, *next; - - - /* delete lights */ - for ( light = lights; light; light = next ) - { - next = light->next; - if ( light->w != NULL ) { - FreeWinding( light->w ); - } - free( light ); - } + lights.clear(); numLights = 0; - lights = NULL; } @@ -388,8 +376,6 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw int i, style = 0; float dist, area, value; Vector3 normal, color, gradient; - light_t *light, *splash; - winding_t *w; /* dummy check */ @@ -445,12 +431,10 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw } } - /* create a regular winding and an average normal */ - w = AllocWinding( rw->numVerts ); + /* create an average normal */ normal.set( 0 ); for ( i = 0; i < rw->numVerts; i++ ) { - w->push_back( rw->verts[ i ].xyz ); normal += rw->verts[ i ].normal; } normal /= rw->numVerts; @@ -484,24 +468,26 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw break; } - /* create a light */ - light = safe_calloc( sizeof( *light ) ); - /* attach it */ + /* create a light */ ThreadLock(); - light->next = lights; - lights = light; + light_t& light = lights.emplace_front(); ThreadUnlock(); /* initialize the light */ - light->flags = LightFlags::DefaultArea; - light->type = ELightType::Area; - light->si = si; - light->fade = 1.0f; - light->w = w; + light.flags = LightFlags::DefaultArea; + light.type = ELightType::Area; + light.si = si; + light.fade = 1.0f; + /* create a regular winding */ + light.w = AllocWinding_( rw->numVerts ); + for ( i = 0; i < rw->numVerts; i++ ) + { + light.w.push_back( rw->verts[ i ].xyz ); + } /* set falloff threshold */ - light->falloffTolerance = falloffTolerance; + light.falloffTolerance = falloffTolerance; /* bouncing light? */ if ( !bouncing ) { @@ -510,45 +496,40 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw /* handle first-pass lights in normal q3a style */ value = si->value; - light->photons = value * area * areaScale; - light->add = value * formFactorValueScale * areaScale; - light->color = si->color; - light->style = noStyles ? LS_NORMAL : si->lightStyle; - if ( light->style < LS_NORMAL || light->style >= LS_NONE ) { - light->style = LS_NORMAL; + light.photons = value * area * areaScale; + light.add = value * formFactorValueScale * areaScale; + light.color = si->color; + light.style = noStyles ? LS_NORMAL : si->lightStyle; + if ( light.style < LS_NORMAL || light.style >= LS_NONE ) { + light.style = LS_NORMAL; } /* set origin */ - light->origin = minmax.origin(); + light.origin = minmax.origin(); /* nudge it off the plane a bit */ - light->normal = normal; - light->origin += light->normal; - light->dist = vector3_dot( light->origin, normal ); + light.normal = normal; + light.origin += light.normal; + light.dist = vector3_dot( light.origin, normal ); #if 0 /* optionally create a point backsplash light */ if ( si->backsplashFraction > 0 ) { - /* allocate a new point light */ - splash = safe_calloc( sizeof( *splash ) ); - - splash->next = lights; - lights = splash; - + light_t& splash = lights.emplace_front(); /* set it up */ - splash->flags = LightFlags::DefaultQ3A; - splash->type = ELightType::Point; - splash->photons = light->photons * si->backsplashFraction; + splash.flags = LightFlags::DefaultQ3A; + splash.type = ELightType::Point; + splash.photons = light.photons * si->backsplashFraction; - splash->fade = 1.0f; - splash->si = si; - splash->origin = normal * si->backsplashDistance + light->origin; - splash->color = si->color; + splash.fade = 1.0f; + splash.si = si; + splash.origin = normal * si->backsplashDistance + light.origin; + splash.color = si->color; - splash->falloffTolerance = falloffTolerance; - splash->style = noStyles ? LS_NORMAL : light->style; + splash.falloffTolerance = falloffTolerance; + splash.style = noStyles ? LS_NORMAL : light.style; /* add to counts */ numPointLights++; @@ -560,36 +541,34 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw //if ( original && si->backsplashFraction > 0 ) { if ( si->backsplashFraction > 0 && !( si->compileFlags & C_SKY ) ) { /* allocate a new area light */ - splash = safe_calloc( sizeof( *splash ) ); ThreadLock(); - splash->next = lights; - lights = splash; + light_t& splash = lights.emplace_front(); ThreadUnlock(); /* set it up */ - splash->flags = LightFlags::DefaultArea; - splash->type = ELightType::Area; - splash->photons = light->photons * 7.0f * si->backsplashFraction; - splash->add = light->add * 7.0f * si->backsplashFraction; - splash->fade = 1.0f; - splash->si = si; - splash->color = si->color; - splash->falloffTolerance = falloffTolerance; - splash->style = noStyles ? LS_NORMAL : si->lightStyle; - if ( splash->style < LS_NORMAL || splash->style >= LS_NONE ) { - splash->style = LS_NORMAL; + splash.flags = LightFlags::DefaultArea; + splash.type = ELightType::Area; + splash.photons = light.photons * 7.0f * si->backsplashFraction; + splash.add = light.add * 7.0f * si->backsplashFraction; + splash.fade = 1.0f; + splash.si = si; + splash.color = si->color; + splash.falloffTolerance = falloffTolerance; + splash.style = noStyles ? LS_NORMAL : si->lightStyle; + if ( splash.style < LS_NORMAL || splash.style >= LS_NONE ) { + splash.style = LS_NORMAL; } /* create a regular winding */ - splash->w = AllocWinding( rw->numVerts ); + splash.w = AllocWinding_( rw->numVerts ); for ( i = 0; i < rw->numVerts; i++ ) - splash->w->push_back( rw->verts[rw->numVerts - 1 - i].xyz + normal * si->backsplashDistance ); + splash.w.push_back( rw->verts[rw->numVerts - 1 - i].xyz + normal * si->backsplashDistance ); - splash->origin = normal * si->backsplashDistance + light->origin; - splash->normal = -normal; - splash->dist = vector3_dot( splash->origin, splash->normal ); + splash.origin = normal * si->backsplashDistance + light.origin; + splash.normal = -normal; + splash.dist = vector3_dot( splash.origin, splash.normal ); -// splash->flags |= LightFlags::Twosided; +// splash.flags |= LightFlags::Twosided; } #endif @@ -598,35 +577,35 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw { /* handle bounced light (radiosity) a little differently */ value = RADIOSITY_VALUE * si->bounceScale * 0.375f; - light->photons = value * area * bounceScale; - light->add = value * formFactorValueScale * bounceScale; - light->color = color; - light->style = noStyles ? LS_NORMAL : style; - if ( light->style < LS_NORMAL || light->style >= LS_NONE ) { - light->style = LS_NORMAL; + light.photons = value * area * bounceScale; + light.add = value * formFactorValueScale * bounceScale; + light.color = color; + light.style = noStyles ? LS_NORMAL : style; + if ( light.style < LS_NORMAL || light.style >= LS_NONE ) { + light.style = LS_NORMAL; } /* set origin */ - light->origin = WindingCenter( *w ); + light.origin = WindingCenter( light.w ); /* nudge it off the plane a bit */ - light->normal = normal; - light->origin += light->normal; - light->dist = vector3_dot( light->origin, normal ); + light.normal = normal; + light.origin += light.normal; + light.dist = vector3_dot( light.origin, normal ); } - if (light->photons < 0 || light->add < 0 || light->color[0] < 0 || light->color[1] < 0 || light->color[2] < 0) + if (light.photons < 0 || light.add < 0 || light.color[0] < 0 || light.color[1] < 0 || light.color[2] < 0) Sys_Printf( "BUG: RadSubdivideDiffuseLight created a darkbulb\n" ); /* emit light from both sides? */ if ( si->compileFlags & C_FOG || si->twoSided ) { - light->flags |= LightFlags::Twosided; + light.flags |= LightFlags::Twosided; } //% Sys_Printf( "\nAL: C: (%6f, %6f, %6f) [%6f] N: (%6f, %6f, %6f) %s\n", - //% light->color[ 0 ], light->color[ 1 ], light->color[ 2 ], light->add, - //% light->normal[ 0 ], light->normal[ 1 ], light->normal[ 2 ], - //% light->si->shader ); + //% light.color[ 0 ], light.color[ 1 ], light.color[ 2 ], light.add, + //% light.normal[ 0 ], light.normal[ 1 ], light.normal[ 2 ], + //% light.si->shader ); } @@ -907,16 +886,14 @@ void RadCreateDiffuseLights( void ){ /* dump the lights generated to a file */ if ( dump ) { char dumpName[ 1024 ], ext[ 64 ]; - FILE *file; - light_t *light; strcpy( dumpName, source ); sprintf( ext, "_bounce_%03d.map", iterations ); path_set_extension( dumpName, ext ); - file = fopen( dumpName, "wb" ); + FILE *file = fopen( dumpName, "wb" ); Sys_Printf( "Writing %s...\n", dumpName ); if ( file ) { - for ( light = lights; light; light = light->next ) + for ( const light_t& light : lights ) { fprintf( file, "{\n" @@ -926,15 +903,15 @@ void RadCreateDiffuseLights( void ){ "\"_color\" \"%.3f %.3f %.3f\"\n" "}\n", - (int) light->add, + (int) light.add, - light->origin[ 0 ], - light->origin[ 1 ], - light->origin[ 2 ], + light.origin[ 0 ], + light.origin[ 1 ], + light.origin[ 2 ], - light->color[ 0 ], - light->color[ 1 ], - light->color[ 2 ] ); + light.color[ 0 ], + light.color[ 1 ], + light.color[ 2 ] ); } fclose( file ); } diff --git a/tools/quake3/q3map2/light_ydnar.cpp b/tools/quake3/q3map2/light_ydnar.cpp index 9303300b..dccb8eae 100644 --- a/tools/quake3/q3map2/light_ydnar.cpp +++ b/tools/quake3/q3map2/light_ydnar.cpp @@ -3326,14 +3326,12 @@ bool ChopBounds( MinMax& minmax, const Vector3& origin, const Vector3& normal ){ void SetupEnvelopes( bool forGrid, bool fastFlag ){ int i, x, y, z, x1, y1, z1; - light_t *light, *light2, **owner; bspLeaf_t *leaf; float radius, intensity; - light_t *buckets[ 256 ]; /* early out for weird cases where there are no lights */ - if ( lights == NULL ) { + if ( lights.empty() ) { return; } @@ -3343,12 +3341,8 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ /* count lights */ numLights = 0; numCulledLights = 0; - owner = &lights; - while ( *owner != NULL ) + for( decltype( lights )::iterator light = lights.begin(); light != lights.end(); ) { - /* get light */ - light = *owner; - /* handle negative lights */ if ( light->photons < 0.0f || light->add < 0.0f ) { light->photons *= -1.0f; @@ -3423,7 +3417,7 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ light->envelope = 0; /* handle area lights */ - if ( exactPointToPolygon && light->type == ELightType::Area && light->w != NULL ) { + if ( exactPointToPolygon && light->type == ELightType::Area && !light->w.empty() ) { light->envelope = MAX_WORLD_COORD * 8.0f; /* check for fast mode */ @@ -3433,7 +3427,7 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ for ( radius = 100.0f; radius < MAX_WORLD_COORD * 8.0f; radius += 10.0f ) { const Vector3 origin = light->origin + light->normal * radius; - const float factor = std::abs( PointToPolygonFormFactor( origin, dir, *light->w ) ); + const float factor = std::abs( PointToPolygonFormFactor( origin, dir, light->w ) ); if ( ( factor * light->add ) <= light->falloffTolerance ) { light->envelope = radius; break; @@ -3572,9 +3566,7 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ /* delete the light */ numCulledLights++; - *owner = light->next; - FreeWinding( light->w ); - free( light ); + light = lights.erase( light ); continue; } } @@ -3586,38 +3578,14 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ numLights++; /* set next light */ - owner = &( ( **owner ).next ); + ++light; } - /* bucket sort lights by style */ - memset( buckets, 0, sizeof( buckets ) ); - light2 = NULL; - for ( light = lights; light != NULL; light = light2 ) - { - /* get next light */ - light2 = light->next; - - /* filter into correct bucket */ - light->next = buckets[ light->style ]; - buckets[ light->style ] = light; - - /* if any styled light is present, automatically set nocollapse */ - if ( light->style != LS_NORMAL ) { - noCollapse = true; - } - } - - /* filter back into light list */ - lights = NULL; - for ( i = 255; i >= 0; i-- ) - { - light2 = NULL; - for ( light = buckets[ i ]; light != NULL; light = light2 ) - { - light2 = light->next; - light->next = lights; - lights = light; - } + /* sort lights by style */ + lights.sort( []( const light_t& a, const light_t& b ){ return a.style < b.style; } ); + /* if any styled light is present, automatically set nocollapse */ + if ( !lights.empty() && lights.back().style != LS_NORMAL ) { + noCollapse = true; } /* emit some statistics */ @@ -3634,7 +3602,6 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){ void CreateTraceLightsForBounds( const MinMax& minmax, const Vector3 *normal, int numClusters, int *clusters, LightFlags flags, trace_t *trace ){ int i; - light_t *light; float length; @@ -3666,21 +3633,21 @@ void CreateTraceLightsForBounds( const MinMax& minmax, const Vector3 *normal, in /* test each light and see if it reaches the sphere */ /* note: the attenuation code MUST match LightingAtSample() */ - for ( light = lights; light; light = light->next ) + for ( const light_t& light : lights ) { /* check zero sized envelope */ - if ( light->envelope <= 0 ) { + if ( light.envelope <= 0 ) { lightsEnvelopeCulled++; continue; } /* check flags */ - if ( !( light->flags & flags ) ) { + if ( !( light.flags & flags ) ) { continue; } /* sunlight skips all this nonsense */ - if ( light->type != ELightType::Sun ) { + if ( light.type != ELightType::Sun ) { /* sun only? */ if ( sunOnly ) { continue; @@ -3690,7 +3657,7 @@ void CreateTraceLightsForBounds( const MinMax& minmax, const Vector3 *normal, in if ( numClusters > 0 && clusters != NULL ) { for ( i = 0; i < numClusters; i++ ) { - if ( ClusterVisible( light->cluster, clusters[ i ] ) ) { + if ( ClusterVisible( light.cluster, clusters[ i ] ) ) { break; } } @@ -3703,14 +3670,14 @@ void CreateTraceLightsForBounds( const MinMax& minmax, const Vector3 *normal, in } /* if the light's bounding sphere intersects with the bounding sphere then this light needs to be tested */ - if ( vector3_length( light->origin - origin ) - light->envelope - radius > 0 ) { + if ( vector3_length( light.origin - origin ) - light.envelope - radius > 0 ) { lightsEnvelopeCulled++; continue; } /* check bounding box against light's pvs envelope (note: this code never eliminated any lights, so disabling it) */ #if 0 - if( !minmax.test( light->minmax ) ){ + if( !minmax.test( light.minmax ) ){ lightsBoundsCulled++; continue; } @@ -3720,20 +3687,20 @@ void CreateTraceLightsForBounds( const MinMax& minmax, const Vector3 *normal, in /* planar surfaces (except twosided surfaces) have a couple more checks */ if ( length > 0.0f && !trace->twoSided ) { /* lights coplanar with a surface won't light it */ - if ( !( light->flags & LightFlags::Twosided ) && vector3_dot( light->normal, *normal ) > 0.999f ) { + if ( !( light.flags & LightFlags::Twosided ) && vector3_dot( light.normal, *normal ) > 0.999f ) { lightsPlaneCulled++; continue; } /* check to see if light is behind the plane */ - if ( vector3_dot( light->origin, *normal ) - vector3_dot( origin, *normal ) < -1.0f ) { + if ( vector3_dot( light.origin, *normal ) - vector3_dot( origin, *normal ) < -1.0f ) { lightsPlaneCulled++; continue; } } /* add this light */ - trace->lights[ trace->numLights++ ] = light; + trace->lights[ trace->numLights++ ] = &light; } /* make last night null */ diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index d517f00e..d1cf664d 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -1241,19 +1241,17 @@ struct LightFlags : BitFlags /* ydnar: new light struct with flags */ struct light_t { - light_t *next; - ELightType type; LightFlags flags; /* ydnar: condensed all the booleans into one flags int */ shaderInfo_t *si; - Vector3 origin; - Vector3 normal; /* for surfaces, spotlights, and suns */ + Vector3 origin{ 0 }; + Vector3 normal{ 0 }; /* for surfaces, spotlights, and suns */ float dist; /* plane location along normal */ float photons; int style; - Vector3 color; + Vector3 color{ 0 }; float radiusByDist; /* for spotlights */ float fade; /* ydnar: from wolf, for linear lights */ float angleScale; /* ydnar: stolen from vlight for K */ @@ -1265,7 +1263,7 @@ struct light_t MinMax minmax; /* ydnar: pvs envelope */ int cluster; /* ydnar: cluster light falls into */ - winding_t *w; + winding_t w; float falloffTolerance; /* ydnar: minimum attenuation threshold */ float filterRadius; /* ydnar: lightmap filter radius in world units, 0 == default */ @@ -1282,7 +1280,7 @@ struct trace_t int *surfaces; int numLights; - light_t **lights; + const light_t **lights; bool twoSided; @@ -1292,7 +1290,7 @@ struct trace_t float inhibitRadius; /* sphere in which occluding geometry is ignored */ /* per-light input */ - light_t *light; + const light_t *light; Vector3 end; /* calculated input */ @@ -2327,7 +2325,7 @@ Q_EXTERN float linearScale Q_ASSIGN( 1.0f / 8000.0f ); Q_EXTERN bool shadersAsBitmap Q_ASSIGN( false ); Q_EXTERN bool lightmapsAsTexcoord Q_ASSIGN( false ); -Q_EXTERN light_t *lights; +Q_EXTERN std::list lights; Q_EXTERN int numPointLights; Q_EXTERN int numSpotLights; Q_EXTERN int numSunLights;