void R_SetupEntityLightingGrid( trRefEntity_t *ent) { #else static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) { #endif vec3_t lightOrigin; int pos[3]; int i, j; float frac[3]; int gridStep[3]; vec3_t direction; float totalFactor; unsigned short *startGridPos; if (r_fullbright->integer) { ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = 255.0; ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = 255.0; VectorCopy( tr.sunDirection, ent->lightDir ); return; } if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) { // seperate lightOrigins are needed so an object that is // sinking into the ground can still be lit, and so // multi-part models can be lit identically VectorCopy( ent->e.lightingOrigin, lightOrigin ); } else { VectorCopy( ent->e.origin, lightOrigin ); } VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin ); for ( i = 0 ; i < 3 ; i++ ) { float v; v = lightOrigin[i]*tr.world->lightGridInverseSize[i]; pos[i] = floor( v ); frac[i] = v - pos[i]; if ( pos[i] < 0 ) { pos[i] = 0; } else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) { pos[i] = tr.world->lightGridBounds[i] - 1; } } VectorClear( ent->ambientLight ); VectorClear( ent->directedLight ); VectorClear( direction ); // trilerp the light value gridStep[0] = 1; gridStep[1] = tr.world->lightGridBounds[0]; gridStep[2] = tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1]; startGridPos = tr.world->lightGridArray + (pos[0] * gridStep[0] + pos[1] * gridStep[1] + pos[2] * gridStep[2]); totalFactor = 0; for ( i = 0 ; i < 8 ; i++ ) { float factor; mgrid_t *data; unsigned short *gridPos; double lat, lng; vec3_t normal; factor = 1.0; gridPos = startGridPos; for ( j = 0 ; j < 3 ; j++ ) { if ( i & (1<<j) ) { factor *= frac[j]; gridPos += gridStep[j]; } else { factor *= (1.0 - frac[j]); } } if (gridPos >= tr.world->lightGridArray + tr.world->numGridArrayElements) {//we've gone off the array somehow continue; } data = tr.world->lightGridData + *gridPos; if ( data->styles[0] == LS_LSNONE ) { continue; // ignore samples in walls } totalFactor += factor; for(j=0;j<MAXLIGHTMAPS;j++) { if (data->styles[j] != LS_LSNONE) { const byte style= data->styles[j]; ent->ambientLight[0] += factor * data->ambientLight[j][0] * styleColors[style][0] / 255.0f; ent->ambientLight[1] += factor * data->ambientLight[j][1] * styleColors[style][1] / 255.0f; ent->ambientLight[2] += factor * data->ambientLight[j][2] * styleColors[style][2] / 255.0f; ent->directedLight[0] += factor * data->directLight[j][0] * styleColors[style][0] / 255.0f; ent->directedLight[1] += factor * data->directLight[j][1] * styleColors[style][1] / 255.0f; ent->directedLight[2] += factor * data->directLight[j][2] * styleColors[style][2] / 255.0f; } else { break; } } lat = data->latLong[1]; lng = data->latLong[0]; // lat *= (FUNCTABLE_SIZE/256); // lng *= (FUNCTABLE_SIZE/256); lat /= 256; lng /= 256; // decode X as cos( lat ) * sin( long ) // decode Y as sin( lat ) * sin( long ) // decode Z as cos( long ) /* normal[0] = tr.sinTable[(lat + (FUNCTABLE_SIZE / 4)) & FUNCTABLE_MASK] * tr.sinTable[lng]; normal[1] = tr.sinTable[lat] * tr.sinTable[lng]; normal[2] = tr.sinTable[(lng + (FUNCTABLE_SIZE / 4)) & FUNCTABLE_MASK];*/ normal[0] = NewCosTable(lat) * NewSinTable(lng); normal[1] = NewSinTable(lat) * NewSinTable(lng); normal[2] = NewCosTable(lng); VectorMA( direction, factor, normal, direction ); } if ( totalFactor > 0 && totalFactor < 0.99 ) { totalFactor = 1.0 / totalFactor; VectorScale( ent->ambientLight, totalFactor, ent->ambientLight ); VectorScale( ent->directedLight, totalFactor, ent->directedLight ); } VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight ); VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight ); VectorNormalize2( direction, ent->lightDir ); }
/* ================= R_SetupEntityLightingGrid ================= */ static void R_SetupEntityLightingGrid( sceneModel_t *ent ) { vec3_t lightOrigin; int pos[3]; int i, j; byte *gridData; float frac[3]; int gridStep[3]; vec3_t direction; float totalFactor; if ( ent->renderfx & RF_LIGHTING_ORIGIN ) { // seperate lightOrigins are needed so an object that is // sinking into the ground can still be lit, and so // multi-part models can be lit identically VectorCopy( ent->lightingOrigin, lightOrigin ); } else { VectorCopy( ent->origin, lightOrigin ); } VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin ); for ( i = 0 ; i < 3 ; i++ ) { float v; v = lightOrigin[i]*tr.world->lightGridInverseSize[i]; pos[i] = floor( v ); frac[i] = v - pos[i]; if ( pos[i] < 0 ) { pos[i] = 0; } else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) { pos[i] = tr.world->lightGridBounds[i] - 1; } } VectorClear( ent->ambientLight ); VectorClear( ent->directedLight ); VectorClear( direction ); assert( tr.world->lightGridData ); // bk010103 - NULL with -nolight maps // trilerp the light value gridStep[0] = 8; gridStep[1] = 8 * tr.world->lightGridBounds[0]; gridStep[2] = 8 * tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1]; gridData = tr.world->lightGridData + pos[0] * gridStep[0] + pos[1] * gridStep[1] + pos[2] * gridStep[2]; totalFactor = 0; for ( i = 0 ; i < 8 ; i++ ) { float factor; byte *data; double lat, lng; vec3_t normal; #if idppc float d0, d1, d2, d3, d4, d5; #endif factor = 1.0; data = gridData; for ( j = 0 ; j < 3 ; j++ ) { if ( i & (1<<j) ) { factor *= frac[j]; data += gridStep[j]; } else { factor *= (1.0f - frac[j]); } } if ( !(data[0]+data[1]+data[2]) ) { continue; // ignore samples in walls } totalFactor += factor; #if idppc d0 = data[0]; d1 = data[1]; d2 = data[2]; d3 = data[3]; d4 = data[4]; d5 = data[5]; ent->ambientLight[0] += factor * d0; ent->ambientLight[1] += factor * d1; ent->ambientLight[2] += factor * d2; ent->directedLight[0] += factor * d3; ent->directedLight[1] += factor * d4; ent->directedLight[2] += factor * d5; #else ent->ambientLight[0] += factor * data[0]; ent->ambientLight[1] += factor * data[1]; ent->ambientLight[2] += factor * data[2]; ent->directedLight[0] += factor * data[3]; ent->directedLight[1] += factor * data[4]; ent->directedLight[2] += factor * data[5]; #endif lat = data[7]; lng = data[6]; // lat *= (FUNCTABLE_SIZE/256); // lng *= (FUNCTABLE_SIZE/256); lat /= 256; lng /= 256; // decode X as cos( lat ) * sin( long ) // decode Y as sin( lat ) * sin( long ) // decode Z as cos( long ) /* normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; normal[1] = tr.sinTable[lat] * tr.sinTable[lng]; normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];*/ normal[0] = NewCosTable(lat) * NewSinTable(lng); normal[1] = NewSinTable(lat) * NewSinTable(lng); normal[2] = NewCosTable(lng); VectorMA( direction, factor, normal, direction ); } if ( totalFactor > 0 && totalFactor < 0.99 ) { totalFactor = 1.0f / totalFactor; VectorScale( ent->ambientLight, totalFactor, ent->ambientLight ); VectorScale( ent->directedLight, totalFactor, ent->directedLight ); } VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight ); VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight ); VectorNormalize2( direction, ent->lightDir ); }