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