diff --git a/utils/pxrad/lightmap.cpp b/utils/pxrad/lightmap.cpp index b3ca2535..b7b04cc4 100644 --- a/utils/pxrad/lightmap.cpp +++ b/utils/pxrad/lightmap.cpp @@ -2813,6 +2813,7 @@ vec3_t *s_light, vec3_t *s_dir, vec_t *s_occ, byte *styles, byte *vislight, bool { vec_t sightarea; vec_t ratio2, frac; + vec3_t sightareadirection; // do things slow if( light_behind_surface ) @@ -2822,7 +2823,8 @@ vec3_t *s_light, vec3_t *s_dir, vec_t *s_occ, byte *styles, byte *vislight, bool } GetAlternateOrigin( *pos, n, dl->patch, testline_origin ); - sightarea = CalcSightArea( *pos, n, dl->patch->winding, dl->patch->emitter_skylevel ); + + sightarea = CalcSightArea( *pos, n, dl->patch->winding, dl->patch->emitter_skylevel, &sightareadirection ); frac = dist / range; frac = ( frac - 0.5 ) * 2.0; // make a smooth transition between the two methods @@ -2830,6 +2832,8 @@ vec3_t *s_light, vec3_t *s_dir, vec_t *s_occ, byte *styles, byte *vislight, bool // because dl->patch_area has been multiplied into dl->intensity ratio2 = (sightarea / dl->patch_area); ratio = frac * ratio + (1.0 - frac) * ratio2; + + VectorLerp( sightareadirection, frac, direction, direction ); } else if( light_behind_surface ) { diff --git a/utils/pxrad/qrad.cpp b/utils/pxrad/qrad.cpp index de63136e..8690adc5 100644 --- a/utils/pxrad/qrad.cpp +++ b/utils/pxrad/qrad.cpp @@ -591,7 +591,7 @@ vec_t CalcFaceSolidAngle( dface_t *f, const vec3_t origin ) // ===================================================================================== // CalcSightArea // ===================================================================================== -vec_t CalcSightArea( const vec3_t receiver_origin, const vec3_t receiver_normal, const winding_t *emitter_winding, int skylevel ) +vec_t CalcSightArea( const vec3_t receiver_origin, const vec3_t receiver_normal, const winding_t *emitter_winding, int skylevel, vec3_t* avg_direction ) { // maybe there are faster ways in calculating the weighted area, but at least this way is not bad. int numedges = emitter_winding->numpoints; @@ -600,6 +600,7 @@ vec_t CalcSightArea( const vec3_t receiver_origin, const vec3_t receiver_normal, vec_t dot; vec_t area = 0.0f; int i, j, x; + vec3_t avg_dir = {0,0,0}; for( x = 0; x < numedges; x++ ) { @@ -634,11 +635,20 @@ vec_t CalcSightArea( const vec3_t receiver_origin, const vec3_t receiver_normal, if( j < numedges ) continue; area += dot; + + VectorMA( avg_dir, dot, *pnormal, avg_dir ); + } + + if( avg_direction ) + { + if( area > 0.0f ) + VectorScale( avg_dir, 1.0f / area, avg_dir ); + VectorCopy( avg_dir, *avg_direction ); } area /= (float)i; - area = area * 4.0 * M_PI; // convert to absolute sphere area + area = area * 4.0f * M_PI; // convert to absolute sphere area Mem_Free( edges ); return area; diff --git a/utils/pxrad/qrad.h b/utils/pxrad/qrad.h index 90028ba0..ea31adee 100644 --- a/utils/pxrad/qrad.h +++ b/utils/pxrad/qrad.h @@ -474,7 +474,7 @@ float GatherSampleDirt( int threadnum, int fn, const vec3_t pos, const vec3_t no const dplane_t *GetPlaneFromFace( const dface_t *face ); const dplane_t *GetPlaneFromFace( const uint facenum ); dleaf_t *HuntForWorld( vec3_t point, const vec3_t plane_offset, const dplane_t *plane, int hunt_size, vec_t hunt_scale, vec_t hunt_offset ); -vec_t CalcSightArea( const vec3_t receiver_origin, const vec3_t receiver_normal, const winding_t *emitter_winding, int skylevel ); +vec_t CalcSightArea( const vec3_t receiver_origin, const vec3_t receiver_normal, const winding_t *emitter_winding, int skylevel, vec3_t* avg_direction = NULL ); void GetAlternateOrigin( const vec3_t pos, const vec3_t normal, const patch_t *patch, vec3_t origin ); vec_t BaseLightForFace( dface_t *f, vec3_t light, vec3_t reflectivity ); void InitWorldLightFromPatch( dworldlight_t *wl, patch_t *p );