/* -------------------------------------------------------------------------------
-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."
-------------------------------------------------------------------------------- */
+ ------------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------------
-this file contains code that doe lightmap allocation and projection that
-runs in the -light phase.
+ this file contains code that doe lightmap allocation and projection that
+ runs in the -light phase.
-this is handled here rather than in the bsp phase for a few reasons--
-surfaces are no longer necessarily convex polygons, patches may or may not be
-planar or have lightmaps projected directly onto control points.
+ this is handled here rather than in the bsp phase for a few reasons--
+ surfaces are no longer necessarily convex polygons, patches may or may not be
+ planar or have lightmaps projected directly onto control points.
-also, this allows lightmaps to be calculated before being allocated and stored
-in the bsp. lightmaps that have little high-frequency information are candidates
-for having their resolutions scaled down.
+ also, this allows lightmaps to be calculated before being allocated and stored
+ in the bsp. lightmaps that have little high-frequency information are candidates
+ for having their resolutions scaled down.
-------------------------------------------------------------------------------- */
+ ------------------------------------------------------------------------------- */
/*
-WriteTGA24()
-based on WriteTGA() from imagelib.c
-*/
-
-void WriteTGA24( char *filename, byte *data, int width, int height, qboolean flip )
-{
- int i, c;
- byte *buffer, *in;
- FILE *file;
-
-
+ WriteTGA24()
+ based on WriteTGA() from imagelib.c
+ */
+
+void WriteTGA24( char *filename, byte *data, int width, int height, qboolean flip ){
+ int i, c;
+ byte *buffer, *in;
+ FILE *file;
+
+
/* allocate a buffer and set it up */
buffer = safe_malloc( width * height * 3 + 18 );
memset( buffer, 0, 18 );
buffer[ 16 ] = 24;
/* swap rgb to bgr */
- c = (width * height * 3) + 18;
- for( i = 18; i < c; i += 3 )
+ c = ( width * height * 3 ) + 18;
+ for ( i = 18; i < c; i += 3 )
{
- buffer[ i ] = data[ i - 18 + 2 ]; /* blue */
- buffer[ i + 1 ] = data[ i - 18 + 1 ]; /* green */
- buffer[ i + 2 ] = data[ i - 18 + 0 ]; /* red */
+ buffer[ i ] = data[ i - 18 + 2 ]; /* blue */
+ buffer[ i + 1 ] = data[ i - 18 + 1 ]; /* green */
+ buffer[ i + 2 ] = data[ i - 18 + 0 ]; /* red */
}
-
+
/* write it and free the buffer */
file = fopen( filename, "wb" );
- if( file == NULL )
+ if ( file == NULL ) {
Error( "Unable to open %s for writing", filename );
-
+ }
+
/* flip vertically? */
- if( flip )
- {
+ if ( flip ) {
fwrite( buffer, 1, 18, file );
- for( in = buffer + ((height - 1) * width * 3) + 18; in >= buffer; in -= (width * 3) )
- fwrite( in, 1, (width * 3), file );
+ for ( in = buffer + ( ( height - 1 ) * width * 3 ) + 18; in >= buffer; in -= ( width * 3 ) )
+ fwrite( in, 1, ( width * 3 ), file );
}
- else
+ else{
fwrite( buffer, 1, c, file );
-
+ }
+
/* close the file */
fclose( file );
free( buffer );
/*
-ExportLightmaps()
-exports the lightmaps as a list of numbered tga images
-*/
-
-void ExportLightmaps( void )
-{
- int i;
- char dirname[ 1024 ], filename[ 1024 ];
- byte *lightmap;
-
-
+ ExportLightmaps()
+ exports the lightmaps as a list of numbered tga images
+ */
+
+void ExportLightmaps( void ){
+ int i;
+ char dirname[ 1024 ], filename[ 1024 ];
+ byte *lightmap;
+
+
/* note it */
- Sys_FPrintf( SYS_VRB, "--- ExportLightmaps ---\n");
-
+ Sys_FPrintf( SYS_VRB, "--- ExportLightmaps ---\n" );
+
/* do some path mangling */
strcpy( dirname, source );
StripExtension( dirname );
-
+
/* sanity check */
- if( bspLightBytes == NULL )
- {
+ if ( bspLightBytes == NULL ) {
Sys_Printf( "WARNING: No BSP lightmap data\n" );
return;
}
-
+
/* make a directory for the lightmaps */
Q_mkdir( dirname );
-
+
/* iterate through the lightmaps */
- for( i = 0, lightmap = bspLightBytes; lightmap < (bspLightBytes + numBSPLightBytes); i++, lightmap += (game->lightmapSize * game->lightmapSize * 3) )
+ for ( i = 0, lightmap = bspLightBytes; lightmap < ( bspLightBytes + numBSPLightBytes ); i++, lightmap += ( game->lightmapSize * game->lightmapSize * 3 ) )
{
/* write a tga image out */
sprintf( filename, "%s/lightmap_%04d.tga", dirname, i );
/*
-ExportLightmapsMain()
-exports the lightmaps as a list of numbered tga images
-*/
+ ExportLightmapsMain()
+ exports the lightmaps as a list of numbered tga images
+ */
-int ExportLightmapsMain( int argc, char **argv )
-{
+int ExportLightmapsMain( int argc, char **argv ){
/* arg checking */
- if( argc < 1 )
- {
+ if ( argc < 1 ) {
Sys_Printf( "Usage: q3map -export [-v] <mapname>\n" );
return 0;
}
-
+
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
-
+
/* load the bsp */
Sys_Printf( "Loading %s\n", source );
LoadBSPFile( source );
-
+
/* export the lightmaps */
ExportLightmaps();
-
+
/* return to sender */
return 0;
}
/*
-ImportLightmapsMain()
-imports the lightmaps from a list of numbered tga images
-*/
-
-int ImportLightmapsMain( int argc, char **argv )
-{
- int i, x, y, len, width, height;
- char dirname[ 1024 ], filename[ 1024 ];
- byte *lightmap, *buffer, *pixels, *in, *out;
-
-
+ ImportLightmapsMain()
+ imports the lightmaps from a list of numbered tga images
+ */
+
+int ImportLightmapsMain( int argc, char **argv ){
+ int i, x, y, len, width, height;
+ char dirname[ 1024 ], filename[ 1024 ];
+ byte *lightmap, *buffer, *pixels, *in, *out;
+
+
/* arg checking */
- if( argc < 1 )
- {
+ if ( argc < 1 ) {
Sys_Printf( "Usage: q3map -import [-v] <mapname>\n" );
return 0;
}
-
+
/* do some path mangling */
strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
StripExtension( source );
DefaultExtension( source, ".bsp" );
-
+
/* load the bsp */
Sys_Printf( "Loading %s\n", source );
LoadBSPFile( source );
-
+
/* note it */
- Sys_FPrintf( SYS_VRB, "--- ImportLightmaps ---\n");
-
+ Sys_FPrintf( SYS_VRB, "--- ImportLightmaps ---\n" );
+
/* do some path mangling */
strcpy( dirname, source );
StripExtension( dirname );
-
+
/* sanity check */
- if( bspLightBytes == NULL )
+ if ( bspLightBytes == NULL ) {
Error( "No lightmap data" );
-
+ }
+
/* make a directory for the lightmaps */
Q_mkdir( dirname );
-
+
/* iterate through the lightmaps */
- for( i = 0, lightmap = bspLightBytes; lightmap < (bspLightBytes + numBSPLightBytes); i++, lightmap += (game->lightmapSize * game->lightmapSize * 3) )
+ for ( i = 0, lightmap = bspLightBytes; lightmap < ( bspLightBytes + numBSPLightBytes ); i++, lightmap += ( game->lightmapSize * game->lightmapSize * 3 ) )
{
/* read a tga image */
sprintf( filename, "%s/lightmap_%04d.tga", dirname, i );
Sys_Printf( "Loading %s\n", filename );
buffer = NULL;
len = vfsLoadFile( filename, (void*) &buffer, -1 );
- if( len < 0 )
- {
+ if ( len < 0 ) {
Sys_Printf( "WARNING: Unable to load image %s\n", filename );
continue;
}
-
+
/* parse file into an image */
pixels = NULL;
LoadTGABuffer( buffer, buffer + len, &pixels, &width, &height );
free( buffer );
-
+
/* sanity check it */
- if( pixels == NULL )
- {
+ if ( pixels == NULL ) {
Sys_Printf( "WARNING: Unable to load image %s\n", filename );
continue;
}
- if( width != game->lightmapSize || height != game->lightmapSize )
+ if ( width != game->lightmapSize || height != game->lightmapSize ) {
Sys_Printf( "WARNING: Image %s is not the right size (%d, %d) != (%d, %d)\n",
- filename, width, height, game->lightmapSize, game->lightmapSize );
-
+ filename, width, height, game->lightmapSize, game->lightmapSize );
+ }
+
/* copy the pixels */
in = pixels;
- for( y = 1; y <= game->lightmapSize; y++ )
+ for ( y = 1; y <= game->lightmapSize; y++ )
{
- out = lightmap + ((game->lightmapSize - y) * game->lightmapSize * 3);
- for( x = 0; x < game->lightmapSize; x++, in += 4, out += 3 )
+ out = lightmap + ( ( game->lightmapSize - y ) * game->lightmapSize * 3 );
+ for ( x = 0; x < game->lightmapSize; x++, in += 4, out += 3 )
VectorCopy( in, out );
}
-
+
/* free the image */
free( pixels );
}
-
+
/* write the bsp */
Sys_Printf( "writing %s\n", source );
WriteBSPFile( source );
-
+
/* return to sender */
return 0;
}
/* -------------------------------------------------------------------------------
-this section deals with projecting a lightmap onto a raw drawsurface
+ this section deals with projecting a lightmap onto a raw drawsurface
-------------------------------------------------------------------------------- */
+ ------------------------------------------------------------------------------- */
/*
-CompareLightSurface()
-compare function for qsort()
-*/
-
-static int CompareLightSurface( const void *a, const void *b )
-{
- shaderInfo_t *asi, *bsi;
-
-
+ CompareLightSurface()
+ compare function for qsort()
+ */
+
+static int CompareLightSurface( const void *a, const void *b ){
+ shaderInfo_t *asi, *bsi;
+
+
/* get shaders */
- asi = surfaceInfos[ *((const int*) a) ].si;
- bsi = surfaceInfos[ *((const int*) b) ].si;
-
+ asi = surfaceInfos[ *( (const int*) a ) ].si;
+ bsi = surfaceInfos[ *( (const int*) b ) ].si;
+
/* dummy check */
- if( asi == NULL )
+ if ( asi == NULL ) {
return -1;
- if( bsi == NULL )
+ }
+ if ( bsi == NULL ) {
return 1;
-
+ }
+
/* compare shader names */
return strcmp( asi->shader, bsi->shader );
}
/*
-FinishRawLightmap()
-allocates a raw lightmap's necessary buffers
-*/
-
-void FinishRawLightmap( rawLightmap_t *lm )
-{
- int i, j, c, size, *sc;
- float is;
- surfaceInfo_t *info;
-
-
+ FinishRawLightmap()
+ allocates a raw lightmap's necessary buffers
+ */
+
+void FinishRawLightmap( rawLightmap_t *lm ){
+ int i, j, c, size, *sc;
+ float is;
+ surfaceInfo_t *info;
+
+
/* sort light surfaces by shader name */
qsort( &lightSurfaces[ lm->firstLightSurface ], lm->numLightSurfaces, sizeof( int ), CompareLightSurface );
-
+
/* count clusters */
lm->numLightClusters = 0;
- for( i = 0; i < lm->numLightSurfaces; i++ )
+ for ( i = 0; i < lm->numLightSurfaces; i++ )
{
/* get surface info */
info = &surfaceInfos[ lightSurfaces[ lm->firstLightSurface + i ] ];
-
+
/* add surface clusters */
lm->numLightClusters += info->numSurfaceClusters;
}
-
+
/* allocate buffer for clusters and copy */
lm->lightClusters = safe_malloc( lm->numLightClusters * sizeof( *lm->lightClusters ) );
c = 0;
- for( i = 0; i < lm->numLightSurfaces; i++ )
+ for ( i = 0; i < lm->numLightSurfaces; i++ )
{
/* get surface info */
info = &surfaceInfos[ lightSurfaces[ lm->firstLightSurface + i ] ];
-
+
/* add surface clusters */
- for( j = 0; j < info->numSurfaceClusters; j++ )
+ for ( j = 0; j < info->numSurfaceClusters; j++ )
lm->lightClusters[ c++ ] = surfaceClusters[ info->firstSurfaceCluster + j ];
}
-
+
/* set styles */
lm->styles[ 0 ] = LS_NORMAL;
- for( i = 1; i < MAX_LIGHTMAPS; i++ )
+ for ( i = 1; i < MAX_LIGHTMAPS; i++ )
lm->styles[ i ] = LS_NONE;
-
+
/* set supersampling size */
lm->sw = lm->w * superSample;
lm->sh = lm->h * superSample;
-
+
/* add to super luxel count */
- numRawSuperLuxels += (lm->sw * lm->sh);
-
+ numRawSuperLuxels += ( lm->sw * lm->sh );
+
/* manipulate origin/vecs for supersampling */
- if( superSample > 1 && lm->vecs != NULL )
- {
+ if ( superSample > 1 && lm->vecs != NULL ) {
/* calc inverse supersample */
is = 1.0f / superSample;
-
+
/* scale the vectors and shift the origin */
#if 1
- /* new code that works for arbitrary supersampling values */
- VectorMA( lm->origin, -0.5, lm->vecs[ 0 ], lm->origin );
- VectorMA( lm->origin, -0.5, lm->vecs[ 1 ], lm->origin );
- VectorScale( lm->vecs[ 0 ], is, lm->vecs[ 0 ] );
- VectorScale( lm->vecs[ 1 ], is, lm->vecs[ 1 ] );
- VectorMA( lm->origin, is, lm->vecs[ 0 ], lm->origin );
- VectorMA( lm->origin, is, lm->vecs[ 1 ], lm->origin );
+ /* new code that works for arbitrary supersampling values */
+ VectorMA( lm->origin, -0.5, lm->vecs[ 0 ], lm->origin );
+ VectorMA( lm->origin, -0.5, lm->vecs[ 1 ], lm->origin );
+ VectorScale( lm->vecs[ 0 ], is, lm->vecs[ 0 ] );
+ VectorScale( lm->vecs[ 1 ], is, lm->vecs[ 1 ] );
+ VectorMA( lm->origin, is, lm->vecs[ 0 ], lm->origin );
+ VectorMA( lm->origin, is, lm->vecs[ 1 ], lm->origin );
#else
- /* old code that only worked with a value of 2 */
- VectorScale( lm->vecs[ 0 ], is, lm->vecs[ 0 ] );
- VectorScale( lm->vecs[ 1 ], is, lm->vecs[ 1 ] );
- VectorMA( lm->origin, -is, lm->vecs[ 0 ], lm->origin );
- VectorMA( lm->origin, -is, lm->vecs[ 1 ], lm->origin );
+ /* old code that only worked with a value of 2 */
+ VectorScale( lm->vecs[ 0 ], is, lm->vecs[ 0 ] );
+ VectorScale( lm->vecs[ 1 ], is, lm->vecs[ 1 ] );
+ VectorMA( lm->origin, -is, lm->vecs[ 0 ], lm->origin );
+ VectorMA( lm->origin, -is, lm->vecs[ 1 ], lm->origin );
#endif
}
-
+
/* allocate bsp lightmap storage */
size = lm->w * lm->h * BSP_LUXEL_SIZE * sizeof( float );
- if( lm->bspLuxels[ 0 ] == NULL )
+ if ( lm->bspLuxels[ 0 ] == NULL ) {
lm->bspLuxels[ 0 ] = safe_malloc( size );
+ }
memset( lm->bspLuxels[ 0 ], 0, size );
-
+
/* allocate radiosity lightmap storage */
- if( bounce )
- {
+ if ( bounce ) {
size = lm->w * lm->h * RAD_LUXEL_SIZE * sizeof( float );
- if( lm->radLuxels[ 0 ] == NULL )
+ if ( lm->radLuxels[ 0 ] == NULL ) {
lm->radLuxels[ 0 ] = safe_malloc( size );
+ }
memset( lm->radLuxels[ 0 ], 0, size );
}
-
+
/* allocate sampling lightmap storage */
size = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( float );
- if( lm->superLuxels[ 0 ] == NULL )
+ if ( lm->superLuxels[ 0 ] == NULL ) {
lm->superLuxels[ 0 ] = safe_malloc( size );
+ }
memset( lm->superLuxels[ 0 ], 0, size );
-
+
/* allocate origin map storage */
size = lm->sw * lm->sh * SUPER_ORIGIN_SIZE * sizeof( float );
- if( lm->superOrigins == NULL )
+ if ( lm->superOrigins == NULL ) {
lm->superOrigins = safe_malloc( size );
+ }
memset( lm->superOrigins, 0, size );
-
+
/* allocate normal map storage */
size = lm->sw * lm->sh * SUPER_NORMAL_SIZE * sizeof( float );
- if( lm->superNormals == NULL )
+ if ( lm->superNormals == NULL ) {
lm->superNormals = safe_malloc( size );
+ }
memset( lm->superNormals, 0, size );
-
- /* allocate floodlight map storage */
+
+ /* allocate floodlight map storage */
size = lm->sw * lm->sh * SUPER_FLOODLIGHT_SIZE * sizeof( float );
- if( lm->superFloodLight == NULL )
+ if ( lm->superFloodLight == NULL ) {
lm->superFloodLight = safe_malloc( size );
+ }
memset( lm->superFloodLight, 0, size );
/* allocate cluster map storage */
size = lm->sw * lm->sh * sizeof( int );
- if( lm->superClusters == NULL )
+ if ( lm->superClusters == NULL ) {
lm->superClusters = safe_malloc( size );
+ }
size = lm->sw * lm->sh;
sc = lm->superClusters;
- for( i = 0; i < size; i++ )
- (*sc++) = CLUSTER_UNMAPPED;
-
+ for ( i = 0; i < size; i++ )
+ ( *sc++ ) = CLUSTER_UNMAPPED;
+
/* deluxemap allocation */
- if( deluxemap )
- {
+ if ( deluxemap ) {
/* allocate sampling deluxel storage */
size = lm->sw * lm->sh * SUPER_DELUXEL_SIZE * sizeof( float );
- if( lm->superDeluxels == NULL )
+ if ( lm->superDeluxels == NULL ) {
lm->superDeluxels = safe_malloc( size );
+ }
memset( lm->superDeluxels, 0, size );
-
+
/* allocate bsp deluxel storage */
size = lm->w * lm->h * BSP_DELUXEL_SIZE * sizeof( float );
- if( lm->bspDeluxels == NULL )
+ if ( lm->bspDeluxels == NULL ) {
lm->bspDeluxels = safe_malloc( size );
+ }
memset( lm->bspDeluxels, 0, size );
}
-
+
/* add to count */
- numLuxels += (lm->sw * lm->sh);
+ numLuxels += ( lm->sw * lm->sh );
}
/*
-AddPatchToRawLightmap()
-projects a lightmap for a patch surface
-since lightmap calculation for surfaces is now handled in a general way (light_ydnar.c),
-it is no longer necessary for patch verts to fall exactly on a lightmap sample
-based on AllocateLightmapForPatch()
-*/
-
-qboolean AddPatchToRawLightmap( int num, rawLightmap_t *lm )
-{
- bspDrawSurface_t *ds;
- surfaceInfo_t *info;
- int x, y;
- bspDrawVert_t *verts, *a, *b;
- vec3_t delta;
- mesh_t src, *subdivided, *mesh;
- float sBasis, tBasis, s, t;
- float length, widthTable[ MAX_EXPANDED_AXIS ], heightTable[ MAX_EXPANDED_AXIS ];
-
-
+ AddPatchToRawLightmap()
+ projects a lightmap for a patch surface
+ since lightmap calculation for surfaces is now handled in a general way (light_ydnar.c),
+ it is no longer necessary for patch verts to fall exactly on a lightmap sample
+ based on AllocateLightmapForPatch()
+ */
+
+qboolean AddPatchToRawLightmap( int num, rawLightmap_t *lm ){
+ bspDrawSurface_t *ds;
+ surfaceInfo_t *info;
+ int x, y;
+ bspDrawVert_t *verts, *a, *b;
+ vec3_t delta;
+ mesh_t src, *subdivided, *mesh;
+ float sBasis, tBasis, s, t;
+ float length, widthTable[ MAX_EXPANDED_AXIS ], heightTable[ MAX_EXPANDED_AXIS ];
+
+
/* patches finish a raw lightmap */
lm->finished = qtrue;
-
+
/* get surface and info */
ds = &bspDrawSurfaces[ num ];
info = &surfaceInfos[ num ];
-
- /* make a temporary mesh from the drawsurf */
+
+ /* make a temporary mesh from the drawsurf */
src.width = ds->patchWidth;
src.height = ds->patchHeight;
src.verts = &yDrawVerts[ ds->firstVert ];
//% subdivided = SubdivideMesh( src, 8, 512 );
subdivided = SubdivideMesh2( src, info->patchIterations );
-
+
/* fit it to the curve and remove colinear verts on rows/columns */
PutMeshOnCurve( *subdivided );
mesh = RemoveLinearMeshColumnsRows( subdivided );
FreeMesh( subdivided );
-
+
/* find the longest distance on each row/column */
verts = mesh->verts;
memset( widthTable, 0, sizeof( widthTable ) );
memset( heightTable, 0, sizeof( heightTable ) );
- for( y = 0; y < mesh->height; y++ )
+ for ( y = 0; y < mesh->height; y++ )
{
- for( x = 0; x < mesh->width; x++ )
+ for ( x = 0; x < mesh->width; x++ )
{
/* get width */
- if( x + 1 < mesh->width )
- {
- a = &verts[ (y * mesh->width) + x ];
- b = &verts[ (y * mesh->width) + x + 1 ];
+ if ( x + 1 < mesh->width ) {
+ a = &verts[ ( y * mesh->width ) + x ];
+ b = &verts[ ( y * mesh->width ) + x + 1 ];
VectorSubtract( a->xyz, b->xyz, delta );
length = VectorLength( delta );
- if( length > widthTable[ x ] )
+ if ( length > widthTable[ x ] ) {
widthTable[ x ] = length;
+ }
}
-
+
/* get height */
- if( y + 1 < mesh->height )
- {
- a = &verts[ (y * mesh->width) + x ];
- b = &verts[ ((y + 1) * mesh->width) + x ];
+ if ( y + 1 < mesh->height ) {
+ a = &verts[ ( y * mesh->width ) + x ];
+ b = &verts[ ( ( y + 1 ) * mesh->width ) + x ];
VectorSubtract( a->xyz, b->xyz, delta );
length = VectorLength( delta );
- if( length > heightTable[ y ] )
+ if ( length > heightTable[ y ] ) {
heightTable[ y ] = length;
+ }
}
}
}
-
+
/* determine lightmap width */
length = 0;
- for( x = 0; x < (mesh->width - 1); x++ )
+ for ( x = 0; x < ( mesh->width - 1 ); x++ )
length += widthTable[ x ];
lm->w = ceil( length / lm->sampleSize ) + 1;
- if( lm->w < ds->patchWidth )
+ if ( lm->w < ds->patchWidth ) {
lm->w = ds->patchWidth;
- if( lm->w > lm->customWidth )
+ }
+ if ( lm->w > lm->customWidth ) {
lm->w = lm->customWidth;
- sBasis = (float) (lm->w - 1) / (float) (ds->patchWidth - 1);
-
+ }
+ sBasis = (float) ( lm->w - 1 ) / (float) ( ds->patchWidth - 1 );
+
/* determine lightmap height */
length = 0;
- for( y = 0; y < (mesh->height - 1); y++ )
+ for ( y = 0; y < ( mesh->height - 1 ); y++ )
length += heightTable[ y ];
lm->h = ceil( length / lm->sampleSize ) + 1;
- if( lm->h < ds->patchHeight )
+ if ( lm->h < ds->patchHeight ) {
lm->h = ds->patchHeight;
- if( lm->h > lm->customHeight )
+ }
+ if ( lm->h > lm->customHeight ) {
lm->h = lm->customHeight;
- tBasis = (float) (lm->h - 1) / (float) (ds->patchHeight - 1);
-
+ }
+ tBasis = (float) ( lm->h - 1 ) / (float) ( ds->patchHeight - 1 );
+
/* free the temporary mesh */
FreeMesh( mesh );
-
+
/* set the lightmap texture coordinates in yDrawVerts */
lm->wrap[ 0 ] = qtrue;
lm->wrap[ 1 ] = qtrue;
verts = &yDrawVerts[ ds->firstVert ];
- for( y = 0; y < ds->patchHeight; y++ )
+ for ( y = 0; y < ds->patchHeight; y++ )
{
- t = (tBasis * y) + 0.5f;
- for( x = 0; x < ds->patchWidth; x++ )
+ t = ( tBasis * y ) + 0.5f;
+ for ( x = 0; x < ds->patchWidth; x++ )
{
- s = (sBasis * x) + 0.5f;
- verts[ (y * ds->patchWidth) + x ].lightmap[ 0 ][ 0 ] = s * superSample;
- verts[ (y * ds->patchWidth) + x ].lightmap[ 0 ][ 1 ] = t * superSample;
-
- if( y == 0 && !VectorCompare( verts[ x ].xyz, verts[ ((ds->patchHeight - 1) * ds->patchWidth) + x ].xyz ) )
+ s = ( sBasis * x ) + 0.5f;
+ verts[ ( y * ds->patchWidth ) + x ].lightmap[ 0 ][ 0 ] = s * superSample;
+ verts[ ( y * ds->patchWidth ) + x ].lightmap[ 0 ][ 1 ] = t * superSample;
+
+ if ( y == 0 && !VectorCompare( verts[ x ].xyz, verts[ ( ( ds->patchHeight - 1 ) * ds->patchWidth ) + x ].xyz ) ) {
lm->wrap[ 1 ] = qfalse;
+ }
}
-
- if( !VectorCompare( verts[ (y * ds->patchWidth) ].xyz, verts[ (y * ds->patchWidth) + (ds->patchWidth - 1) ].xyz ) )
+
+ if ( !VectorCompare( verts[ ( y * ds->patchWidth ) ].xyz, verts[ ( y * ds->patchWidth ) + ( ds->patchWidth - 1 ) ].xyz ) ) {
lm->wrap[ 0 ] = qfalse;
+ }
}
-
+
/* debug code: */
//% Sys_Printf( "wrap S: %d wrap T: %d\n", lm->wrap[ 0 ], lm->wrap[ 1 ] );
//% if( lm->w > (ds->lightmapWidth & 0xFF) || lm->h > (ds->lightmapHeight & 0xFF) )
//% Sys_Printf( "Patch lightmap: (%3d %3d) > (%3d, %3d)\n", lm->w, lm->h, ds->lightmapWidth & 0xFF, ds->lightmapHeight & 0xFF );
//% ds->lightmapWidth = lm->w | (ds->lightmapWidth & 0xFFFF0000);
//% ds->lightmapHeight = lm->h | (ds->lightmapHeight & 0xFFFF0000);
-
+
/* add to counts */
numPatchesLightmapped++;
-
+
/* return */
return qtrue;
}
/*
-AddSurfaceToRawLightmap()
-projects a lightmap for a surface
-based on AllocateLightmapForSurface()
-*/
-
-qboolean AddSurfaceToRawLightmap( int num, rawLightmap_t *lm )
-{
- bspDrawSurface_t *ds, *ds2;
- surfaceInfo_t *info;
- int num2, n, i, axisNum;
- float s, t, d, len, sampleSize;
- vec3_t mins, maxs, origin, faxis, size, delta, normalized, vecs[ 2 ];
- vec4_t plane;
- bspDrawVert_t *verts;
-
-
+ AddSurfaceToRawLightmap()
+ projects a lightmap for a surface
+ based on AllocateLightmapForSurface()
+ */
+
+qboolean AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){
+ bspDrawSurface_t *ds, *ds2;
+ surfaceInfo_t *info;
+ int num2, n, i, axisNum;
+ float s, t, d, len, sampleSize;
+ vec3_t mins, maxs, origin, faxis, size, delta, normalized, vecs[ 2 ];
+ vec4_t plane;
+ bspDrawVert_t *verts;
+
+
/* get surface and info */
ds = &bspDrawSurfaces[ num ];
info = &surfaceInfos[ num ];
-
+
/* add the surface to the raw lightmap */
lightSurfaces[ numLightSurfaces++ ] = num;
lm->numLightSurfaces++;
-
+
/* does this raw lightmap already have any surfaces? */
- if( lm->numLightSurfaces > 1 )
- {
+ if ( lm->numLightSurfaces > 1 ) {
/* surface and raw lightmap must have the same lightmap projection axis */
- if( VectorCompare( info->axis, lm->axis ) == qfalse )
+ if ( VectorCompare( info->axis, lm->axis ) == qfalse ) {
return qfalse;
-
+ }
+
/* match identical attributes */
- if( info->sampleSize != lm->sampleSize ||
- info->entityNum != lm->entityNum ||
- info->recvShadows != lm->recvShadows ||
- info->si->lmCustomWidth != lm->customWidth ||
- info->si->lmCustomHeight != lm->customHeight ||
- info->si->lmBrightness != lm->brightness ||
- info->si->lmFilterRadius != lm->filterRadius ||
- info->si->splotchFix != lm->splotchFix )
+ if ( info->sampleSize != lm->sampleSize ||
+ info->entityNum != lm->entityNum ||
+ info->recvShadows != lm->recvShadows ||
+ info->si->lmCustomWidth != lm->customWidth ||
+ info->si->lmCustomHeight != lm->customHeight ||
+ info->si->lmBrightness != lm->brightness ||
+ info->si->lmFilterRadius != lm->filterRadius ||
+ info->si->splotchFix != lm->splotchFix ) {
return qfalse;
-
+ }
+
/* surface bounds must intersect with raw lightmap bounds */
- for( i = 0; i < 3; i++ )
+ for ( i = 0; i < 3; i++ )
{
- if( info->mins[ i ] > lm->maxs[ i ] )
+ if ( info->mins[ i ] > lm->maxs[ i ] ) {
return qfalse;
- if( info->maxs[ i ] < lm->mins[ i ] )
+ }
+ if ( info->maxs[ i ] < lm->mins[ i ] ) {
return qfalse;
+ }
}
-
+
/* plane check (fixme: allow merging of nonplanars) */
- if( info->si->lmMergable == qfalse )
- {
- if( info->plane == NULL || lm->plane == NULL )
+ if ( info->si->lmMergable == qfalse ) {
+ if ( info->plane == NULL || lm->plane == NULL ) {
return qfalse;
-
+ }
+
/* compare planes */
- for( i = 0; i < 4; i++ )
- if( fabs( info->plane[ i ] - lm->plane[ i ] ) > EQUAL_EPSILON )
+ for ( i = 0; i < 4; i++ )
+ if ( fabs( info->plane[ i ] - lm->plane[ i ] ) > EQUAL_EPSILON ) {
return qfalse;
+ }
}
-
+
/* debug code hacking */
//% if( lm->numLightSurfaces > 1 )
//% return qfalse;
}
-
+
/* set plane */
- if( info->plane == NULL )
+ if ( info->plane == NULL ) {
lm->plane = NULL;
-
+ }
+
/* add surface to lightmap bounds */
AddPointToBounds( info->mins, lm->mins, lm->maxs );
AddPointToBounds( info->maxs, lm->mins, lm->maxs );
-
+
/* check to see if this is a non-planar patch */
- if( ds->surfaceType == MST_PATCH &&
- lm->axis[ 0 ] == 0.0f && lm->axis[ 1 ] == 0.0f && lm->axis[ 2 ] == 0.0f )
+ if ( ds->surfaceType == MST_PATCH &&
+ lm->axis[ 0 ] == 0.0f && lm->axis[ 1 ] == 0.0f && lm->axis[ 2 ] == 0.0f ) {
return AddPatchToRawLightmap( num, lm );
-
+ }
+
/* start with initially requested sample size */
sampleSize = lm->sampleSize;
-
+
/* round to the lightmap resolution */
- for( i = 0; i < 3; i++ )
+ for ( i = 0; i < 3; i++ )
{
- mins[ i ] = sampleSize * floor( lm->mins[ i ] / sampleSize );
- maxs[ i ] = sampleSize * ceil( lm->maxs[ i ] / sampleSize );
- size[ i ] = (maxs[ i ] - mins[ i ]) / sampleSize + 1.0f;
-
+ mins[ i ] = sampleSize * floor( lm->mins[ i ] / sampleSize );
+ maxs[ i ] = sampleSize * ceil( lm->maxs[ i ] / sampleSize );
+ size[ i ] = ( maxs[ i ] - mins[ i ] ) / sampleSize + 1.0f;
+
/* hack (god this sucks) */
- if( size[ i ] > lm->customWidth || size[ i ] > lm->customHeight || (lmLimitSize && size[i] > lmLimitSize))
- {
+ if ( size[ i ] > lm->customWidth || size[ i ] > lm->customHeight || ( lmLimitSize && size[i] > lmLimitSize ) ) {
i = -1;
sampleSize += 1.0f;
}
}
- if(sampleSize != lm->sampleSize && lmLimitSize == 0)
- {
- Sys_FPrintf(SYS_VRB,"WARNING: surface at (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) too large for desired samplesize/lightmapsize/lightmapscale combination, increased samplesize from %d to %d\n",
- info->mins[0],
- info->mins[1],
- info->mins[2],
- info->maxs[0],
- info->maxs[1],
- info->maxs[2],
- lm->sampleSize,
- (int) sampleSize);
- }
-
+ if ( sampleSize != lm->sampleSize && lmLimitSize == 0 ) {
+ Sys_FPrintf( SYS_VRB,"WARNING: surface at (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) too large for desired samplesize/lightmapsize/lightmapscale combination, increased samplesize from %d to %d\n",
+ info->mins[0],
+ info->mins[1],
+ info->mins[2],
+ info->maxs[0],
+ info->maxs[1],
+ info->maxs[2],
+ lm->sampleSize,
+ (int) sampleSize );
+ }
+
/* set actual sample size */
lm->actualSampleSize = sampleSize;
-
+
/* fixme: copy rounded mins/maxes to lightmap record? */
- if( lm->plane == NULL )
- {
+ if ( lm->plane == NULL ) {
VectorCopy( mins, lm->mins );
VectorCopy( maxs, lm->maxs );
VectorCopy( mins, origin );
}
-
+
/* set lightmap origin */
VectorCopy( lm->mins, origin );
-
+
/* make absolute axis */
faxis[ 0 ] = fabs( lm->axis[ 0 ] );
faxis[ 1 ] = fabs( lm->axis[ 1 ] );
faxis[ 2 ] = fabs( lm->axis[ 2 ] );
-
+
/* clear out lightmap vectors */
memset( vecs, 0, sizeof( vecs ) );
-
+
/* classify the plane (x y or z major) (ydnar: biased to z axis projection) */
- if( faxis[ 2 ] >= faxis[ 0 ] && faxis[ 2 ] >= faxis[ 1 ] )
- {
+ if ( faxis[ 2 ] >= faxis[ 0 ] && faxis[ 2 ] >= faxis[ 1 ] ) {
axisNum = 2;
lm->w = size[ 0 ];
lm->h = size[ 1 ];
vecs[ 0 ][ 0 ] = 1.0f / sampleSize;
vecs[ 1 ][ 1 ] = 1.0f / sampleSize;
}
- else if( faxis[ 0 ] >= faxis[ 1 ] && faxis[ 0 ] >= faxis[ 2 ] )
- {
+ else if ( faxis[ 0 ] >= faxis[ 1 ] && faxis[ 0 ] >= faxis[ 2 ] ) {
axisNum = 0;
lm->w = size[ 1 ];
lm->h = size[ 2 ];
vecs[ 0 ][ 0 ] = 1.0f / sampleSize;
vecs[ 1 ][ 2 ] = 1.0f / sampleSize;
}
-
+
/* check for bogus axis */
- if( faxis[ axisNum ] == 0.0f )
- {
+ if ( faxis[ axisNum ] == 0.0f ) {
Sys_Printf( "WARNING: ProjectSurfaceLightmap: Chose a 0 valued axis\n" );
lm->w = lm->h = 0;
return qfalse;
}
-
+
/* store the axis number in the lightmap */
lm->axisNum = axisNum;
-
+
/* walk the list of surfaces on this raw lightmap */
- for( n = 0; n < lm->numLightSurfaces; n++ )
+ for ( n = 0; n < lm->numLightSurfaces; n++ )
{
/* get surface */
num2 = lightSurfaces[ lm->firstLightSurface + n ];
ds2 = &bspDrawSurfaces[ num2 ];
verts = &yDrawVerts[ ds2->firstVert ];
-
+
/* set the lightmap texture coordinates in yDrawVerts in [0, superSample * lm->customWidth] space */
- for( i = 0; i < ds2->numVerts; i++ )
+ for ( i = 0; i < ds2->numVerts; i++ )
{
VectorSubtract( verts[ i ].xyz, origin, delta );
s = DotProduct( delta, vecs[ 0 ] ) + 0.5f;
t = DotProduct( delta, vecs[ 1 ] ) + 0.5f;
verts[ i ].lightmap[ 0 ][ 0 ] = s * superSample;
verts[ i ].lightmap[ 0 ][ 1 ] = t * superSample;
-
- if( s > (float) lm->w || t > (float) lm->h )
- {
+
+ if ( s > (float) lm->w || t > (float) lm->h ) {
Sys_FPrintf( SYS_VRB, "WARNING: Lightmap texture coords out of range: S %1.4f > %3d || T %1.4f > %3d\n",
- s, lm->w, t, lm->h );
+ s, lm->w, t, lm->h );
}
}
}
-
+
/* get first drawsurface */
num2 = lightSurfaces[ lm->firstLightSurface ];
ds2 = &bspDrawSurfaces[ num2 ];
verts = &yDrawVerts[ ds2->firstVert ];
-
+
/* calculate lightmap origin */
- if( VectorLength( ds2->lightmapVecs[ 2 ] ) )
+ if ( VectorLength( ds2->lightmapVecs[ 2 ] ) ) {
VectorCopy( ds2->lightmapVecs[ 2 ], plane );
- else
+ }
+ else{
VectorCopy( lm->axis, plane );
+ }
plane[ 3 ] = DotProduct( verts[ 0 ].xyz, plane );
-
+
VectorCopy( origin, lm->origin );
d = DotProduct( lm->origin, plane ) - plane[ 3 ];
d /= plane[ axisNum ];
lm->origin[ axisNum ] -= d;
-
+
/* legacy support */
VectorCopy( lm->origin, ds->lightmapOrigin );
-
+
/* for planar surfaces, create lightmap vectors for st->xyz conversion */
- if( VectorLength( ds->lightmapVecs[ 2 ] ) || 1 ) /* ydnar: can't remember what exactly i was thinking here... */
- {
+ if ( VectorLength( ds->lightmapVecs[ 2 ] ) || 1 ) { /* ydnar: can't remember what exactly i was thinking here... */
/* allocate space for the vectors */
lm->vecs = safe_malloc( 3 * sizeof( vec3_t ) );
memset( lm->vecs, 0, 3 * sizeof( vec3_t ) );
VectorCopy( ds->lightmapVecs[ 2 ], lm->vecs[ 2 ] );
-
+
/* project stepped lightmap blocks and subtract to get planevecs */
- for( i = 0; i < 2; i++ )
+ for ( i = 0; i < 2; i++ )
{
len = VectorNormalize( vecs[ i ], normalized );
- VectorScale( normalized, (1.0 / len), lm->vecs[ i ] );
+ VectorScale( normalized, ( 1.0 / len ), lm->vecs[ i ] );
d = DotProduct( lm->vecs[ i ], plane );
d /= plane[ axisNum ];
lm->vecs[ i ][ axisNum ] -= d;
/* lightmap vectors are useless on a non-planar surface */
lm->vecs = NULL;
}
-
+
/* add to counts */
- if( ds->surfaceType == MST_PATCH )
- {
+ if ( ds->surfaceType == MST_PATCH ) {
numPatchesLightmapped++;
- if( lm->plane != NULL )
+ if ( lm->plane != NULL ) {
numPlanarPatchesLightmapped++;
+ }
}
else
{
- if( lm->plane != NULL )
+ if ( lm->plane != NULL ) {
numPlanarsLightmapped++;
- else
+ }
+ else{
numNonPlanarsLightmapped++;
+ }
}
-
+
/* return */
return qtrue;
}
/*
-CompareSurfaceInfo()
-compare function for qsort()
-*/
+ CompareSurfaceInfo()
+ compare function for qsort()
+ */
+
+static int CompareSurfaceInfo( const void *a, const void *b ){
+ surfaceInfo_t *aInfo, *bInfo;
+ int i;
-static int CompareSurfaceInfo( const void *a, const void *b )
-{
- surfaceInfo_t *aInfo, *bInfo;
- int i;
-
/* get surface info */
- aInfo = &surfaceInfos[ *((const int*) a) ];
- bInfo = &surfaceInfos[ *((const int*) b) ];
-
+ aInfo = &surfaceInfos[ *( (const int*) a ) ];
+ bInfo = &surfaceInfos[ *( (const int*) b ) ];
+
/* model first */
- if( aInfo->modelindex < bInfo->modelindex )
+ if ( aInfo->modelindex < bInfo->modelindex ) {
return 1;
- else if( aInfo->modelindex > bInfo->modelindex )
+ }
+ else if ( aInfo->modelindex > bInfo->modelindex ) {
return -1;
-
+ }
+
/* then lightmap status */
- if( aInfo->hasLightmap < bInfo->hasLightmap )
+ if ( aInfo->hasLightmap < bInfo->hasLightmap ) {
+ return 1;
+ }
+ else if ( aInfo->hasLightmap > bInfo->hasLightmap ) {
+ return -1;
+ }
+
+ /* 27: then shader! */
+ if ( aInfo->si < bInfo->si ) {
return 1;
- else if( aInfo->hasLightmap > bInfo->hasLightmap )
+ }
+ else if ( aInfo->si > bInfo->si ) {
return -1;
+ }
+
- /* 27: then shader! */
- if (aInfo->si < bInfo->si)
- return 1;
- else if (aInfo->si > bInfo->si)
- return -1;
-
-
/* then lightmap sample size */
- if( aInfo->sampleSize < bInfo->sampleSize )
+ if ( aInfo->sampleSize < bInfo->sampleSize ) {
return 1;
- else if( aInfo->sampleSize > bInfo->sampleSize )
+ }
+ else if ( aInfo->sampleSize > bInfo->sampleSize ) {
return -1;
-
+ }
+
/* then lightmap axis */
- for( i = 0; i < 3; i++ )
+ for ( i = 0; i < 3; i++ )
{
- if( aInfo->axis[ i ] < bInfo->axis[ i ] )
+ if ( aInfo->axis[ i ] < bInfo->axis[ i ] ) {
return 1;
- else if( aInfo->axis[ i ] > bInfo->axis[ i ] )
+ }
+ else if ( aInfo->axis[ i ] > bInfo->axis[ i ] ) {
return -1;
+ }
}
-
+
/* then plane */
- if( aInfo->plane == NULL && bInfo->plane != NULL )
+ if ( aInfo->plane == NULL && bInfo->plane != NULL ) {
return 1;
- else if( aInfo->plane != NULL && bInfo->plane == NULL )
+ }
+ else if ( aInfo->plane != NULL && bInfo->plane == NULL ) {
return -1;
- else if( aInfo->plane != NULL && bInfo->plane != NULL )
- {
- for( i = 0; i < 4; i++ )
+ }
+ else if ( aInfo->plane != NULL && bInfo->plane != NULL ) {
+ for ( i = 0; i < 4; i++ )
{
- if( aInfo->plane[ i ] < bInfo->plane[ i ] )
+ if ( aInfo->plane[ i ] < bInfo->plane[ i ] ) {
return 1;
- else if( aInfo->plane[ i ] > bInfo->plane[ i ] )
+ }
+ else if ( aInfo->plane[ i ] > bInfo->plane[ i ] ) {
return -1;
+ }
}
}
-
+
/* then position in world */
- for( i = 0; i < 3; i++ )
+ for ( i = 0; i < 3; i++ )
{
- if( aInfo->mins[ i ] < bInfo->mins[ i ] )
+ if ( aInfo->mins[ i ] < bInfo->mins[ i ] ) {
return 1;
- else if( aInfo->mins[ i ] > bInfo->mins[ i ] )
+ }
+ else if ( aInfo->mins[ i ] > bInfo->mins[ i ] ) {
return -1;
+ }
}
-
+
/* these are functionally identical (this should almost never happen) */
return 0;
}
/*
-SetupSurfaceLightmaps()
-allocates lightmaps for every surface in the bsp that needs one
-this depends on yDrawVerts being allocated
-*/
-
-void SetupSurfaceLightmaps( void )
-{
- int i, j, k, s,num, num2;
- bspModel_t *model;
- bspLeaf_t *leaf;
- bspDrawSurface_t *ds;
- surfaceInfo_t *info, *info2;
- rawLightmap_t *lm;
- qboolean added;
- vec3_t mapSize, entityOrigin;
-
-
+ SetupSurfaceLightmaps()
+ allocates lightmaps for every surface in the bsp that needs one
+ this depends on yDrawVerts being allocated
+ */
+
+void SetupSurfaceLightmaps( void ){
+ int i, j, k, s,num, num2;
+ bspModel_t *model;
+ bspLeaf_t *leaf;
+ bspDrawSurface_t *ds;
+ surfaceInfo_t *info, *info2;
+ rawLightmap_t *lm;
+ qboolean added;
+ vec3_t mapSize, entityOrigin;
+
+
/* note it */
- Sys_FPrintf( SYS_VRB, "--- SetupSurfaceLightmaps ---\n");
-
+ Sys_FPrintf( SYS_VRB, "--- SetupSurfaceLightmaps ---\n" );
+
/* determine supersample amount */
- if( superSample < 1 )
+ if ( superSample < 1 ) {
superSample = 1;
- else if( superSample > 8 )
- {
+ }
+ else if ( superSample > 8 ) {
Sys_Printf( "WARNING: Insane supersampling amount (%d) detected.\n", superSample );
superSample = 8;
}
-
+
/* clear map bounds */
ClearBounds( mapMins, mapMaxs );
-
+
/* allocate a list of surface clusters */
numSurfaceClusters = 0;
maxSurfaceClusters = numBSPLeafSurfaces;
surfaceClusters = safe_malloc( maxSurfaceClusters * sizeof( *surfaceClusters ) );
memset( surfaceClusters, 0, maxSurfaceClusters * sizeof( *surfaceClusters ) );
-
+
/* allocate a list for per-surface info */
surfaceInfos = safe_malloc( numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
memset( surfaceInfos, 0, numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
- for( i = 0; i < numBSPDrawSurfaces; i++ )
+ for ( i = 0; i < numBSPDrawSurfaces; i++ )
surfaceInfos[ i ].childSurfaceNum = -1;
-
+
/* allocate a list of surface indexes to be sorted */
sortSurfaces = safe_malloc( numBSPDrawSurfaces * sizeof( int ) );
memset( sortSurfaces, 0, numBSPDrawSurfaces * sizeof( int ) );
-
+
/* walk each model in the bsp */
- for( i = 0; i < numBSPModels; i++ )
+ for ( i = 0; i < numBSPModels; i++ )
{
/* get model */
model = &bspModels[ i ];
-
+
/* walk the list of surfaces in this model and fill out the info structs */
- for( j = 0; j < model->numBSPSurfaces; j++ )
+ for ( j = 0; j < model->numBSPSurfaces; j++ )
{
/* make surface index */
num = model->firstBSPSurface + j;
-
+
/* copy index to sort list */
sortSurfaces[ num ] = num;
-
+
/* get surface and info */
ds = &bspDrawSurfaces[ num ];
info = &surfaceInfos[ num ];
-
+
/* set entity origin */
- if( ds->numVerts > 0 )
+ if ( ds->numVerts > 0 ) {
VectorSubtract( yDrawVerts[ ds->firstVert ].xyz, bspDrawVerts[ ds->firstVert ].xyz, entityOrigin );
- else
+ }
+ else{
VectorClear( entityOrigin );
-
+ }
+
/* basic setup */
info->modelindex = i;
info->lm = NULL;
info->plane = NULL;
info->firstSurfaceCluster = numSurfaceClusters;
-
+
/* get extra data */
info->si = GetSurfaceExtraShaderInfo( num );
- if( info->si == NULL )
+ if ( info->si == NULL ) {
info->si = ShaderInfoForShader( bspShaders[ ds->shaderNum ].shader );
+ }
info->parentSurfaceNum = GetSurfaceExtraParentSurfaceNum( num );
info->entityNum = GetSurfaceExtraEntityNum( num );
info->castShadows = GetSurfaceExtraCastShadows( num );
info->longestCurve = GetSurfaceExtraLongestCurve( num );
info->patchIterations = IterationsForCurve( info->longestCurve, patchSubdivisions );
GetSurfaceExtraLightmapAxis( num, info->axis );
-
+
/* mark parent */
- if( info->parentSurfaceNum >= 0 )
+ if ( info->parentSurfaceNum >= 0 ) {
surfaceInfos[ info->parentSurfaceNum ].childSurfaceNum = j;
-
+ }
+
/* determine surface bounds */
ClearBounds( info->mins, info->maxs );
- for( k = 0; k < ds->numVerts; k++ )
+ for ( k = 0; k < ds->numVerts; k++ )
{
AddPointToBounds( yDrawVerts[ ds->firstVert + k ].xyz, mapMins, mapMaxs );
AddPointToBounds( yDrawVerts[ ds->firstVert + k ].xyz, info->mins, info->maxs );
}
-
+
/* find all the bsp clusters the surface falls into */
- for( k = 0; k < numBSPLeafs; k++ )
+ for ( k = 0; k < numBSPLeafs; k++ )
{
/* get leaf */
leaf = &bspLeafs[ k ];
-
+
/* test bbox */
- if( leaf->mins[ 0 ] > info->maxs[ 0 ] || leaf->maxs[ 0 ] < info->mins[ 0 ] ||
- leaf->mins[ 1 ] > info->maxs[ 1 ] || leaf->maxs[ 1 ] < info->mins[ 1 ] ||
- leaf->mins[ 2 ] > info->maxs[ 2 ] || leaf->maxs[ 2 ] < info->mins[ 2 ] )
+ if ( leaf->mins[ 0 ] > info->maxs[ 0 ] || leaf->maxs[ 0 ] < info->mins[ 0 ] ||
+ leaf->mins[ 1 ] > info->maxs[ 1 ] || leaf->maxs[ 1 ] < info->mins[ 1 ] ||
+ leaf->mins[ 2 ] > info->maxs[ 2 ] || leaf->maxs[ 2 ] < info->mins[ 2 ] ) {
continue;
-
+ }
+
/* test leaf surfaces */
- for( s = 0; s < leaf->numBSPLeafSurfaces; s++ )
+ for ( s = 0; s < leaf->numBSPLeafSurfaces; s++ )
{
- if( bspLeafSurfaces[ leaf->firstBSPLeafSurface + s ] == num )
- {
- if( numSurfaceClusters >= maxSurfaceClusters )
+ if ( bspLeafSurfaces[ leaf->firstBSPLeafSurface + s ] == num ) {
+ if ( numSurfaceClusters >= maxSurfaceClusters ) {
Error( "maxSurfaceClusters exceeded" );
+ }
surfaceClusters[ numSurfaceClusters ] = leaf->cluster;
numSurfaceClusters++;
info->numSurfaceClusters++;
}
}
}
-
+
/* determine if surface is planar */
- if( VectorLength( ds->lightmapVecs[ 2 ] ) > 0.0f )
- {
+ if ( VectorLength( ds->lightmapVecs[ 2 ] ) > 0.0f ) {
/* make a plane */
info->plane = safe_malloc( 4 * sizeof( float ) );
VectorCopy( ds->lightmapVecs[ 2 ], info->plane );
info->plane[ 3 ] = DotProduct( yDrawVerts[ ds->firstVert ].xyz, info->plane );
}
-
+
/* determine if surface requires a lightmap */
- if( ds->surfaceType == MST_TRIANGLE_SOUP ||
- ds->surfaceType == MST_FOLIAGE ||
- (info->si->compileFlags & C_VERTEXLIT) )
+ if ( ds->surfaceType == MST_TRIANGLE_SOUP ||
+ ds->surfaceType == MST_FOLIAGE ||
+ ( info->si->compileFlags & C_VERTEXLIT ) ) {
numSurfsVertexLit++;
+ }
else
{
numSurfsLightmapped++;
}
}
}
-
+
/* find longest map distance */
VectorSubtract( mapMaxs, mapMins, mapSize );
maxMapDistance = VectorLength( mapSize );
-
+
/* sort the surfaces info list */
qsort( sortSurfaces, numBSPDrawSurfaces, sizeof( int ), CompareSurfaceInfo );
-
+
/* allocate a list of surfaces that would go into raw lightmaps */
numLightSurfaces = 0;
lightSurfaces = safe_malloc( numSurfsLightmapped * sizeof( int ) );
memset( lightSurfaces, 0, numSurfsLightmapped * sizeof( int ) );
-
+
/* allocate a list of raw lightmaps */
numRawSuperLuxels = 0;
numRawLightmaps = 0;
rawLightmaps = safe_malloc( numSurfsLightmapped * sizeof( *rawLightmaps ) );
memset( rawLightmaps, 0, numSurfsLightmapped * sizeof( *rawLightmaps ) );
-
+
/* walk the list of sorted surfaces */
- for( i = 0; i < numBSPDrawSurfaces; i++ )
+ for ( i = 0; i < numBSPDrawSurfaces; i++ )
{
/* get info and attempt early out */
num = sortSurfaces[ i ];
ds = &bspDrawSurfaces[ num ];
info = &surfaceInfos[ num ];
- if( info->hasLightmap == qfalse || info->lm != NULL || info->parentSurfaceNum >= 0 )
+ if ( info->hasLightmap == qfalse || info->lm != NULL || info->parentSurfaceNum >= 0 ) {
continue;
-
+ }
+
/* allocate a new raw lightmap */
lm = &rawLightmaps[ numRawLightmaps ];
numRawLightmaps++;
-
+
/* set it up */
lm->splotchFix = info->si->splotchFix;
lm->firstLightSurface = numLightSurfaces;
lm->numLightSurfaces = 0;
/* vortex: multiply lightmap sample size by -samplescale */
- if (sampleScale > 0)
- lm->sampleSize = info->sampleSize*sampleScale;
- else
+ if ( sampleScale > 0 ) {
+ lm->sampleSize = info->sampleSize * sampleScale;
+ }
+ else{
lm->sampleSize = info->sampleSize;
+ }
lm->actualSampleSize = lm->sampleSize;
lm->entityNum = info->entityNum;
lm->recvShadows = info->recvShadows;
lm->brightness = info->si->lmBrightness;
lm->filterRadius = info->si->lmFilterRadius;
- VectorCopy(info->si->floodlightRGB, lm->floodlightRGB);
+ VectorCopy( info->si->floodlightRGB, lm->floodlightRGB );
lm->floodlightDistance = info->si->floodlightDistance;
lm->floodlightIntensity = info->si->floodlightIntensity;
lm->floodlightDirectionScale = info->si->floodlightDirectionScale;
VectorCopy( info->axis, lm->axis );
- lm->plane = info->plane;
+ lm->plane = info->plane;
VectorCopy( info->mins, lm->mins );
VectorCopy( info->maxs, lm->maxs );
-
+
lm->customWidth = info->si->lmCustomWidth;
lm->customHeight = info->si->lmCustomHeight;
-
+
/* add the surface to the raw lightmap */
AddSurfaceToRawLightmap( num, lm );
info->lm = lm;
-
+
/* do an exhaustive merge */
added = qtrue;
- while( added )
+ while ( added )
{
/* walk the list of surfaces again */
added = qfalse;
- for( j = i + 1; j < numBSPDrawSurfaces && lm->finished == qfalse; j++ )
+ for ( j = i + 1; j < numBSPDrawSurfaces && lm->finished == qfalse; j++ )
{
/* get info and attempt early out */
num2 = sortSurfaces[ j ];
info2 = &surfaceInfos[ num2 ];
- if( info2->hasLightmap == qfalse || info2->lm != NULL )
+ if ( info2->hasLightmap == qfalse || info2->lm != NULL ) {
continue;
-
+ }
+
/* add the surface to the raw lightmap */
- if( AddSurfaceToRawLightmap( num2, lm ) )
- {
+ if ( AddSurfaceToRawLightmap( num2, lm ) ) {
info2->lm = lm;
added = qtrue;
}
}
}
}
-
+
/* finish the lightmap and allocate the various buffers */
FinishRawLightmap( lm );
}
-
+
/* allocate vertex luxel storage */
- for( k = 0; k < MAX_LIGHTMAPS; k++ )
+ for ( k = 0; k < MAX_LIGHTMAPS; k++ )
{
- vertexLuxels[ k ] = safe_malloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
+ vertexLuxels[ k ] = safe_malloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
memset( vertexLuxels[ k ], 0, numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
radVertexLuxels[ k ] = safe_malloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
memset( radVertexLuxels[ k ], 0, numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
}
-
+
/* emit some stats */
Sys_FPrintf( SYS_VRB, "%9d surfaces\n", numBSPDrawSurfaces );
Sys_FPrintf( SYS_VRB, "%9d raw lightmaps\n", numRawLightmaps );
/*
-StitchSurfaceLightmaps()
-stitches lightmap edges
-2002-11-20 update: use this func only for stitching nonplanar patch lightmap seams
-*/
-
-#define MAX_STITCH_CANDIDATES 32
-#define MAX_STITCH_LUXELS 64
-
-void StitchSurfaceLightmaps( void )
-{
- int i, j, x, y, x2, y2, *cluster, *cluster2,
- numStitched, numCandidates, numLuxels, f, fOld, start;
- rawLightmap_t *lm, *a, *b, *c[ MAX_STITCH_CANDIDATES ];
- float *luxel, *luxel2, *origin, *origin2, *normal, *normal2,
- sampleSize, average[ 3 ], totalColor, ootc;
-
-
- /* disabled for now */
- return;
-
+ StitchSurfaceLightmaps()
+ stitches lightmap edges
+ 2002-11-20 update: use this func only for stitching nonplanar patch lightmap seams
+ */
+
+#define MAX_STITCH_CANDIDATES 32
+#define MAX_STITCH_LUXELS 64
+
+void StitchSurfaceLightmaps( void ){
+ int i, j, x, y, x2, y2, *cluster, *cluster2,
+ numStitched, numCandidates, numLuxels, f, fOld, start;
+ rawLightmap_t *lm, *a, *b, *c[ MAX_STITCH_CANDIDATES ];
+ float *luxel, *luxel2, *origin, *origin2, *normal, *normal2,
+ sampleSize, average[ 3 ], totalColor, ootc;
+
+
+ /* disabled for now */
+ return;
+
/* note it */
- Sys_Printf( "--- StitchSurfaceLightmaps ---\n");
+ Sys_Printf( "--- StitchSurfaceLightmaps ---\n" );
/* init pacifier */
fOld = -1;
start = I_FloatTime();
-
+
/* walk the list of raw lightmaps */
numStitched = 0;
- for( i = 0; i < numRawLightmaps; i++ )
+ for ( i = 0; i < numRawLightmaps; i++ )
{
/* print pacifier */
f = 10 * i / numRawLightmaps;
- if( f != fOld )
- {
+ if ( f != fOld ) {
fOld = f;
Sys_Printf( "%i...", f );
}
-
+
/* get lightmap a */
a = &rawLightmaps[ i ];
-
+
/* walk rest of lightmaps */
numCandidates = 0;
- for( j = i + 1; j < numRawLightmaps && numCandidates < MAX_STITCH_CANDIDATES; j++ )
+ for ( j = i + 1; j < numRawLightmaps && numCandidates < MAX_STITCH_CANDIDATES; j++ )
{
/* get lightmap b */
b = &rawLightmaps[ j ];
-
+
/* test bounding box */
- if( a->mins[ 0 ] > b->maxs[ 0 ] || a->maxs[ 0 ] < b->mins[ 0 ] ||
- a->mins[ 1 ] > b->maxs[ 1 ] || a->maxs[ 1 ] < b->mins[ 1 ] ||
- a->mins[ 2 ] > b->maxs[ 2 ] || a->maxs[ 2 ] < b->mins[ 2 ] )
+ if ( a->mins[ 0 ] > b->maxs[ 0 ] || a->maxs[ 0 ] < b->mins[ 0 ] ||
+ a->mins[ 1 ] > b->maxs[ 1 ] || a->maxs[ 1 ] < b->mins[ 1 ] ||
+ a->mins[ 2 ] > b->maxs[ 2 ] || a->maxs[ 2 ] < b->mins[ 2 ] ) {
continue;
-
+ }
+
/* add candidate */
c[ numCandidates++ ] = b;
}
-
+
/* walk luxels */
- for( y = 0; y < a->sh; y++ )
+ for ( y = 0; y < a->sh; y++ )
{
- for( x = 0; x < a->sw; x++ )
+ for ( x = 0; x < a->sw; x++ )
{
/* ignore unmapped/unlit luxels */
lm = a;
cluster = SUPER_CLUSTER( x, y );
- if( *cluster == CLUSTER_UNMAPPED )
+ if ( *cluster == CLUSTER_UNMAPPED ) {
continue;
+ }
luxel = SUPER_LUXEL( 0, x, y );
- if( luxel[ 3 ] <= 0.0f )
+ if ( luxel[ 3 ] <= 0.0f ) {
continue;
-
+ }
+
/* get particulars */
origin = SUPER_ORIGIN( x, y );
normal = SUPER_NORMAL( x, y );
-
+
/* walk candidate list */
- for( j = 0; j < numCandidates; j++ )
+ for ( j = 0; j < numCandidates; j++ )
{
/* get candidate */
b = c[ j ];
lm = b;
-
+
/* set samplesize to the smaller of the pair */
- sampleSize = 0.5f * (a->actualSampleSize < b->actualSampleSize ? a->actualSampleSize : b->actualSampleSize);
-
+ sampleSize = 0.5f * ( a->actualSampleSize < b->actualSampleSize ? a->actualSampleSize : b->actualSampleSize );
+
/* test bounding box */
- if( origin[ 0 ] < (b->mins[ 0 ] - sampleSize) || (origin[ 0 ] > b->maxs[ 0 ] + sampleSize) ||
- origin[ 1 ] < (b->mins[ 1 ] - sampleSize) || (origin[ 1 ] > b->maxs[ 1 ] + sampleSize) ||
- origin[ 2 ] < (b->mins[ 2 ] - sampleSize) || (origin[ 2 ] > b->maxs[ 2 ] + sampleSize) )
+ if ( origin[ 0 ] < ( b->mins[ 0 ] - sampleSize ) || ( origin[ 0 ] > b->maxs[ 0 ] + sampleSize ) ||
+ origin[ 1 ] < ( b->mins[ 1 ] - sampleSize ) || ( origin[ 1 ] > b->maxs[ 1 ] + sampleSize ) ||
+ origin[ 2 ] < ( b->mins[ 2 ] - sampleSize ) || ( origin[ 2 ] > b->maxs[ 2 ] + sampleSize ) ) {
continue;
-
+ }
+
/* walk candidate luxels */
VectorClear( average );
numLuxels = 0;
totalColor = 0.0f;
- for( y2 = 0; y2 < b->sh && numLuxels < MAX_STITCH_LUXELS; y2++ )
+ for ( y2 = 0; y2 < b->sh && numLuxels < MAX_STITCH_LUXELS; y2++ )
{
- for( x2 = 0; x2 < b->sw && numLuxels < MAX_STITCH_LUXELS; x2++ )
+ for ( x2 = 0; x2 < b->sw && numLuxels < MAX_STITCH_LUXELS; x2++ )
{
/* ignore same luxels */
- if( a == b && abs( x - x2 ) <= 1 && abs( y - y2 ) <= 1 )
+ if ( a == b && abs( x - x2 ) <= 1 && abs( y - y2 ) <= 1 ) {
continue;
-
+ }
+
/* ignore unmapped/unlit luxels */
cluster2 = SUPER_CLUSTER( x2, y2 );
- if( *cluster2 == CLUSTER_UNMAPPED )
+ if ( *cluster2 == CLUSTER_UNMAPPED ) {
continue;
+ }
luxel2 = SUPER_LUXEL( 0, x2, y2 );
- if( luxel2[ 3 ] <= 0.0f )
+ if ( luxel2[ 3 ] <= 0.0f ) {
continue;
-
+ }
+
/* get particulars */
origin2 = SUPER_ORIGIN( x2, y2 );
normal2 = SUPER_NORMAL( x2, y2 );
-
+
/* test normal */
- if( DotProduct( normal, normal2 ) < 0.5f )
+ if ( DotProduct( normal, normal2 ) < 0.5f ) {
continue;
-
+ }
+
/* test bounds */
- if( fabs( origin[ 0 ] - origin2[ 0 ] ) > sampleSize ||
- fabs( origin[ 1 ] - origin2[ 1 ] ) > sampleSize ||
- fabs( origin[ 2 ] - origin2[ 2 ] ) > sampleSize )
+ if ( fabs( origin[ 0 ] - origin2[ 0 ] ) > sampleSize ||
+ fabs( origin[ 1 ] - origin2[ 1 ] ) > sampleSize ||
+ fabs( origin[ 2 ] - origin2[ 2 ] ) > sampleSize ) {
continue;
-
+ }
+
/* add luxel */
//% VectorSet( luxel2, 255, 0, 255 );
VectorAdd( average, luxel2, average );
totalColor += luxel2[ 3 ];
}
}
-
+
/* early out */
- if( numLuxels == 0 )
+ if ( numLuxels == 0 ) {
continue;
-
+ }
+
/* scale average */
ootc = 1.0f / totalColor;
VectorScale( average, ootc, luxel );
}
}
}
-
+
/* emit statistics */
- Sys_Printf( " (%i)\n", (int) (I_FloatTime() - start) );
+ Sys_Printf( " (%i)\n", (int) ( I_FloatTime() - start ) );
Sys_FPrintf( SYS_VRB, "%9d luxels stitched\n", numStitched );
}
/*
-CompareBSPLuxels()
-compares two surface lightmaps' bsp luxels, ignoring occluded luxels
-*/
-
-#define SOLID_EPSILON 0.0625
-#define LUXEL_TOLERANCE 0.0025
-#define LUXEL_COLOR_FRAC 0.001302083 /* 1 / 3 / 256 */
-
-static qboolean CompareBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int bNum )
-{
- rawLightmap_t *lm;
- int x, y;
- double delta, total, rd, gd, bd;
- float *aLuxel, *bLuxel;
-
-
+ CompareBSPLuxels()
+ compares two surface lightmaps' bsp luxels, ignoring occluded luxels
+ */
+
+#define SOLID_EPSILON 0.0625
+#define LUXEL_TOLERANCE 0.0025
+#define LUXEL_COLOR_FRAC 0.001302083 /* 1 / 3 / 256 */
+
+static qboolean CompareBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int bNum ){
+ rawLightmap_t *lm;
+ int x, y;
+ double delta, total, rd, gd, bd;
+ float *aLuxel, *bLuxel;
+
+
/* styled lightmaps will never be collapsed to non-styled lightmaps when there is _minlight */
- if( (minLight[ 0 ] || minLight[ 1 ] || minLight[ 2 ]) &&
- ((aNum == 0 && bNum != 0) || (aNum != 0 && bNum == 0)) )
+ if ( ( minLight[ 0 ] || minLight[ 1 ] || minLight[ 2 ] ) &&
+ ( ( aNum == 0 && bNum != 0 ) || ( aNum != 0 && bNum == 0 ) ) ) {
return qfalse;
-
+ }
+
/* basic tests */
- if( a->customWidth != b->customWidth || a->customHeight != b->customHeight ||
- a->brightness != b->brightness ||
- a->solid[ aNum ] != b->solid[ bNum ] ||
- a->bspLuxels[ aNum ] == NULL || b->bspLuxels[ bNum ] == NULL )
+ if ( a->customWidth != b->customWidth || a->customHeight != b->customHeight ||
+ a->brightness != b->brightness ||
+ a->solid[ aNum ] != b->solid[ bNum ] ||
+ a->bspLuxels[ aNum ] == NULL || b->bspLuxels[ bNum ] == NULL ) {
return qfalse;
-
+ }
+
/* compare solid color lightmaps */
- if( a->solid[ aNum ] && b->solid[ bNum ] )
- {
+ if ( a->solid[ aNum ] && b->solid[ bNum ] ) {
/* get deltas */
rd = fabs( a->solidColor[ aNum ][ 0 ] - b->solidColor[ bNum ][ 0 ] );
gd = fabs( a->solidColor[ aNum ][ 1 ] - b->solidColor[ bNum ][ 1 ] );
bd = fabs( a->solidColor[ aNum ][ 2 ] - b->solidColor[ bNum ][ 2 ] );
-
+
/* compare color */
- if( rd > SOLID_EPSILON || gd > SOLID_EPSILON|| bd > SOLID_EPSILON )
+ if ( rd > SOLID_EPSILON || gd > SOLID_EPSILON || bd > SOLID_EPSILON ) {
return qfalse;
-
+ }
+
/* okay */
return qtrue;
}
-
+
/* compare nonsolid lightmaps */
- if( a->w != b->w || a->h != b->h )
+ if ( a->w != b->w || a->h != b->h ) {
return qfalse;
-
+ }
+
/* compare luxels */
delta = 0.0;
total = 0.0;
- for( y = 0; y < a->h; y++ )
+ for ( y = 0; y < a->h; y++ )
{
- for( x = 0; x < a->w; x++ )
+ for ( x = 0; x < a->w; x++ )
{
/* increment total */
total += 1.0;
-
+
/* get luxels */
- lm = a; aLuxel = BSP_LUXEL( aNum, x, y );
- lm = b; bLuxel = BSP_LUXEL( bNum, x, y );
-
+ lm = a; aLuxel = BSP_LUXEL( aNum, x, y );
+ lm = b; bLuxel = BSP_LUXEL( bNum, x, y );
+
/* ignore unused luxels */
- if( aLuxel[ 0 ] < 0 || bLuxel[ 0 ] < 0 )
+ if ( aLuxel[ 0 ] < 0 || bLuxel[ 0 ] < 0 ) {
continue;
-
+ }
+
/* get deltas */
rd = fabs( aLuxel[ 0 ] - bLuxel[ 0 ] );
gd = fabs( aLuxel[ 1 ] - bLuxel[ 1 ] );
bd = fabs( aLuxel[ 2 ] - bLuxel[ 2 ] );
-
+
/* 2003-09-27: compare individual luxels */
- if( rd > 3.0 || gd > 3.0 || bd > 3.0 )
+ if ( rd > 3.0 || gd > 3.0 || bd > 3.0 ) {
return qfalse;
-
+ }
+
/* compare (fixme: take into account perceptual differences) */
delta += rd * LUXEL_COLOR_FRAC;
delta += gd * LUXEL_COLOR_FRAC;
delta += bd * LUXEL_COLOR_FRAC;
-
+
/* is the change too high? */
- if( total > 0.0 && ((delta / total) > LUXEL_TOLERANCE) )
+ if ( total > 0.0 && ( ( delta / total ) > LUXEL_TOLERANCE ) ) {
return qfalse;
+ }
}
}
-
+
/* made it this far, they must be identical (or close enough) */
return qtrue;
}
/*
-MergeBSPLuxels()
-merges two surface lightmaps' bsp luxels, overwriting occluded luxels
-*/
-
-static qboolean MergeBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int bNum )
-{
- rawLightmap_t *lm;
- int x, y;
- float luxel[ 3 ], *aLuxel, *bLuxel;
-
-
+ MergeBSPLuxels()
+ merges two surface lightmaps' bsp luxels, overwriting occluded luxels
+ */
+
+static qboolean MergeBSPLuxels( rawLightmap_t *a, int aNum, rawLightmap_t *b, int bNum ){
+ rawLightmap_t *lm;
+ int x, y;
+ float luxel[ 3 ], *aLuxel, *bLuxel;
+
+
/* basic tests */
- if( a->customWidth != b->customWidth || a->customHeight != b->customHeight ||
- a->brightness != b->brightness ||
- a->solid[ aNum ] != b->solid[ bNum ] ||
- a->bspLuxels[ aNum ] == NULL || b->bspLuxels[ bNum ] == NULL )
+ if ( a->customWidth != b->customWidth || a->customHeight != b->customHeight ||
+ a->brightness != b->brightness ||
+ a->solid[ aNum ] != b->solid[ bNum ] ||
+ a->bspLuxels[ aNum ] == NULL || b->bspLuxels[ bNum ] == NULL ) {
return qfalse;
-
+ }
+
/* compare solid lightmaps */
- if( a->solid[ aNum ] && b->solid[ bNum ] )
- {
+ if ( a->solid[ aNum ] && b->solid[ bNum ] ) {
/* average */
VectorAdd( a->solidColor[ aNum ], b->solidColor[ bNum ], luxel );
VectorScale( luxel, 0.5f, luxel );
-
+
/* copy to both */
VectorCopy( luxel, a->solidColor[ aNum ] );
VectorCopy( luxel, b->solidColor[ bNum ] );
-
+
/* return to sender */
return qtrue;
}
-
+
/* compare nonsolid lightmaps */
- if( a->w != b->w || a->h != b->h )
+ if ( a->w != b->w || a->h != b->h ) {
return qfalse;
-
+ }
+
/* merge luxels */
- for( y = 0; y < a->h; y++ )
+ for ( y = 0; y < a->h; y++ )
{
- for( x = 0; x < a->w; x++ )
+ for ( x = 0; x < a->w; x++ )
{
/* get luxels */
- lm = a; aLuxel = BSP_LUXEL( aNum, x, y );
- lm = b; bLuxel = BSP_LUXEL( bNum, x, y );
-
+ lm = a; aLuxel = BSP_LUXEL( aNum, x, y );
+ lm = b; bLuxel = BSP_LUXEL( bNum, x, y );
+
/* handle occlusion mismatch */
- if( aLuxel[ 0 ] < 0.0f )
+ if ( aLuxel[ 0 ] < 0.0f ) {
VectorCopy( bLuxel, aLuxel );
- else if( bLuxel[ 0 ] < 0.0f )
+ }
+ else if ( bLuxel[ 0 ] < 0.0f ) {
VectorCopy( aLuxel, bLuxel );
+ }
else
{
/* average */
VectorAdd( aLuxel, bLuxel, luxel );
VectorScale( luxel, 0.5f, luxel );
-
+
/* debugging code */
//% luxel[ 2 ] += 64.0f;
-
+
/* copy to both */
VectorCopy( luxel, aLuxel );
VectorCopy( luxel, bLuxel );
}
}
}
-
+
/* done */
return qtrue;
}
/*
-ApproximateLuxel()
-determines if a single luxel is can be approximated with the interpolated vertex rgba
-*/
-
-static qboolean ApproximateLuxel( rawLightmap_t *lm, bspDrawVert_t *dv )
-{
- int i, x, y, d, lightmapNum;
- float *luxel;
- vec3_t color, vertexColor;
- byte cb[ 4 ], vcb[ 4 ];
-
-
+ ApproximateLuxel()
+ determines if a single luxel is can be approximated with the interpolated vertex rgba
+ */
+
+static qboolean ApproximateLuxel( rawLightmap_t *lm, bspDrawVert_t *dv ){
+ int i, x, y, d, lightmapNum;
+ float *luxel;
+ vec3_t color, vertexColor;
+ byte cb[ 4 ], vcb[ 4 ];
+
+
/* find luxel xy coords */
x = dv->lightmap[ 0 ][ 0 ] / superSample;
y = dv->lightmap[ 0 ][ 1 ] / superSample;
- if( x < 0 )
+ if ( x < 0 ) {
x = 0;
- else if( x >= lm->w )
+ }
+ else if ( x >= lm->w ) {
x = lm->w - 1;
- if( y < 0 )
+ }
+ if ( y < 0 ) {
y = 0;
- else if( y >= lm->h )
+ }
+ else if ( y >= lm->h ) {
y = lm->h - 1;
-
+ }
+
/* walk list */
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
/* early out */
- if( lm->styles[ lightmapNum ] == LS_NONE )
+ if ( lm->styles[ lightmapNum ] == LS_NONE ) {
continue;
-
+ }
+
/* get luxel */
luxel = BSP_LUXEL( lightmapNum, x, y );
-
+
/* ignore occluded luxels */
- if( luxel[ 0 ] < 0.0f || luxel[ 1 ] < 0.0f || luxel[ 2 ] < 0.0f )
+ if ( luxel[ 0 ] < 0.0f || luxel[ 1 ] < 0.0f || luxel[ 2 ] < 0.0f ) {
return qtrue;
-
+ }
+
/* copy, set min color and compare */
VectorCopy( luxel, color );
VectorCopy( dv->color[ 0 ], vertexColor );
/* styles are not affected by minlight */
- if( lightmapNum == 0 )
- {
- for( i = 0; i < 3; i++ )
+ if ( lightmapNum == 0 ) {
+ for ( i = 0; i < 3; i++ )
{
/* set min color */
- if( color[ i ] < minLight[ i ] )
+ if ( color[ i ] < minLight[ i ] ) {
color[ i ] = minLight[ i ];
- if( vertexColor[ i ] < minLight[ i ] ) /* note NOT minVertexLight */
+ }
+ if ( vertexColor[ i ] < minLight[ i ] ) { /* note NOT minVertexLight */
vertexColor[ i ] = minLight[ i ];
+ }
}
}
-
+
/* set to bytes */
ColorToBytes( color, cb, 1.0f );
ColorToBytes( vertexColor, vcb, 1.0f );
-
+
/* compare */
- for( i = 0; i < 3; i++ )
+ for ( i = 0; i < 3; i++ )
{
d = cb[ i ] - vcb[ i ];
- if( d < 0 )
+ if ( d < 0 ) {
d *= -1;
- if( d > approximateTolerance )
+ }
+ if ( d > approximateTolerance ) {
return qfalse;
+ }
}
}
-
+
/* close enough for the girls i date */
return qtrue;
}
/*
-ApproximateTriangle()
-determines if a single triangle can be approximated with vertex rgba
-*/
-
-static qboolean ApproximateTriangle_r( rawLightmap_t *lm, bspDrawVert_t *dv[ 3 ] )
-{
- bspDrawVert_t mid, *dv2[ 3 ];
- int max;
-
-
+ ApproximateTriangle()
+ determines if a single triangle can be approximated with vertex rgba
+ */
+
+static qboolean ApproximateTriangle_r( rawLightmap_t *lm, bspDrawVert_t *dv[ 3 ] ){
+ bspDrawVert_t mid, *dv2[ 3 ];
+ int max;
+
+
/* approximate the vertexes */
- if( ApproximateLuxel( lm, dv[ 0 ] ) == qfalse )
+ if ( ApproximateLuxel( lm, dv[ 0 ] ) == qfalse ) {
return qfalse;
- if( ApproximateLuxel( lm, dv[ 1 ] ) == qfalse )
+ }
+ if ( ApproximateLuxel( lm, dv[ 1 ] ) == qfalse ) {
return qfalse;
- if( ApproximateLuxel( lm, dv[ 2 ] ) == qfalse )
+ }
+ if ( ApproximateLuxel( lm, dv[ 2 ] ) == qfalse ) {
return qfalse;
-
+ }
+
/* subdivide calc */
{
- int i;
- float dx, dy, dist, maxDist;
-
-
+ int i;
+ float dx, dy, dist, maxDist;
+
+
/* find the longest edge and split it */
max = -1;
maxDist = 0;
- for( i = 0; i < 3; i++ )
+ for ( i = 0; i < 3; i++ )
{
- dx = dv[ i ]->lightmap[ 0 ][ 0 ] - dv[ (i + 1) % 3 ]->lightmap[ 0 ][ 0 ];
- dy = dv[ i ]->lightmap[ 0 ][ 1 ] - dv[ (i + 1) % 3 ]->lightmap[ 0 ][ 1 ];
- dist = sqrt( (dx * dx) + (dy * dy) );
- if( dist > maxDist )
- {
+ dx = dv[ i ]->lightmap[ 0 ][ 0 ] - dv[ ( i + 1 ) % 3 ]->lightmap[ 0 ][ 0 ];
+ dy = dv[ i ]->lightmap[ 0 ][ 1 ] - dv[ ( i + 1 ) % 3 ]->lightmap[ 0 ][ 1 ];
+ dist = sqrt( ( dx * dx ) + ( dy * dy ) );
+ if ( dist > maxDist ) {
maxDist = dist;
max = i;
}
}
-
+
/* try to early out */
- if( i < 0 || maxDist < subdivideThreshold )
+ if ( i < 0 || maxDist < subdivideThreshold ) {
return qtrue;
+ }
}
/* split the longest edge and map it */
- LerpDrawVert( dv[ max ], dv[ (max + 1) % 3 ], &mid );
- if( ApproximateLuxel( lm, &mid ) == qfalse )
+ LerpDrawVert( dv[ max ], dv[ ( max + 1 ) % 3 ], &mid );
+ if ( ApproximateLuxel( lm, &mid ) == qfalse ) {
return qfalse;
-
+ }
+
/* recurse to first triangle */
VectorCopy( dv, dv2 );
dv2[ max ] = ∣
- if( ApproximateTriangle_r( lm, dv2 ) == qfalse )
+ if ( ApproximateTriangle_r( lm, dv2 ) == qfalse ) {
return qfalse;
-
+ }
+
/* recurse to second triangle */
VectorCopy( dv, dv2 );
- dv2[ (max + 1) % 3 ] = ∣
+ dv2[ ( max + 1 ) % 3 ] = ∣
return ApproximateTriangle_r( lm, dv2 );
}
/*
-ApproximateLightmap()
-determines if a raw lightmap can be approximated sufficiently with vertex colors
-*/
-
-static qboolean ApproximateLightmap( rawLightmap_t *lm )
-{
- int n, num, i, x, y, pw[ 5 ], r;
- bspDrawSurface_t *ds;
- surfaceInfo_t *info;
- mesh_t src, *subdivided, *mesh;
- bspDrawVert_t *verts, *dv[ 3 ];
- qboolean approximated;
-
-
+ ApproximateLightmap()
+ determines if a raw lightmap can be approximated sufficiently with vertex colors
+ */
+
+static qboolean ApproximateLightmap( rawLightmap_t *lm ){
+ int n, num, i, x, y, pw[ 5 ], r;
+ bspDrawSurface_t *ds;
+ surfaceInfo_t *info;
+ mesh_t src, *subdivided, *mesh;
+ bspDrawVert_t *verts, *dv[ 3 ];
+ qboolean approximated;
+
+
/* approximating? */
- if( approximateTolerance <= 0 )
+ if ( approximateTolerance <= 0 ) {
return qfalse;
-
+ }
+
/* test for jmonroe */
#if 0
- /* don't approx lightmaps with styled twins */
- if( lm->numStyledTwins > 0 )
+ /* don't approx lightmaps with styled twins */
+ if ( lm->numStyledTwins > 0 ) {
+ return qfalse;
+ }
+
+ /* don't approx lightmaps with styles */
+ for ( i = 1; i < MAX_LIGHTMAPS; i++ )
+ {
+ if ( lm->styles[ i ] != LS_NONE ) {
return qfalse;
-
- /* don't approx lightmaps with styles */
- for( i = 1; i < MAX_LIGHTMAPS; i++ )
- {
- if( lm->styles[ i ] != LS_NONE )
- return qfalse;
}
+ }
#endif
-
+
/* assume reduced until shadow detail is found */
approximated = qtrue;
-
+
/* walk the list of surfaces on this raw lightmap */
- for( n = 0; n < lm->numLightSurfaces; n++ )
+ for ( n = 0; n < lm->numLightSurfaces; n++ )
{
/* get surface */
num = lightSurfaces[ lm->firstLightSurface + n ];
ds = &bspDrawSurfaces[ num ];
info = &surfaceInfos[ num ];
-
+
/* assume not-reduced initially */
info->approximated = qfalse;
-
+
/* bail if lightmap doesn't match up */
- if( info->lm != lm )
+ if ( info->lm != lm ) {
continue;
-
+ }
+
/* bail if not vertex lit */
- if( info->si->noVertexLight )
+ if ( info->si->noVertexLight ) {
continue;
-
+ }
+
/* assume that surfaces whose bounding boxes is smaller than 2x samplesize will be forced to vertex */
- if( (info->maxs[ 0 ] - info->mins[ 0 ]) <= (2.0f * info->sampleSize) &&
- (info->maxs[ 1 ] - info->mins[ 1 ]) <= (2.0f * info->sampleSize) &&
- (info->maxs[ 2 ] - info->mins[ 2 ]) <= (2.0f * info->sampleSize) )
- {
+ if ( ( info->maxs[ 0 ] - info->mins[ 0 ] ) <= ( 2.0f * info->sampleSize ) &&
+ ( info->maxs[ 1 ] - info->mins[ 1 ] ) <= ( 2.0f * info->sampleSize ) &&
+ ( info->maxs[ 2 ] - info->mins[ 2 ] ) <= ( 2.0f * info->sampleSize ) ) {
info->approximated = qtrue;
numSurfsVertexForced++;
continue;
}
-
+
/* handle the triangles */
- switch( ds->surfaceType )
+ switch ( ds->surfaceType )
{
- case MST_PLANAR:
- /* get verts */
- verts = yDrawVerts + ds->firstVert;
-
- /* map the triangles */
- info->approximated = qtrue;
- for( i = 0; i < ds->numIndexes && info->approximated; i += 3 )
+ case MST_PLANAR:
+ /* get verts */
+ verts = yDrawVerts + ds->firstVert;
+
+ /* map the triangles */
+ info->approximated = qtrue;
+ for ( i = 0; i < ds->numIndexes && info->approximated; i += 3 )
+ {
+ dv[ 0 ] = &verts[ bspDrawIndexes[ ds->firstIndex + i ] ];
+ dv[ 1 ] = &verts[ bspDrawIndexes[ ds->firstIndex + i + 1 ] ];
+ dv[ 2 ] = &verts[ bspDrawIndexes[ ds->firstIndex + i + 2 ] ];
+ info->approximated = ApproximateTriangle_r( lm, dv );
+ }
+ break;
+
+ case MST_PATCH:
+ /* make a mesh from the drawsurf */
+ src.width = ds->patchWidth;
+ src.height = ds->patchHeight;
+ src.verts = &yDrawVerts[ ds->firstVert ];
+ //% subdivided = SubdivideMesh( src, 8, 512 );
+ subdivided = SubdivideMesh2( src, info->patchIterations );
+
+ /* fit it to the curve and remove colinear verts on rows/columns */
+ PutMeshOnCurve( *subdivided );
+ mesh = RemoveLinearMeshColumnsRows( subdivided );
+ FreeMesh( subdivided );
+
+ /* get verts */
+ verts = mesh->verts;
+
+ /* map the mesh quads */
+ info->approximated = qtrue;
+ for ( y = 0; y < ( mesh->height - 1 ) && info->approximated; y++ )
+ {
+ for ( x = 0; x < ( mesh->width - 1 ) && info->approximated; x++ )
{
- dv[ 0 ] = &verts[ bspDrawIndexes[ ds->firstIndex + i ] ];
- dv[ 1 ] = &verts[ bspDrawIndexes[ ds->firstIndex + i + 1 ] ];
- dv[ 2 ] = &verts[ bspDrawIndexes[ ds->firstIndex + i + 2 ] ];
+ /* set indexes */
+ pw[ 0 ] = x + ( y * mesh->width );
+ pw[ 1 ] = x + ( ( y + 1 ) * mesh->width );
+ pw[ 2 ] = x + 1 + ( ( y + 1 ) * mesh->width );
+ pw[ 3 ] = x + 1 + ( y * mesh->width );
+ pw[ 4 ] = x + ( y * mesh->width ); /* same as pw[ 0 ] */
+
+ /* set radix */
+ r = ( x + y ) & 1;
+
+ /* get drawverts and map first triangle */
+ dv[ 0 ] = &verts[ pw[ r + 0 ] ];
+ dv[ 1 ] = &verts[ pw[ r + 1 ] ];
+ dv[ 2 ] = &verts[ pw[ r + 2 ] ];
info->approximated = ApproximateTriangle_r( lm, dv );
- }
- break;
-
- case MST_PATCH:
- /* make a mesh from the drawsurf */
- src.width = ds->patchWidth;
- src.height = ds->patchHeight;
- src.verts = &yDrawVerts[ ds->firstVert ];
- //% subdivided = SubdivideMesh( src, 8, 512 );
- subdivided = SubdivideMesh2( src, info->patchIterations );
-
- /* fit it to the curve and remove colinear verts on rows/columns */
- PutMeshOnCurve( *subdivided );
- mesh = RemoveLinearMeshColumnsRows( subdivided );
- FreeMesh( subdivided );
-
- /* get verts */
- verts = mesh->verts;
-
- /* map the mesh quads */
- info->approximated = qtrue;
- for( y = 0; y < (mesh->height - 1) && info->approximated; y++ )
- {
- for( x = 0; x < (mesh->width - 1) && info->approximated; x++ )
- {
- /* set indexes */
- pw[ 0 ] = x + (y * mesh->width);
- pw[ 1 ] = x + ((y + 1) * mesh->width);
- pw[ 2 ] = x + 1 + ((y + 1) * mesh->width);
- pw[ 3 ] = x + 1 + (y * mesh->width);
- pw[ 4 ] = x + (y * mesh->width); /* same as pw[ 0 ] */
-
- /* set radix */
- r = (x + y) & 1;
-
- /* get drawverts and map first triangle */
- dv[ 0 ] = &verts[ pw[ r + 0 ] ];
- dv[ 1 ] = &verts[ pw[ r + 1 ] ];
- dv[ 2 ] = &verts[ pw[ r + 2 ] ];
+
+ /* get drawverts and map second triangle */
+ dv[ 0 ] = &verts[ pw[ r + 0 ] ];
+ dv[ 1 ] = &verts[ pw[ r + 2 ] ];
+ dv[ 2 ] = &verts[ pw[ r + 3 ] ];
+ if ( info->approximated ) {
info->approximated = ApproximateTriangle_r( lm, dv );
-
- /* get drawverts and map second triangle */
- dv[ 0 ] = &verts[ pw[ r + 0 ] ];
- dv[ 1 ] = &verts[ pw[ r + 2 ] ];
- dv[ 2 ] = &verts[ pw[ r + 3 ] ];
- if( info->approximated )
- info->approximated = ApproximateTriangle_r( lm, dv );
}
}
-
- /* free the mesh */
- FreeMesh( mesh );
- break;
-
- default:
- break;
- }
-
+ }
+
+ /* free the mesh */
+ FreeMesh( mesh );
+ break;
+
+ default:
+ break;
+ }
+
/* reduced? */
- if( info->approximated == qfalse )
+ if ( info->approximated == qfalse ) {
approximated = qfalse;
- else
+ }
+ else{
numSurfsVertexApproximated++;
+ }
}
-
+
/* return */
return approximated;
}
/*
-TestOutLightmapStamp()
-tests a stamp on a given lightmap for validity
-*/
+ TestOutLightmapStamp()
+ tests a stamp on a given lightmap for validity
+ */
+
+static qboolean TestOutLightmapStamp( rawLightmap_t *lm, int lightmapNum, outLightmap_t *olm, int x, int y ){
+ int sx, sy, ox, oy, offset;
+ float *luxel;
-static qboolean TestOutLightmapStamp( rawLightmap_t *lm, int lightmapNum, outLightmap_t *olm, int x, int y )
-{
- int sx, sy, ox, oy, offset;
- float *luxel;
-
/* bounds check */
- if( x < 0 || y < 0 || (x + lm->w) > olm->customWidth || (y + lm->h) > olm->customHeight )
+ if ( x < 0 || y < 0 || ( x + lm->w ) > olm->customWidth || ( y + lm->h ) > olm->customHeight ) {
return qfalse;
-
+ }
+
/* solid lightmaps test a 1x1 stamp */
- if( lm->solid[ lightmapNum ] )
- {
- offset = (y * olm->customWidth) + x;
- if( olm->lightBits[ offset >> 3 ] & (1 << (offset & 7)) )
+ if ( lm->solid[ lightmapNum ] ) {
+ offset = ( y * olm->customWidth ) + x;
+ if ( olm->lightBits[ offset >> 3 ] & ( 1 << ( offset & 7 ) ) ) {
return qfalse;
+ }
return qtrue;
}
-
+
/* test the stamp */
- for( sy = 0; sy < lm->h; sy++ )
+ for ( sy = 0; sy < lm->h; sy++ )
{
- for( sx = 0; sx < lm->w; sx++ )
+ for ( sx = 0; sx < lm->w; sx++ )
{
/* get luxel */
luxel = BSP_LUXEL( lightmapNum, sx, sy );
- if( luxel[ 0 ] < 0.0f )
+ if ( luxel[ 0 ] < 0.0f ) {
continue;
-
+ }
+
/* get bsp lightmap coords and test */
ox = x + sx;
oy = y + sy;
- offset = (oy * olm->customWidth) + ox;
- if( olm->lightBits[ offset >> 3 ] & (1 << (offset & 7)) )
+ offset = ( oy * olm->customWidth ) + ox;
+ if ( olm->lightBits[ offset >> 3 ] & ( 1 << ( offset & 7 ) ) ) {
return qfalse;
+ }
}
}
-
+
/* stamp is empty */
return qtrue;
}
/*
-SetupOutLightmap()
-sets up an output lightmap
-*/
+ SetupOutLightmap()
+ sets up an output lightmap
+ */
-static void SetupOutLightmap( rawLightmap_t *lm, outLightmap_t *olm )
-{
+static void SetupOutLightmap( rawLightmap_t *lm, outLightmap_t *olm ){
/* dummy check */
- if( lm == NULL || olm == NULL )
+ if ( lm == NULL || olm == NULL ) {
return;
-
+ }
+
/* is this a "normal" bsp-stored lightmap? */
- if( (lm->customWidth == game->lightmapSize && lm->customHeight == game->lightmapSize) || externalLightmaps )
- {
+ if ( ( lm->customWidth == game->lightmapSize && lm->customHeight == game->lightmapSize ) || externalLightmaps ) {
olm->lightmapNum = numBSPLightmaps;
numBSPLightmaps++;
-
+
/* lightmaps are interleaved with light direction maps */
- if( deluxemap )
+ if ( deluxemap ) {
numBSPLightmaps++;
+ }
}
- else
+ else{
olm->lightmapNum = -3;
-
+ }
+
/* set external lightmap number */
olm->extLightmapNum = -1;
-
+
/* set it up */
olm->numLightmaps = 0;
olm->customWidth = lm->customWidth;
olm->customHeight = lm->customHeight;
olm->freeLuxels = olm->customWidth * olm->customHeight;
olm->numShaders = 0;
-
+
/* allocate buffers */
- olm->lightBits = safe_malloc( (olm->customWidth * olm->customHeight / 8) + 8 );
- memset( olm->lightBits, 0, (olm->customWidth * olm->customHeight / 8) + 8 );
+ olm->lightBits = safe_malloc( ( olm->customWidth * olm->customHeight / 8 ) + 8 );
+ memset( olm->lightBits, 0, ( olm->customWidth * olm->customHeight / 8 ) + 8 );
olm->bspLightBytes = safe_malloc( olm->customWidth * olm->customHeight * 3 );
memset( olm->bspLightBytes, 0, olm->customWidth * olm->customHeight * 3 );
- if( deluxemap )
- {
+ if ( deluxemap ) {
olm->bspDirBytes = safe_malloc( olm->customWidth * olm->customHeight * 3 );
memset( olm->bspDirBytes, 0, olm->customWidth * olm->customHeight * 3 );
}
/*
-FindOutLightmaps()
-for a given surface lightmap, find output lightmap pages and positions for it
-*/
+ FindOutLightmaps()
+ for a given surface lightmap, find output lightmap pages and positions for it
+ */
#define LIGHTMAP_RESERVE_COUNT 1
-static void FindOutLightmaps( rawLightmap_t *lm )
-{
- int i, j, k, lightmapNum, xMax, yMax, x = -1, y = -1, sx, sy, ox, oy, offset;
- outLightmap_t *olm;
- surfaceInfo_t *info;
- float *luxel, *deluxel;
- vec3_t color, direction;
- byte *pixel;
- qboolean ok;
-
-
+static void FindOutLightmaps( rawLightmap_t *lm ){
+ int i, j, k, lightmapNum, xMax, yMax, x = -1, y = -1, sx, sy, ox, oy, offset;
+ outLightmap_t *olm;
+ surfaceInfo_t *info;
+ float *luxel, *deluxel;
+ vec3_t color, direction;
+ byte *pixel;
+ qboolean ok;
+
+
/* set default lightmap number (-3 = LIGHTMAP_BY_VERTEX) */
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
lm->outLightmapNums[ lightmapNum ] = -3;
-
+
/* can this lightmap be approximated with vertex color? */
- if( ApproximateLightmap( lm ) )
+ if ( ApproximateLightmap( lm ) ) {
return;
-
+ }
+
/* walk list */
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
/* early out */
- if( lm->styles[ lightmapNum ] == LS_NONE )
+ if ( lm->styles[ lightmapNum ] == LS_NONE ) {
continue;
-
+ }
+
/* don't store twinned lightmaps */
- if( lm->twins[ lightmapNum ] != NULL )
+ if ( lm->twins[ lightmapNum ] != NULL ) {
continue;
-
+ }
+
/* if this is a styled lightmap, try some normalized locations first */
ok = qfalse;
- if( lightmapNum > 0 && outLightmaps != NULL )
- {
+ if ( lightmapNum > 0 && outLightmaps != NULL ) {
/* loop twice */
- for( j = 0; j < 2; j++ )
+ for ( j = 0; j < 2; j++ )
{
/* try identical position */
- for( i = 0; i < numOutLightmaps; i++ )
+ for ( i = 0; i < numOutLightmaps; i++ )
{
/* get the output lightmap */
olm = &outLightmaps[ i ];
-
+
/* simple early out test */
- if( olm->freeLuxels < lm->used )
+ if ( olm->freeLuxels < lm->used ) {
continue;
-
+ }
+
/* don't store non-custom raw lightmaps on custom bsp lightmaps */
- if( olm->customWidth != lm->customWidth ||
- olm->customHeight != lm->customHeight )
+ if ( olm->customWidth != lm->customWidth ||
+ olm->customHeight != lm->customHeight ) {
continue;
-
+ }
+
/* try identical */
- if( j == 0 )
- {
+ if ( j == 0 ) {
x = lm->lightmapX[ 0 ];
y = lm->lightmapY[ 0 ];
ok = TestOutLightmapStamp( lm, lightmapNum, olm, x, y );
}
-
+
/* try shifting */
else
{
- for( sy = -1; sy <= 1; sy++ )
+ for ( sy = -1; sy <= 1; sy++ )
{
- for( sx = -1; sx <= 1; sx++ )
+ for ( sx = -1; sx <= 1; sx++ )
{
- x = lm->lightmapX[ 0 ] + sx * (olm->customWidth >> 1); //% lm->w;
- y = lm->lightmapY[ 0 ] + sy * (olm->customHeight >> 1); //% lm->h;
+ x = lm->lightmapX[ 0 ] + sx * ( olm->customWidth >> 1 ); //% lm->w;
+ y = lm->lightmapY[ 0 ] + sy * ( olm->customHeight >> 1 ); //% lm->h;
ok = TestOutLightmapStamp( lm, lightmapNum, olm, x, y );
- if( ok )
+ if ( ok ) {
break;
+ }
}
-
- if( ok )
+
+ if ( ok ) {
break;
+ }
}
}
-
- if( ok )
+
+ if ( ok ) {
break;
+ }
}
-
- if( ok )
+
+ if ( ok ) {
break;
+ }
}
}
-
+
/* try normal placement algorithm */
- if( ok == qfalse )
- {
+ if ( ok == qfalse ) {
/* reset origin */
x = 0;
y = 0;
-
+
/* walk the list of lightmap pages */
- if(lightmapSearchBlockSize <= 0 || numOutLightmaps < LIGHTMAP_RESERVE_COUNT)
+ if ( lightmapSearchBlockSize <= 0 || numOutLightmaps < LIGHTMAP_RESERVE_COUNT ) {
i = 0;
- else
- i = ((numOutLightmaps - LIGHTMAP_RESERVE_COUNT) / lightmapSearchBlockSize) * lightmapSearchBlockSize;
- for( ; i < numOutLightmaps; i++ )
+ }
+ else{
+ i = ( ( numOutLightmaps - LIGHTMAP_RESERVE_COUNT ) / lightmapSearchBlockSize ) * lightmapSearchBlockSize;
+ }
+ for ( ; i < numOutLightmaps; i++ )
{
/* get the output lightmap */
olm = &outLightmaps[ i ];
-
+
/* simple early out test */
- if( olm->freeLuxels < lm->used )
+ if ( olm->freeLuxels < lm->used ) {
continue;
-
+ }
+
/* don't store non-custom raw lightmaps on custom bsp lightmaps */
- if( olm->customWidth != lm->customWidth ||
- olm->customHeight != lm->customHeight )
+ if ( olm->customWidth != lm->customWidth ||
+ olm->customHeight != lm->customHeight ) {
continue;
-
+ }
+
/* set maxs */
- if( lm->solid[ lightmapNum ] )
- {
+ if ( lm->solid[ lightmapNum ] ) {
xMax = olm->customWidth;
yMax = olm->customHeight;
}
else
{
- xMax = (olm->customWidth - lm->w) + 1;
- yMax = (olm->customHeight - lm->h) + 1;
+ xMax = ( olm->customWidth - lm->w ) + 1;
+ yMax = ( olm->customHeight - lm->h ) + 1;
}
-
+
/* walk the origin around the lightmap */
- for( y = 0; y < yMax; y++ )
+ for ( y = 0; y < yMax; y++ )
{
- for( x = 0; x < xMax; x++ )
+ for ( x = 0; x < xMax; x++ )
{
/* find a fine tract of lauhnd */
ok = TestOutLightmapStamp( lm, lightmapNum, olm, x, y );
-
- if( ok )
+
+ if ( ok ) {
break;
+ }
}
-
- if( ok )
+
+ if ( ok ) {
break;
+ }
}
-
- if( ok )
+
+ if ( ok ) {
break;
-
+ }
+
/* reset x and y */
x = 0;
y = 0;
}
}
-
+
/* no match? */
- if( ok == qfalse )
- {
+ if ( ok == qfalse ) {
/* allocate LIGHTMAP_RESERVE_COUNT new output lightmaps */
numOutLightmaps += LIGHTMAP_RESERVE_COUNT;
olm = safe_malloc( numOutLightmaps * sizeof( outLightmap_t ) );
- if( outLightmaps != NULL && numOutLightmaps > LIGHTMAP_RESERVE_COUNT )
- {
- memcpy( olm, outLightmaps, (numOutLightmaps - LIGHTMAP_RESERVE_COUNT) * sizeof( outLightmap_t ) );
+ if ( outLightmaps != NULL && numOutLightmaps > LIGHTMAP_RESERVE_COUNT ) {
+ memcpy( olm, outLightmaps, ( numOutLightmaps - LIGHTMAP_RESERVE_COUNT ) * sizeof( outLightmap_t ) );
free( outLightmaps );
}
outLightmaps = olm;
-
+
/* initialize both out lightmaps */
- for(k = numOutLightmaps - LIGHTMAP_RESERVE_COUNT; k < numOutLightmaps; ++k)
+ for ( k = numOutLightmaps - LIGHTMAP_RESERVE_COUNT; k < numOutLightmaps; ++k )
SetupOutLightmap( lm, &outLightmaps[ k ] );
-
+
/* set out lightmap */
i = numOutLightmaps - LIGHTMAP_RESERVE_COUNT;
olm = &outLightmaps[ i ];
-
+
/* set stamp xy origin to the first surface lightmap */
- if( lightmapNum > 0 )
- {
+ if ( lightmapNum > 0 ) {
x = lm->lightmapX[ 0 ];
y = lm->lightmapY[ 0 ];
}
}
-
+
/* if this is a style-using lightmap, it must be exported */
- if( lightmapNum > 0 && game->load != LoadRBSPFile )
+ if ( lightmapNum > 0 && game->load != LoadRBSPFile ) {
olm->extLightmapNum = 0;
-
+ }
+
/* add the surface lightmap to the bsp lightmap */
lm->outLightmapNums[ lightmapNum ] = i;
lm->lightmapX[ lightmapNum ] = x;
lm->lightmapY[ lightmapNum ] = y;
olm->numLightmaps++;
-
+
/* add shaders */
- for( i = 0; i < lm->numLightSurfaces; i++ )
+ for ( i = 0; i < lm->numLightSurfaces; i++ )
{
/* get surface info */
info = &surfaceInfos[ lightSurfaces[ lm->firstLightSurface + i ] ];
-
+
/* test for shader */
- for( j = 0; j < olm->numShaders; j++ )
+ for ( j = 0; j < olm->numShaders; j++ )
{
- if( olm->shaders[ j ] == info->si )
+ if ( olm->shaders[ j ] == info->si ) {
break;
+ }
}
-
+
/* if it doesn't exist, add it */
- if( j >= olm->numShaders && olm->numShaders < MAX_LIGHTMAP_SHADERS )
- {
+ if ( j >= olm->numShaders && olm->numShaders < MAX_LIGHTMAP_SHADERS ) {
olm->shaders[ olm->numShaders ] = info->si;
olm->numShaders++;
numLightmapShaders++;
}
}
-
+
/* set maxs */
- if( lm->solid[ lightmapNum ] )
- {
+ if ( lm->solid[ lightmapNum ] ) {
xMax = 1;
yMax = 1;
}
xMax = lm->w;
yMax = lm->h;
}
-
+
/* mark the bits used */
- for( y = 0; y < yMax; y++ )
+ for ( y = 0; y < yMax; y++ )
{
- for( x = 0; x < xMax; x++ )
+ for ( x = 0; x < xMax; x++ )
{
/* get luxel */
luxel = BSP_LUXEL( lightmapNum, x, y );
deluxel = BSP_DELUXEL( x, y );
- if( luxel[ 0 ] < 0.0f && !lm->solid[ lightmapNum ])
+ if ( luxel[ 0 ] < 0.0f && !lm->solid[ lightmapNum ] ) {
continue;
-
+ }
+
/* set minimum light */
- if( lm->solid[ lightmapNum ] )
- {
- if( debug )
+ if ( lm->solid[ lightmapNum ] ) {
+ if ( debug ) {
VectorSet( color, 255.0f, 0.0f, 0.0f );
- else
+ }
+ else{
VectorCopy( lm->solidColor[ lightmapNum ], color );
+ }
}
- else
+ else{
VectorCopy( luxel, color );
-
+ }
+
/* styles are not affected by minlight */
- if( lightmapNum == 0 )
- {
- for( i = 0; i < 3; i++ )
+ if ( lightmapNum == 0 ) {
+ for ( i = 0; i < 3; i++ )
{
- if( color[ i ] < minLight[ i ] )
+ if ( color[ i ] < minLight[ i ] ) {
color[ i ] = minLight[ i ];
+ }
}
}
-
+
/* get bsp lightmap coords */
ox = x + lm->lightmapX[ lightmapNum ];
oy = y + lm->lightmapY[ lightmapNum ];
- offset = (oy * olm->customWidth) + ox;
-
+ offset = ( oy * olm->customWidth ) + ox;
+
/* flag pixel as used */
- olm->lightBits[ offset >> 3 ] |= (1 << (offset & 7));
+ olm->lightBits[ offset >> 3 ] |= ( 1 << ( offset & 7 ) );
olm->freeLuxels--;
-
+
/* store color */
- pixel = olm->bspLightBytes + (((oy * olm->customWidth) + ox) * 3);
+ pixel = olm->bspLightBytes + ( ( ( oy * olm->customWidth ) + ox ) * 3 );
ColorToBytes( color, pixel, lm->brightness );
-
+
/* store direction */
- if( deluxemap )
- {
+ if ( deluxemap ) {
/* normalize average light direction */
- pixel = olm->bspDirBytes + (((oy * olm->customWidth) + ox) * 3);
+ pixel = olm->bspDirBytes + ( ( ( oy * olm->customWidth ) + ox ) * 3 );
VectorScale( deluxel, 1000.0f, direction );
VectorNormalize( direction, direction );
VectorScale( direction, 127.5f, direction );
- for( i = 0; i < 3; i++ )
+ for ( i = 0; i < 3; i++ )
pixel[ i ] = (byte)( 127.5f + direction[ i ] );
}
}
/*
-CompareRawLightmap()
-compare function for qsort()
-*/
-
-static int CompareRawLightmap( const void *a, const void *b )
-{
- rawLightmap_t *alm, *blm;
- surfaceInfo_t *aInfo, *bInfo;
- int i, min, diff;
-
-
+ CompareRawLightmap()
+ compare function for qsort()
+ */
+
+static int CompareRawLightmap( const void *a, const void *b ){
+ rawLightmap_t *alm, *blm;
+ surfaceInfo_t *aInfo, *bInfo;
+ int i, min, diff;
+
+
/* get lightmaps */
- alm = &rawLightmaps[ *((const int*) a) ];
- blm = &rawLightmaps[ *((const int*) b) ];
-
+ alm = &rawLightmaps[ *( (const int*) a ) ];
+ blm = &rawLightmaps[ *( (const int*) b ) ];
+
/* get min number of surfaces */
- min = (alm->numLightSurfaces < blm->numLightSurfaces ? alm->numLightSurfaces : blm->numLightSurfaces);
-
+ min = ( alm->numLightSurfaces < blm->numLightSurfaces ? alm->numLightSurfaces : blm->numLightSurfaces );
+
/* iterate */
- for( i = 0; i < min; i++ )
+ for ( i = 0; i < min; i++ )
{
/* get surface info */
aInfo = &surfaceInfos[ lightSurfaces[ alm->firstLightSurface + i ] ];
bInfo = &surfaceInfos[ lightSurfaces[ blm->firstLightSurface + i ] ];
-
+
/* compare shader names */
diff = strcmp( aInfo->si->shader, bInfo->si->shader );
- if( diff != 0 )
+ if ( diff != 0 ) {
return diff;
+ }
}
/* test style count */
diff = 0;
- for( i = 0; i < MAX_LIGHTMAPS; i++ )
+ for ( i = 0; i < MAX_LIGHTMAPS; i++ )
diff += blm->styles[ i ] - alm->styles[ i ];
- if( diff )
+ if ( diff ) {
return diff;
-
+ }
+
/* compare size */
- diff = (blm->w * blm->h) - (alm->w * alm->h);
- if( diff != 0 )
+ diff = ( blm->w * blm->h ) - ( alm->w * alm->h );
+ if ( diff != 0 ) {
return diff;
-
+ }
+
/* must be equivalent */
return 0;
}
-void FillOutLightmap(outLightmap_t *olm)
-{
+void FillOutLightmap( outLightmap_t *olm ){
int x, y;
int ofs;
vec3_t dir_sum, light_sum;
byte *lightBytesNew = NULL;
byte *dirBytesNew = NULL;
- lightBitsNew = safe_malloc((olm->customWidth * olm->customHeight + 8) / 8);
- lightBytesNew = safe_malloc(olm->customWidth * olm->customHeight * 3);
- if(deluxemap)
- dirBytesNew = safe_malloc(olm->customWidth * olm->customHeight * 3);
+ lightBitsNew = safe_malloc( ( olm->customWidth * olm->customHeight + 8 ) / 8 );
+ lightBytesNew = safe_malloc( olm->customWidth * olm->customHeight * 3 );
+ if ( deluxemap ) {
+ dirBytesNew = safe_malloc( olm->customWidth * olm->customHeight * 3 );
+ }
/*
- memset(olm->lightBits, 0, (olm->customWidth * olm->customHeight + 8) / 8);
- olm->lightBits[0] |= 1;
- olm->lightBits[(10 * olm->customWidth + 30) >> 3] |= 1 << ((10 * olm->customWidth + 30) & 7);
- memset(olm->bspLightBytes, 0, olm->customWidth * olm->customHeight * 3);
- olm->bspLightBytes[0] = 255;
- olm->bspLightBytes[(10 * olm->customWidth + 30) * 3 + 2] = 255;
- */
-
- memcpy(lightBitsNew, olm->lightBits, (olm->customWidth * olm->customHeight + 8) / 8);
- memcpy(lightBytesNew, olm->bspLightBytes, olm->customWidth * olm->customHeight * 3);
- if(deluxemap)
- memcpy(dirBytesNew, olm->bspDirBytes, olm->customWidth * olm->customHeight * 3);
-
- for(;;)
+ memset(olm->lightBits, 0, (olm->customWidth * olm->customHeight + 8) / 8);
+ olm->lightBits[0] |= 1;
+ olm->lightBits[(10 * olm->customWidth + 30) >> 3] |= 1 << ((10 * olm->customWidth + 30) & 7);
+ memset(olm->bspLightBytes, 0, olm->customWidth * olm->customHeight * 3);
+ olm->bspLightBytes[0] = 255;
+ olm->bspLightBytes[(10 * olm->customWidth + 30) * 3 + 2] = 255;
+ */
+
+ memcpy( lightBitsNew, olm->lightBits, ( olm->customWidth * olm->customHeight + 8 ) / 8 );
+ memcpy( lightBytesNew, olm->bspLightBytes, olm->customWidth * olm->customHeight * 3 );
+ if ( deluxemap ) {
+ memcpy( dirBytesNew, olm->bspDirBytes, olm->customWidth * olm->customHeight * 3 );
+ }
+
+ for (;; )
{
filled = 0;
- for(y = 0; y < olm->customHeight; ++y)
+ for ( y = 0; y < olm->customHeight; ++y )
{
- for(x = 0; x < olm->customWidth; ++x)
+ for ( x = 0; x < olm->customWidth; ++x )
{
ofs = y * olm->customWidth + x;
- if(olm->lightBits[ofs >> 3] & (1 << (ofs & 7))) /* already filled */
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
continue;
+ }
cnt = 0;
- VectorClear(dir_sum);
- VectorClear(light_sum);
+ VectorClear( dir_sum );
+ VectorClear( light_sum );
/* try all four neighbors */
- ofs = ((y + olm->customHeight - 1) % olm->customHeight) * olm->customWidth + x;
- if(olm->lightBits[ofs >> 3] & (1 << (ofs & 7))) /* already filled */
- {
+ ofs = ( ( y + olm->customHeight - 1 ) % olm->customHeight ) * olm->customWidth + x;
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
++cnt;
- VectorAdd(light_sum, olm->bspLightBytes + ofs * 3, light_sum);
- if(deluxemap)
- VectorAdd(dir_sum, olm->bspDirBytes + ofs * 3, dir_sum);
+ VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum );
+ if ( deluxemap ) {
+ VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum );
+ }
}
- ofs = ((y + 1) % olm->customHeight) * olm->customWidth + x;
- if(olm->lightBits[ofs >> 3] & (1 << (ofs & 7))) /* already filled */
- {
+ ofs = ( ( y + 1 ) % olm->customHeight ) * olm->customWidth + x;
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
++cnt;
- VectorAdd(light_sum, olm->bspLightBytes + ofs * 3, light_sum);
- if(deluxemap)
- VectorAdd(dir_sum, olm->bspDirBytes + ofs * 3, dir_sum);
+ VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum );
+ if ( deluxemap ) {
+ VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum );
+ }
}
- ofs = y * olm->customWidth + (x + olm->customWidth - 1) % olm->customWidth;
- if(olm->lightBits[ofs >> 3] & (1 << (ofs & 7))) /* already filled */
- {
+ ofs = y * olm->customWidth + ( x + olm->customWidth - 1 ) % olm->customWidth;
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
++cnt;
- VectorAdd(light_sum, olm->bspLightBytes + ofs * 3, light_sum);
- if(deluxemap)
- VectorAdd(dir_sum, olm->bspDirBytes + ofs * 3, dir_sum);
+ VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum );
+ if ( deluxemap ) {
+ VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum );
+ }
}
- ofs = y * olm->customWidth + (x + 1) % olm->customWidth;
- if(olm->lightBits[ofs >> 3] & (1 << (ofs & 7))) /* already filled */
- {
+ ofs = y * olm->customWidth + ( x + 1 ) % olm->customWidth;
+ if ( olm->lightBits[ofs >> 3] & ( 1 << ( ofs & 7 ) ) ) { /* already filled */
++cnt;
- VectorAdd(light_sum, olm->bspLightBytes + ofs * 3, light_sum);
- if(deluxemap)
- VectorAdd(dir_sum, olm->bspDirBytes + ofs * 3, dir_sum);
+ VectorAdd( light_sum, olm->bspLightBytes + ofs * 3, light_sum );
+ if ( deluxemap ) {
+ VectorAdd( dir_sum, olm->bspDirBytes + ofs * 3, dir_sum );
+ }
}
- if(cnt)
- {
+ if ( cnt ) {
++filled;
ofs = y * olm->customWidth + x;
- lightBitsNew[ofs >> 3] |= (1 << (ofs & 7));
- VectorScale(light_sum, 1.0/cnt, lightBytesNew + ofs * 3);
- if(deluxemap)
- VectorScale(dir_sum, 1.0/cnt, dirBytesNew + ofs * 3);
+ lightBitsNew[ofs >> 3] |= ( 1 << ( ofs & 7 ) );
+ VectorScale( light_sum, 1.0 / cnt, lightBytesNew + ofs * 3 );
+ if ( deluxemap ) {
+ VectorScale( dir_sum, 1.0 / cnt, dirBytesNew + ofs * 3 );
+ }
}
}
}
- if(!filled)
+ if ( !filled ) {
break;
+ }
- memcpy(olm->lightBits, lightBitsNew, (olm->customWidth * olm->customHeight + 8) / 8);
- memcpy(olm->bspLightBytes, lightBytesNew, olm->customWidth * olm->customHeight * 3);
- if(deluxemap)
- memcpy(olm->bspDirBytes, dirBytesNew, olm->customWidth * olm->customHeight * 3);
+ memcpy( olm->lightBits, lightBitsNew, ( olm->customWidth * olm->customHeight + 8 ) / 8 );
+ memcpy( olm->bspLightBytes, lightBytesNew, olm->customWidth * olm->customHeight * 3 );
+ if ( deluxemap ) {
+ memcpy( olm->bspDirBytes, dirBytesNew, olm->customWidth * olm->customHeight * 3 );
+ }
}
- free(lightBitsNew);
- free(lightBytesNew);
- if(deluxemap)
- free(dirBytesNew);
+ free( lightBitsNew );
+ free( lightBytesNew );
+ if ( deluxemap ) {
+ free( dirBytesNew );
+ }
}
/*
-StoreSurfaceLightmaps()
-stores the surface lightmaps into the bsp as byte rgb triplets
-*/
-
-void StoreSurfaceLightmaps( void )
-{
- int i, j, k, x, y, lx, ly, sx, sy, *cluster, mappedSamples;
- int style, size, lightmapNum, lightmapNum2;
- float *normal, *luxel, *bspLuxel, *bspLuxel2, *radLuxel, samples, occludedSamples;
- vec3_t sample, occludedSample, dirSample, colorMins, colorMaxs;
- float *deluxel, *bspDeluxel, *bspDeluxel2;
- byte *lb;
- int numUsed, numTwins, numTwinLuxels, numStored;
- float lmx, lmy, efficiency;
- vec3_t color;
- bspDrawSurface_t *ds, *parent, dsTemp;
- surfaceInfo_t *info;
- rawLightmap_t *lm, *lm2;
- outLightmap_t *olm;
- bspDrawVert_t *dv, *ydv, *dvParent;
- char dirname[ 1024 ], filename[ 1024 ];
- shaderInfo_t *csi;
- char lightmapName[ 128 ];
- const char *rgbGenValues[ 256 ];
- const char *alphaGenValues[ 256 ];
-
-
+ StoreSurfaceLightmaps()
+ stores the surface lightmaps into the bsp as byte rgb triplets
+ */
+
+void StoreSurfaceLightmaps( void ){
+ int i, j, k, x, y, lx, ly, sx, sy, *cluster, mappedSamples;
+ int style, size, lightmapNum, lightmapNum2;
+ float *normal, *luxel, *bspLuxel, *bspLuxel2, *radLuxel, samples, occludedSamples;
+ vec3_t sample, occludedSample, dirSample, colorMins, colorMaxs;
+ float *deluxel, *bspDeluxel, *bspDeluxel2;
+ byte *lb;
+ int numUsed, numTwins, numTwinLuxels, numStored;
+ float lmx, lmy, efficiency;
+ vec3_t color;
+ bspDrawSurface_t *ds, *parent, dsTemp;
+ surfaceInfo_t *info;
+ rawLightmap_t *lm, *lm2;
+ outLightmap_t *olm;
+ bspDrawVert_t *dv, *ydv, *dvParent;
+ char dirname[ 1024 ], filename[ 1024 ];
+ shaderInfo_t *csi;
+ char lightmapName[ 128 ];
+ const char *rgbGenValues[ 256 ];
+ const char *alphaGenValues[ 256 ];
+
+
/* note it */
- Sys_Printf( "--- StoreSurfaceLightmaps ---\n");
-
+ Sys_Printf( "--- StoreSurfaceLightmaps ---\n" );
+
/* setup */
- if(lmCustomDir)
- {
+ if ( lmCustomDir ) {
strcpy( dirname, lmCustomDir );
}
else
}
memset( rgbGenValues, 0, sizeof( rgbGenValues ) );
memset( alphaGenValues, 0, sizeof( alphaGenValues ) );
-
+
/* -----------------------------------------------------------------
average the sampled luxels into the bsp luxels
----------------------------------------------------------------- */
-
+
/* note it */
Sys_Printf( "Subsampling..." );
-
+
/* walk the list of raw lightmaps */
numUsed = 0;
numTwins = 0;
numTwinLuxels = 0;
numSolidLightmaps = 0;
- for( i = 0; i < numRawLightmaps; i++ )
+ for ( i = 0; i < numRawLightmaps; i++ )
{
/* get lightmap */
lm = &rawLightmaps[ i ];
-
+
/* walk individual lightmaps */
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
/* early outs */
- if( lm->superLuxels[ lightmapNum ] == NULL )
+ if ( lm->superLuxels[ lightmapNum ] == NULL ) {
continue;
-
+ }
+
/* allocate bsp luxel storage */
- if( lm->bspLuxels[ lightmapNum ] == NULL )
- {
+ if ( lm->bspLuxels[ lightmapNum ] == NULL ) {
size = lm->w * lm->h * BSP_LUXEL_SIZE * sizeof( float );
lm->bspLuxels[ lightmapNum ] = safe_malloc( size );
memset( lm->bspLuxels[ lightmapNum ], 0, size );
}
/* allocate radiosity lightmap storage */
- if( bounce )
- {
+ if ( bounce ) {
size = lm->w * lm->h * RAD_LUXEL_SIZE * sizeof( float );
- if( lm->radLuxels[ lightmapNum ] == NULL )
+ if ( lm->radLuxels[ lightmapNum ] == NULL ) {
lm->radLuxels[ lightmapNum ] = safe_malloc( size );
+ }
memset( lm->radLuxels[ lightmapNum ], 0, size );
}
-
+
/* average supersampled luxels */
- for( y = 0; y < lm->h; y++ )
+ for ( y = 0; y < lm->h; y++ )
{
- for( x = 0; x < lm->w; x++ )
+ for ( x = 0; x < lm->w; x++ )
{
/* subsample */
samples = 0.0f;
VectorClear( sample );
VectorClear( occludedSample );
VectorClear( dirSample );
- for( ly = 0; ly < superSample; ly++ )
+ for ( ly = 0; ly < superSample; ly++ )
{
- for( lx = 0; lx < superSample; lx++ )
+ for ( lx = 0; lx < superSample; lx++ )
{
/* sample luxel */
sx = x * superSample + lx;
deluxel = SUPER_DELUXEL( sx, sy );
normal = SUPER_NORMAL( sx, sy );
cluster = SUPER_CLUSTER( sx, sy );
-
+
/* sample deluxemap */
- if( deluxemap && lightmapNum == 0 )
+ if ( deluxemap && lightmapNum == 0 ) {
VectorAdd( dirSample, deluxel, dirSample );
-
+ }
+
/* keep track of used/occluded samples */
- if( *cluster != CLUSTER_UNMAPPED )
+ if ( *cluster != CLUSTER_UNMAPPED ) {
mappedSamples++;
-
+ }
+
/* handle lightmap border? */
- if( lightmapBorder && (sx == 0 || sx == (lm->sw - 1) || sy == 0 || sy == (lm->sh - 1) ) && luxel[ 3 ] > 0.0f )
- {
+ if ( lightmapBorder && ( sx == 0 || sx == ( lm->sw - 1 ) || sy == 0 || sy == ( lm->sh - 1 ) ) && luxel[ 3 ] > 0.0f ) {
VectorSet( sample, 255.0f, 0.0f, 0.0f );
samples += 1.0f;
}
-
+
/* handle debug */
- else if( debug && *cluster < 0 )
- {
- if( *cluster == CLUSTER_UNMAPPED )
+ else if ( debug && *cluster < 0 ) {
+ if ( *cluster == CLUSTER_UNMAPPED ) {
VectorSet( luxel, 255, 204, 0 );
- else if( *cluster == CLUSTER_OCCLUDED )
+ }
+ else if ( *cluster == CLUSTER_OCCLUDED ) {
VectorSet( luxel, 255, 0, 255 );
- else if( *cluster == CLUSTER_FLOODED )
+ }
+ else if ( *cluster == CLUSTER_FLOODED ) {
VectorSet( luxel, 0, 32, 255 );
+ }
VectorAdd( occludedSample, luxel, occludedSample );
occludedSamples += 1.0f;
}
-
+
/* normal luxel handling */
- else if( luxel[ 3 ] > 0.0f )
- {
+ else if ( luxel[ 3 ] > 0.0f ) {
/* handle lit or flooded luxels */
- if( *cluster > 0 || *cluster == CLUSTER_FLOODED )
- {
+ if ( *cluster > 0 || *cluster == CLUSTER_FLOODED ) {
VectorAdd( sample, luxel, sample );
samples += luxel[ 3 ];
}
-
+
/* handle occluded or unmapped luxels */
else
{
VectorAdd( occludedSample, luxel, occludedSample );
occludedSamples += luxel[ 3 ];
}
-
+
/* handle style debugging */
- if( debug && lightmapNum > 0 && x < 2 && y < 2 )
- {
+ if ( debug && lightmapNum > 0 && x < 2 && y < 2 ) {
VectorCopy( debugColors[ 0 ], sample );
samples = 1;
}
}
}
}
-
+
/* only use occluded samples if necessary */
- if( samples <= 0.0f )
- {
+ if ( samples <= 0.0f ) {
VectorCopy( occludedSample, sample );
samples = occludedSamples;
}
-
+
/* get luxels */
luxel = SUPER_LUXEL( lightmapNum, x, y );
deluxel = SUPER_DELUXEL( x, y );
-
+
/* store light direction */
- if( deluxemap && lightmapNum == 0 )
+ if ( deluxemap && lightmapNum == 0 ) {
VectorCopy( dirSample, deluxel );
-
+ }
+
/* store the sample back in super luxels */
- if( samples > 0.01f )
- {
- VectorScale( sample, (1.0f / samples), luxel );
+ if ( samples > 0.01f ) {
+ VectorScale( sample, ( 1.0f / samples ), luxel );
luxel[ 3 ] = 1.0f;
}
-
+
/* if any samples were mapped in any way, store ambient color */
- else if( mappedSamples > 0 )
- {
- if( lightmapNum == 0 )
+ else if ( mappedSamples > 0 ) {
+ if ( lightmapNum == 0 ) {
VectorCopy( ambientColor, luxel );
- else
+ }
+ else{
VectorClear( luxel );
+ }
luxel[ 3 ] = 1.0f;
}
-
- /* store a bogus value to be fixed later */
+
+ /* store a bogus value to be fixed later */
else
{
VectorClear( luxel );
}
}
}
-
+
/* setup */
lm->used = 0;
ClearBounds( colorMins, colorMaxs );
-
+
/* clean up and store into bsp luxels */
- for( y = 0; y < lm->h; y++ )
+ for ( y = 0; y < lm->h; y++ )
{
- for( x = 0; x < lm->w; x++ )
+ for ( x = 0; x < lm->w; x++ )
{
/* get luxels */
luxel = SUPER_LUXEL( lightmapNum, x, y );
deluxel = SUPER_DELUXEL( x, y );
-
+
/* copy light direction */
- if( deluxemap && lightmapNum == 0 )
+ if ( deluxemap && lightmapNum == 0 ) {
VectorCopy( deluxel, dirSample );
-
+ }
+
/* is this a valid sample? */
- if( luxel[ 3 ] > 0.0f )
- {
+ if ( luxel[ 3 ] > 0.0f ) {
VectorCopy( luxel, sample );
samples = luxel[ 3 ];
numUsed++;
lm->used++;
-
+
/* fix negative samples */
- for( j = 0; j < 3; j++ )
+ for ( j = 0; j < 3; j++ )
{
- if( sample[ j ] < 0.0f )
+ if ( sample[ j ] < 0.0f ) {
sample[ j ] = 0.0f;
+ }
}
}
else
VectorClear( sample );
VectorClear( dirSample );
samples = 0.0f;
-
+
/* fixme: why is this disabled?? */
- for( sy = (y - 1); sy <= (y + 1); sy++ )
+ for ( sy = ( y - 1 ); sy <= ( y + 1 ); sy++ )
{
- if( sy < 0 || sy >= lm->h )
+ if ( sy < 0 || sy >= lm->h ) {
continue;
-
- for( sx = (x - 1); sx <= (x + 1); sx++ )
+ }
+
+ for ( sx = ( x - 1 ); sx <= ( x + 1 ); sx++ )
{
- if( sx < 0 || sx >= lm->w || (sx == x && sy == y) )
+ if ( sx < 0 || sx >= lm->w || ( sx == x && sy == y ) ) {
continue;
-
+ }
+
/* get neighbor's particulars */
luxel = SUPER_LUXEL( lightmapNum, sx, sy );
- if( luxel[ 3 ] < 0.0f )
+ if ( luxel[ 3 ] < 0.0f ) {
continue;
+ }
VectorAdd( sample, luxel, sample );
samples += luxel[ 3 ];
}
}
-
+
/* no samples? */
- if( samples == 0.0f )
- {
+ if ( samples == 0.0f ) {
VectorSet( sample, -1.0f, -1.0f, -1.0f );
samples = 1.0f;
}
{
numUsed++;
lm->used++;
-
+
/* fix negative samples */
- for( j = 0; j < 3; j++ )
+ for ( j = 0; j < 3; j++ )
{
- if( sample[ j ] < 0.0f )
+ if ( sample[ j ] < 0.0f ) {
sample[ j ] = 0.0f;
+ }
}
}
}
-
+
/* scale the sample */
- VectorScale( sample, (1.0f / samples), sample );
-
+ VectorScale( sample, ( 1.0f / samples ), sample );
+
/* store the sample in the radiosity luxels */
- if( bounce > 0 )
- {
+ if ( bounce > 0 ) {
radLuxel = RAD_LUXEL( lightmapNum, x, y );
VectorCopy( sample, radLuxel );
-
+
/* if only storing bounced light, early out here */
- if( bounceOnly && !bouncing )
+ if ( bounceOnly && !bouncing ) {
continue;
+ }
}
-
+
/* store the sample in the bsp luxels */
bspLuxel = BSP_LUXEL( lightmapNum, x, y );
bspDeluxel = BSP_DELUXEL( x, y );
-
+
VectorAdd( bspLuxel, sample, bspLuxel );
- if( deluxemap && lightmapNum == 0 )
+ if ( deluxemap && lightmapNum == 0 ) {
VectorAdd( bspDeluxel, dirSample, bspDeluxel );
-
+ }
+
/* add color to bounds for solid checking */
- if( samples > 0.0f )
+ if ( samples > 0.0f ) {
AddPointToBounds( bspLuxel, colorMins, colorMaxs );
+ }
}
}
-
+
/* set solid color */
lm->solid[ lightmapNum ] = qfalse;
VectorAdd( colorMins, colorMaxs, lm->solidColor[ lightmapNum ] );
VectorScale( lm->solidColor[ lightmapNum ], 0.5f, lm->solidColor[ lightmapNum ] );
-
+
/* nocollapse prevents solid lightmaps */
- if( noCollapse == qfalse )
- {
+ if ( noCollapse == qfalse ) {
/* check solid color */
VectorSubtract( colorMaxs, colorMins, sample );
- if( (sample[ 0 ] <= SOLID_EPSILON && sample[ 1 ] <= SOLID_EPSILON && sample[ 2 ] <= SOLID_EPSILON) ||
- (lm->w <= 2 && lm->h <= 2) ) /* small lightmaps get forced to solid color */
- {
+ if ( ( sample[ 0 ] <= SOLID_EPSILON && sample[ 1 ] <= SOLID_EPSILON && sample[ 2 ] <= SOLID_EPSILON ) ||
+ ( lm->w <= 2 && lm->h <= 2 ) ) { /* small lightmaps get forced to solid color */
/* set to solid */
VectorCopy( colorMins, lm->solidColor[ lightmapNum ] );
lm->solid[ lightmapNum ] = qtrue;
numSolidLightmaps++;
}
-
+
/* if all lightmaps aren't solid, then none of them are solid */
- if( lm->solid[ lightmapNum ] != lm->solid[ 0 ] )
- {
- for( y = 0; y < MAX_LIGHTMAPS; y++ )
+ if ( lm->solid[ lightmapNum ] != lm->solid[ 0 ] ) {
+ for ( y = 0; y < MAX_LIGHTMAPS; y++ )
{
- if( lm->solid[ y ] )
+ if ( lm->solid[ y ] ) {
numSolidLightmaps--;
+ }
lm->solid[ y ] = qfalse;
}
}
}
-
+
/* wrap bsp luxels if necessary */
- if( lm->wrap[ 0 ] )
- {
- for( y = 0; y < lm->h; y++ )
+ if ( lm->wrap[ 0 ] ) {
+ for ( y = 0; y < lm->h; y++ )
{
bspLuxel = BSP_LUXEL( lightmapNum, 0, y );
bspLuxel2 = BSP_LUXEL( lightmapNum, lm->w - 1, y );
VectorAdd( bspLuxel, bspLuxel2, bspLuxel );
VectorScale( bspLuxel, 0.5f, bspLuxel );
VectorCopy( bspLuxel, bspLuxel2 );
- if( deluxemap && lightmapNum == 0 )
- {
+ if ( deluxemap && lightmapNum == 0 ) {
bspDeluxel = BSP_DELUXEL( 0, y );
bspDeluxel2 = BSP_DELUXEL( lm->w - 1, y );
VectorAdd( bspDeluxel, bspDeluxel2, bspDeluxel );
}
}
}
- if( lm->wrap[ 1 ] )
- {
- for( x = 0; x < lm->w; x++ )
+ if ( lm->wrap[ 1 ] ) {
+ for ( x = 0; x < lm->w; x++ )
{
bspLuxel = BSP_LUXEL( lightmapNum, x, 0 );
bspLuxel2 = BSP_LUXEL( lightmapNum, x, lm->h - 1 );
VectorAdd( bspLuxel, bspLuxel2, bspLuxel );
VectorScale( bspLuxel, 0.5f, bspLuxel );
VectorCopy( bspLuxel, bspLuxel2 );
- if( deluxemap && lightmapNum == 0 )
- {
+ if ( deluxemap && lightmapNum == 0 ) {
bspDeluxel = BSP_DELUXEL( x, 0 );
bspDeluxel2 = BSP_DELUXEL( x, lm->h - 1 );
VectorAdd( bspDeluxel, bspDeluxel2, bspDeluxel );
}
}
}
-
+
/* -----------------------------------------------------------------
convert modelspace deluxemaps to tangentspace
----------------------------------------------------------------- */
/* note it */
- if( !bouncing )
- {
- if( deluxemap && deluxemode == 1)
- {
- vec3_t worldUp, myNormal, myTangent, myBinormal;
+ if ( !bouncing ) {
+ if ( deluxemap && deluxemode == 1 ) {
+ vec3_t worldUp, myNormal, myTangent, myBinormal;
float dist;
Sys_Printf( "converting..." );
- for( i = 0; i < numRawLightmaps; i++ )
+ for ( i = 0; i < numRawLightmaps; i++ )
{
/* get lightmap */
lm = &rawLightmaps[ i ];
/* walk lightmap samples */
- for( y = 0; y < lm->sh; y++ )
+ for ( y = 0; y < lm->sh; y++ )
{
- for( x = 0; x < lm->sw; x++ )
+ for ( x = 0; x < lm->sw; x++ )
{
/* get normal and deluxel */
- normal = SUPER_NORMAL(x, y);
- cluster = SUPER_CLUSTER(x, y);
+ normal = SUPER_NORMAL( x, y );
+ cluster = SUPER_CLUSTER( x, y );
bspDeluxel = BSP_DELUXEL( x, y );
- deluxel = SUPER_DELUXEL( x, y );
+ deluxel = SUPER_DELUXEL( x, y );
/* get normal */
VectorSet( myNormal, normal[0], normal[1], normal[2] );
-
+
/* get tangent vectors */
- if( myNormal[ 0 ] == 0.0f && myNormal[ 1 ] == 0.0f )
- {
- if( myNormal[ 2 ] == 1.0f )
- {
+ if ( myNormal[ 0 ] == 0.0f && myNormal[ 1 ] == 0.0f ) {
+ if ( myNormal[ 2 ] == 1.0f ) {
VectorSet( myTangent, 1.0f, 0.0f, 0.0f );
VectorSet( myBinormal, 0.0f, 1.0f, 0.0f );
}
- else if( myNormal[ 2 ] == -1.0f )
- {
+ else if ( myNormal[ 2 ] == -1.0f ) {
VectorSet( myTangent, -1.0f, 0.0f, 0.0f );
VectorSet( myBinormal, 0.0f, 1.0f, 0.0f );
}
}
/* project onto plane */
- dist = -DotProduct(myTangent, myNormal);
- VectorMA(myTangent, dist, myNormal, myTangent);
- dist = -DotProduct(myBinormal, myNormal);
- VectorMA(myBinormal, dist, myNormal, myBinormal);
+ dist = -DotProduct( myTangent, myNormal );
+ VectorMA( myTangent, dist, myNormal, myTangent );
+ dist = -DotProduct( myBinormal, myNormal );
+ VectorMA( myBinormal, dist, myNormal, myBinormal );
/* renormalize */
VectorNormalize( myTangent, myTangent );
dirSample[0] = bspDeluxel[0];
dirSample[1] = bspDeluxel[1];
dirSample[2] = bspDeluxel[2];
- VectorNormalize(dirSample, dirSample);
+ VectorNormalize( dirSample, dirSample );
/* fix tangents to world matrix */
- if (myNormal[0] > 0 || myNormal[1] < 0 || myNormal[2] < 0)
- VectorNegate(myTangent, myTangent);
+ if ( myNormal[0] > 0 || myNormal[1] < 0 || myNormal[2] < 0 ) {
+ VectorNegate( myTangent, myTangent );
+ }
/* build tangentspace vectors */
- bspDeluxel[0] = DotProduct(dirSample, myTangent);
- bspDeluxel[1] = DotProduct(dirSample, myBinormal);
- bspDeluxel[2] = DotProduct(dirSample, myNormal);
+ bspDeluxel[0] = DotProduct( dirSample, myTangent );
+ bspDeluxel[1] = DotProduct( dirSample, myBinormal );
+ bspDeluxel[2] = DotProduct( dirSample, myNormal );
}
}
}
/* note it */
Sys_Printf( "blending..." );
- for( i = 0; i < numRawLightmaps; i++ )
+ for ( i = 0; i < numRawLightmaps; i++ )
{
- vec3_t myColor;
+ vec3_t myColor;
float myBrightness;
/* get lightmap */
lm = &rawLightmaps[ i ];
/* walk individual lightmaps */
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
/* early outs */
- if( lm->superLuxels[ lightmapNum ] == NULL )
+ if ( lm->superLuxels[ lightmapNum ] == NULL ) {
continue;
+ }
/* walk lightmap samples */
- for( y = 0; y < lm->sh; y++ )
+ for ( y = 0; y < lm->sh; y++ )
{
- for( x = 0; x < lm->sw; x++ )
+ for ( x = 0; x < lm->sw; x++ )
{
/* get luxel */
bspLuxel = BSP_LUXEL( lightmapNum, x, y );
/* get color */
- VectorNormalize(bspLuxel, myColor);
- myBrightness = VectorLength(bspLuxel);
- myBrightness *= (1 / 127.0f);
- myBrightness = myBrightness*myBrightness;
+ VectorNormalize( bspLuxel, myColor );
+ myBrightness = VectorLength( bspLuxel );
+ myBrightness *= ( 1 / 127.0f );
+ myBrightness = myBrightness * myBrightness;
myBrightness *= 127.0f;
- VectorScale(myColor, myBrightness, bspLuxel);
+ VectorScale( myColor, myBrightness, bspLuxel );
}
}
}
/* -----------------------------------------------------------------
collapse non-unique lightmaps
----------------------------------------------------------------- */
-
- if( noCollapse == qfalse && deluxemap == qfalse )
- {
+
+ if ( noCollapse == qfalse && deluxemap == qfalse ) {
/* note it */
Sys_Printf( "collapsing..." );
-
+
/* set all twin refs to null */
- for( i = 0; i < numRawLightmaps; i++ )
+ for ( i = 0; i < numRawLightmaps; i++ )
{
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
rawLightmaps[ i ].twins[ lightmapNum ] = NULL;
rawLightmaps[ i ].twinNums[ lightmapNum ] = -1;
rawLightmaps[ i ].numStyledTwins = 0;
}
}
-
+
/* walk the list of raw lightmaps */
- for( i = 0; i < numRawLightmaps; i++ )
+ for ( i = 0; i < numRawLightmaps; i++ )
{
/* get lightmap */
lm = &rawLightmaps[ i ];
-
+
/* walk lightmaps */
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
/* early outs */
- if( lm->bspLuxels[ lightmapNum ] == NULL ||
- lm->twins[ lightmapNum ] != NULL )
+ if ( lm->bspLuxels[ lightmapNum ] == NULL ||
+ lm->twins[ lightmapNum ] != NULL ) {
continue;
-
+ }
+
/* find all lightmaps that are virtually identical to this one */
- for( j = i + 1; j < numRawLightmaps; j++ )
+ for ( j = i + 1; j < numRawLightmaps; j++ )
{
/* get lightmap */
lm2 = &rawLightmaps[ j ];
-
+
/* walk lightmaps */
- for( lightmapNum2 = 0; lightmapNum2 < MAX_LIGHTMAPS; lightmapNum2++ )
+ for ( lightmapNum2 = 0; lightmapNum2 < MAX_LIGHTMAPS; lightmapNum2++ )
{
/* early outs */
- if( lm2->bspLuxels[ lightmapNum2 ] == NULL ||
- lm2->twins[ lightmapNum2 ] != NULL )
+ if ( lm2->bspLuxels[ lightmapNum2 ] == NULL ||
+ lm2->twins[ lightmapNum2 ] != NULL ) {
continue;
-
+ }
+
/* compare them */
- if( CompareBSPLuxels( lm, lightmapNum, lm2, lightmapNum2 ) )
- {
+ if ( CompareBSPLuxels( lm, lightmapNum, lm2, lightmapNum2 ) ) {
/* merge and set twin */
- if( MergeBSPLuxels( lm, lightmapNum, lm2, lightmapNum2 ) )
- {
+ if ( MergeBSPLuxels( lm, lightmapNum, lm2, lightmapNum2 ) ) {
lm2->twins[ lightmapNum2 ] = lm;
lm2->twinNums[ lightmapNum2 ] = lightmapNum;
numTwins++;
- numTwinLuxels += (lm->w * lm->h);
-
+ numTwinLuxels += ( lm->w * lm->h );
+
/* count styled twins */
- if( lightmapNum > 0 )
+ if ( lightmapNum > 0 ) {
lm->numStyledTwins++;
+ }
}
}
}
}
}
}
-
+
/* -----------------------------------------------------------------
sort raw lightmaps by shader
----------------------------------------------------------------- */
-
+
/* note it */
Sys_Printf( "sorting..." );
-
+
/* allocate a new sorted list */
- if( sortLightmaps == NULL )
+ if ( sortLightmaps == NULL ) {
sortLightmaps = safe_malloc( numRawLightmaps * sizeof( int ) );
-
+ }
+
/* fill it out and sort it */
- for( i = 0; i < numRawLightmaps; i++ )
+ for ( i = 0; i < numRawLightmaps; i++ )
sortLightmaps[ i ] = i;
qsort( sortLightmaps, numRawLightmaps, sizeof( int ), CompareRawLightmap );
-
+
/* -----------------------------------------------------------------
allocate output lightmaps
----------------------------------------------------------------- */
-
+
/* note it */
Sys_Printf( "allocating..." );
-
+
/* kill all existing output lightmaps */
- if( outLightmaps != NULL )
- {
- for( i = 0; i < numOutLightmaps; i++ )
+ if ( outLightmaps != NULL ) {
+ for ( i = 0; i < numOutLightmaps; i++ )
{
free( outLightmaps[ i ].lightBits );
free( outLightmaps[ i ].bspLightBytes );
free( outLightmaps );
outLightmaps = NULL;
}
-
+
numLightmapShaders = 0;
numOutLightmaps = 0;
numBSPLightmaps = 0;
numExtLightmaps = 0;
-
+
/* find output lightmap */
- for( i = 0; i < numRawLightmaps; i++ )
+ for ( i = 0; i < numRawLightmaps; i++ )
{
lm = &rawLightmaps[ sortLightmaps[ i ] ];
FindOutLightmaps( lm );
}
-
+
/* set output numbers in twinned lightmaps */
- for( i = 0; i < numRawLightmaps; i++ )
+ for ( i = 0; i < numRawLightmaps; i++ )
{
/* get lightmap */
lm = &rawLightmaps[ sortLightmaps[ i ] ];
-
+
/* walk lightmaps */
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
/* get twin */
lm2 = lm->twins[ lightmapNum ];
- if( lm2 == NULL )
+ if ( lm2 == NULL ) {
continue;
+ }
lightmapNum2 = lm->twinNums[ lightmapNum ];
-
+
/* find output lightmap from twin */
lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ];
lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ];
lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ];
}
}
-
+
/* -----------------------------------------------------------------
store output lightmaps
----------------------------------------------------------------- */
-
+
/* note it */
Sys_Printf( "storing..." );
-
+
/* count the bsp lightmaps and allocate space */
- if( bspLightBytes != NULL )
+ if ( bspLightBytes != NULL ) {
free( bspLightBytes );
- if( numBSPLightmaps == 0 || externalLightmaps )
- {
+ }
+ if ( numBSPLightmaps == 0 || externalLightmaps ) {
numBSPLightBytes = 0;
bspLightBytes = NULL;
}
else
{
- numBSPLightBytes = (numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3);
+ numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 );
bspLightBytes = safe_malloc( numBSPLightBytes );
memset( bspLightBytes, 0, numBSPLightBytes );
}
-
+
/* walk the list of output lightmaps */
- for( i = 0; i < numOutLightmaps; i++ )
+ for ( i = 0; i < numOutLightmaps; i++ )
{
/* get output lightmap */
olm = &outLightmaps[ i ];
/* fill output lightmap */
- if(lightmapFill)
- FillOutLightmap(olm);
-
+ if ( lightmapFill ) {
+ FillOutLightmap( olm );
+ }
+
/* is this a valid bsp lightmap? */
- if( olm->lightmapNum >= 0 && !externalLightmaps )
- {
+ if ( olm->lightmapNum >= 0 && !externalLightmaps ) {
/* copy lighting data */
- lb = bspLightBytes + (olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3);
+ lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 );
memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 );
-
+
/* copy direction data */
- if( deluxemap )
- {
- lb = bspLightBytes + ((olm->lightmapNum + 1) * game->lightmapSize * game->lightmapSize * 3);
+ if ( deluxemap ) {
+ lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 );
memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 );
}
}
-
+
/* external lightmap? */
- if( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps )
- {
+ if ( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps ) {
/* make a directory for the lightmaps */
Q_mkdir( dirname );
-
+
/* set external lightmap number */
olm->extLightmapNum = numExtLightmaps;
-
+
/* write lightmap */
sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, qtrue );
numExtLightmaps++;
-
+
/* write deluxemap */
- if( deluxemap )
- {
+ if ( deluxemap ) {
sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, qtrue );
numExtLightmaps++;
-
- if( debugDeluxemap )
+
+ if ( debugDeluxemap ) {
olm->extLightmapNum++;
+ }
}
}
}
-
- if( numExtLightmaps > 0 )
+
+ if ( numExtLightmaps > 0 ) {
Sys_Printf( "\n" );
-
+ }
+
/* delete unused external lightmaps */
- for( i = numExtLightmaps; i; i++ )
+ for ( i = numExtLightmaps; i; i++ )
{
/* determine if file exists */
sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, i );
- if( !FileExists( filename ) )
+ if ( !FileExists( filename ) ) {
break;
-
+ }
+
/* delete it */
remove( filename );
}
-
+
/* -----------------------------------------------------------------
project the lightmaps onto the bsp surfaces
----------------------------------------------------------------- */
-
+
/* note it */
Sys_Printf( "projecting..." );
-
+
/* walk the list of surfaces */
- for( i = 0; i < numBSPDrawSurfaces; i++ )
+ for ( i = 0; i < numBSPDrawSurfaces; i++ )
{
/* get the surface and info */
ds = &bspDrawSurfaces[ i ];
info = &surfaceInfos[ i ];
lm = info->lm;
olm = NULL;
-
+
/* handle surfaces with identical parent */
- if( info->parentSurfaceNum >= 0 )
- {
+ if ( info->parentSurfaceNum >= 0 ) {
/* preserve original data and get parent */
parent = &bspDrawSurfaces[ info->parentSurfaceNum ];
memcpy( &dsTemp, ds, sizeof( *ds ) );
-
+
/* overwrite child with parent data */
memcpy( ds, parent, sizeof( *ds ) );
-
+
/* restore key parts */
ds->fogNum = dsTemp.fogNum;
ds->firstVert = dsTemp.firstVert;
ds->firstIndex = dsTemp.firstIndex;
memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) );
-
+
/* set vertex data */
dv = &bspDrawVerts[ ds->firstVert ];
dvParent = &bspDrawVerts[ parent->firstVert ];
- for( j = 0; j < ds->numVerts; j++ )
+ for ( j = 0; j < ds->numVerts; j++ )
{
memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) );
memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) );
}
-
+
/* skip the rest */
continue;
}
-
+
/* handle vertex lit or approximated surfaces */
- else if( lm == NULL || lm->outLightmapNums[ 0 ] < 0 )
- {
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ else if ( lm == NULL || lm->outLightmapNums[ 0 ] < 0 ) {
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
ds->lightmapNum[ lightmapNum ] = -3;
ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ];
}
}
-
+
/* handle lightmapped surfaces */
else
{
/* walk lightmaps */
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
/* set style */
ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
-
+
/* handle unused style */
- if( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 )
- {
+ if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
ds->lightmapNum[ lightmapNum ] = -3;
continue;
}
-
+
/* get output lightmap */
olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
-
+
/* set bsp lightmap number */
ds->lightmapNum[ lightmapNum ] = olm->lightmapNum;
-
+
/* deluxemap debugging makes the deluxemap visible */
- if( deluxemap && debugDeluxemap && lightmapNum == 0 )
+ if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) {
ds->lightmapNum[ lightmapNum ]++;
-
+ }
+
/* calc lightmap origin in texture space */
lmx = (float) lm->lightmapX[ lightmapNum ] / (float) olm->customWidth;
lmy = (float) lm->lightmapY[ lightmapNum ] / (float) olm->customHeight;
-
+
/* calc lightmap st coords */
dv = &bspDrawVerts[ ds->firstVert ];
ydv = &yDrawVerts[ ds->firstVert ];
- for( j = 0; j < ds->numVerts; j++ )
+ for ( j = 0; j < ds->numVerts; j++ )
{
- if( lm->solid[ lightmapNum ] )
- {
- dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + (0.5f / (float) olm->customWidth);
- dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + (0.5f / (float) olm->customWidth);
+ if ( lm->solid[ lightmapNum ] ) {
+ dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / (float) olm->customWidth );
+ dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( 0.5f / (float) olm->customWidth );
}
else
{
- dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + (ydv[ j ].lightmap[ 0 ][ 0 ] / (superSample * olm->customWidth));
- dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + (ydv[ j ].lightmap[ 0 ][ 1 ] / (superSample * olm->customHeight));
+ dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( ydv[ j ].lightmap[ 0 ][ 0 ] / ( superSample * olm->customWidth ) );
+ dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( ydv[ j ].lightmap[ 0 ][ 1 ] / ( superSample * olm->customHeight ) );
}
}
}
}
-
+
/* store vertex colors */
dv = &bspDrawVerts[ ds->firstVert ];
- for( j = 0; j < ds->numVerts; j++ )
+ for ( j = 0; j < ds->numVerts; j++ )
{
/* walk lightmaps */
- for( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
/* handle unused style */
- if( ds->vertexStyles[ lightmapNum ] == LS_NONE )
+ if ( ds->vertexStyles[ lightmapNum ] == LS_NONE ) {
VectorClear( color );
+ }
else
{
/* get vertex color */
luxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + j );
VectorCopy( luxel, color );
-
+
/* set minimum light */
- if( lightmapNum == 0 )
- {
- for( k = 0; k < 3; k++ )
- if( color[ k ] < minVertexLight[ k ] )
+ if ( lightmapNum == 0 ) {
+ for ( k = 0; k < 3; k++ )
+ if ( color[ k ] < minVertexLight[ k ] ) {
color[ k ] = minVertexLight[ k ];
+ }
}
}
-
+
/* store to bytes */
- if( !info->si->noVertexLight )
+ if ( !info->si->noVertexLight ) {
ColorToBytes( color, dv[ j ].color[ lightmapNum ], info->si->vertexScale );
+ }
}
}
-
+
/* surfaces with styled lightmaps and a style marker get a custom generated shader (fixme: make this work with external lightmaps) */
- if( olm != NULL && lm != NULL && lm->styles[ 1 ] != LS_NONE && game->load != LoadRBSPFile ) //% info->si->styleMarker > 0 )
- {
- qboolean dfEqual;
- char key[ 32 ], styleStage[ 512 ], styleStages[ 4096 ], rgbGen[ 128 ], alphaGen[ 128 ];
-
-
+ if ( olm != NULL && lm != NULL && lm->styles[ 1 ] != LS_NONE && game->load != LoadRBSPFile ) { //% info->si->styleMarker > 0 )
+ qboolean dfEqual;
+ char key[ 32 ], styleStage[ 512 ], styleStages[ 4096 ], rgbGen[ 128 ], alphaGen[ 128 ];
+
+
/* setup */
sprintf( styleStages, "\n\t// Q3Map2 custom lightstyle stage(s)\n" );
dv = &bspDrawVerts[ ds->firstVert ];
-
+
/* depthFunc equal? */
- if( info->si->styleMarker == 2 || info->si->implicitMap == IM_MASKED )
+ if ( info->si->styleMarker == 2 || info->si->implicitMap == IM_MASKED ) {
dfEqual = qtrue;
- else
+ }
+ else{
dfEqual = qfalse;
-
+ }
+
/* generate stages for styled lightmaps */
- for( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ for ( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
/* early out */
style = lm->styles[ lightmapNum ];
- if( style == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 )
+ if ( style == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
continue;
-
+ }
+
/* get output lightmap */
olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
-
+
/* lightmap name */
- if( lm->outLightmapNums[ lightmapNum ] == lm->outLightmapNums[ 0 ] )
+ if ( lm->outLightmapNums[ lightmapNum ] == lm->outLightmapNums[ 0 ] ) {
strcpy( lightmapName, "$lightmap" );
- else
+ }
+ else{
sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
-
+ }
+
/* get rgbgen string */
- if( rgbGenValues[ style ] == NULL )
- {
+ if ( rgbGenValues[ style ] == NULL ) {
sprintf( key, "_style%drgbgen", style );
rgbGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
- if( rgbGenValues[ style ][ 0 ] == '\0' )
+ if ( rgbGenValues[ style ][ 0 ] == '\0' ) {
rgbGenValues[ style ] = "wave noise 0.5 1 0 5.37";
+ }
}
rgbGen[ 0 ] = '\0';
- if( rgbGenValues[ style ][ 0 ] != '\0' )
+ if ( rgbGenValues[ style ][ 0 ] != '\0' ) {
sprintf( rgbGen, "\t\trgbGen %s // style %d\n", rgbGenValues[ style ], style );
- else
+ }
+ else{
rgbGen[ 0 ] = '\0';
-
+ }
+
/* get alphagen string */
- if( alphaGenValues[ style ] == NULL )
- {
+ if ( alphaGenValues[ style ] == NULL ) {
sprintf( key, "_style%dalphagen", style );
alphaGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
}
- if( alphaGenValues[ style ][ 0 ] != '\0' )
+ if ( alphaGenValues[ style ][ 0 ] != '\0' ) {
sprintf( alphaGen, "\t\talphaGen %s // style %d\n", alphaGenValues[ style ], style );
- else
+ }
+ else{
alphaGen[ 0 ] = '\0';
-
+ }
+
/* calculate st offset */
lmx = dv[ 0 ].lightmap[ lightmapNum ][ 0 ] - dv[ 0 ].lightmap[ 0 ][ 0 ];
lmy = dv[ 0 ].lightmap[ lightmapNum ][ 1 ] - dv[ 0 ].lightmap[ 0 ][ 1 ];
-
+
/* create additional stage */
- if( lmx == 0.0f && lmy == 0.0f )
- {
- sprintf( styleStage, "\t{\n"
- "\t\tmap %s\n" /* lightmap */
+ if ( lmx == 0.0f && lmy == 0.0f ) {
+ sprintf( styleStage, "\t{\n"
+ "\t\tmap %s\n" /* lightmap */
"\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
- "%s" /* depthFunc equal */
- "%s" /* rgbGen */
- "%s" /* alphaGen */
+ "%s" /* depthFunc equal */
+ "%s" /* rgbGen */
+ "%s" /* alphaGen */
"\t\ttcGen lightmap\n"
"\t}\n",
- lightmapName,
- (dfEqual ? "\t\tdepthFunc equal\n" : ""),
- rgbGen,
- alphaGen );
+ lightmapName,
+ ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
+ rgbGen,
+ alphaGen );
}
else
{
- sprintf( styleStage, "\t{\n"
- "\t\tmap %s\n" /* lightmap */
+ sprintf( styleStage, "\t{\n"
+ "\t\tmap %s\n" /* lightmap */
"\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
- "%s" /* depthFunc equal */
- "%s" /* rgbGen */
- "%s" /* alphaGen */
+ "%s" /* depthFunc equal */
+ "%s" /* rgbGen */
+ "%s" /* alphaGen */
"\t\ttcGen lightmap\n"
- "\t\ttcMod transform 1 0 0 1 %1.5f %1.5f\n" /* st offset */
+ "\t\ttcMod transform 1 0 0 1 %1.5f %1.5f\n" /* st offset */
"\t}\n",
- lightmapName,
- (dfEqual ? "\t\tdepthFunc equal\n" : ""),
- rgbGen,
- alphaGen,
- lmx, lmy );
-
+ lightmapName,
+ ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
+ rgbGen,
+ alphaGen,
+ lmx, lmy );
+
}
-
+
/* concatenate */
strcat( styleStages, styleStage );
}
-
+
/* create custom shader */
- if( info->si->styleMarker == 2 )
+ if ( info->si->styleMarker == 2 ) {
csi = CustomShader( info->si, "q3map_styleMarker2", styleStages );
- else
+ }
+ else{
csi = CustomShader( info->si, "q3map_styleMarker", styleStages );
-
+ }
+
/* emit remap command */
//% EmitVertexRemapShader( csi->shader, info->si->shader );
-
+
/* store it */
//% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
//% Sys_Printf( ")\n" );
}
-
+
/* devise a custom shader for this surface (fixme: make this work with light styles) */
- else if( olm != NULL && lm != NULL && !externalLightmaps &&
- (olm->customWidth != game->lightmapSize || olm->customHeight != game->lightmapSize) )
- {
+ else if ( olm != NULL && lm != NULL && !externalLightmaps &&
+ ( olm->customWidth != game->lightmapSize || olm->customHeight != game->lightmapSize ) ) {
/* get output lightmap */
olm = &outLightmaps[ lm->outLightmapNums[ 0 ] ];
-
+
/* do some name mangling */
sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
-
+
/* create custom shader */
csi = CustomShader( info->si, "$lightmap", lightmapName );
-
+
/* store it */
//% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
//% Sys_Printf( ")\n" );
}
-
+
/* use the normal plain-jane shader */
- else
+ else{
ds->shaderNum = EmitShader( info->si->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ }
}
-
+
/* finish */
Sys_Printf( "done.\n" );
-
+
/* calc num stored */
numStored = numBSPLightBytes / 3;
- efficiency = (numStored <= 0)
- ? 0
- : (float) numUsed / (float) numStored;
-
+ efficiency = ( numStored <= 0 )
+ ? 0
+ : (float) numUsed / (float) numStored;
+
/* print stats */
Sys_Printf( "%9d luxels used\n", numUsed );
Sys_Printf( "%9d luxels stored (%3.2f percent efficiency)\n", numStored, efficiency * 100.0f );
Sys_Printf( "%9d BSP lightmaps\n", numBSPLightmaps );
Sys_Printf( "%9d total lightmaps\n", numOutLightmaps );
Sys_Printf( "%9d unique lightmap/shader combinations\n", numLightmapShaders );
-
+
/* write map shader file */
WriteMapShaderFile();
}
-
-
-
-