From 0955d04426a7cedc535c6a166bfaedec3d078bf3 Mon Sep 17 00:00:00 2001 From: Shpoike Date: Sat, 25 Sep 2021 02:18:23 +0100 Subject: [PATCH] Revert the lavaman 'fix' as it caused all sorts of other issues. Instead use QS's traceline logic when extensions are disabled, to ensure compatible behaviour. Its not automatic though, which sucks. --- Quake/world.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 139 insertions(+), 7 deletions(-) diff --git a/Quake/world.c b/Quake/world.c index 8c631215..19814c26 100644 --- a/Quake/world.c +++ b/Quake/world.c @@ -677,6 +677,7 @@ reenter: } else { + trace->allsolid = false; if (num == CONTENTS_EMPTY) trace->inopen = true; else if (num != CONTENTS_SOLID) @@ -737,7 +738,6 @@ reenter: rht = Q1BSP_RecursiveHullTrace(ctx, node->children[side], p1f, midf, p1, mid, trace); if (rht != rht_empty && !trace->allsolid) return rht; - trace->allsolid = false; rht = Q1BSP_RecursiveHullTrace(ctx, node->children[side^1], midf, p2f, mid, p2, trace); if (rht != rht_solid) return rht; @@ -769,6 +769,140 @@ reenter: return rht_impact; } + +qboolean SV_SlowRecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace) +{ + mclipnode_t *node; //johnfitz -- was dclipnode_t + mplane_t *plane; + float t1, t2; + float frac; + int i; + vec3_t mid; + int side; + float midf; + +// check for empty + if (num < 0) + { + if (num != CONTENTS_SOLID) + { + trace->allsolid = false; + if (num == CONTENTS_EMPTY) + trace->inopen = true; + else + trace->inwater = true; + } + else + trace->startsolid = true; + return true; // empty + } + + if (num < hull->firstclipnode || num > hull->lastclipnode) + Sys_Error ("SV_RecursiveHullCheck: bad node number"); + +// +// find the point distances +// + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + if (plane->type < 3) + { + t1 = p1[plane->type] - plane->dist; + t2 = p2[plane->type] - plane->dist; + } + else + { + t1 = DoublePrecisionDotProduct (plane->normal, p1) - plane->dist; + t2 = DoublePrecisionDotProduct (plane->normal, p2) - plane->dist; + } + +#if 1 + if (t1 >= 0 && t2 >= 0) + return SV_SlowRecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); + if (t1 < 0 && t2 < 0) + return SV_SlowRecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace); +#else + if ( (t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0) ) + return SV_SlowRecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); + if ( (t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0) ) + return SV_SlowRecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace); +#endif + +// put the crosspoint DIST_EPSILON pixels on the near side + if (t1 < 0) + frac = (t1 + DIST_EPSILON)/(t1-t2); + else + frac = (t1 - DIST_EPSILON)/(t1-t2); + if (frac < 0) + frac = 0; + if (frac > 1) + frac = 1; + + midf = p1f + (p2f - p1f)*frac; + for (i=0 ; i<3 ; i++) + mid[i] = p1[i] + frac*(p2[i] - p1[i]); + + side = (t1 < 0); + +// move up to the node + if (!SV_SlowRecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) ) + return false; + +#ifdef PARANOID + if (SV_HullPointContents (sv_hullmodel, mid, node->children[side]) + == CONTENTS_SOLID) + { + Con_Printf ("mid PointInHullSolid\n"); + return false; + } +#endif + + if (SV_HullPointContents (hull, node->children[side^1], mid) + != CONTENTS_SOLID) +// go past the node + return SV_SlowRecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace); + + if (trace->allsolid) + return false; // never got out of the solid area + +//================== +// the other side of the node is solid, this is the impact point +//================== + if (!side) + { + VectorCopy (plane->normal, trace->plane.normal); + trace->plane.dist = plane->dist; + } + else + { + VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); + trace->plane.dist = -plane->dist; + } + + while (SV_HullPointContents (hull, hull->firstclipnode, mid) + == CONTENTS_SOLID) + { // shouldn't really happen, but does occasionally + frac -= 0.1; + if (frac < 0) + { + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + Con_DPrintf ("backup past 0\n"); + return false; + } + midf = p1f + (p2f - p1f)*frac; + for (i=0 ; i<3 ; i++) + mid[i] = p1[i] + frac*(p2[i] - p1[i]); + } + + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + + return false; +} + + /* ================== SV_RecursiveHullCheck @@ -778,7 +912,9 @@ Decides if its a simple point test, or does a slightly more expensive check. */ qboolean SV_RecursiveHullCheck (hull_t *hull, vec3_t p1, vec3_t p2, trace_t *trace, unsigned int hitcontents) { - if (p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2]) + if (!pr_checkextension.value) + return SV_SlowRecursiveHullCheck (hull, hull->firstclipnode, 0, 1, p1, p2, trace); + else if (p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2]) { /*points cannot cross planes, so do it faster*/ int c = SV_HullPointContents(hull, hull->firstclipnode, p1); @@ -797,17 +933,13 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, vec3_t p1, vec3_t p2, trace_t *tra } else { - qboolean ret; struct rhtctx_s ctx; VectorCopy(p1, ctx.start); VectorCopy(p2, ctx.end); ctx.clipnodes = hull->clipnodes; ctx.planes = hull->planes; ctx.hitcontents = hitcontents; - ret = Q1BSP_RecursiveHullTrace(&ctx, hull->firstclipnode, 0, 1, p1, p2, trace) != rht_impact; - if (!trace->startsolid) - trace->allsolid = false; - return ret; + return Q1BSP_RecursiveHullTrace(&ctx, hull->firstclipnode, 0, 1, p1, p2, trace) != rht_impact; } }