From 1d3774a9e05ef756700f38b5a516c239953226e9 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 19 Jun 2016 15:38:09 -0600 Subject: [PATCH] light: make DirtTrace take dir / dist instead of endpoint to reduce VectorNormalize calls --- include/light/light.h | 4 ++-- light/ltface.c | 27 +++++++++++++-------------- light/trace.c | 17 +++++++++-------- light/trace_embree.cc | 12 ++++-------- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/include/light/light.h b/include/light/light.h index 5acde4e8..90d7c667 100644 --- a/include/light/light.h +++ b/include/light/light.h @@ -42,12 +42,12 @@ extern "C" { */ qboolean TestSky(const vec3_t start, const vec3_t dirn, const dmodel_t *self); qboolean TestLight(const vec3_t start, const vec3_t stop, const dmodel_t *self); -qboolean DirtTrace(const vec3_t start, const vec3_t stop, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out); +qboolean DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out); void Embree_TraceInit(const bsp2_t *bsp); qboolean Embree_TestSky(const vec3_t start, const vec3_t dirn, const dmodel_t *self); qboolean Embree_TestLight(const vec3_t start, const vec3_t stop, const dmodel_t *self); -qboolean Embree_DirtTrace(const vec3_t start, const vec3_t stop, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out); +qboolean Embree_DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out); int SampleTexture(const bsp2_dface_t *face, const bsp2_t *bsp, const vec3_t point); diff --git a/light/ltface.c b/light/ltface.c index c1263ccb..c4d1669a 100644 --- a/light/ltface.c +++ b/light/ltface.c @@ -607,7 +607,15 @@ CheckObstructed(const lightsurf_t *surf, const vec3_t offset, const vec_t us, co const dmodel_t *selfshadow = (surf->modelinfo->shadowself) ? surf->modelinfo->model : NULL; - if (DirtTrace(surf->midpoint, testpoint, selfshadow, hitpoint, &hitplane, NULL)) { + vec3_t dirn; + VectorSubtract(testpoint, surf->midpoint, dirn); + vec_t dist = VectorNormalize(dirn); + if (dist == 0.0f) { + continue; // testpoint == surf->midpoint + } + + // trace from surf->midpoint to testpoint + if (DirtTrace(surf->midpoint, dirn, dist, selfshadow, hitpoint, &hitplane, NULL)) { // make a corrected point vec3_t tracedir; @@ -1824,7 +1832,7 @@ DirtForSample(const dmodel_t *model, const vec3_t origin, const vec3_t normal){ int i; float gatherDirt, angle, elevation, ooDepth; vec3_t worldUp, myUp, myRt, temp, direction, displacement; - vec3_t traceEnd, traceHitpoint; + vec3_t traceHitpoint; /* dummy check */ if ( !dirty.value ) { @@ -1868,11 +1876,8 @@ DirtForSample(const dmodel_t *model, const vec3_t origin, const vec3_t normal){ direction[ 1 ] = myRt[ 1 ] * temp[ 0 ] + myUp[ 1 ] * temp[ 1 ] + normal[ 1 ] * temp[ 2 ]; direction[ 2 ] = myRt[ 2 ] * temp[ 0 ] + myUp[ 2 ] * temp[ 1 ] + normal[ 2 ] * temp[ 2 ]; - /* set endpoint */ - VectorMA( origin, dirtDepth.value, direction, traceEnd ); - /* trace */ - if (DirtTrace(origin, traceEnd, model, traceHitpoint, NULL, NULL)) { + if (DirtTrace(origin, direction, dirtDepth.value, model, traceHitpoint, NULL, NULL)) { VectorSubtract( traceHitpoint, origin, displacement ); gatherDirt += 1.0f - ooDepth * VectorLength( displacement ); } @@ -1885,22 +1890,16 @@ DirtForSample(const dmodel_t *model, const vec3_t origin, const vec3_t normal){ direction[ 1 ] = myRt[ 1 ] * dirtVectors[ i ][ 0 ] + myUp[ 1 ] * dirtVectors[ i ][ 1 ] + normal[ 1 ] * dirtVectors[ i ][ 2 ]; direction[ 2 ] = myRt[ 2 ] * dirtVectors[ i ][ 0 ] + myUp[ 2 ] * dirtVectors[ i ][ 1 ] + normal[ 2 ] * dirtVectors[ i ][ 2 ]; - /* set endpoint */ - VectorMA( origin, dirtDepth.value, direction, traceEnd ); - /* trace */ - if (DirtTrace(origin, traceEnd, model, traceHitpoint, NULL, NULL)) { + if (DirtTrace(origin, direction, dirtDepth.value, model, traceHitpoint, NULL, NULL)) { VectorSubtract( traceHitpoint, origin, displacement ); gatherDirt += 1.0f - ooDepth * VectorLength( displacement ); } } } - - /* direct ray */ - VectorMA( origin, dirtDepth.value, normal, traceEnd ); /* trace */ - if (DirtTrace(origin, traceEnd, model, traceHitpoint, NULL, NULL)) { + if (DirtTrace(origin, direction, dirtDepth.value, model, traceHitpoint, NULL, NULL)) { VectorSubtract( traceHitpoint, origin, displacement ); gatherDirt += 1.0f - ooDepth * VectorLength( displacement ); } diff --git a/light/trace.c b/light/trace.c index f3f78735..607a4eaf 100644 --- a/light/trace.c +++ b/light/trace.c @@ -659,13 +659,13 @@ BSP_TestSky(const vec3_t start, const vec3_t dirn, const dmodel_t *self) * ============ */ qboolean -BSP_DirtTrace(const vec3_t start, const vec3_t stop, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out) +BSP_DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out) { - const modelinfo_t *const *model; + vec3_t stop; + VectorMA(start, dist, dirn, stop); + traceinfo_t ti = {0}; - - VectorSubtract(stop, start, ti.dir); - VectorNormalize(ti.dir); + VectorCopy(dirn, ti.dir); if (self) { if (TraceFaces (&ti, self->headnode[0], start, stop)) { @@ -681,6 +681,7 @@ BSP_DirtTrace(const vec3_t start, const vec3_t stop, const dmodel_t *self, vec3_ } /* Check against the list of global shadow casters */ + const modelinfo_t *const *model; for (model = tracelist; *model; model++) { if ((*model)->model == self) continue; @@ -814,15 +815,15 @@ qboolean TestLight(const vec3_t start, const vec3_t stop, const dmodel_t *self) } -qboolean DirtTrace(const vec3_t start, const vec3_t stop, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out) +qboolean DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out) { #ifdef HAVE_EMBREE if (rtbackend == backend_embree) { - return Embree_DirtTrace(start, stop, self, hitpoint_out, hitplane_out, face_out); + return Embree_DirtTrace(start, dirn, dist, self, hitpoint_out, hitplane_out, face_out); } #endif if (rtbackend == backend_bsp) { - return BSP_DirtTrace(start, stop, self, hitpoint_out, hitplane_out, face_out); + return BSP_DirtTrace(start, dirn, dist, self, hitpoint_out, hitplane_out, face_out); } Error("no backend available"); } diff --git a/light/trace_embree.cc b/light/trace_embree.cc index 9e691286..724bb404 100644 --- a/light/trace_embree.cc +++ b/light/trace_embree.cc @@ -289,13 +289,9 @@ qboolean Embree_TestSky(const vec3_t start, const vec3_t dirn, const dmodel_t *s } //public -qboolean Embree_DirtTrace(const vec3_t start, const vec3_t stop, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out) +qboolean Embree_DirtTrace(const vec3_t start, const vec3_t dirn, vec_t dist, const dmodel_t *self, vec3_t hitpoint_out, plane_t *hitplane_out, const bsp2_dface_t **face_out) { - vec3_t dir; - VectorSubtract(stop, start, dir); - const vec_t dist = VectorNormalize(dir); - - RTCRay ray = SetupRay(start, dir, dist, self); + RTCRay ray = SetupRay(start, dirn, dist, self); rtcIntersect(scene, ray); if (ray.geomID == RTC_INVALID_GEOMETRY_ID @@ -304,7 +300,7 @@ qboolean Embree_DirtTrace(const vec3_t start, const vec3_t stop, const dmodel_t // compute hitpoint_out if (hitpoint_out) { - VectorMA(start, ray.tfar, dir, hitpoint_out); + VectorMA(start, ray.tfar, dirn, hitpoint_out); } if (hitplane_out) { for (int i=0; i<3; i++) { @@ -313,7 +309,7 @@ qboolean Embree_DirtTrace(const vec3_t start, const vec3_t stop, const dmodel_t VectorNormalize(hitplane_out->normal); vec3_t hitpoint; - VectorMA(start, ray.tfar, dir, hitpoint); + VectorMA(start, ray.tfar, dirn, hitpoint); hitplane_out->dist = DotProduct(hitplane_out->normal, hitpoint); }