From a439f891a1971815ce1357658f89936aafa1b56d Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Thu, 11 Feb 2016 22:38:23 -0700 Subject: [PATCH] CalcPoints: Skip the trace if a PointContents says the point is already unobstructed. Handles beveled walkways in telefragged.bsp which touch a wall along one edge, but don't split the wall. Previously, the walkways were blocking most of the traces for the wall, messing up all of the wall sample points. --- include/light/light.h | 2 ++ light/ltface.c | 37 +++++++++++++++++++++++++++++++++++++ light/trace.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/include/light/light.h b/include/light/light.h index aa075c54..b910dac4 100644 --- a/include/light/light.h +++ b/include/light/light.h @@ -37,6 +37,8 @@ #define TRACE_HIT_LAVA (1 << 3) #define TRACE_HIT_SKY (1 << 4) +int Light_PointContents( const vec3_t point ); + typedef struct { const dplane_t *dplane; int side; diff --git a/light/ltface.c b/light/ltface.c index 8753f649..f4d3d842 100644 --- a/light/ltface.c +++ b/light/ltface.c @@ -284,6 +284,7 @@ TexCoordToWorld(vec_t s, vec_t t, const texorg_t *texorg, vec3_t world) rhs[0] = s - texorg->texinfo->vecs[0][3]; rhs[1] = t - texorg->texinfo->vecs[1][3]; + // FIXME: This could be more or less than one unit in world space? rhs[2] = texorg->planedist + 1; /* one "unit" in front of surface */ Solve3(&texorg->transform, rhs, world); @@ -446,6 +447,35 @@ WarnBadMidpoint(const vec3_t point) #endif } +/* + * ================= + * NearWall + * + * returns true if any of the 6 points up/down/left/right/front/back + * within 0.1 units of 'point' are in CONTENTS_SOLID + * ================= + */ +bool NearWall(const vec3_t point) +{ + int i; + int insolid = 0; + + for (i = 0; i < 6; i++) { + vec3_t testpoint; + VectorCopy(point, testpoint); + + int axis = i/2; + bool add = i%2; + testpoint[axis] += (add ? 0.1 : -0.1); + + if (Light_PointContents(testpoint) == CONTENTS_SOLID) { + insolid++; + } + } + + return insolid > 0; +} + /* * ================= * CalcPoints @@ -486,6 +516,13 @@ CalcPoints(const dmodel_t *model, const vec3_t offset, const texorg_t *texorg, l TexCoordToWorld(us, ut, texorg, point); VectorAdd(point, offset, point); + + // Is the point already unbostructed? Skip doing the traceline. + // There could be an obstruction near the face that would block most of the traces + // (e.g. beveled walkways in telefragged.bsp touch a wall along one edge, but don't split the wall) + if (!NearWall(point)) + continue; // all good + for (i = 0; i < 6; i++) { const int flags = TRACE_HIT_SOLID; tracepoint_t hit; diff --git a/light/trace.c b/light/trace.c index 4e683f09..1bd36130 100644 --- a/light/trace.c +++ b/light/trace.c @@ -33,6 +33,38 @@ static tnode_t *tnodes; static tnode_t *tnode_p; static const bsp2_t *bsp_static; +// from hmap2 +#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist) + +/* +============== +Light_PointInLeaf + +from hmap2 +============== +*/ +bsp2_dleaf_t *Light_PointInLeaf( const vec3_t point ) +{ + int num = 0; + + while( num >= 0 ) + num = bsp_static->dnodes[num].children[PlaneDiff(point, &bsp_static->dplanes[bsp_static->dnodes[num].planenum]) < 0]; + + return bsp_static->dleafs + (-1 - num); +} + +/* +============== +Light_PointContents + +from hmap2 +============== +*/ +int Light_PointContents( const vec3_t point ) +{ + return Light_PointInLeaf(point)->contents; +} + /* * ============== * MakeTnodes