X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=tools%2Fquake3%2Fq3map2%2Flight.c;h=2571d4d2080cfefb656cd13b5e8e0964f4121fc8;hb=82acc9660942603b8f2eb0a70fc1e3aa2074b46f;hp=db1cc576c96d2e39e8b9baf789ebfabbd5038a34;hpb=d5d6e981910d68cc6604e15833a431ebf3fe7aac;p=xonotic%2Fnetradiant.git diff --git a/tools/quake3/q3map2/light.c b/tools/quake3/q3map2/light.c index db1cc576..2571d4d2 100644 --- a/tools/quake3/q3map2/light.c +++ b/tools/quake3/q3map2/light.c @@ -1,30 +1,30 @@ /* ------------------------------------------------------------------------------- -Copyright (C) 1999-2007 id Software, Inc. and contributors. -For a list of contributors, see the accompanying CONTRIBUTORS file. + Copyright (C) 1999-2007 id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ----------------------------------------------------------------------------------- + ---------------------------------------------------------------------------------- -This code has been altered significantly from its original form, to support -several games based on the Quake III Arena engine, in the form of "Q3Map2." + This code has been altered significantly from its original form, to support + several games based on the Quake III Arena engine, in the form of "Q3Map2." -------------------------------------------------------------------------------- */ + ------------------------------------------------------------------------------- */ @@ -39,77 +39,79 @@ several games based on the Quake III Arena engine, in the form of "Q3Map2." /* -CreateSunLight() - ydnar -this creates a sun light -*/ + CreateSunLight() - ydnar + this creates a sun light + */ + +static void CreateSunLight( sun_t *sun ){ + int i; + float photons, d, angle, elevation, da, de; + vec3_t direction; + light_t *light; + -static void CreateSunLight( sun_t *sun ) -{ - int i; - float photons, d, angle, elevation, da, de; - vec3_t direction; - light_t *light; - - /* dummy check */ - if( sun == NULL ) + if ( sun == NULL ) { return; - + } + /* fixup */ - if( sun->numSamples < 1 ) + if ( sun->numSamples < 1 ) { sun->numSamples = 1; - + } + /* set photons */ photons = sun->photons / sun->numSamples; - + /* create the right number of suns */ - for( i = 0; i < sun->numSamples; i++ ) + for ( i = 0; i < sun->numSamples; i++ ) { /* calculate sun direction */ - if( i == 0 ) + if ( i == 0 ) { VectorCopy( sun->direction, direction ); + } else { /* - sun->direction[ 0 ] = cos( angle ) * cos( elevation ); - sun->direction[ 1 ] = sin( angle ) * cos( elevation ); - sun->direction[ 2 ] = sin( elevation ); - - xz_dist = sqrt( x*x + z*z ) - latitude = atan2( xz_dist, y ) * RADIANS - longitude = atan2( x, z ) * RADIANS - */ - + sun->direction[ 0 ] = cos( angle ) * cos( elevation ); + sun->direction[ 1 ] = sin( angle ) * cos( elevation ); + sun->direction[ 2 ] = sin( elevation ); + + xz_dist = sqrt( x*x + z*z ) + latitude = atan2( xz_dist, y ) * RADIANS + longitude = atan2( x, z ) * RADIANS + */ + d = sqrt( sun->direction[ 0 ] * sun->direction[ 0 ] + sun->direction[ 1 ] * sun->direction[ 1 ] ); angle = atan2( sun->direction[ 1 ], sun->direction[ 0 ] ); elevation = atan2( sun->direction[ 2 ], d ); - + /* jitter the angles (loop to keep random sample within sun->deviance steridians) */ do { - da = (Random() * 2.0f - 1.0f) * sun->deviance; - de = (Random() * 2.0f - 1.0f) * sun->deviance; + da = ( Random() * 2.0f - 1.0f ) * sun->deviance; + de = ( Random() * 2.0f - 1.0f ) * sun->deviance; } - while( (da * da + de * de) > (sun->deviance * sun->deviance) ); + while ( ( da * da + de * de ) > ( sun->deviance * sun->deviance ) ); angle += da; elevation += de; - + /* debug code */ //% Sys_Printf( "%d: Angle: %3.4f Elevation: %3.3f\n", sun->numSamples, (angle / Q_PI * 180.0f), (elevation / Q_PI * 180.0f) ); - + /* create new vector */ direction[ 0 ] = cos( angle ) * cos( elevation ); direction[ 1 ] = sin( angle ) * cos( elevation ); direction[ 2 ] = sin( elevation ); } - + /* create a light */ numSunLights++; light = safe_malloc( sizeof( *light ) ); memset( light, 0, sizeof( *light ) ); light->next = lights; lights = light; - + /* initialize the light */ light->flags = LIGHT_SUN_DEFAULT; light->type = EMIT_SUN; @@ -117,44 +119,45 @@ static void CreateSunLight( sun_t *sun ) light->falloffTolerance = falloffTolerance; light->filterRadius = sun->filterRadius / sun->numSamples; light->style = noStyles ? LS_NORMAL : sun->style; - + /* set the light's position out to infinity */ - VectorMA( vec3_origin, (MAX_WORLD_COORD * 8.0f), direction, light->origin ); /* MAX_WORLD_COORD * 2.0f */ - + VectorMA( vec3_origin, ( MAX_WORLD_COORD * 8.0f ), direction, light->origin ); /* MAX_WORLD_COORD * 2.0f */ + /* set the facing to be the inverse of the sun direction */ VectorScale( direction, -1.0, light->normal ); light->dist = DotProduct( light->origin, light->normal ); - + /* set color and photons */ VectorCopy( sun->color, light->color ); light->photons = photons * skyScale; } /* another sun? */ - if( sun->next != NULL ) + if ( sun->next != NULL ) { CreateSunLight( sun->next ); + } } /* -CreateSkyLights() - ydnar -simulates sky light with multiple suns -*/ + CreateSkyLights() - ydnar + simulates sky light with multiple suns + */ + +static void CreateSkyLights( vec3_t color, float value, int iterations, float filterRadius, int style ){ + int i, j, numSuns; + int angleSteps, elevationSteps; + float angle, elevation; + float angleStep, elevationStep; + sun_t sun; + -static void CreateSkyLights( vec3_t color, float value, int iterations, float filterRadius, int style ) -{ - int i, j, numSuns; - int angleSteps, elevationSteps; - float angle, elevation; - float angleStep, elevationStep; - sun_t sun; - - /* dummy check */ - if( value <= 0.0f || iterations < 2 ) + if ( value <= 0.0f || iterations < 2 ) { return; - + } + /* basic sun setup */ VectorCopy( color, sun.color ); sun.deviance = 0.0f; @@ -162,45 +165,45 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi sun.numSamples = 1; sun.style = noStyles ? LS_NORMAL : style; sun.next = NULL; - + /* setup */ elevationSteps = iterations - 1; angleSteps = elevationSteps * 4; angle = 0.0f; - elevationStep = DEG2RAD( 90.0f / iterations ); /* skip elevation 0 */ + elevationStep = DEG2RAD( 90.0f / iterations ); /* skip elevation 0 */ angleStep = DEG2RAD( 360.0f / angleSteps ); - + /* calc individual sun brightness */ numSuns = angleSteps * elevationSteps + 1; sun.photons = value / numSuns; - + /* iterate elevation */ elevation = elevationStep * 0.5f; angle = 0.0f; - for( i = 0, elevation = elevationStep * 0.5f; i < elevationSteps; i++ ) + for ( i = 0, elevation = elevationStep * 0.5f; i < elevationSteps; i++ ) { /* iterate angle */ - for( j = 0; j < angleSteps; j++ ) + for ( j = 0; j < angleSteps; j++ ) { /* create sun */ sun.direction[ 0 ] = cos( angle ) * cos( elevation ); sun.direction[ 1 ] = sin( angle ) * cos( elevation ); sun.direction[ 2 ] = sin( elevation ); CreateSunLight( &sun ); - + /* move */ angle += angleStep; } - + /* move */ elevation += elevationStep; angle += angleStep / elevationSteps; } - + /* create vertical sun */ VectorSet( sun.direction, 0.0f, 0.0f, 1.0f ); CreateSunLight( &sun ); - + /* short circuit */ return; } @@ -208,227 +211,239 @@ static void CreateSkyLights( vec3_t color, float value, int iterations, float fi /* -CreateEntityLights() -creates lights from light entities -*/ + CreateEntityLights() + creates lights from light entities + */ + +void CreateEntityLights( void ){ + int i, j; + light_t *light, *light2; + entity_t *e, *e2; + const char *name; + const char *target; + vec3_t dest; + const char *_color; + float intensity, scale, deviance, filterRadius; + int spawnflags, flags, numSamples; + qboolean junior; + -void CreateEntityLights( void ) -{ - int i, j; - light_t *light, *light2; - entity_t *e, *e2; - const char *name; - const char *target; - vec3_t dest; - const char *_color; - float intensity, scale, deviance, filterRadius; - int spawnflags, flags, numSamples; - qboolean junior; - - /* go throught entity list and find lights */ - for( i = 0; i < numEntities; i++ ) + for ( i = 0; i < numEntities; i++ ) { /* get entity */ e = &entities[ i ]; name = ValueForKey( e, "classname" ); - + /* ydnar: check for lightJunior */ - if( Q_strncasecmp( name, "lightJunior", 11 ) == 0 ) + if ( Q_strncasecmp( name, "lightJunior", 11 ) == 0 ) { junior = qtrue; - else if( Q_strncasecmp( name, "light", 5 ) == 0 ) + } + else if ( Q_strncasecmp( name, "light", 5 ) == 0 ) { junior = qfalse; - else + } + else{ continue; - + } + /* lights with target names (and therefore styles) are only parsed from BSP */ target = ValueForKey( e, "targetname" ); - if( target[ 0 ] != '\0' && i >= numBSPEntities ) + if ( target[ 0 ] != '\0' && i >= numBSPEntities ) { continue; - + } + /* create a light */ numPointLights++; light = safe_malloc( sizeof( *light ) ); memset( light, 0, sizeof( *light ) ); light->next = lights; lights = light; - + /* handle spawnflags */ spawnflags = IntForKey( e, "spawnflags" ); - + /* ydnar: quake 3+ light behavior */ - if( wolfLight == qfalse ) - { + if ( wolfLight == qfalse ) { /* set default flags */ flags = LIGHT_Q3A_DEFAULT; - + /* linear attenuation? */ - if( spawnflags & 1 ) - { + if ( spawnflags & 1 ) { flags |= LIGHT_ATTEN_LINEAR; flags &= ~LIGHT_ATTEN_ANGLE; } - + /* no angle attenuate? */ - if( spawnflags & 2 ) + if ( spawnflags & 2 ) { flags &= ~LIGHT_ATTEN_ANGLE; + } } - + /* ydnar: wolf light behavior */ else { /* set default flags */ flags = LIGHT_WOLF_DEFAULT; - + /* inverse distance squared attenuation? */ - if( spawnflags & 1 ) - { + if ( spawnflags & 1 ) { flags &= ~LIGHT_ATTEN_LINEAR; flags |= LIGHT_ATTEN_ANGLE; } - + /* angle attenuate? */ - if( spawnflags & 2 ) + if ( spawnflags & 2 ) { flags |= LIGHT_ATTEN_ANGLE; + } } - + /* other flags (borrowed from wolf) */ - + /* wolf dark light? */ - if( (spawnflags & 4) || (spawnflags & 8) ) + if ( ( spawnflags & 4 ) || ( spawnflags & 8 ) ) { flags |= LIGHT_DARK; - + } + /* nogrid? */ - if( spawnflags & 16 ) + if ( spawnflags & 16 ) { flags &= ~LIGHT_GRID; - + } + /* junior? */ - if( junior ) - { + if ( junior ) { flags |= LIGHT_GRID; flags &= ~LIGHT_SURFACES; } /* vortex: unnormalized? */ - if (spawnflags & 32) + if ( spawnflags & 32 ) { flags |= LIGHT_UNNORMALIZED; + } /* vortex: distance atten? */ - if (spawnflags & 64) + if ( spawnflags & 64 ) { flags |= LIGHT_ATTEN_DISTANCE; + } /* store the flags */ light->flags = flags; - + /* ydnar: set fade key (from wolf) */ light->fade = 1.0f; - if( light->flags & LIGHT_ATTEN_LINEAR ) - { + if ( light->flags & LIGHT_ATTEN_LINEAR ) { light->fade = FloatForKey( e, "fade" ); - if( light->fade == 0.0f ) + if ( light->fade == 0.0f ) { light->fade = 1.0f; + } } - + /* ydnar: set angle scaling (from vlight) */ light->angleScale = FloatForKey( e, "_anglescale" ); - if( light->angleScale != 0.0f ) + if ( light->angleScale != 0.0f ) { light->flags |= LIGHT_ATTEN_ANGLE; - + } + /* set origin */ - GetVectorForKey( e, "origin", light->origin); + GetVectorForKey( e, "origin", light->origin ); light->style = IntForKey( e, "_style" ); - if( light->style == LS_NORMAL ) + if ( light->style == LS_NORMAL ) { light->style = IntForKey( e, "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 %d", light->style, i ); - - if( light->style != LS_NORMAL ) { - Sys_FPrintf (SYS_WRN, "WARNING: Styled light found targeting %s\n **", target ); + } + + if ( light->style != LS_NORMAL ) { + Sys_FPrintf( SYS_WRN, "WARNING: Styled light found targeting %s\n **", target ); } /* set light intensity */ intensity = FloatForKey( e, "_light" ); - if( intensity == 0.0f ) + if ( intensity == 0.0f ) { intensity = FloatForKey( e, "light" ); - if( intensity == 0.0f) + } + if ( intensity == 0.0f ) { intensity = 300.0f; - + } + /* ydnar: set light scale (sof2) */ scale = FloatForKey( e, "scale" ); - if( scale == 0.0f ) + if ( scale == 0.0f ) { scale = 1.0f; + } intensity *= scale; - + /* ydnar: get deviance and samples */ deviance = FloatForKey( e, "_deviance" ); - if( deviance == 0.0f ) + if ( deviance == 0.0f ) { deviance = FloatForKey( e, "_deviation" ); - if( deviance == 0.0f ) + } + if ( deviance == 0.0f ) { deviance = FloatForKey( e, "_jitter" ); + } numSamples = IntForKey( e, "_samples" ); - if( deviance < 0.0f || numSamples < 1 ) - { + if ( deviance < 0.0f || numSamples < 1 ) { deviance = 0.0f; numSamples = 1; } intensity /= numSamples; - + /* ydnar: get filter radius */ filterRadius = FloatForKey( e, "_filterradius" ); - if( filterRadius == 0.0f ) + if ( filterRadius == 0.0f ) { filterRadius = FloatForKey( e, "_filteradius" ); - if( filterRadius == 0.0f ) + } + if ( filterRadius == 0.0f ) { filterRadius = FloatForKey( e, "_filter" ); - if( filterRadius < 0.0f ) + } + if ( filterRadius < 0.0f ) { filterRadius = 0.0f; + } light->filterRadius = filterRadius; - + /* set light color */ _color = ValueForKey( e, "_color" ); - if( _color && _color[ 0 ] ) - { + if ( _color && _color[ 0 ] ) { sscanf( _color, "%f %f %f", &light->color[ 0 ], &light->color[ 1 ], &light->color[ 2 ] ); - 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]); + 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] ); } - if (!(light->flags & LIGHT_UNNORMALIZED)) - { + if ( !( light->flags & LIGHT_UNNORMALIZED ) ) { ColorNormalize( light->color, light->color ); } } - else + else{ light->color[ 0 ] = light->color[ 1 ] = light->color[ 2 ] = 1.0f; + } light->extraDist = FloatForKey( e, "_extradist" ); - if(light->extraDist == 0.0f) + if ( light->extraDist == 0.0f ) { light->extraDist = extraDist; - + } + light->photons = intensity; light->type = EMIT_POINT; - + /* set falloff threshold */ light->falloffTolerance = falloffTolerance / numSamples; - + /* lights with a target will be spotlights */ target = ValueForKey( e, "target" ); - if( target[ 0 ] ) - { - float radius; - float dist; - sun_t sun; - const char *_sun; - - + if ( target[ 0 ] ) { + float radius; + float dist; + sun_t sun; + const char *_sun; + + /* get target */ e2 = FindTargetEntity( target ); - if( e2 == NULL ) - { + if ( e2 == NULL ) { Sys_Printf( "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; } else @@ -436,34 +451,35 @@ void CreateEntityLights( void ) /* not a point light */ numPointLights--; numSpotLights++; - + /* make a spotlight */ GetVectorForKey( e2, "origin", dest ); VectorSubtract( dest, light->origin, light->normal ); dist = VectorNormalize( light->normal, light->normal ); radius = FloatForKey( e, "radius" ); - if( !radius ) + if ( !radius ) { radius = 64; - if( !dist ) + } + if ( !dist ) { dist = 64; - light->radiusByDist = (radius + 16) / dist; + } + light->radiusByDist = ( radius + 16 ) / dist; light->type = EMIT_SPOT; - + /* ydnar: wolf mods: spotlights always use nonlinear + angle attenuation */ light->flags &= ~LIGHT_ATTEN_LINEAR; light->flags |= LIGHT_ATTEN_ANGLE; light->fade = 1.0f; - + /* ydnar: is this a sun? */ _sun = ValueForKey( e, "_sun" ); - if( _sun[ 0 ] == '1' ) - { + if ( _sun[ 0 ] == '1' ) { /* not a spot light */ numSpotLights--; - + /* unlink this light */ lights = light->next; - + /* make a sun */ VectorScale( light->normal, -1.0f, sun.direction ); VectorCopy( light->color, sun.color ); @@ -472,14 +488,14 @@ void CreateEntityLights( void ) sun.numSamples = numSamples; sun.style = noStyles ? LS_NORMAL : light->style; sun.next = NULL; - + /* make a sun light */ CreateSunLight( &sun ); - + /* free original light */ free( light ); light = NULL; - + /* skip the rest of this love story */ continue; } @@ -489,28 +505,31 @@ void CreateEntityLights( void ) } } } - else + else{ light->photons *= pointScale; - + } + /* jitter the light */ - for( j = 1; j < numSamples; j++ ) + for ( j = 1; j < numSamples; j++ ) { /* create a light */ light2 = safe_malloc( sizeof( *light ) ); memcpy( light2, light, sizeof( *light ) ); light2->next = lights; lights = light2; - + /* add to counts */ - if( light->type == EMIT_SPOT ) + if ( light->type == EMIT_SPOT ) { numSpotLights++; - else + } + else{ numPointLights++; - + } + /* 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; } } } @@ -518,69 +537,66 @@ void CreateEntityLights( void ) /* -CreateSurfaceLights() - ydnar -this hijacks the radiosity code to generate surface lights for first pass -*/ + CreateSurfaceLights() - ydnar + this hijacks the radiosity code to generate surface lights for first pass + */ + +#define APPROX_BOUNCE 1.0f + +void CreateSurfaceLights( void ){ + int i; + bspDrawSurface_t *ds; + surfaceInfo_t *info; + shaderInfo_t *si; + light_t *light; + float subdivide; + vec3_t origin; + clipWork_t cw; + const char *nss; -#define APPROX_BOUNCE 1.0f -void CreateSurfaceLights( void ) -{ - int i; - bspDrawSurface_t *ds; - surfaceInfo_t *info; - shaderInfo_t *si; - light_t *light; - float subdivide; - vec3_t origin; - clipWork_t cw; - const char *nss; - - /* get sun shader supressor */ nss = ValueForKey( &entities[ 0 ], "_noshadersun" ); - + /* walk the list of surfaces */ - for( i = 0; i < numBSPDrawSurfaces; i++ ) + for ( i = 0; i < numBSPDrawSurfaces; i++ ) { /* get surface and other bits */ ds = &bspDrawSurfaces[ i ]; info = &surfaceInfos[ i ]; si = info->si; - + /* sunlight? */ - if( si->sun != NULL && nss[ 0 ] != '1' ) - { + if ( si->sun != NULL && nss[ 0 ] != '1' ) { Sys_FPrintf( SYS_VRB, "Sun: %s\n", si->shader ); CreateSunLight( si->sun ); si->sun = NULL; /* FIXME: leak! */ } - + /* sky light? */ - if( si->skyLightValue > 0.0f ) - { + if ( si->skyLightValue > 0.0f ) { Sys_FPrintf( SYS_VRB, "Sky: %s\n", si->shader ); CreateSkyLights( si->color, si->skyLightValue, si->skyLightIterations, si->lightFilterRadius, si->lightStyle ); - si->skyLightValue = 0.0f; /* FIXME: hack! */ + si->skyLightValue = 0.0f; /* FIXME: hack! */ } - + /* try to early out */ - if( si->value <= 0 ) + if ( si->value <= 0 ) { continue; - + } + /* autosprite shaders become point lights */ - if( si->autosprite ) - { + if ( si->autosprite ) { /* create an average xyz */ VectorAdd( info->mins, info->maxs, origin ); VectorScale( origin, 0.5f, origin ); - + /* create a light */ light = safe_malloc( sizeof( *light ) ); memset( light, 0, sizeof( *light ) ); light->next = lights; lights = light; - + /* set it up */ light->flags = LIGHT_Q3A_DEFAULT; light->type = EMIT_POINT; @@ -591,32 +607,34 @@ void CreateSurfaceLights( void ) VectorCopy( si->color, light->color ); light->falloffTolerance = falloffTolerance; light->style = si->lightStyle; - + /* add to point light count and continue */ numPointLights++; continue; } - + /* get subdivision amount */ - if( si->lightSubdivide > 0 ) + if ( si->lightSubdivide > 0 ) { subdivide = si->lightSubdivide; - else + } + else{ subdivide = defaultLightSubdivide; - + } + /* switch on type */ - switch( ds->surfaceType ) + switch ( ds->surfaceType ) { - case MST_PLANAR: - case MST_TRIANGLE_SOUP: - RadLightForTriangles( i, 0, info->lm, si, APPROX_BOUNCE, subdivide, &cw ); - break; - - case MST_PATCH: - RadLightForPatch( i, 0, info->lm, si, APPROX_BOUNCE, subdivide, &cw ); - break; - - default: - break; + case MST_PLANAR: + case MST_TRIANGLE_SOUP: + RadLightForTriangles( i, 0, info->lm, si, APPROX_BOUNCE, subdivide, &cw ); + break; + + case MST_PATCH: + RadLightForPatch( i, 0, info->lm, si, APPROX_BOUNCE, subdivide, &cw ); + break; + + default: + break; } } } @@ -624,50 +642,51 @@ void CreateSurfaceLights( void ) /* -SetEntityOrigins() -find the offset values for inline models -*/ + SetEntityOrigins() + find the offset values for inline models + */ + +void SetEntityOrigins( void ){ + int i, j, k, f; + entity_t *e; + vec3_t origin; + const char *key; + int modelnum; + bspModel_t *dm; + bspDrawSurface_t *ds; + -void SetEntityOrigins( void ) -{ - int i, j, k, f; - entity_t *e; - vec3_t origin; - const char *key; - int modelnum; - bspModel_t *dm; - bspDrawSurface_t *ds; - - /* ydnar: copy drawverts into private storage for nefarious purposes */ yDrawVerts = safe_malloc( numBSPDrawVerts * sizeof( bspDrawVert_t ) ); memcpy( yDrawVerts, bspDrawVerts, numBSPDrawVerts * sizeof( bspDrawVert_t ) ); - + /* set the entity origins */ - for( i = 0; i < numEntities; i++ ) + for ( i = 0; i < numEntities; i++ ) { /* get entity and model */ e = &entities[ i ]; key = ValueForKey( e, "model" ); - if( key[ 0 ] != '*' ) + if ( key[ 0 ] != '*' ) { continue; + } modelnum = atoi( key + 1 ); dm = &bspModels[ modelnum ]; - + /* get entity origin */ key = ValueForKey( e, "origin" ); - if( key[ 0 ] == '\0' ) + if ( key[ 0 ] == '\0' ) { continue; + } GetVectorForKey( e, "origin", origin ); - + /* set origin for all surfaces for this model */ - for( j = 0; j < dm->numBSPSurfaces; j++ ) + for ( j = 0; j < dm->numBSPSurfaces; j++ ) { /* get drawsurf */ ds = &bspDrawSurfaces[ dm->firstBSPSurface + j ]; - + /* set its verts */ - for( k = 0; k < ds->numVerts; k++ ) + for ( k = 0; k < ds->numVerts; k++ ) { f = ds->firstVert + k; VectorAdd( origin, bspDrawVerts[ f ].xyz, yDrawVerts[ f ].xyz ); @@ -679,64 +698,67 @@ void SetEntityOrigins( void ) /* -PointToPolygonFormFactor() -calculates the area over a point/normal hemisphere a winding covers -ydnar: fixme: there has to be a faster way to calculate this -without the expensive per-vert sqrts and transcendental functions -ydnar 2002-09-30: added -faster switch because only 19% deviance > 10% -between this and the approximation -*/ + PointToPolygonFormFactor() + calculates the area over a point/normal hemisphere a winding covers + ydnar: fixme: there has to be a faster way to calculate this + without the expensive per-vert sqrts and transcendental functions + ydnar 2002-09-30: added -faster switch because only 19% deviance > 10% + between this and the approximation + */ + +#define ONE_OVER_2PI 0.159154942f //% (1.0f / (2.0f * 3.141592657f)) + +float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w ){ + vec3_t triVector, triNormal; + int i, j; + vec3_t dirs[ MAX_POINTS_ON_WINDING ]; + float total; + float dot, angle, facing; -#define ONE_OVER_2PI 0.159154942f //% (1.0f / (2.0f * 3.141592657f)) -float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const winding_t *w ) -{ - vec3_t triVector, triNormal; - int i, j; - vec3_t dirs[ MAX_POINTS_ON_WINDING ]; - float total; - float dot, angle, facing; - - /* this is expensive */ - for( i = 0; i < w->numpoints; i++ ) + for ( i = 0; i < w->numpoints; i++ ) { VectorSubtract( w->p[ i ], point, dirs[ i ] ); VectorNormalize( dirs[ i ], dirs[ i ] ); } - + /* duplicate first vertex to avoid mod operation */ VectorCopy( dirs[ 0 ], dirs[ i ] ); - + /* calculcate relative area */ total = 0.0f; - for( i = 0; i < w->numpoints; i++ ) + for ( i = 0; i < w->numpoints; i++ ) { /* get a triangle */ j = i + 1; dot = DotProduct( dirs[ i ], dirs[ j ] ); - + /* roundoff can cause slight creep, which gives an IND from acos */ - if( dot > 1.0f ) + if ( dot > 1.0f ) { dot = 1.0f; - else if( dot < -1.0f ) + } + else if ( dot < -1.0f ) { dot = -1.0f; - + } + /* get the angle */ angle = acos( dot ); - + CrossProduct( dirs[ i ], dirs[ j ], triVector ); - if( VectorNormalize( triVector, triNormal ) < 0.0001f ) + if ( VectorNormalize( triVector, triNormal ) < 0.0001f ) { continue; - + } + facing = DotProduct( normal, triNormal ); total += facing * angle; - + /* ydnar: this was throwing too many errors with radiosity + crappy maps. ignoring it. */ - if( total > 6.3f || total < -6.3f ) + if ( total > 6.3f || total < -6.3f ) { return 0.0f; + } } - + /* now in the range of 0 to 1 over the entire incoming hemisphere */ //% total /= (2.0f * 3.141592657f); total *= ONE_OVER_2PI; @@ -746,104 +768,107 @@ float PointToPolygonFormFactor( const vec3_t point, const vec3_t normal, const w /* -LightContributionTosample() -determines the amount of light reaching a sample (luxel or vertex) from a given light -*/ + LightContributionTosample() + determines the amount of light reaching a sample (luxel or vertex) from a given light + */ + +int LightContributionToSample( trace_t *trace ){ + light_t *light; + float angle; + float add; + float dist; + float addDeluxe = 0.0f, addDeluxeBounceScale = 0.25f; + qboolean angledDeluxe = qtrue; + float colorBrightness; + qboolean doAddDeluxe = qtrue; -int LightContributionToSample( trace_t *trace ) -{ - light_t *light; - float angle; - float add; - float dist; - float addDeluxe = 0.0f, addDeluxeBounceScale = 0.25f; - qboolean angledDeluxe = qtrue; - float colorBrightness; - qboolean doAddDeluxe = qtrue; - /* get light */ light = trace->light; - + /* clear color */ trace->forceSubsampling = 0.0f; /* to make sure */ VectorClear( trace->color ); VectorClear( trace->colorNoShadow ); VectorClear( trace->directionContribution ); - colorBrightness = RGBTOGRAY( light->color ) * ( 1.0f/255.0f ); - + colorBrightness = RGBTOGRAY( light->color ) * ( 1.0f / 255.0f ); + /* ydnar: early out */ - if( !(light->flags & LIGHT_SURFACES) || light->envelope <= 0.0f ) + if ( !( light->flags & LIGHT_SURFACES ) || light->envelope <= 0.0f ) { return 0; - + } + /* do some culling checks */ - if( light->type != EMIT_SUN ) - { + if ( light->type != EMIT_SUN ) { /* MrE: if the light is behind the surface */ - if( trace->twoSided == qfalse ) - if( DotProduct( light->origin, trace->normal ) - DotProduct( trace->origin, trace->normal ) < 0.0f ) + if ( trace->twoSided == qfalse ) { + if ( DotProduct( light->origin, trace->normal ) - DotProduct( trace->origin, trace->normal ) < 0.0f ) { return 0; - + } + } + /* ydnar: test pvs */ - if( !ClusterVisible( trace->cluster, light->cluster ) ) + if ( !ClusterVisible( trace->cluster, light->cluster ) ) { return 0; + } } - + /* exact point to polygon form factor */ - if( light->type == EMIT_AREA ) - { - float factor; - float d; - vec3_t pushedOrigin; - + if ( light->type == EMIT_AREA ) { + float factor; + float d; + vec3_t pushedOrigin; + /* project sample point into light plane */ d = DotProduct( trace->origin, light->normal ) - light->dist; - if( d < 3.0f ) - { + if ( d < 3.0f ) { /* sample point behind plane? */ - if( !(light->flags & LIGHT_TWOSIDED) && d < -1.0f ) + if ( !( light->flags & LIGHT_TWOSIDED ) && d < -1.0f ) { return 0; - + } + /* sample plane coincident? */ - if( d > -3.0f && DotProduct( trace->normal, light->normal ) > 0.9f ) + if ( d > -3.0f && DotProduct( trace->normal, light->normal ) > 0.9f ) { return 0; + } } - + /* nudge the point so that it is clearly forward of the light */ /* so that surfaces meeting a light emitter don't get black edges */ - if( d > -8.0f && d < 8.0f ) - VectorMA( trace->origin, (8.0f - d), light->normal, pushedOrigin ); - else + if ( d > -8.0f && d < 8.0f ) { + VectorMA( trace->origin, ( 8.0f - d ), light->normal, pushedOrigin ); + } + else{ VectorCopy( trace->origin, pushedOrigin ); - + } + /* get direction and distance */ VectorCopy( light->origin, trace->end ); dist = SetupTrace( trace ); - if( dist >= light->envelope ) + if ( dist >= light->envelope ) { return 0; - + } + /* ptpff approximation */ - if( faster ) - { + if ( faster ) { /* angle attenuation */ angle = DotProduct( trace->normal, trace->direction ); - + /* twosided lighting */ - if( trace->twoSided && angle < 0 ) - { + if ( trace->twoSided && angle < 0 ) { angle = -angle; /* no deluxemap contribution from "other side" light */ doAddDeluxe = qfalse; } - + /* attenuate */ angle *= -DotProduct( light->normal, trace->direction ); - if( angle == 0.0f ) + if ( angle == 0.0f ) { return 0; - else if( angle < 0.0f && - (trace->twoSided || (light->flags & LIGHT_TWOSIDED)) ) - { + } + else if ( angle < 0.0f && + ( trace->twoSided || ( light->flags & LIGHT_TWOSIDED ) ) ) { angle = -angle; /* no deluxemap contribution from "other side" light */ @@ -851,84 +876,86 @@ int LightContributionToSample( trace_t *trace ) } /* clamp the distance to prevent super hot spots */ - dist = sqrt(dist * dist + light->extraDist * light->extraDist); - if( dist < 16.0f ) + dist = sqrt( dist * dist + light->extraDist * light->extraDist ); + if ( dist < 16.0f ) { dist = 16.0f; + } - add = light->photons / (dist * dist) * angle; + add = light->photons / ( dist * dist ) * angle; - if( deluxemap ) - { - if( angledDeluxe ) - addDeluxe = light->photons / (dist * dist) * angle; - else - addDeluxe = light->photons / (dist * dist); + if ( deluxemap ) { + if ( angledDeluxe ) { + addDeluxe = light->photons / ( dist * dist ) * angle; + } + else{ + addDeluxe = light->photons / ( dist * dist ); + } } } else { /* calculate the contribution */ factor = PointToPolygonFormFactor( pushedOrigin, trace->normal, light->w ); - if( factor == 0.0f ) + if ( factor == 0.0f ) { return 0; - else if( factor < 0.0f ) - { + } + else if ( factor < 0.0f ) { /* twosided lighting */ - if( trace->twoSided || (light->flags & LIGHT_TWOSIDED) ) - { + if ( trace->twoSided || ( light->flags & LIGHT_TWOSIDED ) ) { factor = -factor; /* push light origin to other side of the plane */ VectorMA( light->origin, -2.0f, light->normal, trace->end ); dist = SetupTrace( trace ); - if( dist >= light->envelope ) + if ( dist >= light->envelope ) { return 0; + } /* no deluxemap contribution from "other side" light */ doAddDeluxe = qfalse; } - else + else{ return 0; + } } /* also don't deluxe if the direction is on the wrong side */ - if(DotProduct(trace->normal, trace->direction) < 0) - { + if ( DotProduct( trace->normal, trace->direction ) < 0 ) { /* no deluxemap contribution from "other side" light */ doAddDeluxe = qfalse; } - + /* ydnar: moved to here */ add = factor * light->add; - if( deluxemap ) + if ( deluxemap ) { addDeluxe = add; + } } } - + /* point/spot lights */ - else if( light->type == EMIT_POINT || light->type == EMIT_SPOT ) - { + else if ( light->type == EMIT_POINT || light->type == EMIT_SPOT ) { /* get direction and distance */ VectorCopy( light->origin, trace->end ); dist = SetupTrace( trace ); - if( dist >= light->envelope ) + if ( dist >= light->envelope ) { return 0; + } /* clamp the distance to prevent super hot spots */ - dist = sqrt(dist * dist + light->extraDist * light->extraDist); - if( dist < 16.0f ) + dist = sqrt( dist * dist + light->extraDist * light->extraDist ); + if ( dist < 16.0f ) { dist = 16.0f; + } /* angle attenuation */ - if( light->flags & LIGHT_ATTEN_ANGLE ) - { + if ( light->flags & LIGHT_ATTEN_ANGLE ) { /* standard Lambert attenuation */ - float dot = DotProduct( trace->normal, trace->direction ); + float dot = DotProduct( trace->normal, trace->direction ); /* twosided lighting */ - if( trace->twoSided && dot < 0 ) - { + if ( trace->twoSided && dot < 0 ) { dot = -dot; /* no deluxemap contribution from "other side" light */ @@ -936,116 +963,122 @@ int LightContributionToSample( trace_t *trace ) } /* jal: optional half Lambert attenuation (http://developer.valvesoftware.com/wiki/Half_Lambert) */ - if( lightAngleHL ) - { - if( dot > 0.001f ) // skip coplanar - { - if( dot > 1.0f ) dot = 1.0f; + if ( lightAngleHL ) { + if ( dot > 0.001f ) { // skip coplanar + if ( dot > 1.0f ) { + dot = 1.0f; + } dot = ( dot * 0.5f ) + 0.5f; dot *= dot; } - else + else{ dot = 0; + } } angle = dot; } - else + else{ angle = 1.0f; + } - if( light->angleScale != 0.0f ) - { + if ( light->angleScale != 0.0f ) { angle /= light->angleScale; - if( angle > 1.0f ) + if ( angle > 1.0f ) { angle = 1.0f; + } } - + /* attenuate */ - if( light->flags & LIGHT_ATTEN_LINEAR ) - { - add = angle * light->photons * linearScale - (dist * light->fade); - if( add < 0.0f ) + if ( light->flags & LIGHT_ATTEN_LINEAR ) { + add = angle * light->photons * linearScale - ( dist * light->fade ); + if ( add < 0.0f ) { add = 0.0f; + } - if( deluxemap ) - { - if( angledDeluxe ) - addDeluxe = angle * light->photons * linearScale - (dist * light->fade); - else - addDeluxe = light->photons * linearScale - (dist * light->fade); + if ( deluxemap ) { + if ( angledDeluxe ) { + addDeluxe = angle * light->photons * linearScale - ( dist * light->fade ); + } + else{ + addDeluxe = light->photons * linearScale - ( dist * light->fade ); + } - if( addDeluxe < 0.0f ) + if ( addDeluxe < 0.0f ) { addDeluxe = 0.0f; + } } } else { - add = (light->photons / (dist * dist)) * angle; - if( add < 0.0f ) + add = ( light->photons / ( dist * dist ) ) * angle; + if ( add < 0.0f ) { add = 0.0f; + } - if( deluxemap ) - { - if( angledDeluxe ) - addDeluxe = (light->photons / (dist * dist)) * angle; - else - addDeluxe = (light->photons / (dist * dist)); + if ( deluxemap ) { + if ( angledDeluxe ) { + addDeluxe = ( light->photons / ( dist * dist ) ) * angle; + } + else{ + addDeluxe = ( light->photons / ( dist * dist ) ); + } } - if( addDeluxe < 0.0f ) + if ( addDeluxe < 0.0f ) { addDeluxe = 0.0f; + } } - + /* handle spotlights */ - if( light->type == EMIT_SPOT ) - { - float distByNormal, radiusAtDist, sampleRadius; - vec3_t pointAtDist, distToSample; - + if ( light->type == EMIT_SPOT ) { + float distByNormal, radiusAtDist, sampleRadius; + vec3_t pointAtDist, distToSample; + /* do cone calculation */ distByNormal = -DotProduct( trace->displacement, light->normal ); - if( distByNormal < 0.0f ) + if ( distByNormal < 0.0f ) { return 0; + } VectorMA( light->origin, distByNormal, light->normal, pointAtDist ); radiusAtDist = light->radiusByDist * distByNormal; VectorSubtract( trace->origin, pointAtDist, distToSample ); sampleRadius = VectorLength( distToSample ); - + /* outside the cone */ - if( sampleRadius >= radiusAtDist ) + if ( sampleRadius >= radiusAtDist ) { return 0; - + } + /* attenuate */ - if( sampleRadius > (radiusAtDist - 32.0f) ) - { - add *= ((radiusAtDist - sampleRadius) / 32.0f); - if( add < 0.0f ) + if ( sampleRadius > ( radiusAtDist - 32.0f ) ) { + add *= ( ( radiusAtDist - sampleRadius ) / 32.0f ); + if ( add < 0.0f ) { add = 0.0f; + } - addDeluxe *= ((radiusAtDist - sampleRadius) / 32.0f); + addDeluxe *= ( ( radiusAtDist - sampleRadius ) / 32.0f ); - if( addDeluxe < 0.0f ) + if ( addDeluxe < 0.0f ) { addDeluxe = 0.0f; + } } } } - + /* ydnar: sunlight */ - else if( light->type == EMIT_SUN ) - { + else if ( light->type == EMIT_SUN ) { /* get origin and direction */ VectorAdd( trace->origin, light->origin, trace->end ); dist = SetupTrace( trace ); /* angle attenuation */ - if( light->flags & LIGHT_ATTEN_ANGLE ) - { + if ( light->flags & LIGHT_ATTEN_ANGLE ) { /* standard Lambert attenuation */ - float dot = DotProduct( trace->normal, trace->direction ); + float dot = DotProduct( trace->normal, trace->direction ); /* twosided lighting */ - if( trace->twoSided && dot < 0 ) - { + if ( trace->twoSided && dot < 0 ) { dot = -dot; /* no deluxemap contribution from "other side" light */ @@ -1053,129 +1086,131 @@ int LightContributionToSample( trace_t *trace ) } /* jal: optional half Lambert attenuation (http://developer.valvesoftware.com/wiki/Half_Lambert) */ - if( lightAngleHL ) - { - if( dot > 0.001f ) // skip coplanar - { - if( dot > 1.0f ) dot = 1.0f; + if ( lightAngleHL ) { + if ( dot > 0.001f ) { // skip coplanar + if ( dot > 1.0f ) { + dot = 1.0f; + } dot = ( dot * 0.5f ) + 0.5f; dot *= dot; } - else + else{ dot = 0; + } } - + angle = dot; } - else + else{ angle = 1.0f; - + } + /* attenuate */ add = light->photons * angle; - if( deluxemap ) - { - if( angledDeluxe ) + if ( deluxemap ) { + if ( angledDeluxe ) { addDeluxe = light->photons * angle; - else + } + else{ addDeluxe = light->photons; + } - if( addDeluxe < 0.0f ) + if ( addDeluxe < 0.0f ) { addDeluxe = 0.0f; + } } - if( add <= 0.0f ) + if ( add <= 0.0f ) { return 0; + } /* VorteX: set noShadow color */ - VectorScale(light->color, add, trace->colorNoShadow); + VectorScale( light->color, add, trace->colorNoShadow ); addDeluxe *= colorBrightness; - if( bouncing ) - { + if ( bouncing ) { addDeluxe *= addDeluxeBounceScale; - if( addDeluxe < 0.00390625f ) + if ( addDeluxe < 0.00390625f ) { addDeluxe = 0.00390625f; + } } VectorScale( trace->direction, addDeluxe, trace->directionContribution ); - + /* setup trace */ trace->testAll = qtrue; VectorScale( light->color, add, trace->color ); - + /* trace to point */ - if( trace->testOcclusion && !trace->forceSunlight ) - { + if ( trace->testOcclusion && !trace->forceSunlight ) { /* trace */ TraceLine( trace ); trace->forceSubsampling *= add; - if( !(trace->compileFlags & C_SKY) || trace->opaque ) - { + if ( !( trace->compileFlags & C_SKY ) || trace->opaque ) { VectorClear( trace->color ); VectorClear( trace->directionContribution ); return -1; } } - + /* return to sender */ return 1; } - else - Error("Light of undefined type!"); + else{ + Error( "Light of undefined type!" ); + } /* VorteX: set noShadow color */ - VectorScale(light->color, add, trace->colorNoShadow); - + VectorScale( light->color, add, trace->colorNoShadow ); + /* ydnar: changed to a variable number */ - if( add <= 0.0f || (add <= light->falloffTolerance && (light->flags & LIGHT_FAST_ACTUAL)) ) + if ( add <= 0.0f || ( add <= light->falloffTolerance && ( light->flags & LIGHT_FAST_ACTUAL ) ) ) { return 0; + } addDeluxe *= colorBrightness; /* hack land: scale down the radiosity contribution to light directionality. - Deluxemaps fusion many light directions into one. In a rtl process all lights - would contribute individually to the bump map, so several light sources together - would make it more directional (example: a yellow and red lights received from - opposing sides would light one side in red and the other in blue, adding - the effect of 2 directions applied. In the deluxemapping case, this 2 lights would - neutralize each other making it look like having no direction. - Same thing happens with radiosity. In deluxemapping case the radiosity contribution - is modifying the direction applied from directional lights, making it go closer and closer - to the surface normal the bigger is the amount of radiosity received. - So, for preserving the directional lights contributions, we scale down the radiosity - contribution. It's a hack, but there's a reason behind it */ - if( bouncing ) - { + Deluxemaps fusion many light directions into one. In a rtl process all lights + would contribute individually to the bump map, so several light sources together + would make it more directional (example: a yellow and red lights received from + opposing sides would light one side in red and the other in blue, adding + the effect of 2 directions applied. In the deluxemapping case, this 2 lights would + neutralize each other making it look like having no direction. + Same thing happens with radiosity. In deluxemapping case the radiosity contribution + is modifying the direction applied from directional lights, making it go closer and closer + to the surface normal the bigger is the amount of radiosity received. + So, for preserving the directional lights contributions, we scale down the radiosity + contribution. It's a hack, but there's a reason behind it */ + if ( bouncing ) { addDeluxe *= addDeluxeBounceScale; /* better NOT increase it beyond the original value - if( addDeluxe < 0.00390625f ) - addDeluxe = 0.00390625f; - */ + if( addDeluxe < 0.00390625f ) + addDeluxe = 0.00390625f; + */ } - if(doAddDeluxe) - { + if ( doAddDeluxe ) { VectorScale( trace->direction, addDeluxe, trace->directionContribution ); } - + /* setup trace */ trace->testAll = qfalse; VectorScale( light->color, add, trace->color ); - + /* raytrace */ TraceLine( trace ); trace->forceSubsampling *= add; - if( trace->passSolid || trace->opaque ) - { + if ( trace->passSolid || trace->opaque ) { VectorClear( trace->color ); VectorClear( trace->directionContribution ); return -1; } - + /* return to sender */ return 1; } @@ -1183,274 +1218,285 @@ int LightContributionToSample( trace_t *trace ) /* -LightingAtSample() -determines the amount of light reaching a sample (luxel or vertex) -*/ + LightingAtSample() + determines the amount of light reaching a sample (luxel or vertex) + */ + +void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colors[ MAX_LIGHTMAPS ] ){ + int i, lightmapNum; + -void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], vec3_t colors[ MAX_LIGHTMAPS ] ) -{ - int i, lightmapNum; - - /* clear colors */ - for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) VectorClear( colors[ lightmapNum ] ); - + /* ydnar: normalmap */ - if( normalmap ) - { - colors[ 0 ][ 0 ] = (trace->normal[ 0 ] + 1.0f) * 127.5f; - colors[ 0 ][ 1 ] = (trace->normal[ 1 ] + 1.0f) * 127.5f; - colors[ 0 ][ 2 ] = (trace->normal[ 2 ] + 1.0f) * 127.5f; + if ( normalmap ) { + colors[ 0 ][ 0 ] = ( trace->normal[ 0 ] + 1.0f ) * 127.5f; + colors[ 0 ][ 1 ] = ( trace->normal[ 1 ] + 1.0f ) * 127.5f; + colors[ 0 ][ 2 ] = ( trace->normal[ 2 ] + 1.0f ) * 127.5f; return; } - + /* ydnar: don't bounce ambient all the time */ - if( !bouncing ) + if ( !bouncing ) { VectorCopy( ambientColor, colors[ 0 ] ); - + } + /* ydnar: trace to all the list of lights pre-stored in tw */ - for( i = 0; i < trace->numLights && trace->lights[ i ] != NULL; i++ ) + for ( i = 0; i < trace->numLights && trace->lights[ i ] != NULL; i++ ) { /* set light */ trace->light = trace->lights[ i ]; - + /* style check */ - for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) + for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ ) { - if( styles[ lightmapNum ] == trace->light->style || - styles[ lightmapNum ] == LS_NONE ) + if ( styles[ lightmapNum ] == trace->light->style || + styles[ lightmapNum ] == LS_NONE ) { break; + } } - + /* max of MAX_LIGHTMAPS (4) styles allowed to hit a sample */ - if( lightmapNum >= MAX_LIGHTMAPS ) + if ( lightmapNum >= MAX_LIGHTMAPS ) { continue; - + } + /* sample light */ LightContributionToSample( trace ); - if( trace->color[ 0 ] == 0.0f && trace->color[ 1 ] == 0.0f && trace->color[ 2 ] == 0.0f ) + if ( trace->color[ 0 ] == 0.0f && trace->color[ 1 ] == 0.0f && trace->color[ 2 ] == 0.0f ) { continue; - + } + /* handle negative light */ - if( trace->light->flags & LIGHT_NEGATIVE ) + if ( trace->light->flags & LIGHT_NEGATIVE ) { VectorScale( trace->color, -1.0f, trace->color ); - + } + /* set style */ styles[ lightmapNum ] = trace->light->style; - + /* add it */ VectorAdd( colors[ lightmapNum ], trace->color, colors[ lightmapNum ] ); - + /* cheap mode */ - if( cheap && - colors[ 0 ][ 0 ] >= 255.0f && - colors[ 0 ][ 1 ] >= 255.0f && - colors[ 0 ][ 2 ] >= 255.0f ) + if ( cheap && + colors[ 0 ][ 0 ] >= 255.0f && + colors[ 0 ][ 1 ] >= 255.0f && + colors[ 0 ][ 2 ] >= 255.0f ) { break; + } } } /* -LightContributionToPoint() -for a given light, how much light/color reaches a given point in space (with no facing) -note: this is similar to LightContributionToSample() but optimized for omnidirectional sampling -*/ + LightContributionToPoint() + for a given light, how much light/color reaches a given point in space (with no facing) + note: this is similar to LightContributionToSample() but optimized for omnidirectional sampling + */ + +int LightContributionToPoint( trace_t *trace ){ + light_t *light; + float add, dist; + -int LightContributionToPoint( trace_t *trace ) -{ - light_t *light; - float add, dist; - - /* get light */ light = trace->light; - + /* clear color */ VectorClear( trace->color ); - + /* ydnar: early out */ - if( !(light->flags & LIGHT_GRID) || light->envelope <= 0.0f ) + if ( !( light->flags & LIGHT_GRID ) || light->envelope <= 0.0f ) { return qfalse; - + } + /* is this a sun? */ - if( light->type != EMIT_SUN ) - { + if ( light->type != EMIT_SUN ) { /* sun only? */ - if( sunOnly ) + if ( sunOnly ) { return qfalse; - + } + /* test pvs */ - if( !ClusterVisible( trace->cluster, light->cluster ) ) + if ( !ClusterVisible( trace->cluster, light->cluster ) ) { return qfalse; + } } - + /* ydnar: check origin against light's pvs envelope */ - if( trace->origin[ 0 ] > light->maxs[ 0 ] || trace->origin[ 0 ] < light->mins[ 0 ] || - trace->origin[ 1 ] > light->maxs[ 1 ] || trace->origin[ 1 ] < light->mins[ 1 ] || - trace->origin[ 2 ] > light->maxs[ 2 ] || trace->origin[ 2 ] < light->mins[ 2 ] ) - { + if ( trace->origin[ 0 ] > light->maxs[ 0 ] || trace->origin[ 0 ] < light->mins[ 0 ] || + trace->origin[ 1 ] > light->maxs[ 1 ] || trace->origin[ 1 ] < light->mins[ 1 ] || + trace->origin[ 2 ] > light->maxs[ 2 ] || trace->origin[ 2 ] < light->mins[ 2 ] ) { gridBoundsCulled++; return qfalse; } - + /* set light origin */ - if( light->type == EMIT_SUN ) + if ( light->type == EMIT_SUN ) { VectorAdd( trace->origin, light->origin, trace->end ); - else + } + else{ VectorCopy( light->origin, trace->end ); - + } + /* set direction */ dist = SetupTrace( trace ); - + /* test envelope */ - if( dist > light->envelope ) - { + if ( dist > light->envelope ) { gridEnvelopeCulled++; return qfalse; } - + /* ptpff approximation */ - if( light->type == EMIT_AREA && faster ) - { + if ( light->type == EMIT_AREA && faster ) { /* clamp the distance to prevent super hot spots */ - dist = sqrt(dist * dist + light->extraDist * light->extraDist); - if( dist < 16.0f ) + dist = sqrt( dist * dist + light->extraDist * light->extraDist ); + if ( dist < 16.0f ) { dist = 16.0f; + } /* attenuate */ - add = light->photons / (dist * dist); + add = light->photons / ( dist * dist ); } - + /* exact point to polygon form factor */ - else if( light->type == EMIT_AREA ) - { - float factor, d; - vec3_t pushedOrigin; - - + else if ( light->type == EMIT_AREA ) { + float factor, d; + vec3_t pushedOrigin; + + /* see if the point is behind the light */ d = DotProduct( trace->origin, light->normal ) - light->dist; - if( !(light->flags & LIGHT_TWOSIDED) && d < -1.0f ) + if ( !( light->flags & LIGHT_TWOSIDED ) && d < -1.0f ) { return qfalse; - + } + /* nudge the point so that it is clearly forward of the light */ /* so that surfaces meeting a light emiter don't get black edges */ - if( d > -8.0f && d < 8.0f ) - VectorMA( trace->origin, (8.0f - d), light->normal, pushedOrigin ); - else + if ( d > -8.0f && d < 8.0f ) { + VectorMA( trace->origin, ( 8.0f - d ), light->normal, pushedOrigin ); + } + else{ VectorCopy( trace->origin, pushedOrigin ); - + } + /* calculate the contribution (ydnar 2002-10-21: [bug 642] bad normal calc) */ factor = PointToPolygonFormFactor( pushedOrigin, trace->direction, light->w ); - if( factor == 0.0f ) + if ( factor == 0.0f ) { return qfalse; - else if( factor < 0.0f ) - { - if( light->flags & LIGHT_TWOSIDED ) + } + else if ( factor < 0.0f ) { + if ( light->flags & LIGHT_TWOSIDED ) { factor = -factor; - else + } + else{ return qfalse; + } } - + /* ydnar: moved to here */ add = factor * light->add; } - + /* point/spot lights */ - else if( light->type == EMIT_POINT || light->type == EMIT_SPOT ) - { + else if ( light->type == EMIT_POINT || light->type == EMIT_SPOT ) { /* clamp the distance to prevent super hot spots */ - dist = sqrt(dist * dist + light->extraDist * light->extraDist); - if( dist < 16.0f ) + dist = sqrt( dist * dist + light->extraDist * light->extraDist ); + if ( dist < 16.0f ) { dist = 16.0f; - + } + /* attenuate */ - if( light->flags & LIGHT_ATTEN_LINEAR ) - { - add = light->photons * linearScale - (dist * light->fade); - if( add < 0.0f ) + if ( light->flags & LIGHT_ATTEN_LINEAR ) { + add = light->photons * linearScale - ( dist * light->fade ); + if ( add < 0.0f ) { add = 0.0f; + } } - else - add = light->photons / (dist * dist); - + else{ + add = light->photons / ( dist * dist ); + } + /* handle spotlights */ - if( light->type == EMIT_SPOT ) - { - float distByNormal, radiusAtDist, sampleRadius; - vec3_t pointAtDist, distToSample; - - + if ( light->type == EMIT_SPOT ) { + float distByNormal, radiusAtDist, sampleRadius; + vec3_t pointAtDist, distToSample; + + /* do cone calculation */ distByNormal = -DotProduct( trace->displacement, light->normal ); - if( distByNormal < 0.0f ) + if ( distByNormal < 0.0f ) { return qfalse; + } VectorMA( light->origin, distByNormal, light->normal, pointAtDist ); radiusAtDist = light->radiusByDist * distByNormal; VectorSubtract( trace->origin, pointAtDist, distToSample ); sampleRadius = VectorLength( distToSample ); - + /* outside the cone */ - if( sampleRadius >= radiusAtDist ) + if ( sampleRadius >= radiusAtDist ) { return qfalse; - + } + /* attenuate */ - if( sampleRadius > (radiusAtDist - 32.0f) ) - add *= ((radiusAtDist - sampleRadius) / 32.0f); + if ( sampleRadius > ( radiusAtDist - 32.0f ) ) { + add *= ( ( radiusAtDist - sampleRadius ) / 32.0f ); + } } } - + /* ydnar: sunlight */ - else if( light->type == EMIT_SUN ) - { + else if ( light->type == EMIT_SUN ) { /* attenuate */ add = light->photons; - if( add <= 0.0f ) + if ( add <= 0.0f ) { return qfalse; - + } + /* setup trace */ trace->testAll = qtrue; VectorScale( light->color, add, trace->color ); - + /* trace to point */ - if( trace->testOcclusion && !trace->forceSunlight ) - { + if ( trace->testOcclusion && !trace->forceSunlight ) { /* trace */ TraceLine( trace ); - if( !(trace->compileFlags & C_SKY) || trace->opaque ) - { + if ( !( trace->compileFlags & C_SKY ) || trace->opaque ) { VectorClear( trace->color ); return -1; } } - + /* return to sender */ return qtrue; } - + /* unknown light type */ - else + else{ return qfalse; - + } + /* ydnar: changed to a variable number */ - if( add <= 0.0f || (add <= light->falloffTolerance && (light->flags & LIGHT_FAST_ACTUAL)) ) + if ( add <= 0.0f || ( add <= light->falloffTolerance && ( light->flags & LIGHT_FAST_ACTUAL ) ) ) { return qfalse; - + } + /* setup trace */ trace->testAll = qfalse; VectorScale( light->color, add, trace->color ); - + /* trace */ TraceLine( trace ); - if( trace->passSolid ) - { + if ( trace->passSolid ) { VectorClear( trace->color ); return qfalse; } - + /* we have a valid sample */ return qtrue; } @@ -1458,80 +1504,83 @@ int LightContributionToPoint( trace_t *trace ) /* -TraceGrid() -grid samples are for quickly determining the lighting -of dynamically placed entities in the world -*/ + TraceGrid() + grid samples are for quickly determining the lighting + of dynamically placed entities in the world + */ -#define MAX_CONTRIBUTIONS 32768 +#define MAX_CONTRIBUTIONS 32768 typedef struct { - vec3_t dir; - vec3_t color; - vec3_t ambient; - int style; + vec3_t dir; + vec3_t color; + vec3_t ambient; + int style; } contribution_t; -void TraceGrid( int num ) -{ - int i, j, x, y, z, mod, numCon, numStyles; - float d, step; - vec3_t baseOrigin, cheapColor, color, thisdir; - rawGridPoint_t *gp; - bspGridPoint_t *bgp; - contribution_t contributions[ MAX_CONTRIBUTIONS ]; - trace_t trace; - +void TraceGrid( int num ){ + int i, j, x, y, z, mod, numCon, numStyles; + float d, step; + vec3_t baseOrigin, cheapColor, color, thisdir; + rawGridPoint_t *gp; + bspGridPoint_t *bgp; + contribution_t contributions[ MAX_CONTRIBUTIONS ]; + trace_t trace; + /* get grid points */ gp = &rawGridPoints[ num ]; bgp = &bspGridPoints[ num ]; - + /* get grid origin */ mod = num; - z = mod / (gridBounds[ 0 ] * gridBounds[ 1 ]); - mod -= z * (gridBounds[ 0 ] * gridBounds[ 1 ]); + z = mod / ( gridBounds[ 0 ] * gridBounds[ 1 ] ); + mod -= z * ( gridBounds[ 0 ] * gridBounds[ 1 ] ); y = mod / gridBounds[ 0 ]; mod -= y * gridBounds[ 0 ]; x = mod; - + trace.origin[ 0 ] = gridMins[ 0 ] + x * gridSize[ 0 ]; trace.origin[ 1 ] = gridMins[ 1 ] + y * gridSize[ 1 ]; trace.origin[ 2 ] = gridMins[ 2 ] + z * gridSize[ 2 ]; - + /* set inhibit sphere */ - if( gridSize[ 0 ] > gridSize[ 1 ] && gridSize[ 0 ] > gridSize[ 2 ] ) + if ( gridSize[ 0 ] > gridSize[ 1 ] && gridSize[ 0 ] > gridSize[ 2 ] ) { trace.inhibitRadius = gridSize[ 0 ] * 0.5f; - else if( gridSize[ 1 ] > gridSize[ 0 ] && gridSize[ 1 ] > gridSize[ 2 ] ) + } + else if ( gridSize[ 1 ] > gridSize[ 0 ] && gridSize[ 1 ] > gridSize[ 2 ] ) { trace.inhibitRadius = gridSize[ 1 ] * 0.5f; - else + } + else{ trace.inhibitRadius = gridSize[ 2 ] * 0.5f; - + } + /* find point cluster */ trace.cluster = ClusterForPointExt( trace.origin, GRID_EPSILON ); - if( trace.cluster < 0 ) - { + if ( trace.cluster < 0 ) { /* try to nudge the origin around to find a valid point */ VectorCopy( trace.origin, baseOrigin ); - for( step = 0; (step += 0.005) <= 1.0; ) + for ( step = 0; ( step += 0.005 ) <= 1.0; ) { VectorCopy( baseOrigin, trace.origin ); - trace.origin[ 0 ] += step * (Random() - 0.5) * gridSize[0]; - trace.origin[ 1 ] += step * (Random() - 0.5) * gridSize[1]; - trace.origin[ 2 ] += step * (Random() - 0.5) * gridSize[2]; - + trace.origin[ 0 ] += step * ( Random() - 0.5 ) * gridSize[0]; + trace.origin[ 1 ] += step * ( Random() - 0.5 ) * gridSize[1]; + trace.origin[ 2 ] += step * ( Random() - 0.5 ) * gridSize[2]; + /* ydnar: changed to find cluster num */ trace.cluster = ClusterForPointExt( trace.origin, VERTEX_EPSILON ); - if( trace.cluster >= 0 ) + if ( trace.cluster >= 0 ) { break; + } } - + /* can't find a valid point at all */ - if( step > 1.0 ) + if ( step > 1.0 ) { return; + } } - + /* setup trace */ trace.testOcclusion = !noTrace; trace.forceSunlight = qfalse; @@ -1540,51 +1589,54 @@ void TraceGrid( int num ) trace.surfaces = NULL; trace.numLights = 0; trace.lights = NULL; - + /* clear */ numCon = 0; VectorClear( cheapColor ); - + /* 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 ( trace.light = lights; trace.light != NULL; trace.light = trace.light->next ) { - float addSize; - - + float addSize; + + /* sample light */ - if( !LightContributionToPoint( &trace ) ) + if ( !LightContributionToPoint( &trace ) ) { continue; - + } + /* handle negative light */ - if( trace.light->flags & LIGHT_NEGATIVE ) + if ( trace.light->flags & LIGHT_NEGATIVE ) { VectorScale( trace.color, -1.0f, trace.color ); - + } + /* add a contribution */ VectorCopy( trace.color, contributions[ numCon ].color ); VectorCopy( trace.direction, contributions[ numCon ].dir ); VectorClear( contributions[ numCon ].ambient ); contributions[ numCon ].style = trace.light->style; numCon++; - + /* push average direction around */ addSize = VectorLength( trace.color ); VectorMA( gp->dir, addSize, trace.direction, gp->dir ); - + /* stop after a while */ - if( numCon >= (MAX_CONTRIBUTIONS - 1) ) + if ( numCon >= ( MAX_CONTRIBUTIONS - 1 ) ) { break; - + } + /* ydnar: cheap mode */ VectorAdd( cheapColor, trace.color, cheapColor ); - if( cheapgrid && cheapColor[ 0 ] >= 255.0f && cheapColor[ 1 ] >= 255.0f && cheapColor[ 2 ] >= 255.0f ) + if ( cheapgrid && cheapColor[ 0 ] >= 255.0f && cheapColor[ 1 ] >= 255.0f && cheapColor[ 2 ] >= 255.0f ) { break; + } } - + /////// Floodlighting for point ////////////////// //do our floodlight ambient occlusion loop, and add a single contribution based on the brightest dir - if( floodlighty ) - { + if ( floodlighty ) { int k; float addSize, f; vec3_t dir = { 0, 0, 1 }; @@ -1595,10 +1647,9 @@ void TraceGrid( int num ) trace.inhibitRadius = DEFAULT_INHIBIT_RADIUS; trace.testAll = qtrue; - for( k = 0; k < 2; k++ ) + for ( k = 0; k < 2; k++ ) { - if( k == 0 ) // upper hemisphere - { + if ( k == 0 ) { // upper hemisphere trace.normal[0] = 0; trace.normal[1] = 0; trace.normal[2] = 1; @@ -1613,13 +1664,13 @@ void TraceGrid( int num ) f = FloodLightForSample( &trace, floodlightDistance, floodlight_lowquality ); /* add a fraction as pure ambient, half as top-down direction */ - contributions[ numCon ].color[0]= floodlightRGB[0] * floodlightIntensity * f * ( 1.0f - ambientFrac ); - contributions[ numCon ].color[1]= floodlightRGB[1] * floodlightIntensity * f * ( 1.0f - ambientFrac ); - contributions[ numCon ].color[2]= floodlightRGB[2] * floodlightIntensity * f * ( 1.0f - ambientFrac ); + contributions[ numCon ].color[0] = floodlightRGB[0] * floodlightIntensity * f * ( 1.0f - ambientFrac ); + contributions[ numCon ].color[1] = floodlightRGB[1] * floodlightIntensity * f * ( 1.0f - ambientFrac ); + contributions[ numCon ].color[2] = floodlightRGB[2] * floodlightIntensity * f * ( 1.0f - ambientFrac ); - contributions[ numCon ].ambient[0]= floodlightRGB[0] * floodlightIntensity * f * ambientFrac; - contributions[ numCon ].ambient[1]= floodlightRGB[1] * floodlightIntensity * f * ambientFrac; - contributions[ numCon ].ambient[2]= floodlightRGB[2] * floodlightIntensity * f * ambientFrac; + contributions[ numCon ].ambient[0] = floodlightRGB[0] * floodlightIntensity * f * ambientFrac; + contributions[ numCon ].ambient[1] = floodlightRGB[1] * floodlightIntensity * f * ambientFrac; + contributions[ numCon ].ambient[2] = floodlightRGB[2] * floodlightIntensity * f * ambientFrac; contributions[ numCon ].dir[0] = dir[0]; contributions[ numCon ].dir[1] = dir[1]; @@ -1638,53 +1689,54 @@ void TraceGrid( int num ) /* normalize to get primary light direction */ VectorNormalize( gp->dir, thisdir ); - + /* now that we have identified the primary light direction, go back and separate all the light into directed and ambient */ numStyles = 1; - for( i = 0; i < numCon; i++ ) + for ( i = 0; i < numCon; i++ ) { /* get relative directed strength */ d = DotProduct( contributions[ i ].dir, thisdir ); /* we map 1 to gridDirectionality, and 0 to gridAmbientDirectionality */ - d = gridAmbientDirectionality + d * (gridDirectionality - gridAmbientDirectionality); - if( d < 0.0f ) + d = gridAmbientDirectionality + d * ( gridDirectionality - gridAmbientDirectionality ); + if ( d < 0.0f ) { d = 0.0f; - + } + /* find appropriate style */ - for( j = 0; j < numStyles; j++ ) + for ( j = 0; j < numStyles; j++ ) { - if( gp->styles[ j ] == contributions[ i ].style ) + if ( gp->styles[ j ] == contributions[ i ].style ) { break; + } } - + /* style not found? */ - if( j >= numStyles ) - { + if ( j >= numStyles ) { /* add a new style */ - if( numStyles < MAX_LIGHTMAPS ) - { + if ( numStyles < MAX_LIGHTMAPS ) { gp->styles[ numStyles ] = contributions[ i ].style; bgp->styles[ numStyles ] = contributions[ i ].style; numStyles++; //% Sys_Printf( "(%d, %d) ", num, contributions[ i ].style ); } - + /* fallback */ - else + else{ j = 0; + } } - + /* add the directed color */ VectorMA( gp->directed[ j ], d, contributions[ i ].color, gp->directed[ j ] ); - + /* ambient light will be at 1/4 the value of directed light */ /* (ydnar: nuke this in favor of more dramatic lighting?) */ /* (PM: how about actually making it work? d=1 when it got here for single lights/sun :P */ // d = 0.25f; /* (Hobbes: always setting it to .25 is hardly any better) */ - d = 0.25f * (1.0f - d); + d = 0.25f * ( 1.0f - d ); VectorMA( gp->ambient[ j ], d, contributions[ i ].color, gp->ambient[ j ] ); VectorAdd( gp->ambient[ j ], contributions[ i ].ambient, gp->ambient[ j ] ); @@ -1702,37 +1754,39 @@ void TraceGrid( int num ) * So, 0.25f * (1.0f - d) IS RIGHT. If you want to tune it, tune d BEFORE. */ } - - + + /* store off sample */ - for( i = 0; i < MAX_LIGHTMAPS; i++ ) + for ( i = 0; i < MAX_LIGHTMAPS; i++ ) { #if 0 /* do some fudging to keep the ambient from being too low (2003-07-05: 0.25 -> 0.125) */ - if( !bouncing ) + if ( !bouncing ) { VectorMA( gp->ambient[ i ], 0.125f, gp->directed[ i ], gp->ambient[ i ] ); + } #endif - + /* set minimum light and copy off to bytes */ VectorCopy( gp->ambient[ i ], color ); - for( j = 0; j < 3; j++ ) - if( color[ j ] < minGridLight[ j ] ) + for ( j = 0; j < 3; j++ ) + if ( color[ j ] < minGridLight[ j ] ) { color[ j ] = minGridLight[ j ]; + } /* vortex: apply gridscale and gridambientscale here */ - ColorToBytes( color, bgp->ambient[ i ], gridScale*gridAmbientScale ); + ColorToBytes( color, bgp->ambient[ i ], gridScale * gridAmbientScale ); ColorToBytes( gp->directed[ i ], bgp->directed[ i ], gridScale ); } - + /* debug code */ #if 0 - //% Sys_FPrintf( SYS_VRB, "%10d %10d %10d ", &gp->ambient[ 0 ][ 0 ], &gp->ambient[ 0 ][ 1 ], &gp->ambient[ 0 ][ 2 ] ); - Sys_FPrintf( SYS_VRB, "%9d Amb: (%03.1f %03.1f %03.1f) Dir: (%03.1f %03.1f %03.1f)\n", - num, - gp->ambient[ 0 ][ 0 ], gp->ambient[ 0 ][ 1 ], gp->ambient[ 0 ][ 2 ], - gp->directed[ 0 ][ 0 ], gp->directed[ 0 ][ 1 ], gp->directed[ 0 ][ 2 ] ); + //% Sys_FPrintf( SYS_VRB, "%10d %10d %10d ", &gp->ambient[ 0 ][ 0 ], &gp->ambient[ 0 ][ 1 ], &gp->ambient[ 0 ][ 2 ] ); + Sys_FPrintf( SYS_VRB, "%9d Amb: (%03.1f %03.1f %03.1f) Dir: (%03.1f %03.1f %03.1f)\n", + num, + gp->ambient[ 0 ][ 0 ], gp->ambient[ 0 ][ 1 ], gp->ambient[ 0 ][ 2 ], + gp->directed[ 0 ][ 0 ], gp->directed[ 0 ][ 1 ], gp->directed[ 0 ][ 2 ] ); #endif - + /* store direction */ NormalToLatLong( thisdir, bgp->latLong ); } @@ -1740,89 +1794,91 @@ void TraceGrid( int num ) /* -SetupGrid() -calculates the size of the lightgrid and allocates memory -*/ + SetupGrid() + calculates the size of the lightgrid and allocates memory + */ + +void SetupGrid( void ){ + int i, j; + vec3_t maxs, oldGridSize; + const char *value; + char temp[ 64 ]; + -void SetupGrid( void ) -{ - int i, j; - vec3_t maxs, oldGridSize; - const char *value; - char temp[ 64 ]; - - /* don't do this if not grid lighting */ - if( noGridLighting ) + if ( noGridLighting ) { return; - + } + /* ydnar: set grid size */ value = ValueForKey( &entities[ 0 ], "gridsize" ); - if( value[ 0 ] != '\0' ) + if ( value[ 0 ] != '\0' ) { sscanf( value, "%f %f %f", &gridSize[ 0 ], &gridSize[ 1 ], &gridSize[ 2 ] ); - + } + /* quantize it */ VectorCopy( gridSize, oldGridSize ); - for( i = 0; i < 3; i++ ) + for ( i = 0; i < 3; i++ ) gridSize[ i ] = gridSize[ i ] >= 8.0f ? floor( gridSize[ i ] ) : 8.0f; - + /* ydnar: increase gridSize until grid count is smaller than max allowed */ numRawGridPoints = MAX_MAP_LIGHTGRID + 1; j = 0; - while( numRawGridPoints > MAX_MAP_LIGHTGRID ) + while ( numRawGridPoints > MAX_MAP_LIGHTGRID ) { /* get world bounds */ - for( i = 0; i < 3; i++ ) + for ( i = 0; i < 3; i++ ) { gridMins[ i ] = gridSize[ i ] * ceil( bspModels[ 0 ].mins[ i ] / gridSize[ i ] ); maxs[ i ] = gridSize[ i ] * floor( bspModels[ 0 ].maxs[ i ] / gridSize[ i ] ); - gridBounds[ i ] = (maxs[ i ] - gridMins[ i ]) / gridSize[ i ] + 1; + gridBounds[ i ] = ( maxs[ i ] - gridMins[ i ] ) / gridSize[ i ] + 1; } - + /* set grid size */ numRawGridPoints = gridBounds[ 0 ] * gridBounds[ 1 ] * gridBounds[ 2 ]; - + /* increase grid size a bit */ - if( numRawGridPoints > MAX_MAP_LIGHTGRID ) + if ( numRawGridPoints > MAX_MAP_LIGHTGRID ) { gridSize[ j++ % 3 ] += 16.0f; + } } - + /* print it */ Sys_Printf( "Grid size = { %1.0f, %1.0f, %1.0f }\n", gridSize[ 0 ], gridSize[ 1 ], gridSize[ 2 ] ); - + /* different? */ - if( !VectorCompare( gridSize, oldGridSize ) ) - { + if ( !VectorCompare( gridSize, oldGridSize ) ) { sprintf( temp, "%.0f %.0f %.0f", gridSize[ 0 ], gridSize[ 1 ], gridSize[ 2 ] ); SetKeyValue( &entities[ 0 ], "gridsize", (const char*) temp ); Sys_FPrintf( SYS_VRB, "Storing adjusted grid size\n" ); } - + /* 2nd variable. fixme: is this silly? */ numBSPGridPoints = numRawGridPoints; - + /* allocate lightgrid */ rawGridPoints = safe_malloc( numRawGridPoints * sizeof( *rawGridPoints ) ); memset( rawGridPoints, 0, numRawGridPoints * sizeof( *rawGridPoints ) ); - - if( bspGridPoints != NULL ) + + if ( bspGridPoints != NULL ) { free( bspGridPoints ); + } bspGridPoints = safe_malloc( numBSPGridPoints * sizeof( *bspGridPoints ) ); memset( bspGridPoints, 0, numBSPGridPoints * sizeof( *bspGridPoints ) ); - + /* clear lightgrid */ - for( i = 0; i < numRawGridPoints; i++ ) + for ( i = 0; i < numRawGridPoints; i++ ) { VectorCopy( ambientColor, rawGridPoints[ i ].ambient[ j ] ); rawGridPoints[ i ].styles[ 0 ] = LS_NORMAL; bspGridPoints[ i ].styles[ 0 ] = LS_NORMAL; - for( j = 1; j < MAX_LIGHTMAPS; j++ ) + for ( j = 1; j < MAX_LIGHTMAPS; j++ ) { rawGridPoints[ i ].styles[ j ] = LS_NONE; bspGridPoints[ i ].styles[ j ] = LS_NONE; } } - + /* note it */ Sys_Printf( "%9d grid points\n", numRawGridPoints ); } @@ -1830,79 +1886,77 @@ void SetupGrid( void ) /* -LightWorld() -does what it says... -*/ + LightWorld() + does what it says... + */ + +void LightWorld( const char *BSPFilePath, qboolean fastAllocate ){ + vec3_t color; + float f; + int b, bt; + qboolean minVertex, minGrid; + const char *value; -void LightWorld( void ) -{ - vec3_t color; - float f; - int b, bt; - qboolean minVertex, minGrid; - const char *value; - /* ydnar: smooth normals */ - if( shade ) - { + if ( shade ) { Sys_Printf( "--- SmoothNormals ---\n" ); SmoothNormals(); } - + /* determine the number of grid points */ Sys_Printf( "--- SetupGrid ---\n" ); SetupGrid(); - + /* find the optional minimum lighting values */ GetVectorForKey( &entities[ 0 ], "_color", color ); - if (colorsRGB) - { - color[0] = Image_LinearFloatFromsRGBFloat(color[0]); - color[1] = Image_LinearFloatFromsRGBFloat(color[1]); - color[2] = Image_LinearFloatFromsRGBFloat(color[2]); - } - if( VectorLength( color ) == 0.0f ) + if ( VectorLength( color ) == 0.0f ) { VectorSet( color, 1.0, 1.0, 1.0 ); - + } + if ( colorsRGB ) { + color[0] = Image_LinearFloatFromsRGBFloat( color[0] ); + color[1] = Image_LinearFloatFromsRGBFloat( color[1] ); + color[2] = Image_LinearFloatFromsRGBFloat( color[2] ); + } + /* ambient */ f = FloatForKey( &entities[ 0 ], "_ambient" ); - if( f == 0.0f ) + if ( f == 0.0f ) { f = FloatForKey( &entities[ 0 ], "ambient" ); + } VectorScale( color, f, ambientColor ); - + /* minvertexlight */ minVertex = qfalse; value = ValueForKey( &entities[ 0 ], "_minvertexlight" ); - if( value[ 0 ] != '\0' ) - { + if ( value[ 0 ] != '\0' ) { minVertex = qtrue; f = atof( value ); VectorScale( color, f, minVertexLight ); } - + /* mingridlight */ minGrid = qfalse; value = ValueForKey( &entities[ 0 ], "_mingridlight" ); - if( value[ 0 ] != '\0' ) - { + if ( value[ 0 ] != '\0' ) { minGrid = qtrue; f = atof( value ); VectorScale( color, f, minGridLight ); } - + /* minlight */ value = ValueForKey( &entities[ 0 ], "_minlight" ); - if( value[ 0 ] != '\0' ) - { + if ( value[ 0 ] != '\0' ) { f = atof( value ); VectorScale( color, f, minLight ); - if( minVertex == qfalse ) + if ( minVertex == qfalse ) { VectorScale( color, f, minVertexLight ); - if( minGrid == qfalse ) + } + if ( minGrid == qfalse ) { VectorScale( color, f, minGridLight ); + } } - + /* create world lights */ Sys_FPrintf( SYS_VRB, "--- CreateLights ---\n" ); CreateEntityLights(); @@ -1911,107 +1965,103 @@ void LightWorld( void ) Sys_Printf( "%9d spotlights\n", numSpotLights ); Sys_Printf( "%9d diffuse (area) lights\n", numDiffuseLights ); Sys_Printf( "%9d sun/sky lights\n", numSunLights ); - + /* calculate lightgrid */ - if( !noGridLighting ) - { + if ( !noGridLighting ) { /* ydnar: set up light envelopes */ SetupEnvelopes( qtrue, fastgrid ); - + Sys_Printf( "--- TraceGrid ---\n" ); inGrid = qtrue; RunThreadsOnIndividual( numRawGridPoints, qtrue, TraceGrid ); inGrid = qfalse; Sys_Printf( "%d x %d x %d = %d grid\n", - gridBounds[ 0 ], gridBounds[ 1 ], gridBounds[ 2 ], numBSPGridPoints ); - + gridBounds[ 0 ], gridBounds[ 1 ], gridBounds[ 2 ], numBSPGridPoints ); + /* ydnar: emit statistics on light culling */ Sys_FPrintf( SYS_VRB, "%9d grid points envelope culled\n", gridEnvelopeCulled ); Sys_FPrintf( SYS_VRB, "%9d grid points bounds culled\n", gridBoundsCulled ); } - + /* slight optimization to remove a sqrt */ subdivideThreshold *= subdivideThreshold; - + /* map the world luxels */ Sys_Printf( "--- MapRawLightmap ---\n" ); RunThreadsOnIndividual( numRawLightmaps, qtrue, MapRawLightmap ); Sys_Printf( "%9d luxels\n", numLuxels ); Sys_Printf( "%9d luxels mapped\n", numLuxelsMapped ); Sys_Printf( "%9d luxels occluded\n", numLuxelsOccluded ); - + /* dirty them up */ - if( dirty ) - { + if ( dirty ) { Sys_Printf( "--- DirtyRawLightmap ---\n" ); RunThreadsOnIndividual( numRawLightmaps, qtrue, DirtyRawLightmap ); } - + /* floodlight pass */ FloodlightRawLightmaps(); /* ydnar: set up light envelopes */ SetupEnvelopes( qfalse, fast ); - + /* light up my world */ lightsPlaneCulled = 0; lightsEnvelopeCulled = 0; lightsBoundsCulled = 0; lightsClusterCulled = 0; - + Sys_Printf( "--- IlluminateRawLightmap ---\n" ); RunThreadsOnIndividual( numRawLightmaps, qtrue, IlluminateRawLightmap ); Sys_Printf( "%9d luxels illuminated\n", numLuxelsIlluminated ); - + StitchSurfaceLightmaps(); - + Sys_Printf( "--- IlluminateVertexes ---\n" ); RunThreadsOnIndividual( numBSPDrawSurfaces, qtrue, IlluminateVertexes ); Sys_Printf( "%9d vertexes illuminated\n", numVertsIlluminated ); - + /* ydnar: emit statistics on light culling */ Sys_FPrintf( SYS_VRB, "%9d lights plane culled\n", lightsPlaneCulled ); Sys_FPrintf( SYS_VRB, "%9d lights envelope culled\n", lightsEnvelopeCulled ); Sys_FPrintf( SYS_VRB, "%9d lights bounds culled\n", lightsBoundsCulled ); Sys_FPrintf( SYS_VRB, "%9d lights cluster culled\n", lightsClusterCulled ); - + /* radiosity */ b = 1; bt = bounce; - while( bounce > 0 ) + while ( bounce > 0 ) { /* store off the bsp between bounces */ - StoreSurfaceLightmaps(); + StoreSurfaceLightmaps( fastAllocate ); UnparseEntities(); - Sys_Printf( "Writing %s\n", source ); - WriteBSPFile( source ); - + Sys_Printf( "Writing %s\n", BSPFilePath ); + WriteBSPFile( BSPFilePath ); + /* note it */ Sys_Printf( "\n--- Radiosity (bounce %d of %d) ---\n", b, bt ); - + /* flag bouncing */ bouncing = qtrue; VectorClear( ambientColor ); floodlighty = qfalse; - + /* generate diffuse lights */ RadFreeLights(); RadCreateDiffuseLights(); - + /* setup light envelopes */ SetupEnvelopes( qfalse, fastbounce ); - if( numLights == 0 ) - { + if ( numLights == 0 ) { Sys_Printf( "No diffuse light to calculate, ending radiosity.\n" ); break; } - + /* add to lightgrid */ - if( bouncegrid ) - { + if ( bouncegrid ) { gridEnvelopeCulled = 0; gridBoundsCulled = 0; - + Sys_Printf( "--- BounceGrid ---\n" ); inGrid = qtrue; RunThreadsOnIndividual( numRawGridPoints, qtrue, TraceGrid ); @@ -2019,30 +2069,30 @@ void LightWorld( void ) Sys_FPrintf( SYS_VRB, "%9d grid points envelope culled\n", gridEnvelopeCulled ); Sys_FPrintf( SYS_VRB, "%9d grid points bounds culled\n", gridBoundsCulled ); } - + /* light up my world */ lightsPlaneCulled = 0; lightsEnvelopeCulled = 0; lightsBoundsCulled = 0; lightsClusterCulled = 0; - + Sys_Printf( "--- IlluminateRawLightmap ---\n" ); RunThreadsOnIndividual( numRawLightmaps, qtrue, IlluminateRawLightmap ); Sys_Printf( "%9d luxels illuminated\n", numLuxelsIlluminated ); Sys_Printf( "%9d vertexes illuminated\n", numVertsIlluminated ); - + StitchSurfaceLightmaps(); - + Sys_Printf( "--- IlluminateVertexes ---\n" ); RunThreadsOnIndividual( numBSPDrawSurfaces, qtrue, IlluminateVertexes ); Sys_Printf( "%9d vertexes illuminated\n", numVertsIlluminated ); - + /* ydnar: emit statistics on light culling */ Sys_FPrintf( SYS_VRB, "%9d lights plane culled\n", lightsPlaneCulled ); Sys_FPrintf( SYS_VRB, "%9d lights envelope culled\n", lightsEnvelopeCulled ); Sys_FPrintf( SYS_VRB, "%9d lights bounds culled\n", lightsBoundsCulled ); Sys_FPrintf( SYS_VRB, "%9d lights cluster culled\n", lightsClusterCulled ); - + /* interate */ bounce--; b++; @@ -2052,30 +2102,35 @@ void LightWorld( void ) /* -LightMain() -main routine for light processing -*/ + LightMain() + main routine for light processing + */ -int LightMain( int argc, char **argv ) -{ - int i; - float f; - char mapSource[ 1024 ]; - const char *value; +int LightMain( int argc, char **argv ){ + int i; + float f; + char BSPFilePath[ 1024 ]; + char surfaceFilePath[ 1024 ]; + BSPFilePath[0] = 0; + surfaceFilePath[0] = 0; + const char *value; int lightmapMergeSize = 0; - qboolean lightSamplesInsist = qfalse; - - + qboolean lightSamplesInsist = qfalse; + qboolean fastAllocate = qfalse; + + /* note it */ Sys_Printf( "--- Light ---\n" ); Sys_Printf( "--- ProcessGameSpecific ---\n" ); /* set standard game flags */ wolfLight = game->wolfLight; - if (wolfLight == qtrue) + if ( wolfLight == qtrue ) { Sys_Printf( " lightning model: wolf\n" ); - else + } + else{ Sys_Printf( " lightning model: quake3\n" ); + } lmCustomSize = game->lightmapSize; Sys_Printf( " lightmap size: %d x %d pixels\n", lmCustomSize, lmCustomSize ); @@ -2084,22 +2139,28 @@ int LightMain( int argc, char **argv ) Sys_Printf( " lightning gamma: %f\n", lightmapGamma ); lightmapsRGB = game->lightmapsRGB; - if(lightmapsRGB) + if ( lightmapsRGB ) { Sys_Printf( " lightmap colorspace: sRGB\n" ); - else + } + else{ Sys_Printf( " lightmap colorspace: linear\n" ); + } texturesRGB = game->texturesRGB; - if(texturesRGB) + if ( texturesRGB ) { Sys_Printf( " texture colorspace: sRGB\n" ); - else + } + else{ Sys_Printf( " texture colorspace: linear\n" ); + } colorsRGB = game->colorsRGB; - if(colorsRGB) + if ( colorsRGB ) { Sys_Printf( " _color colorspace: sRGB\n" ); - else + } + else{ Sys_Printf( " _color colorspace: linear\n" ); + } lightmapCompensate = game->lightmapCompensate; Sys_Printf( " lightning compensation: %f\n", lightmapCompensate ); @@ -2114,41 +2175,47 @@ int LightMain( int argc, char **argv ) Sys_Printf( " lightgrid ambient scale: %f\n", gridAmbientScale ); lightAngleHL = game->lightAngleHL; - if( lightAngleHL ) + if ( lightAngleHL ) { Sys_Printf( " half lambert light angle attenuation enabled \n" ); + } noStyles = game->noStyles; - if (noStyles == qtrue) + if ( noStyles == qtrue ) { Sys_Printf( " shader lightstyles hack: disabled\n" ); - else + } + else{ Sys_Printf( " shader lightstyles hack: enabled\n" ); + } patchShadows = game->patchShadows; - if (patchShadows == qtrue) + if ( patchShadows == qtrue ) { Sys_Printf( " patch shadows: enabled\n" ); - else + } + else{ Sys_Printf( " patch shadows: disabled\n" ); + } deluxemap = game->deluxeMap; deluxemode = game->deluxeMode; - if (deluxemap == qtrue) - { - if (deluxemode) + if ( deluxemap == qtrue ) { + if ( deluxemode ) { Sys_Printf( " deluxemapping: enabled with tangentspace deluxemaps\n" ); - else + } + else{ Sys_Printf( " deluxemapping: enabled with modelspace deluxemaps\n" ); + } } - else + else{ Sys_Printf( " deluxemapping: disabled\n" ); + } Sys_Printf( "--- ProcessCommandLine ---\n" ); - + /* process commandline arguments */ - for( i = 1; i < (argc - 1); i++ ) + for ( i = 1; i < ( argc - 1 ); i++ ) { /* lightsource scaling */ - if( !strcmp( argv[ i ], "-point" ) || !strcmp( argv[ i ], "-pointscale" ) ) - { + if ( !strcmp( argv[ i ], "-point" ) || !strcmp( argv[ i ], "-pointscale" ) ) { f = atof( argv[ i + 1 ] ); pointScale *= f; spotScale *= f; @@ -2156,49 +2223,43 @@ int LightMain( int argc, char **argv ) Sys_Printf( "Spot point (entity) light scaled by %f to %f\n", f, spotScale ); i++; } - - else if( !strcmp( argv[ i ], "-spherical" ) || !strcmp( argv[ i ], "-sphericalscale" ) ) - { + + else if ( !strcmp( argv[ i ], "-spherical" ) || !strcmp( argv[ i ], "-sphericalscale" ) ) { f = atof( argv[ i + 1 ] ); pointScale *= f; Sys_Printf( "Spherical point (entity) light scaled by %f to %f\n", f, pointScale ); i++; } - - else if( !strcmp( argv[ i ], "-spot" ) || !strcmp( argv[ i ], "-spotscale" ) ) - { + + else if ( !strcmp( argv[ i ], "-spot" ) || !strcmp( argv[ i ], "-spotscale" ) ) { f = atof( argv[ i + 1 ] ); spotScale *= f; Sys_Printf( "Spot point (entity) light scaled by %f to %f\n", f, spotScale ); i++; } - - else if( !strcmp( argv[ i ], "-area" ) || !strcmp( argv[ i ], "-areascale" ) ) - { + + else if ( !strcmp( argv[ i ], "-area" ) || !strcmp( argv[ i ], "-areascale" ) ) { f = atof( argv[ i + 1 ] ); areaScale *= f; Sys_Printf( "Area (shader) light scaled by %f to %f\n", f, areaScale ); i++; } - - else if( !strcmp( argv[ i ], "-sky" ) || !strcmp( argv[ i ], "-skyscale" ) ) - { + + else if ( !strcmp( argv[ i ], "-sky" ) || !strcmp( argv[ i ], "-skyscale" ) ) { f = atof( argv[ i + 1 ] ); skyScale *= f; Sys_Printf( "Sky/sun light scaled by %f to %f\n", f, skyScale ); i++; } - - else if( !strcmp( argv[ i ], "-bouncescale" ) ) - { + + else if ( !strcmp( argv[ i ], "-bouncescale" ) ) { f = atof( argv[ i + 1 ] ); bounceScale *= f; Sys_Printf( "Bounce (radiosity) light scaled by %f to %f\n", f, bounceScale ); i++; } - - else if( !strcmp( argv[ i ], "-scale" ) ) - { + + else if ( !strcmp( argv[ i ], "-scale" ) ) { f = atof( argv[ i + 1 ] ); pointScale *= f; spotScale *= f; @@ -2209,647 +2270,616 @@ int LightMain( int argc, char **argv ) i++; } - else if( !strcmp( argv[ i ], "-gridscale" ) ) - { + else if ( !strcmp( argv[ i ], "-gridscale" ) ) { f = atof( argv[ i + 1 ] ); Sys_Printf( "Grid lightning scaled by %f\n", f ); gridScale *= f; i++; } - else if( !strcmp( argv[ i ], "-gridambientscale" ) ) - { + else if ( !strcmp( argv[ i ], "-gridambientscale" ) ) { f = atof( argv[ i + 1 ] ); Sys_Printf( "Grid ambient lightning scaled by %f\n", f ); gridAmbientScale *= f; i++; } - else if( !strcmp( argv[ i ], "-griddirectionality" ) ) - { + else if ( !strcmp( argv[ i ], "-griddirectionality" ) ) { f = atof( argv[ i + 1 ] ); - if(f > 1) f = 1; - if(f < gridAmbientDirectionality) gridAmbientDirectionality = f; + if ( f > 1 ) { + f = 1; + } + if ( f < gridAmbientDirectionality ) { + gridAmbientDirectionality = f; + } Sys_Printf( "Grid directionality is %f\n", f ); gridDirectionality = f; i++; } - else if( !strcmp( argv[ i ], "-gridambientdirectionality" ) ) - { + else if ( !strcmp( argv[ i ], "-gridambientdirectionality" ) ) { f = atof( argv[ i + 1 ] ); - if(f < -1) f = -1; - if(f > gridDirectionality) gridDirectionality = f; + if ( f < -1 ) { + f = -1; + } + if ( f > gridDirectionality ) { + gridDirectionality = f; + } Sys_Printf( "Grid ambient directionality is %f\n", f ); gridAmbientDirectionality = f; i++; } - - else if( !strcmp( argv[ i ], "-gamma" ) ) - { + + else if ( !strcmp( argv[ i ], "-gamma" ) ) { f = atof( argv[ i + 1 ] ); lightmapGamma = f; Sys_Printf( "Lighting gamma set to %f\n", lightmapGamma ); i++; } - - else if( !strcmp( argv[ i ], "-sRGBlight" ) ) - { + + else if ( !strcmp( argv[ i ], "-sRGBlight" ) ) { lightmapsRGB = qtrue; Sys_Printf( "Lighting is in sRGB\n" ); } - else if( !strcmp( argv[ i ], "-nosRGBlight" ) ) - { + else if ( !strcmp( argv[ i ], "-nosRGBlight" ) ) { lightmapsRGB = qfalse; Sys_Printf( "Lighting is linear\n" ); } - else if( !strcmp( argv[ i ], "-sRGBtex" ) ) - { + else if ( !strcmp( argv[ i ], "-sRGBtex" ) ) { texturesRGB = qtrue; Sys_Printf( "Textures are in sRGB\n" ); } - else if( !strcmp( argv[ i ], "-nosRGBtex" ) ) - { + else if ( !strcmp( argv[ i ], "-nosRGBtex" ) ) { texturesRGB = qfalse; Sys_Printf( "Textures are linear\n" ); } - else if( !strcmp( argv[ i ], "-sRGBcolor" ) ) - { + else if ( !strcmp( argv[ i ], "-sRGBcolor" ) ) { colorsRGB = qtrue; Sys_Printf( "Colors are in sRGB\n" ); } - else if( !strcmp( argv[ i ], "-nosRGBcolor" ) ) - { + else if ( !strcmp( argv[ i ], "-nosRGBcolor" ) ) { colorsRGB = qfalse; Sys_Printf( "Colors are linear\n" ); } - else if( !strcmp( argv[ i ], "-nosRGB" ) ) - { + else if ( !strcmp( argv[ i ], "-sRGB" ) ) { lightmapsRGB = qtrue; - Sys_Printf( "Lighting is linear\n" ); + Sys_Printf( "Lighting is in sRGB\n" ); texturesRGB = qtrue; - Sys_Printf( "Textures are linear\n" ); + Sys_Printf( "Textures are in sRGB\n" ); colorsRGB = qtrue; + Sys_Printf( "Colors are in sRGB\n" ); + } + + else if ( !strcmp( argv[ i ], "-nosRGB" ) ) { + lightmapsRGB = qfalse; + Sys_Printf( "Lighting is linear\n" ); + texturesRGB = qfalse; + Sys_Printf( "Textures are linear\n" ); + colorsRGB = qfalse; Sys_Printf( "Colors are linear\n" ); } - else if( !strcmp( argv[ i ], "-exposure" ) ) - { + else if ( !strcmp( argv[ i ], "-exposure" ) ) { f = atof( argv[ i + 1 ] ); lightmapExposure = f; Sys_Printf( "Lighting exposure set to %f\n", lightmapExposure ); i++; } - else if( !strcmp( argv[ i ], "-compensate" ) ) - { + else if ( !strcmp( argv[ i ], "-compensate" ) ) { f = atof( argv[ i + 1 ] ); - if( f <= 0.0f ) + if ( f <= 0.0f ) { f = 1.0f; + } lightmapCompensate = f; Sys_Printf( "Lighting compensation set to 1/%f\n", lightmapCompensate ); i++; } - + /* ydnar switches */ - else if( !strcmp( argv[ i ], "-bounce" ) ) - { + else if ( !strcmp( argv[ i ], "-bounce" ) ) { bounce = atoi( argv[ i + 1 ] ); - if( bounce < 0 ) + if ( bounce < 0 ) { bounce = 0; - else if( bounce > 0 ) + } + else if ( bounce > 0 ) { Sys_Printf( "Radiosity enabled with %d bounce(s)\n", bounce ); + } i++; } - - else if( !strcmp( argv[ i ], "-supersample" ) || !strcmp( argv[ i ], "-super" ) ) - { + + else if ( !strcmp( argv[ i ], "-supersample" ) || !strcmp( argv[ i ], "-super" ) ) { superSample = atoi( argv[ i + 1 ] ); - if( superSample < 1 ) + if ( superSample < 1 ) { superSample = 1; - else if( superSample > 1 ) - Sys_Printf( "Ordered-grid supersampling enabled with %d sample(s) per lightmap texel\n", (superSample * superSample) ); + } + else if ( superSample > 1 ) { + Sys_Printf( "Ordered-grid supersampling enabled with %d sample(s) per lightmap texel\n", ( superSample * superSample ) ); + } i++; } - - else if( !strcmp( argv[ i ], "-randomsamples" ) ) - { + + else if ( !strcmp( argv[ i ], "-randomsamples" ) ) { lightRandomSamples = qtrue; Sys_Printf( "Random sampling enabled\n", lightRandomSamples ); } - - else if( !strcmp( argv[ i ], "-samples" ) ) - { - if(*argv[i+1] == '+') + + else if ( !strcmp( argv[ i ], "-samples" ) ) { + if ( *argv[i + 1] == '+' ) { lightSamplesInsist = qtrue; - else + } + else{ lightSamplesInsist = qfalse; + } lightSamples = atoi( argv[ i + 1 ] ); - if( lightSamples < 1 ) + if ( lightSamples < 1 ) { lightSamples = 1; - else if( lightSamples > 1 ) + } + else if ( lightSamples > 1 ) { Sys_Printf( "Adaptive supersampling enabled with %d sample(s) per lightmap texel\n", lightSamples ); + } i++; } - - else if( !strcmp( argv[ i ], "-samplessearchboxsize" ) ) - { + + else if ( !strcmp( argv[ i ], "-samplessearchboxsize" ) ) { lightSamplesSearchBoxSize = atoi( argv[ i + 1 ] ); - if( lightSamplesSearchBoxSize <= 0 ) + if ( lightSamplesSearchBoxSize <= 0 ) { lightSamplesSearchBoxSize = 1; - if( lightSamplesSearchBoxSize > 4 ) + } + if ( lightSamplesSearchBoxSize > 4 ) { lightSamplesSearchBoxSize = 4; /* more makes no sense */ - else if( lightSamplesSearchBoxSize != 1 ) + } + else if ( lightSamplesSearchBoxSize != 1 ) { Sys_Printf( "Adaptive supersampling uses %f times the normal search box size\n", lightSamplesSearchBoxSize ); + } i++; } - else if( !strcmp( argv[ i ], "-filter" ) ) - { + else if ( !strcmp( argv[ i ], "-filter" ) ) { filter = qtrue; Sys_Printf( "Lightmap filtering enabled\n" ); } - - else if( !strcmp( argv[ i ], "-dark" ) ) - { + + else if ( !strcmp( argv[ i ], "-dark" ) ) { dark = qtrue; Sys_Printf( "Dark lightmap seams enabled\n" ); } - - else if( !strcmp( argv[ i ], "-shadeangle" ) ) - { + + else if ( !strcmp( argv[ i ], "-shadeangle" ) ) { shadeAngleDegrees = atof( argv[ i + 1 ] ); - if( shadeAngleDegrees < 0.0f ) + if ( shadeAngleDegrees < 0.0f ) { shadeAngleDegrees = 0.0f; - else if( shadeAngleDegrees > 0.0f ) - { + } + else if ( shadeAngleDegrees > 0.0f ) { shade = qtrue; Sys_Printf( "Phong shading enabled with a breaking angle of %f degrees\n", shadeAngleDegrees ); } i++; } - - else if( !strcmp( argv[ i ], "-thresh" ) ) - { + + else if ( !strcmp( argv[ i ], "-thresh" ) ) { subdivideThreshold = atof( argv[ i + 1 ] ); - if( subdivideThreshold < 0 ) + if ( subdivideThreshold < 0 ) { subdivideThreshold = DEFAULT_SUBDIVIDE_THRESHOLD; - else + } + else{ Sys_Printf( "Subdivision threshold set at %.3f\n", subdivideThreshold ); + } i++; } - - else if( !strcmp( argv[ i ], "-approx" ) ) - { + + else if ( !strcmp( argv[ i ], "-approx" ) ) { approximateTolerance = atoi( argv[ i + 1 ] ); - if( approximateTolerance < 0 ) + if ( approximateTolerance < 0 ) { approximateTolerance = 0; - else if( approximateTolerance > 0 ) + } + else if ( approximateTolerance > 0 ) { Sys_Printf( "Approximating lightmaps within a byte tolerance of %d\n", approximateTolerance ); + } i++; } - else if( !strcmp( argv[ i ], "-deluxe" ) || !strcmp( argv[ i ], "-deluxemap" ) ) - { + else if ( !strcmp( argv[ i ], "-deluxe" ) || !strcmp( argv[ i ], "-deluxemap" ) ) { deluxemap = qtrue; Sys_Printf( "Generating deluxemaps for average light direction\n" ); } - else if( !strcmp( argv[ i ], "-deluxemode" )) - { + else if ( !strcmp( argv[ i ], "-deluxemode" ) ) { deluxemode = atoi( argv[ i + 1 ] ); - if (deluxemode == 0 || deluxemode > 1 || deluxemode < 0) - { + if ( deluxemode == 0 || deluxemode > 1 || deluxemode < 0 ) { Sys_Printf( "Generating modelspace deluxemaps\n" ); deluxemode = 0; } - else + else{ Sys_Printf( "Generating tangentspace deluxemaps\n" ); + } i++; } - else if( !strcmp( argv[ i ], "-nodeluxe" ) || !strcmp( argv[ i ], "-nodeluxemap" ) ) - { + else if ( !strcmp( argv[ i ], "-nodeluxe" ) || !strcmp( argv[ i ], "-nodeluxemap" ) ) { deluxemap = qfalse; Sys_Printf( "Disabling generating of deluxemaps for average light direction\n" ); } - else if( !strcmp( argv[ i ], "-external" ) ) - { + else if ( !strcmp( argv[ i ], "-external" ) ) { externalLightmaps = qtrue; Sys_Printf( "Storing all lightmaps externally\n" ); } - else if( !strcmp( argv[ i ], "-lightmapsize" ) ) - { + else if ( !strcmp( argv[ i ], "-lightmapsize" ) ) { lmCustomSize = atoi( argv[ i + 1 ] ); - + /* must be a power of 2 and greater than 2 */ - if( ((lmCustomSize - 1) & lmCustomSize) || lmCustomSize < 2 ) - { + if ( ( ( lmCustomSize - 1 ) & lmCustomSize ) || lmCustomSize < 2 ) { Sys_Printf( "WARNING: Lightmap size must be a power of 2, greater or equal to 2 pixels.\n" ); lmCustomSize = game->lightmapSize; } i++; Sys_Printf( "Default lightmap size set to %d x %d pixels\n", lmCustomSize, lmCustomSize ); - + /* enable external lightmaps */ - if( lmCustomSize != game->lightmapSize ) - { + if ( lmCustomSize != game->lightmapSize ) { externalLightmaps = qtrue; Sys_Printf( "Storing all lightmaps externally\n" ); } } - - else if( !strcmp( argv[ i ], "-rawlightmapsizelimit" ) ) - { + + else if ( !strcmp( argv[ i ], "-rawlightmapsizelimit" ) ) { lmLimitSize = atoi( argv[ i + 1 ] ); - + i++; Sys_Printf( "Raw lightmap size limit set to %d x %d pixels\n", lmLimitSize, lmLimitSize ); } - - else if( !strcmp( argv[ i ], "-lightmapdir" ) ) - { + + else if ( !strcmp( argv[ i ], "-lightmapdir" ) ) { lmCustomDir = argv[i + 1]; i++; Sys_Printf( "Lightmap directory set to %s\n", lmCustomDir ); externalLightmaps = qtrue; Sys_Printf( "Storing all lightmaps externally\n" ); } - + /* ydnar: add this to suppress warnings */ - else if( !strcmp( argv[ i ], "-custinfoparms") ) - { + else if ( !strcmp( argv[ i ], "-custinfoparms" ) ) { Sys_Printf( "Custom info parms enabled\n" ); useCustomInfoParms = qtrue; } - - else if( !strcmp( argv[ i ], "-wolf" ) ) - { + + else if ( !strcmp( argv[ i ], "-wolf" ) ) { /* -game should already be set */ wolfLight = qtrue; Sys_Printf( "Enabling Wolf lighting model (linear default)\n" ); } - - else if( !strcmp( argv[ i ], "-q3" ) ) - { + + else if ( !strcmp( argv[ i ], "-q3" ) ) { /* -game should already be set */ wolfLight = qfalse; Sys_Printf( "Enabling Quake 3 lighting model (nonlinear default)\n" ); } - else if( !strcmp( argv[ i ], "-extradist" ) ) - { + else if ( !strcmp( argv[ i ], "-extradist" ) ) { extraDist = atof( argv[ i + 1 ] ); - if( extraDist < 0 ) + if ( extraDist < 0 ) { extraDist = 0; + } i++; Sys_Printf( "Default extra radius set to %f units\n", extraDist ); } - - else if( !strcmp( argv[ i ], "-sunonly" ) ) - { + + else if ( !strcmp( argv[ i ], "-sunonly" ) ) { sunOnly = qtrue; Sys_Printf( "Only computing sunlight\n" ); } - - else if( !strcmp( argv[ i ], "-bounceonly" ) ) - { + + else if ( !strcmp( argv[ i ], "-bounceonly" ) ) { bounceOnly = qtrue; Sys_Printf( "Storing bounced light (radiosity) only\n" ); } - - else if( !strcmp( argv[ i ], "-nocollapse" ) ) - { + + else if ( !strcmp( argv[ i ], "-nocollapse" ) ) { noCollapse = qtrue; Sys_Printf( "Identical lightmap collapsing disabled\n" ); } - else if( !strcmp( argv[ i ], "-nolightmapsearch" ) ) - { + else if ( !strcmp( argv[ i ], "-nolightmapsearch" ) ) { lightmapSearchBlockSize = 1; Sys_Printf( "No lightmap searching - all lightmaps will be sequential\n" ); } - - else if( !strcmp( argv[ i ], "-lightmapsearchpower" ) ) - { - lightmapMergeSize = (game->lightmapSize << atoi(argv[i+1])); + + else if ( !strcmp( argv[ i ], "-lightmapsearchpower" ) ) { + lightmapMergeSize = ( game->lightmapSize << atoi( argv[i + 1] ) ); ++i; - Sys_Printf( "Restricted lightmap searching enabled - optimize for lightmap merge power %d (size %d)\n", atoi(argv[i]), lightmapMergeSize ); + Sys_Printf( "Restricted lightmap searching enabled - optimize for lightmap merge power %d (size %d)\n", atoi( argv[i] ), lightmapMergeSize ); } - - else if( !strcmp( argv[ i ], "-lightmapsearchblocksize" ) ) - { - lightmapSearchBlockSize = atoi(argv[i+1]); + + else if ( !strcmp( argv[ i ], "-lightmapsearchblocksize" ) ) { + lightmapSearchBlockSize = atoi( argv[i + 1] ); ++i; Sys_Printf( "Restricted lightmap searching enabled - block size set to %d\n", lightmapSearchBlockSize ); } - - else if( !strcmp( argv[ i ], "-shade" ) ) - { + + else if ( !strcmp( argv[ i ], "-shade" ) ) { shade = qtrue; Sys_Printf( "Phong shading enabled\n" ); } - - else if( !strcmp( argv[ i ], "-bouncegrid") ) - { + + else if ( !strcmp( argv[ i ], "-bouncegrid" ) ) { bouncegrid = qtrue; - if( bounce > 0 ) + if ( bounce > 0 ) { Sys_Printf( "Grid lighting with radiosity enabled\n" ); + } } - - else if( !strcmp( argv[ i ], "-smooth" ) ) - { + + else if ( !strcmp( argv[ i ], "-smooth" ) ) { lightSamples = EXTRA_SCALE; Sys_Printf( "The -smooth argument is deprecated, use \"-samples 2\" instead\n" ); } - - else if( !strcmp( argv[ i ], "-nofastpoint" ) ) - { + + else if ( !strcmp( argv[ i ], "-nofastpoint" ) ) { fastpoint = qfalse; Sys_Printf( "Automatic fast mode for point lights disabled\n" ); } - - else if( !strcmp( argv[ i ], "-fast" ) ) - { + + else if ( !strcmp( argv[ i ], "-fast" ) ) { fast = qtrue; fastgrid = qtrue; fastbounce = qtrue; Sys_Printf( "Fast mode enabled for all area lights\n" ); } - - else if( !strcmp( argv[ i ], "-faster" ) ) - { + + else if ( !strcmp( argv[ i ], "-faster" ) ) { faster = qtrue; fast = qtrue; fastgrid = qtrue; fastbounce = qtrue; Sys_Printf( "Faster mode enabled\n" ); } - - else if( !strcmp( argv[ i ], "-fastgrid" ) ) - { + + else if ( !strcmp( argv[ i ], "-fastallocate" ) ) { + fastAllocate = qtrue; + Sys_Printf( "Fast allocation mode enabled\n" ); + } + + else if ( !strcmp( argv[ i ], "-fastgrid" ) ) { fastgrid = qtrue; Sys_Printf( "Fast grid lighting enabled\n" ); } - - else if( !strcmp( argv[ i ], "-fastbounce" ) ) - { + + else if ( !strcmp( argv[ i ], "-fastbounce" ) ) { fastbounce = qtrue; Sys_Printf( "Fast bounce mode enabled\n" ); } - - else if( !strcmp( argv[ i ], "-cheap" ) ) - { + + else if ( !strcmp( argv[ i ], "-cheap" ) ) { cheap = qtrue; cheapgrid = qtrue; Sys_Printf( "Cheap mode enabled\n" ); } - else if( !strcmp( argv[ i ], "-cheapgrid" ) ) - { + else if ( !strcmp( argv[ i ], "-cheapgrid" ) ) { cheapgrid = qtrue; Sys_Printf( "Cheap grid mode enabled\n" ); } - - else if( !strcmp( argv[ i ], "-normalmap" ) ) - { + + else if ( !strcmp( argv[ i ], "-normalmap" ) ) { normalmap = qtrue; Sys_Printf( "Storing normal map instead of lightmap\n" ); } - - else if( !strcmp( argv[ i ], "-trisoup" ) ) - { + + else if ( !strcmp( argv[ i ], "-trisoup" ) ) { trisoup = qtrue; Sys_Printf( "Converting brush faces to triangle soup\n" ); } - - else if( !strcmp( argv[ i ], "-debug" ) ) - { + + else if ( !strcmp( argv[ i ], "-debug" ) ) { debug = qtrue; Sys_Printf( "Lightmap debugging enabled\n" ); } - - else if( !strcmp( argv[ i ], "-debugsurfaces" ) || !strcmp( argv[ i ], "-debugsurface" ) ) - { + + else if ( !strcmp( argv[ i ], "-debugsurfaces" ) || !strcmp( argv[ i ], "-debugsurface" ) ) { debugSurfaces = qtrue; Sys_Printf( "Lightmap surface debugging enabled\n" ); } - - else if( !strcmp( argv[ i ], "-debugunused" ) ) - { + + else if ( !strcmp( argv[ i ], "-debugunused" ) ) { debugUnused = qtrue; Sys_Printf( "Unused luxel debugging enabled\n" ); } - else if( !strcmp( argv[ i ], "-debugaxis" ) ) - { + else if ( !strcmp( argv[ i ], "-debugaxis" ) ) { debugAxis = qtrue; Sys_Printf( "Lightmap axis debugging enabled\n" ); } - - else if( !strcmp( argv[ i ], "-debugcluster" ) ) - { + + else if ( !strcmp( argv[ i ], "-debugcluster" ) ) { debugCluster = qtrue; Sys_Printf( "Luxel cluster debugging enabled\n" ); } - - else if( !strcmp( argv[ i ], "-debugorigin" ) ) - { + + else if ( !strcmp( argv[ i ], "-debugorigin" ) ) { debugOrigin = qtrue; Sys_Printf( "Luxel origin debugging enabled\n" ); } - - else if( !strcmp( argv[ i ], "-debugdeluxe" ) ) - { + + else if ( !strcmp( argv[ i ], "-debugdeluxe" ) ) { deluxemap = qtrue; debugDeluxemap = qtrue; Sys_Printf( "Deluxemap debugging enabled\n" ); } - - else if( !strcmp( argv[ i ], "-export" ) ) - { + + else if ( !strcmp( argv[ i ], "-export" ) ) { exportLightmaps = qtrue; Sys_Printf( "Exporting lightmaps\n" ); } - - else if( !strcmp(argv[ i ], "-notrace" )) - { + + else if ( !strcmp( argv[ i ], "-notrace" ) ) { noTrace = qtrue; Sys_Printf( "Shadow occlusion disabled\n" ); } - else if( !strcmp(argv[ i ], "-patchshadows" ) ) - { + else if ( !strcmp( argv[ i ], "-patchshadows" ) ) { patchShadows = qtrue; Sys_Printf( "Patch shadow casting enabled\n" ); } - else if( !strcmp( argv[ i ], "-extra" ) ) - { - superSample = EXTRA_SCALE; /* ydnar */ + else if ( !strcmp( argv[ i ], "-extra" ) ) { + superSample = EXTRA_SCALE; /* ydnar */ Sys_Printf( "The -extra argument is deprecated, use \"-super 2\" instead\n" ); } - else if( !strcmp( argv[ i ], "-extrawide" ) ) - { - superSample = EXTRAWIDE_SCALE; /* ydnar */ - filter = qtrue; /* ydnar */ - Sys_Printf( "The -extrawide argument is deprecated, use \"-filter [-super 2]\" instead\n"); + else if ( !strcmp( argv[ i ], "-extrawide" ) ) { + superSample = EXTRAWIDE_SCALE; /* ydnar */ + filter = qtrue; /* ydnar */ + Sys_Printf( "The -extrawide argument is deprecated, use \"-filter [-super 2]\" instead\n" ); } - else if( !strcmp( argv[ i ], "-samplesize" ) ) - { + else if ( !strcmp( argv[ i ], "-samplesize" ) ) { sampleSize = atoi( argv[ i + 1 ] ); - if( sampleSize < 1 ) + if ( sampleSize < 1 ) { sampleSize = 1; + } i++; Sys_Printf( "Default lightmap sample size set to %dx%d units\n", sampleSize, sampleSize ); } - else if( !strcmp( argv[ i ], "-minsamplesize" ) ) - { + else if ( !strcmp( argv[ i ], "-minsamplesize" ) ) { minSampleSize = atoi( argv[ i + 1 ] ); - if( minSampleSize < 1 ) + if ( minSampleSize < 1 ) { minSampleSize = 1; + } i++; Sys_Printf( "Minimum lightmap sample size set to %dx%d units\n", minSampleSize, minSampleSize ); } - else if( !strcmp( argv[ i ], "-samplescale" ) ) - { + else if ( !strcmp( argv[ i ], "-samplescale" ) ) { sampleScale = atoi( argv[ i + 1 ] ); - i++; - Sys_Printf( "Lightmaps sample scale set to %d\n", sampleScale); - } - else if( !strcmp( argv[ i ], "-novertex" ) ) - { + i++; + Sys_Printf( "Lightmaps sample scale set to %d\n", sampleScale ); + } + else if ( !strcmp( argv[ i ], "-novertex" ) ) { noVertexLighting = qtrue; Sys_Printf( "Disabling vertex lighting\n" ); } - else if( !strcmp( argv[ i ], "-nogrid" ) ) - { + else if ( !strcmp( argv[ i ], "-nogrid" ) ) { noGridLighting = qtrue; Sys_Printf( "Disabling grid lighting\n" ); } - else if( !strcmp( argv[ i ], "-border" ) ) - { + else if ( !strcmp( argv[ i ], "-border" ) ) { lightmapBorder = qtrue; Sys_Printf( "Adding debug border to lightmaps\n" ); } - else if( !strcmp( argv[ i ], "-nosurf" ) ) - { + else if ( !strcmp( argv[ i ], "-nosurf" ) ) { noSurfaces = qtrue; Sys_Printf( "Not tracing against surfaces\n" ); } - else if( !strcmp( argv[ i ], "-dump" ) ) - { + else if ( !strcmp( argv[ i ], "-dump" ) ) { dump = qtrue; Sys_Printf( "Dumping radiosity lights into numbered prefabs\n" ); } - else if( !strcmp( argv[ i ], "-lomem" ) ) - { + else if ( !strcmp( argv[ i ], "-lomem" ) ) { loMem = qtrue; Sys_Printf( "Enabling low-memory (potentially slower) lighting mode\n" ); } - else if( !strcmp( argv[ i ], "-lightanglehl" ) ) - { - if( ( atoi( argv[ i + 1 ] ) != 0 ) != lightAngleHL ) - { + else if ( !strcmp( argv[ i ], "-lightanglehl" ) ) { + if ( ( atoi( argv[ i + 1 ] ) != 0 ) != lightAngleHL ) { lightAngleHL = ( atoi( argv[ i + 1 ] ) != 0 ); - if( lightAngleHL ) + if ( lightAngleHL ) { Sys_Printf( "Enabling half lambert light angle attenuation\n" ); - else + } + else{ Sys_Printf( "Disabling half lambert light angle attenuation\n" ); + } } } - else if( !strcmp( argv[ i ], "-nostyle" ) || !strcmp( argv[ i ], "-nostyles" ) ) - { + else if ( !strcmp( argv[ i ], "-nostyle" ) || !strcmp( argv[ i ], "-nostyles" ) ) { noStyles = qtrue; Sys_Printf( "Disabling lightstyles\n" ); } - else if( !strcmp( argv[ i ], "-style" ) || !strcmp( argv[ i ], "-styles" ) ) - { + else if ( !strcmp( argv[ i ], "-style" ) || !strcmp( argv[ i ], "-styles" ) ) { noStyles = qfalse; Sys_Printf( "Enabling lightstyles\n" ); } - else if( !strcmp( argv[ i ], "-cpma" ) ) - { + else if ( !strcmp( argv[ i ], "-cpma" ) ) { cpmaHack = qtrue; Sys_Printf( "Enabling Challenge Pro Mode Asstacular Vertex Lighting Mode (tm)\n" ); } - else if( !strcmp( argv[ i ], "-floodlight" ) ) - { + else if ( !strcmp( argv[ i ], "-floodlight" ) ) { floodlighty = qtrue; Sys_Printf( "FloodLighting enabled\n" ); } - else if( !strcmp( argv[ i ], "-debugnormals" ) ) - { + else if ( !strcmp( argv[ i ], "-debugnormals" ) ) { debugnormals = qtrue; Sys_Printf( "DebugNormals enabled\n" ); } - else if( !strcmp( argv[ i ], "-lowquality" ) ) - { + else if ( !strcmp( argv[ i ], "-lowquality" ) ) { floodlight_lowquality = qtrue; Sys_Printf( "Low Quality FloodLighting enabled\n" ); } - + /* r7: dirtmapping */ - else if( !strcmp( argv[ i ], "-dirty" ) ) - { + else if ( !strcmp( argv[ i ], "-dirty" ) ) { dirty = qtrue; Sys_Printf( "Dirtmapping enabled\n" ); } - else if( !strcmp( argv[ i ], "-dirtdebug" ) || !strcmp( argv[ i ], "-debugdirt" ) ) - { + else if ( !strcmp( argv[ i ], "-dirtdebug" ) || !strcmp( argv[ i ], "-debugdirt" ) ) { dirtDebug = qtrue; Sys_Printf( "Dirtmap debugging enabled\n" ); } - else if( !strcmp( argv[ i ], "-dirtmode" ) ) - { + else if ( !strcmp( argv[ i ], "-dirtmode" ) ) { dirtMode = atoi( argv[ i + 1 ] ); - if( dirtMode != 0 && dirtMode != 1 ) + if ( dirtMode != 0 && dirtMode != 1 ) { dirtMode = 0; - if( dirtMode == 1 ) + } + if ( dirtMode == 1 ) { Sys_Printf( "Enabling randomized dirtmapping\n" ); - else + } + else{ Sys_Printf( "Enabling ordered dir mapping\n" ); + } i++; } - else if( !strcmp( argv[ i ], "-dirtdepth" ) ) - { + else if ( !strcmp( argv[ i ], "-dirtdepth" ) ) { dirtDepth = atof( argv[ i + 1 ] ); - if( dirtDepth <= 0.0f ) + if ( dirtDepth <= 0.0f ) { dirtDepth = 128.0f; + } Sys_Printf( "Dirtmapping depth set to %.1f\n", dirtDepth ); i++; } - else if( !strcmp( argv[ i ], "-dirtscale" ) ) - { + else if ( !strcmp( argv[ i ], "-dirtscale" ) ) { dirtScale = atof( argv[ i + 1 ] ); - if( dirtScale <= 0.0f ) + if ( dirtScale <= 0.0f ) { dirtScale = 1.0f; + } Sys_Printf( "Dirtmapping scale set to %.1f\n", dirtScale ); i++; } - else if( !strcmp( argv[ i ], "-dirtgain" ) ) - { + else if ( !strcmp( argv[ i ], "-dirtgain" ) ) { dirtGain = atof( argv[ i + 1 ] ); - if( dirtGain <= 0.0f ) + if ( dirtGain <= 0.0f ) { dirtGain = 1.0f; + } Sys_Printf( "Dirtmapping gain set to %.1f\n", dirtGain ); i++; } - else if( !strcmp( argv[ i ], "-trianglecheck" ) ) - { + else if ( !strcmp( argv[ i ], "-trianglecheck" ) ) { lightmapTriangleCheck = qtrue; } - else if( !strcmp( argv[ i ], "-extravisnudge" ) ) - { + else if ( !strcmp( argv[ i ], "-extravisnudge" ) ) { lightmapExtraVisClusterNudge = qtrue; } - else if( !strcmp( argv[ i ], "-fill" ) ) - { + else if ( !strcmp( argv[ i ], "-fill" ) ) { lightmapFill = qtrue; Sys_Printf( "Filling lightmap colors from surrounding pixels to improve JPEG compression\n" ); } + else if ( !strcmp( argv[ i ], "-bspfile" ) ) + { + strcpy( BSPFilePath, argv[i + 1] ); + i++; + Sys_Printf( "Use %s as bsp file\n", BSPFilePath ); + } + else if ( !strcmp( argv[ i ], "-srffile" ) ) + { + strcpy( surfaceFilePath, argv[i + 1] ); + i++; + Sys_Printf( "Use %s as surface file\n", surfaceFilePath ); + } /* unhandled args */ else { @@ -2859,114 +2889,122 @@ int LightMain( int argc, char **argv ) } /* fix up falloff tolerance for sRGB */ - if(lightmapsRGB) - falloffTolerance = Image_LinearFloatFromsRGBFloat(falloffTolerance * (1.0 / 255.0)) * 255.0; + if ( lightmapsRGB ) { + falloffTolerance = Image_LinearFloatFromsRGBFloat( falloffTolerance * ( 1.0 / 255.0 ) ) * 255.0; + } /* fix up samples count */ - if(lightRandomSamples) - { - if(!lightSamplesInsist) - { + if ( lightRandomSamples ) { + if ( !lightSamplesInsist ) { /* approximately match -samples in quality */ - switch(lightSamples) + switch ( lightSamples ) { - /* somewhat okay */ - case 1: - case 2: - lightSamples = 16; - Sys_Printf( "Adaptive supersampling preset enabled with %d random sample(s) per lightmap texel\n", lightSamples ); - break; + /* somewhat okay */ + case 1: + case 2: + lightSamples = 16; + Sys_Printf( "Adaptive supersampling preset enabled with %d random sample(s) per lightmap texel\n", lightSamples ); + break; - /* good */ - case 3: - lightSamples = 64; - Sys_Printf( "Adaptive supersampling preset enabled with %d random sample(s) per lightmap texel\n", lightSamples ); - break; + /* good */ + case 3: + lightSamples = 64; + Sys_Printf( "Adaptive supersampling preset enabled with %d random sample(s) per lightmap texel\n", lightSamples ); + break; - /* perfect */ - case 4: - lightSamples = 256; - Sys_Printf( "Adaptive supersampling preset enabled with %d random sample(s) per lightmap texel\n", lightSamples ); - break; + /* perfect */ + case 4: + lightSamples = 256; + Sys_Printf( "Adaptive supersampling preset enabled with %d random sample(s) per lightmap texel\n", lightSamples ); + break; - default: break; + default: break; } } } /* fix up lightmap search power */ - if(lightmapMergeSize) - { - lightmapSearchBlockSize = (lightmapMergeSize / lmCustomSize) * (lightmapMergeSize / lmCustomSize); - if(lightmapSearchBlockSize < 1) + if ( lightmapMergeSize ) { + lightmapSearchBlockSize = ( lightmapMergeSize / lmCustomSize ) * ( lightmapMergeSize / lmCustomSize ); + if ( lightmapSearchBlockSize < 1 ) { lightmapSearchBlockSize = 1; + } Sys_Printf( "Restricted lightmap searching enabled - block size adjusted to %d\n", lightmapSearchBlockSize ); } - - /* clean up map name */ + strcpy( source, ExpandArg( argv[ i ] ) ); StripExtension( source ); - DefaultExtension( source, ".bsp" ); - strcpy( mapSource, ExpandArg( argv[ i ] ) ); - StripExtension( mapSource ); - DefaultExtension( mapSource, ".map" ); - + DefaultExtension( source, ".map" ); + + if (!BSPFilePath[0]) { + strcpy( BSPFilePath, ExpandArg( argv[ i ] ) ); + StripExtension( BSPFilePath ); + DefaultExtension( BSPFilePath, ".bsp" ); + } + + if (!surfaceFilePath[0]) { + strcpy( surfaceFilePath, ExpandArg( argv[ i ] ) ); + StripExtension( surfaceFilePath ); + DefaultExtension( surfaceFilePath, ".srf" ); + } + /* ydnar: set default sample size */ SetDefaultSampleSize( sampleSize ); - + /* ydnar: handle shaders */ - BeginMapShaderFile( source ); + BeginMapShaderFile( BSPFilePath ); LoadShaderInfo(); - + /* note loading */ Sys_Printf( "Loading %s\n", source ); - + /* ydnar: load surface file */ - LoadSurfaceExtraFile( source ); - + LoadSurfaceExtraFile( surfaceFilePath ); + /* load bsp file */ - LoadBSPFile( source ); - + LoadBSPFile( BSPFilePath ); + /* parse bsp entities */ ParseEntities(); /* inject command line parameters */ - InjectCommandLine(argv, 0, argc - 1); - + InjectCommandLine( argv, 0, argc - 1 ); + /* load map file */ value = ValueForKey( &entities[ 0 ], "_keepLights" ); - if( value[ 0 ] != '1' ) - LoadMapFile( mapSource, qtrue, qfalse ); - + if ( value[ 0 ] != '1' ) { + LoadMapFile( source, qtrue, qfalse ); + } + /* set the entity/model origins and init yDrawVerts */ SetEntityOrigins(); - + /* ydnar: set up optimization */ SetupBrushes(); SetupDirt(); SetupFloodLight(); SetupSurfaceLightmaps(); - + /* initialize the surface facet tracing */ SetupTraceNodes(); - + /* light the world */ - LightWorld(); - + LightWorld( BSPFilePath, fastAllocate ); + /* ydnar: store off lightmaps */ - StoreSurfaceLightmaps(); - + StoreSurfaceLightmaps( fastAllocate ); + /* write out the bsp */ UnparseEntities(); - Sys_Printf( "Writing %s\n", source ); - WriteBSPFile( source ); - + Sys_Printf( "Writing %s\n", BSPFilePath ); + WriteBSPFile( BSPFilePath ); + /* ydnar: export lightmaps */ - if( exportLightmaps && !externalLightmaps ) + if ( exportLightmaps && !externalLightmaps ) { ExportLightmaps(); - + } + /* return to sender */ return 0; } -