int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *world ) { trRefEntity_t ent; if ( world->lightGridData == NULL ) return qfalse; Com_Memset(&ent, 0, sizeof(ent)); VectorCopy( point, ent.e.origin ); R_SetupEntityLightingGrid( &ent, world ); VectorCopy(ent.lightDir, lightDir); return qtrue; }
/* ================= R_LightForPoint ================= */ int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir ) { trRefEntity_t ent; if ( tr.world->lightGridData == NULL ) return qfalse; memset(&ent, 0, sizeof(ent)); VectorCopy( point, ent.e.origin ); R_SetupEntityLightingGrid( &ent ); VectorCopy(ent.ambientLight, ambientLight); VectorCopy(ent.directedLight, directedLight); VectorCopy(ent.lightDir, lightDir); return qtrue; }
/* * R_LightForPoint */ int R_LightForPoint(Vec3 point, Vec3 ambientLight, Vec3 directedLight, Vec3 lightDir) { trRefEntity_t ent; if(tr.world->lightGridData == NULL) return qfalse; Q_Memset(&ent, 0, sizeof(ent)); copyv3(point, ent.e.origin); R_SetupEntityLightingGrid(&ent); copyv3(ent.ambientLight, ambientLight); copyv3(ent.directedLight, directedLight); copyv3(ent.lightDir, lightDir); return qtrue; }
/* ================= R_LightForPoint ================= */ int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir ) { trRefEntity_t ent; // bk010103 - this segfaults with -nolight maps if ( tr.world->lightGridData == NULL ) { return qfalse; } Com_Memset( &ent, 0, sizeof( ent ) ); VectorCopy( point, ent.e.origin ); R_SetupEntityLightingGrid( &ent ); VectorCopy( ent.ambientLight, ambientLight ); VectorCopy( ent.directedLight, directedLight ); VectorCopy( ent.lightDir, lightDir ); return qtrue; }
/* ================= R_LightForPoint ================= */ int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir ) { sceneModel_t ent; // bk010103 - this segfaults with -nolight maps if ( tr.world->lightGridData == NULL ) return qfalse; //Doesn't really need to be fully cleared, and it's basically still slow... :) // Com_Memset(&ent, 0, sizeof(ent)); VectorCopy( point, ent.origin ); R_SetupEntityLightingGrid( &ent ); VectorCopy(ent.ambientLight, ambientLight); VectorCopy(ent.directedLight, directedLight); VectorCopy(ent.lightDir, lightDir); return qtrue; }
int R_LightDirForPoint(Vec3 point, Vec3 lightDir, Vec3 normal, world_t *world) { trRefEntity_t ent; if(world->lightGridData == NULL) return qfalse; Q_Memset(&ent, 0, sizeof(ent)); copyv3(point, ent.e.origin); R_SetupEntityLightingGrid(&ent, world); if((dotv3(ent.lightDir, ent.lightDir) < 0.9f) || (dotv3(ent.lightDir, normal) < 0.3f)){ copyv3(normal, lightDir); }else{ copyv3(ent.lightDir, lightDir); } return qtrue; }
//pass in origin qboolean RE_GetLighting( const vec3_t origin, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir) { trRefEntity_t tr_ent; if ( !tr.world || !tr.world->lightGridData) { ambientLight[0] = ambientLight[1] = ambientLight[2] = 255.0; directedLight[0] = directedLight[1] = directedLight[2] = 255.0; VectorCopy( tr.sunDirection, lightDir ); return qfalse; } memset (&tr_ent, 0, sizeof(tr_ent) ); if ( ambientLight[0] == 666 ) {//HAX0R tr_ent.e.hModel = -1; } VectorCopy (origin, tr_ent.e.origin); R_SetupEntityLightingGrid( &tr_ent ); VectorCopy ( tr_ent.ambientLight, ambientLight); VectorCopy ( tr_ent.directedLight, directedLight); VectorCopy ( tr_ent.lightDir, lightDir); return qtrue; }
/* ================= R_SetupEntityLighting Calculates all the lighting values that will be used by the Calc_* functions ================= */ void R_SetupEntityLighting(const trRefdef_t *refdef, trRefEntity_t *ent) { int i; dlight_t *dl; float power; vec3_t dir; float d; vec3_t lightDir; vec3_t lightOrigin; // qboolean highlighted = qfalse; // TTimo: unused // lighting calculations if(ent->lightingCalculated) { return; } ent->lightingCalculated = qtrue; // // trace a sample point down to find ambient light // 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); } // if NOWORLDMODEL, only use dynamic lights (menu system, etc) if(!(refdef->rdflags & RDF_NOWORLDMODEL) && tr.world->lightGridData) { R_SetupEntityLightingGrid(ent); } else { ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = tr.identityLight * 150; ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = tr.identityLight * 150; VectorCopy(tr.sunDirection, ent->lightDir); } if(ent->e.hilightIntensity) { // level of intensity was set because the item was looked at ent->ambientLight[0] += tr.identityLight * 128 * ent->e.hilightIntensity; ent->ambientLight[1] += tr.identityLight * 128 * ent->e.hilightIntensity; ent->ambientLight[2] += tr.identityLight * 128 * ent->e.hilightIntensity; } else if(ent->e.renderfx & RF_MINLIGHT) { // give everything a minimum light add ent->ambientLight[0] += tr.identityLight * 32; ent->ambientLight[1] += tr.identityLight * 32; ent->ambientLight[2] += tr.identityLight * 32; } if(ent->e.entityNum < MAX_CLIENTS && (refdef->rdflags & RDF_SNOOPERVIEW)) { VectorSet(ent->ambientLight, 245, 245, 245); // allow a little room for flicker from directed light } // // modify the light by dynamic lights // d = VectorLength(ent->directedLight); VectorScale(ent->lightDir, d, lightDir); for(i = 0 ; i < refdef->num_dlights ; i++) { dl = &refdef->dlights[i]; if(dl->dlshader) //----(SA) if the dlight has a diff shader specified, you don't know what it does, so don't let it affect entities lighting { continue; } VectorSubtract(dl->origin, lightOrigin, dir); d = VectorNormalize(dir); power = DLIGHT_AT_RADIUS * (dl->radius * dl->radius); if(d < DLIGHT_MINIMUM_RADIUS) { d = DLIGHT_MINIMUM_RADIUS; } d = power / (d * d); VectorMA(ent->directedLight, d, dl->color, ent->directedLight); VectorMA(lightDir, d, dir, lightDir); } // clamp ambient for(i = 0 ; i < 3 ; i++) { if(ent->ambientLight[i] > tr.identityLightByte) { ent->ambientLight[i] = tr.identityLightByte; } } if(r_debugLight->integer) { LogLight(ent); } // save out the byte packet version ((byte *)&ent->ambientLightInt)[0] = myftol(ent->ambientLight[0]); ((byte *)&ent->ambientLightInt)[1] = myftol(ent->ambientLight[1]); ((byte *)&ent->ambientLightInt)[2] = myftol(ent->ambientLight[2]); ((byte *)&ent->ambientLightInt)[3] = 0xff; // transform the direction to local space VectorNormalize(lightDir); ent->lightDir[0] = DotProduct(lightDir, ent->e.axis[0]); ent->lightDir[1] = DotProduct(lightDir, ent->e.axis[1]); ent->lightDir[2] = DotProduct(lightDir, ent->e.axis[2]); }
/* * R_SetupEntityLighting * * Calculates all the lighting values that will be used * by the Calc_* functions */ void R_SetupEntityLighting(const trRefdef_t *refdef, trRefEntity_t *ent) { int i; dlight_t *dl; float power; Vec3 dir; float d; Vec3 lightDir; Vec3 lightOrigin; /* lighting calculations */ if(ent->lightingCalculated){ return; } ent->lightingCalculated = qtrue; /* * trace a sample point down to find ambient light * */ 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 */ copyv3(ent->e.lightingOrigin, lightOrigin); }else{ copyv3(ent->e.origin, lightOrigin); } /* if NOWORLDMODEL, only use dynamic lights (menu system, etc) */ if(!(refdef->rdflags & RDF_NOWORLDMODEL) && tr.world->lightGridData){ R_SetupEntityLightingGrid(ent); }else{ ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = tr.identityLight * 150; ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = tr.identityLight * 150; copyv3(tr.sunDirection, ent->lightDir); } /* bonus items and view weapons have a fixed minimum add */ if(1 /* ent->e.renderfx & RF_MINLIGHT */){ /* give everything a minimum light add */ ent->ambientLight[0] += tr.identityLight * 32; ent->ambientLight[1] += tr.identityLight * 32; ent->ambientLight[2] += tr.identityLight * 32; } /* * modify the light by dynamic lights * */ d = lenv3(ent->directedLight); scalev3(ent->lightDir, d, lightDir); for(i = 0; i < refdef->num_dlights; i++){ dl = &refdef->dlights[i]; subv3(dl->origin, lightOrigin, dir); d = normv3(dir); power = DLIGHT_AT_RADIUS * (dl->radius * dl->radius); if(d < DLIGHT_MINIMUM_RADIUS){ d = DLIGHT_MINIMUM_RADIUS; } d = power / (d * d); saddv3(ent->directedLight, d, dl->color, ent->directedLight); saddv3(lightDir, d, dir, lightDir); } /* clamp ambient */ for(i = 0; i < 3; i++) if(ent->ambientLight[i] > tr.identityLightByte){ ent->ambientLight[i] = tr.identityLightByte; } if(r_debugLight->integer){ LogLight(ent); } /* save out the byte packet version */ ((byte*)&ent->ambientLightInt)[0] = ri.ftol(ent->ambientLight[0]); ((byte*)&ent->ambientLightInt)[1] = ri.ftol(ent->ambientLight[1]); ((byte*)&ent->ambientLightInt)[2] = ri.ftol(ent->ambientLight[2]); ((byte*)&ent->ambientLightInt)[3] = 0xff; /* transform the direction to local space */ normv3(lightDir); ent->lightDir[0] = dotv3(lightDir, ent->e.axis[0]); ent->lightDir[1] = dotv3(lightDir, ent->e.axis[1]); ent->lightDir[2] = dotv3(lightDir, ent->e.axis[2]); }
/* ================= R_SetupEntityLighting Calculates all the lighting values that will be used by the Calc_* functions ================= */ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) { #ifndef VV_LIGHTING int i; dlight_t *dl; float power; vec3_t dir; float d; vec3_t lightDir; vec3_t lightOrigin; // lighting calculations if ( ent->lightingCalculated ) { return; } ent->lightingCalculated = qtrue; // // trace a sample point down to find ambient light // 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 ); } // if NOWORLDMODEL, only use dynamic lights (menu system, etc) if ( !(refdef->rdflags & RDF_NOWORLDMODEL ) && tr.world->lightGridData ) { R_SetupEntityLightingGrid( ent ); } else { ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = tr.identityLight * 150; ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = tr.identityLight * 150; VectorCopy( tr.sunDirection, ent->lightDir ); } // bonus items and view weapons have a fixed minimum add if ( ent->e.renderfx & RF_MORELIGHT ) { ent->ambientLight[0] += tr.identityLight * 96; ent->ambientLight[1] += tr.identityLight * 96; ent->ambientLight[2] += tr.identityLight * 96; } else { // give everything a minimum light add ent->ambientLight[0] += tr.identityLight * 32; ent->ambientLight[1] += tr.identityLight * 32; ent->ambientLight[2] += tr.identityLight * 32; } // // modify the light by dynamic lights // d = VectorLength( ent->directedLight ); VectorScale( ent->lightDir, d, lightDir ); for ( i = 0 ; i < refdef->num_dlights ; i++ ) { dl = &refdef->dlights[i]; VectorSubtract( dl->origin, lightOrigin, dir ); d = VectorNormalize( dir ); power = DLIGHT_AT_RADIUS * ( dl->radius * dl->radius ); if ( d < DLIGHT_MINIMUM_RADIUS ) { d = DLIGHT_MINIMUM_RADIUS; } d = power / ( d * d ); VectorMA( ent->directedLight, d, dl->color, ent->directedLight ); VectorMA( lightDir, d, dir, lightDir ); } // clamp ambient for ( i = 0 ; i < 3 ; i++ ) { if ( ent->ambientLight[i] > tr.identityLightByte ) { ent->ambientLight[i] = tr.identityLightByte; } } if ( r_debugLight->integer ) { LogLight( ent ); } // save out the byte packet version ((byte *)&ent->ambientLightInt)[0] = Q_ftol( ent->ambientLight[0] ); ((byte *)&ent->ambientLightInt)[1] = Q_ftol( ent->ambientLight[1] ); ((byte *)&ent->ambientLightInt)[2] = Q_ftol( ent->ambientLight[2] ); ((byte *)&ent->ambientLightInt)[3] = 0xff; // transform the direction to local space VectorNormalize( lightDir ); ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] ); ent->lightDir[1] = DotProduct( lightDir, ent->e.axis[1] ); ent->lightDir[2] = DotProduct( lightDir, ent->e.axis[2] ); #endif // VV_LIGHTING }
/* ================= R_SetupEntityLighting Calculates all the lighting values that will be used by the Calc_* functions ================= */ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) { int i; dlight_t *dl; vec3_t dir; float d, modulate; vec3_t lightDir; vec3_t lightOrigin; vec3_t lightValue; byte *entityLight; // lighting calculations if ( ent->lightingCalculated ) { return; } ent->lightingCalculated = qtrue; // // trace a sample point down to find ambient light // if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) { // separate 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 ); } // if NOWORLDMODEL, only use dynamic lights (menu system, etc) if ( tr.world && tr.world->lightGridData && ( !( refdef->rdflags & RDF_NOWORLDMODEL ) || ( ( refdef->rdflags & RDF_NOWORLDMODEL ) && ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) ) ) ) { R_SetupEntityLightingGrid( ent ); } else { //% ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = tr.identityLight * 150; //% ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = tr.identityLight * 150; //% VectorCopy( tr.sunDirection, ent->lightDir ); ent->ambientLight[ 0 ] = tr.identityLight * 64; ent->ambientLight[ 1 ] = tr.identityLight * 64; ent->ambientLight[ 2 ] = tr.identityLight * 96; ent->directedLight[ 0 ] = tr.identityLight * 255; ent->directedLight[ 1 ] = tr.identityLight * 232; ent->directedLight[ 2 ] = tr.identityLight * 224; VectorSet( ent->lightDir, -1, 1, 1.25 ); VectorNormalize( ent->lightDir ); } if ( ent->e.hilightIntensity ) { // level of intensity was set because the item was looked at ent->ambientLight[ 0 ] += tr.identityLight * 128 * ent->e.hilightIntensity; ent->ambientLight[ 1 ] += tr.identityLight * 128 * ent->e.hilightIntensity; ent->ambientLight[ 2 ] += tr.identityLight * 128 * ent->e.hilightIntensity; } else if ( ent->e.renderfx & RF_MINLIGHT ) { // give everything a minimum light add ent->ambientLight[ 0 ] += tr.identityLight * 32; ent->ambientLight[ 1 ] += tr.identityLight * 32; ent->ambientLight[ 2 ] += tr.identityLight * 32; } if ( ent->e.entityNum < MAX_CLIENTS && ( refdef->rdflags & RDF_SNOOPERVIEW ) ) { VectorSet( ent->ambientLight, 245, 245, 245 ); // allow a little room for flicker from directed light } // // modify the light by dynamic lights // d = VectorLength( ent->directedLight ); VectorScale( ent->lightDir, d, lightDir ); for ( i = 0; i < refdef->num_dlights; i++ ) { dl = &refdef->dlights[ i ]; if ( dl->shader ) { //----(SA) if the dlight has a diff shader specified, you don't know what it does, so don't let it affect entities lighting continue; } #if 0 VectorSubtract( dl->origin, lightOrigin, dir ); d = VectorNormalize( dir ); modulate = DLIGHT_AT_RADIUS * ( dl->radius * dl->radius ); if ( d < DLIGHT_MINIMUM_RADIUS ) { d = DLIGHT_MINIMUM_RADIUS; } modulate = modulate / ( d * d ); #else // directional dlight, origin is a directional normal if ( dl->flags & REF_DIRECTED_DLIGHT ) { modulate = dl->intensity * 255.0; VectorCopy( dl->origin, dir ); } // ball dlight else { VectorSubtract( dl->origin, lightOrigin, dir ); d = dl->radius - VectorNormalize( dir ); if ( d <= 0.0 ) { modulate = 0; } else { modulate = dl->intensity * d; } } #endif VectorMA( ent->directedLight, modulate, dl->color, ent->directedLight ); VectorMA( lightDir, modulate, dir, lightDir ); } // clamp ambient for ( i = 0; i < 3; i++ ) { if ( ent->ambientLight[ i ] > tr.identityLightByte ) { ent->ambientLight[ i ] = tr.identityLightByte; } } if ( r_debugLight->integer ) { LogLight( ent ); } // ydnar: test code //% VectorClear( ent->ambientLight ); // save out the byte packet version ( ( byte * ) &ent->ambientLightInt ) [ 0 ] = ri.ftol( ent->ambientLight[ 0 ] ); ( ( byte * ) &ent->ambientLightInt ) [ 1 ] = ri.ftol( ent->ambientLight[ 1 ] ); ( ( byte * ) &ent->ambientLightInt ) [ 2 ] = ri.ftol( ent->ambientLight[ 2 ] ); ( ( byte * ) &ent->ambientLightInt ) [ 3 ] = 0xff; // ydnar: save out the light table d = 0.0f; entityLight = ( byte * ) ent->entityLightInt; modulate = 1.0f / ( ENTITY_LIGHT_STEPS - 1 ); for ( i = 0; i < ENTITY_LIGHT_STEPS; i++ ) { VectorMA( ent->ambientLight, d, ent->directedLight, lightValue ); entityLight[ 0 ] = lightValue[ 0 ] > 255.0f ? 255 : ri.ftol( lightValue[ 0 ] ); entityLight[ 1 ] = lightValue[ 1 ] > 255.0f ? 255 : ri.ftol( lightValue[ 1 ] ); entityLight[ 2 ] = lightValue[ 2 ] > 255.0f ? 255 : ri.ftol( lightValue[ 2 ] ); entityLight[ 3 ] = 0xFF; d += modulate; entityLight += 4; } // ydnar: test code //% VectorSet( lightDir, 0, 0, 1 ); // transform the direction to local space VectorNormalize( lightDir ); ent->lightDir[ 0 ] = DotProduct( lightDir, ent->e.axis[ 0 ] ); ent->lightDir[ 1 ] = DotProduct( lightDir, ent->e.axis[ 1 ] ); ent->lightDir[ 2 ] = DotProduct( lightDir, ent->e.axis[ 2 ] ); // ydnar: renormalize if necessary if ( ent->e.nonNormalizedAxes ) { VectorNormalize( ent->lightDir ); } }
/* ================= R_SetupEntityLighting Calculates all the lighting values that will be used by the Calc_* functions ================= */ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) { int i; dlight_t *dl; float modulate; vec3_t dir; float d; vec3_t lightDir; vec3_t lightOrigin; // lighting calculations if ( ent->lightingCalculated ) { return; } ent->lightingCalculated = qtrue; // // trace a sample point down to find ambient light // 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 ); } // if NOWORLDMODEL, only use dynamic lights (menu system, etc) if ( !(refdef->rdflags & RDF_NOWORLDMODEL ) && tr.world->lightGridData ) { R_SetupEntityLightingGrid( ent ); } else { ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = tr.identityLight * 150; ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = tr.identityLight * 150; VectorCopy( tr.sunDirection, ent->lightDir ); } // only use ambient light from refent if ( ent->e.renderfx & RF_CONST_AMBIENT ) { VectorClear( ent->ambientLight ); } // add ambient light from refent for ( i = 0; i < 3; i++ ) { ent->ambientLight[i] += tr.identityLight * Com_Clamp( -255, 255, ent->e.ambientLight[i] ); if ( ent->ambientLight[i] < 0 ) { ent->ambientLight[i] = 0; } } if ( ent->e.renderfx & RF_NO_DIRECTED_LIGHT ) { VectorClear( ent->directedLight ); VectorClear( lightDir ); } else { // // modify the light by dynamic lights // d = VectorLength( ent->directedLight ); VectorScale( ent->lightDir, d, lightDir ); for ( i = 0 ; i < refdef->num_dlights ; i++ ) { dl = &refdef->dlights[i]; if ( !( dl->flags & REF_GRID_DLIGHT ) ) { continue; } // directional dlight, origin is a directional normal if ( dl->flags & REF_DIRECTED_DLIGHT ) { modulate = dl->intensity * 255.0; VectorCopy( dl->origin, dir ); } // ET dlight else if ( dl->flags & REF_VERTEX_DLIGHT ) { VectorSubtract( dl->origin, lightOrigin, dir ); d = dl->radius - VectorNormalize( dir ); if ( d <= 0.0 ) { modulate = 0; } else { modulate = dl->intensity * d; } } // Q3 dlight else { VectorSubtract( dl->origin, lightOrigin, dir ); d = VectorNormalize( dir ); modulate = DLIGHT_AT_RADIUS * ( dl->radius * dl->radius ); if ( d < DLIGHT_MINIMUM_RADIUS ) { d = DLIGHT_MINIMUM_RADIUS; } modulate = modulate / ( d * d ) * dl->intensity; } VectorMA( ent->directedLight, modulate, dl->color, ent->directedLight ); VectorMA( lightDir, modulate, dir, lightDir ); } } // clamp ambient for ( i = 0 ; i < 3 ; i++ ) { if ( ent->ambientLight[i] > tr.identityLightByte ) { ent->ambientLight[i] = tr.identityLightByte; } } if ( r_debugLight->integer ) { LogLight( ent ); } // save out the byte packet version ((byte *)&ent->ambientLightInt)[0] = ri.ftol(ent->ambientLight[0]); ((byte *)&ent->ambientLightInt)[1] = ri.ftol(ent->ambientLight[1]); ((byte *)&ent->ambientLightInt)[2] = ri.ftol(ent->ambientLight[2]); ((byte *)&ent->ambientLightInt)[3] = 0xff; // transform the direction to local space VectorNormalize( lightDir ); ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] ); ent->lightDir[1] = DotProduct( lightDir, ent->e.axis[1] ); ent->lightDir[2] = DotProduct( lightDir, ent->e.axis[2] ); }