-void AllocateLightmapForSurface( mapDrawSurface_t *ds )
-{
- vec3_t mins, maxs, size, exactSize, delta;
- int i;
- drawVert_t *verts;
- int w, h;
- int x, y, ssize;
- int axis;
- vec3_t vecs[ 2 ];
- float s, t;
- vec3_t origin;
- vec4_t plane;
- float d;
-
-
- /* debug code */
- #if 0
- if( ds->type == SURF_META && ds->planar == qfalse )
- Sys_Printf( "NPMS: %3d vertexes, %s\n", ds->numVerts, ds->shaderInfo->shader );
- else if( ds->type == SURF_META && ds->planar == qtrue )
- Sys_Printf( "PMS: %3d vertexes, %s\n", ds->numVerts, ds->shaderInfo->shader );
- #endif
-
- /* ydnar: handle planar patches */
- if( noPatchFix == qtrue || (ds->type == SURF_PATCH && ds->planeNum < 0) )
- {
- AllocateLightmapForPatch( ds );
- return;
- }
-
- /* get sample size */
- ssize = ds->sampleSize;
-
- /* bound the surface */
- ClearBounds( mins, maxs );
- verts = ds->verts;
- for ( i = 0 ; i < ds->numVerts ; i++ )
- AddPointToBounds( verts[i].xyz, mins, maxs );
-
- /* round to the lightmap resolution */
- for( i = 0; i < 3; i++ )
- {
- exactSize[i] = maxs[i] - mins[i];
- mins[i] = ssize * floor( mins[i] / ssize );
- maxs[i] = ssize * ceil( maxs[i] / ssize );
- size[i] = (maxs[i] - mins[i]) / ssize + 1;
- }
-
- /* ydnar: lightmap projection axis is already stored */
- memset( vecs, 0, sizeof( vecs ) );
-
- /* classify the plane (x y or z major) (ydnar: biased to z axis projection) */
- if( ds->lightmapAxis[ 2 ] >= ds->lightmapAxis[ 0 ] && ds->lightmapAxis[ 2 ] >= ds->lightmapAxis[ 1 ] )
- {
- w = size[ 0 ];
- h = size[ 1 ];
- axis = 2;
- vecs[ 0 ][ 0 ] = 1.0 / ssize;
- vecs[ 1 ][ 1 ] = 1.0 / ssize;
- }
- else if( ds->lightmapAxis[ 0 ] >= ds->lightmapAxis[ 1 ] && ds->lightmapAxis[ 0 ] >= ds->lightmapAxis[ 2 ] )
- {
- w = size[ 1 ];
- h = size[ 2 ];
- axis = 0;
- vecs[ 0 ][ 1 ] = 1.0 / ssize;
- vecs[ 1 ][ 2 ] = 1.0 / ssize;
- }
- else
- {
- w = size[ 0 ];
- h = size[ 2 ];
- axis = 1;
- vecs[ 0 ][ 0 ] = 1.0 / ssize;
- vecs[ 1 ][ 2 ] = 1.0 / ssize;
- }
-
- /* odd check, given projection is now precalculated */
- if( ds->lightmapAxis[ axis ] == 0 )
- Error( "Chose a 0 valued axis" );
-
- /* clamp to lightmap texture resolution */
- if( w > LIGHTMAP_WIDTH )
- {
- VectorScale ( vecs[0], (float) LIGHTMAP_WIDTH / w, vecs[0] );
- w = LIGHTMAP_WIDTH;
- }
- if( h > LIGHTMAP_HEIGHT )
- {
- VectorScale ( vecs[1], (float) LIGHTMAP_HEIGHT / h, vecs[1] );
- h = LIGHTMAP_HEIGHT;
- }
-
-
- /* ydnar */
- if( ds->planar == qfalse )
- c_nonplanarLightmap += w * h;
- c_exactLightmap += w * h;
-
-
- if( !AllocLMBlock( w, h, &x, &y ) )
- {
- PrepareNewLightmap();
- if ( !AllocLMBlock( w, h, &x, &y ) )
- {
- Error( "Entity %i, brush %i: Lightmap allocation failed",
- ds->mapBrush->entitynum, ds->mapBrush->brushnum );
- }
- }
-
- /* set the lightmap texture coordinates in the drawVerts */
- ds->lightmapNum = numLightmaps - 1;
- ds->lightmapWidth = w;
- ds->lightmapHeight = h;
- ds->lightmapX = x;
- ds->lightmapY = y;
- for ( i = 0 ; i < ds->numVerts ; i++ )
- {
- VectorSubtract( verts[i].xyz, mins, delta );
- s = DotProduct( delta, vecs[0] ) + x + 0.5;
- t = DotProduct( delta, vecs[1] ) + y + 0.5;
- verts[i].lightmap[0] = s / LIGHTMAP_WIDTH;
- verts[i].lightmap[1] = t / LIGHTMAP_HEIGHT;
- }
-
- /* calculate the world coordinates of the lightmap samples */
-
- /* construct a plane from the first vert and clear bounding box */
-
- /* project mins onto plane to get origin */
- VectorCopy( ds->lightmapVecs[ 2 ], plane );
- plane[ 3 ] = DotProduct( ds->verts[ 0 ].xyz, plane );
- d = DotProduct( mins, plane ) - plane[ 3 ];
- d /= plane[ axis ];
-
- //% d = DotProduct( mins, plane->normal ) - plane->dist;
- //% d /= plane->normal[ axis ];
- VectorCopy( mins, origin );
- origin[ axis ] -= d;
-
- /* project stepped lightmap blocks and subtract to get planevecs */
- for( i = 0; i < 2; i++ )
- {
- vec3_t normalized;
- float len;
-
- len = VectorNormalize( vecs[i], normalized );
- VectorScale( normalized, (1.0/len), vecs[i] );
- d = DotProduct( vecs[i], plane );
- d /= plane[ axis ];
- //%d = DotProduct( vecs[i], plane->normal );
- //%d /= plane->normal[ axis ];
- vecs[i][axis] -= d;
- }
-
- /* store lightmap origin and vectors (fixme: make this work right) */
- VectorCopy( origin, ds->lightmapOrigin );
- //% VectorCopy( plane->normal, ds->lightmapVecs[ 2 ] );
-
- /* ydnar: lightmap vectors 0 and 1 are used for lod bounds, so don't overwrite */
- if( ds->type == SURF_PATCH )
- c_planarPatch++;
-
- /* store lightmap vectors */
- VectorCopy( vecs[ 0 ], ds->lightmapVecs[ 0 ] );
- VectorCopy( vecs[ 1 ], ds->lightmapVecs[ 1 ] );
-
- /* ydnar: print some stats */
- //Sys_FPrintf( SYS_VRB, "Lightmap block %3d (%3d, %3d) (%3d x %3d) emitted\n", (numLightmaps - 1), x, y, w, h );
-}