take the hull/line fixes to the server internals and re-merge world.c for

nq and qw. This fixes the corner sticking for everything.
This commit is contained in:
Bill Currie 2001-11-23 18:58:23 +00:00
parent 7cad26038e
commit 4eebbb8ae6
3 changed files with 92 additions and 128 deletions

View file

@ -44,6 +44,7 @@ static const char rcsid[] =
#include "QF/crc.h" #include "QF/crc.h"
#include "QF/sys.h" #include "QF/sys.h"
#include "compat.h"
#include "server.h" #include "server.h"
#include "sv_progs.h" #include "sv_progs.h"
#include "world.h" #include "world.h"
@ -67,9 +68,7 @@ typedef struct {
int SV_HullPointContents (hull_t *hull, int num, vec3_t p); int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
/* /* HULL BOXES */
HULL BOXES
*/
static hull_t box_hull; static hull_t box_hull;
static dclipnode_t box_clipnodes[6]; static dclipnode_t box_clipnodes[6];
@ -85,8 +84,7 @@ static mplane_t box_planes[6];
void void
SV_InitHull (hull_t *hull, dclipnode_t *clipnodes, mplane_t *planes) SV_InitHull (hull_t *hull, dclipnode_t *clipnodes, mplane_t *planes)
{ {
int i; int side, i;
int side;
hull->clipnodes = clipnodes; hull->clipnodes = clipnodes;
hull->planes = planes; hull->planes = planes;
@ -115,7 +113,6 @@ SV_InitBoxHull (void)
SV_InitHull (&box_hull, box_clipnodes, box_planes); SV_InitHull (&box_hull, box_clipnodes, box_planes);
} }
/* /*
SV_HullForBox SV_HullForBox
@ -135,7 +132,6 @@ SV_HullForBox (vec3_t mins, vec3_t maxs)
return &box_hull; return &box_hull;
} }
/* /*
SV_HullForEntity SV_HullForEntity
@ -147,11 +143,10 @@ SV_HullForBox (vec3_t mins, vec3_t maxs)
hull_t * hull_t *
SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset) SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
{ {
model_t *model;
vec3_t size;
vec3_t hullmins, hullmaxs;
hull_t *hull = 0; hull_t *hull = 0;
int hull_index = 0; int hull_index = 0;
model_t *model;
vec3_t hullmins, hullmaxs, size;
if ((sv_fields.rotated_bbox != -1 if ((sv_fields.rotated_bbox != -1
&& SVinteger (ent, rotated_bbox)) && SVinteger (ent, rotated_bbox))
@ -198,21 +193,16 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
return hull; return hull;
} }
/* ENTITY AREA CHECKING */
/*
ENTITY AREA CHECKING
*/
areanode_t sv_areanodes[AREA_NODES]; areanode_t sv_areanodes[AREA_NODES];
int sv_numareanodes; int sv_numareanodes;
areanode_t * areanode_t *
SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs)
{ {
areanode_t *anode; areanode_t *anode;
vec3_t size; vec3_t mins1, maxs1, mins2, maxs2, size;
vec3_t mins1, maxs1, mins2, maxs2;
anode = &sv_areanodes[sv_numareanodes]; anode = &sv_areanodes[sv_numareanodes];
sv_numareanodes++; sv_numareanodes++;
@ -246,7 +236,6 @@ SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs)
return anode; return anode;
} }
void void
SV_ClearWorld (void) SV_ClearWorld (void)
{ {
@ -271,9 +260,9 @@ SV_UnlinkEdict (edict_t *ent)
void void
SV_TouchLinks (edict_t *ent, areanode_t *node) SV_TouchLinks (edict_t *ent, areanode_t *node)
{ {
link_t *l, *next;
edict_t *touch; edict_t *touch;
int old_self, old_other; int old_self, old_other;
link_t *l, *next;
// touch linked edicts // touch linked edicts
for (l = node->trigger_edicts.next; l != &node->trigger_edicts; l = next) { for (l = node->trigger_edicts.next; l != &node->trigger_edicts; l = next) {
@ -318,10 +307,9 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
void void
SV_FindTouchedLeafs (edict_t *ent, mnode_t *node) SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
{ {
mplane_t *splitplane; int leafnum, sides;
mleaf_t *leaf; mleaf_t *leaf;
int sides; mplane_t *splitplane;
int leafnum;
if (node->contents == CONTENTS_SOLID) if (node->contents == CONTENTS_SOLID)
return; return;
@ -352,7 +340,6 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
SV_FindTouchedLeafs (ent, node->children[1]); SV_FindTouchedLeafs (ent, node->children[1]);
} }
void void
SV_LinkEdict (edict_t *ent, qboolean touch_triggers) SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
{ {
@ -422,18 +409,14 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
SV_TouchLinks (ent, sv_areanodes); SV_TouchLinks (ent, sv_areanodes);
} }
/* POINT TESTING IN HULLS */
/*
POINT TESTING IN HULLS
*/
#ifndef USE_INTEL_ASM #ifndef USE_INTEL_ASM
int int
SV_HullPointContents (hull_t *hull, int num, vec3_t p) SV_HullPointContents (hull_t *hull, int num, vec3_t p)
{ {
float d;
dclipnode_t *node; dclipnode_t *node;
float d;
mplane_t *plane; mplane_t *plane;
while (num >= 0) { while (num >= 0) {
@ -457,7 +440,6 @@ SV_HullPointContents (hull_t *hull, int num, vec3_t p)
} }
#endif // !USE_INTEL_ASM #endif // !USE_INTEL_ASM
int int
SV_PointContents (vec3_t p) SV_PointContents (vec3_t p)
{ {
@ -469,14 +451,12 @@ SV_PointContents (vec3_t p)
return cont; return cont;
} }
int int
SV_TruePointContents (vec3_t p) SV_TruePointContents (vec3_t p)
{ {
return SV_HullPointContents (&sv.worldmodel->hulls[0], 0, p); return SV_HullPointContents (&sv.worldmodel->hulls[0], 0, p);
} }
/* /*
SV_TestEntityPosition SV_TestEntityPosition
@ -500,27 +480,20 @@ SV_TestEntityPosition (edict_t *ent)
return NULL; return NULL;
} }
/* LINE TESTING IN HULLS */
/*
LINE TESTING IN HULLS
*/
// 1/32 epsilon to keep floating point happy // 1/32 epsilon to keep floating point happy
#define DIST_EPSILON (0.03125) #define DIST_EPSILON (0.03125)
qboolean qboolean
SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
vec3_t p2, trace_t *trace) vec3_t p2, trace_t *trace)
{ {
dclipnode_t *node; dclipnode_t *node;
float frac, midf, t1, t2;
int side, i;
mplane_t *plane; mplane_t *plane;
float t1, t2;
float frac;
int i;
vec3_t mid; vec3_t mid;
int side;
float midf;
// check for empty // check for empty
if (num < 0) { if (num < 0) {
@ -535,9 +508,6 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
return true; // empty return true; // empty
} }
if (num < hull->firstclipnode || num > hull->lastclipnode)
Sys_Error ("SV_RecursiveHullCheck: bad node number");
// find the point distances // find the point distances
node = hull->clipnodes + num; node = hull->clipnodes + num;
plane = hull->planes + node->planenum; plane = hull->planes + node->planenum;
@ -550,44 +520,28 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
t2 = DotProduct (plane->normal, p2) - plane->dist; t2 = DotProduct (plane->normal, p2) - plane->dist;
} }
#if 1
if (t1 >= 0 && t2 >= 0) if (t1 >= 0 && t2 >= 0)
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
p2, trace); p2, trace);
if (t1 < 0 && t2 < 0) if (t1 < 0 && t2 < 0)
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
p2, trace); p2, trace);
#else
if ((t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0))
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
p2, trace);
if ((t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0))
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
p2, trace);
#endif
// put the crosspoint DIST_EPSILON pixels on the near side side = (t1 < 0);
if (t1 < 0) frac = t1 / (t1 - t2);
frac = (t1 + DIST_EPSILON) / (t1 - t2); //frac = bound (0, frac, 1); // is this needed?
else
frac = (t1 - DIST_EPSILON) / (t1 - t2);
if (frac < 0)
frac = 0;
if (frac > 1)
frac = 1;
midf = p1f + (p2f - p1f) * frac; midf = p1f + (p2f - p1f) * frac;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
mid[i] = p1[i] + frac * (p2[i] - p1[i]); mid[i] = p1[i] + frac * (p2[i] - p1[i]);
side = (t1 < 0);
// move up to the node // move up to the node
if (!SV_RecursiveHullCheck if (!SV_RecursiveHullCheck (hull, node->children[side],
(hull, node->children[side], p1f, midf, p1, mid, trace)) return false; p1f, midf, p1, mid, trace))
return false;
#ifdef PARANOID #ifdef PARANOID
if (SV_HullPointContents (sv_hullmodel, mid, node->children[side]) if (SV_HullPointContents (hull, mid, node->children[side])
== CONTENTS_SOLID) { == CONTENTS_SOLID) {
Con_Printf ("mid PointInHullSolid\n"); Con_Printf ("mid PointInHullSolid\n");
return false; return false;
@ -595,10 +549,11 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
#endif #endif
if (SV_HullPointContents (hull, node->children[side ^ 1], mid) if (SV_HullPointContents (hull, node->children[side ^ 1], mid)
!= CONTENTS_SOLID) != CONTENTS_SOLID) {
// go past the node // go past the node
return SV_RecursiveHullCheck (hull, node->children[side ^ 1], midf, return SV_RecursiveHullCheck (hull, node->children[side ^ 1], midf,
p2f, mid, p2, trace); p2f, mid, p2, trace);
}
if (trace->allsolid) if (trace->allsolid)
return false; // never got out of the solid area return false; // never got out of the solid area
@ -608,13 +563,17 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
VectorCopy (plane->normal, trace->plane.normal); VectorCopy (plane->normal, trace->plane.normal);
trace->plane.dist = plane->dist; trace->plane.dist = plane->dist;
} else { } else {
VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); // invert plane paramterers
trace->plane.normal[0] = -plane->normal[0];
trace->plane.normal[1] = -plane->normal[1];
trace->plane.normal[2] = -plane->normal[2];
trace->plane.dist = -plane->dist; trace->plane.dist = -plane->dist;
} }
#if 0 //XXX I don't think this is needed any more, but leave it in for now
while (SV_HullPointContents (hull, hull->firstclipnode, mid) while (SV_HullPointContents (hull, hull->firstclipnode, mid)
== CONTENTS_SOLID) { // shouldn't really happen, but does == CONTENTS_SOLID) {
// occasionally // shouldn't really happen, but does occasionally
frac -= 0.1; frac -= 0.1;
if (frac < 0) { if (frac < 0) {
trace->fraction = midf; trace->fraction = midf;
@ -626,6 +585,18 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
mid[i] = p1[i] + frac * (p2[i] - p1[i]); mid[i] = p1[i] + frac * (p2[i] - p1[i]);
} }
#endif
// put the crosspoint DIST_EPSILON pixels on the near side to guarantee
// mid is on the correct side of the plane
if (side)
frac = (t1 + DIST_EPSILON) / (t1 - t2);
else
frac = (t1 - DIST_EPSILON) / (t1 - t2);
frac = bound (0, frac, 1);
midf = p1f + (p2f - p1f) * frac;
for (i = 0; i < 3; i++)
mid[i] = p1[i] + frac * (p2[i] - p1[i]);
trace->fraction = midf; trace->fraction = midf;
VectorCopy (mid, trace->endpos); VectorCopy (mid, trace->endpos);
@ -633,7 +604,6 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
return false; return false;
} }
/* /*
SV_ClipMoveToEntity SV_ClipMoveToEntity
@ -644,10 +614,9 @@ trace_t
SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, vec3_t start, SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, vec3_t start,
vec3_t mins, vec3_t maxs, vec3_t end) vec3_t mins, vec3_t maxs, vec3_t end)
{ {
trace_t trace;
vec3_t offset;
vec3_t start_l, end_l;
hull_t *hull; hull_t *hull;
trace_t trace;
vec3_t offset, start_l, end_l;
// fill in a default trace // fill in a default trace
memset (&trace, 0, sizeof (trace_t)); memset (&trace, 0, sizeof (trace_t));
@ -677,7 +646,6 @@ SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, vec3_t start,
return trace; return trace;
} }
/* /*
SV_ClipToLinks SV_ClipToLinks
@ -686,8 +654,8 @@ SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, vec3_t start,
void void
SV_ClipToLinks (areanode_t *node, moveclip_t * clip) SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
{ {
link_t *l, *next;
edict_t *touch; edict_t *touch;
link_t *l, *next;
trace_t trace; trace_t trace;
// touch linked edicts // touch linked edicts
@ -757,7 +725,6 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
SV_ClipToLinks (node->children[1], clip); SV_ClipToLinks (node->children[1], clip);
} }
void void
SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
vec3_t boxmins, vec3_t boxmaxs) vec3_t boxmins, vec3_t boxmaxs)
@ -781,13 +748,12 @@ SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
#endif #endif
} }
trace_t trace_t
SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type,
edict_t *passedict) edict_t *passedict)
{ {
moveclip_t clip;
int i; int i;
moveclip_t clip;
memset (&clip, 0, sizeof (moveclip_t)); memset (&clip, 0, sizeof (moveclip_t));
@ -825,11 +791,10 @@ SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type,
edict_t * edict_t *
SV_TestPlayerPosition (edict_t *ent, vec3_t origin) SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
{ {
hull_t *hull;
edict_t *check; edict_t *check;
vec3_t boxmins, boxmaxs; hull_t *hull;
vec3_t offset;
int e; int e;
vec3_t boxmins, boxmaxs, offset;
// check world first // check world first
hull = &sv.worldmodel->hulls[1]; hull = &sv.worldmodel->hulls[1];
@ -841,7 +806,8 @@ SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
VectorAdd (origin, SVvector (ent, maxs), boxmaxs); VectorAdd (origin, SVvector (ent, maxs), boxmaxs);
check = NEXT_EDICT (&sv_pr_state, sv.edicts); check = NEXT_EDICT (&sv_pr_state, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_pr_state, check)) { for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_pr_state,
check)) {
if (check->free) if (check->free)
continue; continue;
if (check == ent) if (check == ent)

View file

@ -208,8 +208,8 @@ PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
goto loc0; goto loc0;
} }
side = (t1 < 0); side = (t1 < 0);
//frac = bound (0, t1 / (t1 - t2), 1); // use this if below causes probs
frac = t1 / (t1 - t2); frac = t1 / (t1 - t2);
//frac = bound (0, frac, 1); // is this needed?
midf = p1f + (p2f - p1f) * frac; midf = p1f + (p2f - p1f) * frac;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
@ -221,15 +221,15 @@ PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
return false; return false;
#ifdef PARANOID #ifdef PARANOID
if (PM_HullPointContents (pm_hullmodel, mid, node->children[side]) == if (PM_HullPointContents (hull, mid, node->children[side])
CONTENTS_SOLID) { == CONTENTS_SOLID) {
Con_Printf ("mid PointInHullSolid\n"); Con_Printf ("mid PointInHullSolid\n");
return false; return false;
} }
#endif #endif
if (PM_HullPointContents (hull, node->children[side ^ 1], if (PM_HullPointContents (hull, node->children[side ^ 1], mid)
mid) != CONTENTS_SOLID) { != CONTENTS_SOLID) {
// go past the node // go past the node
return PM_RecursiveHullCheck (hull, node->children[side ^ 1], midf, return PM_RecursiveHullCheck (hull, node->children[side ^ 1], midf,
p2f, mid, p2, trace); p2f, mid, p2, trace);
@ -238,9 +238,7 @@ PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
if (trace->allsolid) if (trace->allsolid)
return false; // never got out of the solid area return false; // never got out of the solid area
//==================
// the other side of the node is solid, this is the impact point // the other side of the node is solid, this is the impact point
//==================
if (!side) { if (!side) {
VectorCopy (plane->normal, trace->plane.normal); VectorCopy (plane->normal, trace->plane.normal);
trace->plane.dist = plane->dist; trace->plane.dist = plane->dist;
@ -253,8 +251,8 @@ PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
} }
#if 0 //XXX I don't think this is needed any more, but leave it in for now #if 0 //XXX I don't think this is needed any more, but leave it in for now
while (PM_HullPointContents (hull, hull->firstclipnode, while (PM_HullPointContents (hull, hull->firstclipnode, mid)
mid) == CONTENTS_SOLID) { == CONTENTS_SOLID) {
// shouldn't really happen, but does occasionally // shouldn't really happen, but does occasionally
frac -= 0.1; frac -= 0.1;
if (frac < 0) { if (frac < 0) {
@ -271,9 +269,10 @@ PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
// put the crosspoint DIST_EPSILON pixels on the near side to guarantee // put the crosspoint DIST_EPSILON pixels on the near side to guarantee
// mid is on the correct side of the plane // mid is on the correct side of the plane
if (side) if (side)
frac = bound (0, (t1 + DIST_EPSILON) / (t1 - t2), 1); frac = (t1 + DIST_EPSILON) / (t1 - t2);
else else
frac = bound (0, (t1 - DIST_EPSILON) / (t1 - t2), 1); frac = (t1 - DIST_EPSILON) / (t1 - t2);
frac = bound (0, frac, 1);
midf = p1f + (p2f - p1f) * frac; midf = p1f + (p2f - p1f) * frac;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)

View file

@ -43,6 +43,7 @@ static const char rcsid[] =
#include "QF/console.h" #include "QF/console.h"
#include "QF/crc.h" #include "QF/crc.h"
#include "compat.h"
#include "server.h" #include "server.h"
#include "sv_progs.h" #include "sv_progs.h"
#include "world.h" #include "world.h"
@ -414,8 +415,8 @@ int
SV_HullPointContents (hull_t *hull, int num, vec3_t p) SV_HullPointContents (hull_t *hull, int num, vec3_t p)
{ {
dclipnode_t *node; dclipnode_t *node;
float d; float d;
mplane_t *plane; mplane_t *plane;
while (num >= 0) { while (num >= 0) {
if (num < hull->firstclipnode || num > hull->lastclipnode) if (num < hull->firstclipnode || num > hull->lastclipnode)
@ -506,9 +507,6 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
return true; // empty return true; // empty
} }
if (num < hull->firstclipnode || num > hull->lastclipnode)
SV_Error ("SV_RecursiveHullCheck: bad node number");
// find the point distances // find the point distances
node = hull->clipnodes + num; node = hull->clipnodes + num;
plane = hull->planes + node->planenum; plane = hull->planes + node->planenum;
@ -521,44 +519,28 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
t2 = DotProduct (plane->normal, p2) - plane->dist; t2 = DotProduct (plane->normal, p2) - plane->dist;
} }
#if 1
if (t1 >= 0 && t2 >= 0) if (t1 >= 0 && t2 >= 0)
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
p2, trace); p2, trace);
if (t1 < 0 && t2 < 0) if (t1 < 0 && t2 < 0)
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
p2, trace); p2, trace);
#else
if ((t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0))
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
p2, trace);
if ((t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0))
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
p2, trace);
#endif
// put the crosspoint DIST_EPSILON pixels on the near side side = (t1 < 0);
if (t1 < 0) frac = t1 / (t1 - t2);
frac = (t1 + DIST_EPSILON) / (t1 - t2); //frac = bound (0, frac, 1); // is this needed?
else
frac = (t1 - DIST_EPSILON) / (t1 - t2);
if (frac < 0)
frac = 0;
if (frac > 1)
frac = 1;
midf = p1f + (p2f - p1f) * frac; midf = p1f + (p2f - p1f) * frac;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
mid[i] = p1[i] + frac * (p2[i] - p1[i]); mid[i] = p1[i] + frac * (p2[i] - p1[i]);
side = (t1 < 0);
// move up to the node // move up to the node
if (!SV_RecursiveHullCheck if (!SV_RecursiveHullCheck (hull, node->children[side],
(hull, node->children[side], p1f, midf, p1, mid, trace)) return false; p1f, midf, p1, mid, trace))
return false;
#ifdef PARANOID #ifdef PARANOID
if (SV_HullPointContents (sv_hullmodel, mid, node->children[side]) if (SV_HullPointContents (hull, mid, node->children[side])
== CONTENTS_SOLID) { == CONTENTS_SOLID) {
SV_Printf ("mid PointInHullSolid\n"); SV_Printf ("mid PointInHullSolid\n");
return false; return false;
@ -566,10 +548,11 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
#endif #endif
if (SV_HullPointContents (hull, node->children[side ^ 1], mid) if (SV_HullPointContents (hull, node->children[side ^ 1], mid)
!= CONTENTS_SOLID) != CONTENTS_SOLID) {
// go past the node // go past the node
return SV_RecursiveHullCheck (hull, node->children[side ^ 1], midf, return SV_RecursiveHullCheck (hull, node->children[side ^ 1], midf,
p2f, mid, p2, trace); p2f, mid, p2, trace);
}
if (trace->allsolid) if (trace->allsolid)
return false; // never got out of the solid area return false; // never got out of the solid area
@ -579,13 +562,17 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
VectorCopy (plane->normal, trace->plane.normal); VectorCopy (plane->normal, trace->plane.normal);
trace->plane.dist = plane->dist; trace->plane.dist = plane->dist;
} else { } else {
VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); // invert plane paramterers
trace->plane.normal[0] = -plane->normal[0];
trace->plane.normal[1] = -plane->normal[1];
trace->plane.normal[2] = -plane->normal[2];
trace->plane.dist = -plane->dist; trace->plane.dist = -plane->dist;
} }
#if 0 //XXX I don't think this is needed any more, but leave it in for now
while (SV_HullPointContents (hull, hull->firstclipnode, mid) while (SV_HullPointContents (hull, hull->firstclipnode, mid)
== CONTENTS_SOLID) { // shouldn't really happen, but does == CONTENTS_SOLID) {
// occasionally // shouldn't really happen, but does occasionally
frac -= 0.1; frac -= 0.1;
if (frac < 0) { if (frac < 0) {
trace->fraction = midf; trace->fraction = midf;
@ -597,6 +584,18 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
mid[i] = p1[i] + frac * (p2[i] - p1[i]); mid[i] = p1[i] + frac * (p2[i] - p1[i]);
} }
#endif
// put the crosspoint DIST_EPSILON pixels on the near side to guarantee
// mid is on the correct side of the plane
if (side)
frac = (t1 + DIST_EPSILON) / (t1 - t2);
else
frac = (t1 - DIST_EPSILON) / (t1 - t2);
frac = bound (0, frac, 1);
midf = p1f + (p2f - p1f) * frac;
for (i = 0; i < 3; i++)
mid[i] = p1[i] + frac * (p2[i] - p1[i]);
trace->fraction = midf; trace->fraction = midf;
VectorCopy (mid, trace->endpos); VectorCopy (mid, trace->endpos);