diff --git a/include/world.h b/include/world.h index 8366741ea..1a92a7f97 100644 --- a/include/world.h +++ b/include/world.h @@ -55,8 +55,7 @@ typedef struct trace_s #define MOVE_NOMONSTERS 1 #define MOVE_MISSILE 2 -typedef struct areanode_s -{ +typedef struct areanode_s { int axis; // -1 = leaf node float dist; struct areanode_s *children[2]; @@ -116,5 +115,7 @@ hull_t *SV_HullForEntity (struct edict_s *ent, const vec3_t mins, qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2, trace_t *trace); +qboolean MOD_TraceLine (hull_t *hull, int num, + const vec3_t start, const vec3_t end, trace_t *trace); #endif // __world_h diff --git a/libs/models/Makefile.am b/libs/models/Makefile.am index e85bf9caa..cf6a1d374 100644 --- a/libs/models/Makefile.am +++ b/libs/models/Makefile.am @@ -8,7 +8,7 @@ lib_LTLIBRARIES= libQFmodels.la @VID_MODEL_TARGETS@ EXTRA_LTLIBRARIES= \ libQFmodels_gl.la libQFmodels_sw.la -models_sources = clip_hull.c model.c +models_sources = clip_hull.c model.c trace.c libQFmodels_la_LDFLAGS= -version-info 1:0:0 -no-undefined libQFmodels_la_LIBADD= brush/libbrush.la $(top_builddir)/libs/util/libQFutil.la diff --git a/libs/models/trace.c b/libs/models/trace.c new file mode 100644 index 000000000..f4c2287d3 --- /dev/null +++ b/libs/models/trace.c @@ -0,0 +1,189 @@ +/* + trace.c + + BSP line tracing + + Copyright (C) 2004 Bill Currie + + Author: Bill Currie + Date: 2004/9/25 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((unused)) const char rcsid[] = + "$Id$"; + +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include "QF/model.h" + +#include "compat.h" +#include "world.h" + +/* LINE TESTING IN HULLS */ + +// 1/32 epsilon to keep floating point happy +#define DIST_EPSILON (0.03125) + +typedef struct { + vec3_t backpt; + int side; + int num; + mplane_t *plane; +} tracestack_t; + +static inline void +calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, + mplane_t *plane) +{ + vec_t t1, t2, frac; + int i, side; + + if (plane->type < 3) { + t1 = start[plane->type] - plane->dist; + t2 = end[plane->type] - plane->dist; + } else { + t1 = DotProduct (plane->normal, start) - plane->dist; + t2 = DotProduct (plane->normal, end) - plane->dist; + } + + side = t1 < 0; + if (side) { + frac = (t1 + DIST_EPSILON) / (t1 - t2); + // 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; + } else { + frac = (t1 - DIST_EPSILON) / (t1 - t2); + VectorCopy (plane->normal, trace->plane.normal); + trace->plane.dist = plane->dist; + } + frac = bound (0, frac, 1); + trace->fraction = frac; + for (i = 0; i < 3; i++) + trace->endpos[i] = start[i] + frac * (end[i] - start[i]); +} + +qboolean +MOD_TraceLine (hull_t *hull, int num, const vec3_t start, const vec3_t end, + trace_t *trace) +{ + vec_t front, back; + vec3_t frontpt, backpt; + int side, empty, solid; + tracestack_t *tstack; + tracestack_t tracestack[256]; + dclipnode_t *node; + mplane_t *plane, *split_plane; + + VectorCopy (start, frontpt); + VectorCopy (end, backpt); + + tstack = tracestack; + empty = 0; + solid = 0; + split_plane = 0; + + while (1) { + while (num < 0) { + if (!solid && num != CONTENTS_SOLID) { + empty = 1; + if (num == CONTENTS_EMPTY) + trace->inopen = true; + else + trace->inwater = true; + } else if (!empty && num == CONTENTS_SOLID) { + solid = 1; + } else if (empty || solid) { + // DONE! + trace->allsolid = solid & (num == CONTENTS_SOLID); + trace->startsolid = solid; + calc_impact (trace, start, end, split_plane); + return false; + } + + // pop up the stack for a back side + if (tstack-- == tracestack) { + trace->allsolid = solid & (num == CONTENTS_SOLID); + trace->startsolid = solid; + return true; + } + + // set the hit point for this plane + VectorCopy (backpt, frontpt); + + // go down the back side + VectorCopy (tstack->backpt, backpt); + side = tstack->side; + split_plane = tstack->plane; + + num = hull->clipnodes[tstack->num].children[side ^ 1]; + } + + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + if (plane->type < 3) { + front = frontpt[plane->type] - plane->dist; + back = backpt[plane->type] - plane->dist; + } else { + front = DotProduct (plane->normal, frontpt) - plane->dist; + back = DotProduct (plane->normal, backpt) - plane->dist; + } + + if (front >= 0 && back >= 0) { + num = node->children[0]; + continue; + } + + if (front < 0 && back < 0) { + num = node->children[1]; + continue; + } + + side = front < 0; + + front = front / (front - back); + + tstack->num = num; + tstack->side = side; + tstack->plane = plane; + VectorCopy (backpt, tstack->backpt); + + tstack++; + + backpt[0] = frontpt[0] + front * (backpt[0] - frontpt[0]); + backpt[1] = frontpt[1] + front * (backpt[1] - frontpt[1]); + backpt[2] = frontpt[2] + front * (backpt[2] - frontpt[2]); + + num = node->children[side]; + } +} diff --git a/nq/source/cl_cam.c b/nq/source/cl_cam.c index f5f232d5e..cf12bb5bc 100644 --- a/nq/source/cl_cam.c +++ b/nq/source/cl_cam.c @@ -74,13 +74,13 @@ Chase_Reset (void) // start position 12 units behind head } -static void +static inline void TraceLine (vec3_t start, vec3_t end, vec3_t impact) { trace_t trace; memset (&trace, 0, sizeof (trace)); - SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace); + MOD_TraceLine (cl.worldmodel->hulls, 0, start, end, &trace); VectorCopy (trace.endpos, impact); } diff --git a/nq/source/sv_phys.c b/nq/source/sv_phys.c index b71f898be..5be0b6b89 100644 --- a/nq/source/sv_phys.c +++ b/nq/source/sv_phys.c @@ -37,7 +37,6 @@ static __attribute__ ((unused)) const char rcsid[] = #include "host.h" #include "server.h" -#include "sv_progs.h" #include "world.h" #define sv_frametime host_frametime @@ -93,9 +92,6 @@ SV_CheckAllEnts (void) void SV_CheckVelocity (edict_t *ent) { -#if 0 - float wishspeed; -#endif int i; // bound velocity @@ -112,29 +108,20 @@ SV_CheckVelocity (edict_t *ent) classname))); SVvector (ent, origin)[i] = 0; } -#if 1 if (SVvector (ent, velocity)[i] > sv_maxvelocity->value) SVvector (ent, velocity)[i] = sv_maxvelocity->value; else if (SVvector (ent, velocity)[i] < -sv_maxvelocity->value) SVvector (ent, velocity)[i] = -sv_maxvelocity->value; -#endif } -#if 0 - wishspeed = VectorLength (SVvector (ent, velocity)); - if (wishspeed > sv_maxvelocity->value) { - VectorScale (SVvector (ent, velocity), sv_maxvelocity->value / - wishspeed, SVvector (ent, velocity)); - } -#endif } /* - SV_RunThink + SV_RunThink - Runs thinking code if time. There is some play in the exact time the think - function will be called, because it is called before any movement is done - in a frame. Not used for pushmove objects, because they must be exact. - Returns false if the entity removed itself. + Runs thinking code if time. There is some play in the exact time the think + function will be called, because it is called before any movement is done + in a frame. Not used for pushmove objects, because they must be exact. + Returns false if the entity removed itself. */ qboolean SV_RunThink (edict_t *ent) @@ -188,10 +175,10 @@ SV_Impact (edict_t *e1, edict_t *e2) } /* - ClipVelocity + ClipVelocity - Slide off of the impacting object - returns the blocked flags (1 = floor, 2 = step / wall) + Slide off of the impacting object + returns the blocked flags (1 = floor, 2 = step / wall) */ static int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) @@ -743,6 +730,7 @@ SV_RunEntity (edict_t *ent) default: Sys_Error ("SV_Physics: bad movetype %i", (int) SVfloat (ent, movetype)); + break; } } diff --git a/nq/source/world.c b/nq/source/world.c index 23c5d7dbd..11b995441 100644 --- a/nq/source/world.c +++ b/nq/source/world.c @@ -647,8 +647,8 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip) if (SVfloat (touch, solid) == SOLID_TRIGGER) Sys_Error ("Trigger in clipping list"); - if (clip->type == MOVE_NOMONSTERS && SVfloat (touch, solid) - != SOLID_BSP) + if (clip->type == MOVE_NOMONSTERS + && SVfloat (touch, solid) != SOLID_BSP) continue; if (clip->boxmins[0] > SVvector (touch, absmax)[0] diff --git a/qw/include/pmove.h b/qw/include/pmove.h index 0328dc13c..606e7d176 100644 --- a/qw/include/pmove.h +++ b/qw/include/pmove.h @@ -33,29 +33,12 @@ #include "QF/mathlib.h" #include "QF/model.h" +#include "world.h" + #define STOP_EPSILON 0.1 -typedef struct -{ - vec3_t normal; - float dist; -} pmplane_t; - -typedef struct -{ - qboolean allsolid; // if true, plane is not valid - qboolean startsolid; // if true, the initial point was in a solid area - qboolean inopen, inwater; - float fraction; // time completed, 1.0 = didn't hit anything - vec3_t endpos; // final position - pmplane_t plane; // surface normal at impact - int ent; // entity the surface is on -} pmtrace_t; - - #define MAX_PHYSENTS (MAX_CLIENTS + MAX_PACKET_ENTITIES) -typedef struct -{ +typedef struct { vec3_t origin; model_t *model; // only for bsp models vec3_t mins, maxs; // only for non-bsp models @@ -64,31 +47,30 @@ typedef struct } physent_t; -typedef struct -{ - int sequence; // just for debugging prints +typedef struct { + int sequence; // just for debugging prints // player state - vec3_t origin; - vec3_t angles; - vec3_t velocity; - int oldbuttons; - int oldonground; - float waterjumptime; - qboolean dead; - qboolean flying; - int spectator; + vec3_t origin; + vec3_t angles; + vec3_t velocity; + int oldbuttons; + int oldonground; + float waterjumptime; + qboolean dead; + qboolean flying; + int spectator; // world state - int numphysent; - physent_t physents[MAX_PHYSENTS]; // 0 should be the world + int numphysent; + physent_t physents[MAX_PHYSENTS]; // 0 should be the world // input - usercmd_t cmd; + usercmd_t cmd; // results - int numtouch; - int touchindex[MAX_PHYSENTS]; + int numtouch; + physent_t *touchindex[MAX_PHYSENTS]; } playermove_t; typedef struct { @@ -126,9 +108,6 @@ int PM_HullPointContents (hull_t *hull, int num, const vec3_t p); int PM_PointContents (const vec3_t point); qboolean PM_TestPlayerPosition (const vec3_t point); -pmtrace_t PM_PlayerMove (const vec3_t start, const vec3_t stop); -qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, - const vec3_t p1, const vec3_t p2, - pmtrace_t *trace); +trace_t PM_PlayerMove (const vec3_t start, const vec3_t stop); #endif // _PMOVE_H diff --git a/qw/source/cl_cam.c b/qw/source/cl_cam.c index 59866ab18..7264f97f7 100644 --- a/qw/source/cl_cam.c +++ b/qw/source/cl_cam.c @@ -202,7 +202,7 @@ Cam_Lock (int playernum) Sbar_Changed (); } -static pmtrace_t +static trace_t Cam_DoTrace (vec3_t vec1, vec3_t vec2) { #if 0 @@ -223,7 +223,7 @@ Cam_TryFlyby (player_state_t * self, player_state_t * player, vec3_t vec, qboolean checkvis) { float len; - pmtrace_t trace; + trace_t trace; vec3_t v; vectoangles (vec, v); @@ -256,7 +256,7 @@ static qboolean Cam_IsVisible (player_state_t * player, vec3_t vec) { float d; - pmtrace_t trace; + trace_t trace; vec3_t v; trace = Cam_DoTrace (player->origin, vec); @@ -682,10 +682,10 @@ CL_Cam_Init_Cvars (void) static void TraceLine (vec3_t start, vec3_t end, vec3_t impact) { - pmtrace_t trace; + trace_t trace; memset (&trace, 0, sizeof (trace)); - PM_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace); + MOD_TraceLine (cl.worldmodel->hulls, 0, start, end, &trace); VectorCopy (trace.endpos, impact); } diff --git a/qw/source/pmove.c b/qw/source/pmove.c index 2641f7fea..08f9ef19b 100644 --- a/qw/source/pmove.c +++ b/qw/source/pmove.c @@ -116,7 +116,7 @@ PM_FlyMove (void) { float time_left, d; int blocked, bumpcount, numbumps, numplanes, i, j; - pmtrace_t trace; + trace_t trace; vec3_t dir, end, primal_velocity, original_velocity; vec3_t planes[MAX_CLIP_PLANES]; @@ -152,7 +152,7 @@ PM_FlyMove (void) break; // moved the entire distance // save entity for contact - pmove.touchindex[pmove.numtouch] = trace.ent; + pmove.touchindex[pmove.numtouch] = (physent_t *) trace.ent; pmove.numtouch++; if (trace.plane.normal[2] > 0.7) { @@ -221,7 +221,7 @@ static void PM_FlymodeMove (void) { float pmspeed; - pmtrace_t trace; + trace_t trace; vec3_t start, dest, pmvel, pmtmp; pmvel[0] = forward[0] * pmove.cmd.forwardmove + @@ -261,7 +261,7 @@ static void PM_GroundMove (void) { float downdist, updist; - pmtrace_t trace; + trace_t trace; vec3_t start, dest; vec3_t original, originalvel, down, up, downvel; @@ -340,7 +340,7 @@ PM_Friction (void) { float drop, friction, speed, newspeed; float *vel; - pmtrace_t trace; + trace_t trace; vec3_t start, stop; if (pmove.waterjumptime) @@ -443,7 +443,7 @@ PM_WaterMove (void) { float wishspeed; int i; - pmtrace_t trace; + trace_t trace; vec3_t start, dest, wishdir, wishvel; // user intentions @@ -554,7 +554,7 @@ void PM_CategorizePosition (void) { int cont; - pmtrace_t tr; + trace_t tr; vec3_t point; // if the player hull point one unit down is solid, the player is on ground @@ -567,18 +567,18 @@ PM_CategorizePosition (void) onground = -1; } else { tr = PM_PlayerMove (pmove.origin, point); - if (tr.plane.normal[2] < 0.7) + if (tr.plane.normal[2] < 0.7 || !tr.ent) onground = -1; // too steep else - onground = tr.ent; + onground = (physent_t *) tr.ent - pmove.physents; if (onground != -1) { pmove.waterjumptime = 0; if (!tr.startsolid && !tr.allsolid) VectorCopy (tr.endpos, pmove.origin); } // standing on an entity other than the world - if (tr.ent > 0) { - pmove.touchindex[pmove.numtouch] = tr.ent; + if (tr.ent && (physent_t *) tr.ent - pmove.physents > 0) { + pmove.touchindex[pmove.numtouch] = (physent_t *) tr.ent; pmove.numtouch++; } } diff --git a/qw/source/pmovetst.c b/qw/source/pmovetst.c index a5f960ed6..e30c5f32e 100644 --- a/qw/source/pmovetst.c +++ b/qw/source/pmovetst.c @@ -45,6 +45,7 @@ static __attribute__ ((unused)) const char rcsid[] = #include "compat.h" #include "pmove.h" +#include "world.h" static hull_t box_hull; static dclipnode_t box_clipnodes[6]; @@ -157,223 +158,6 @@ PM_PointContents (const vec3_t p) return num; } -/* LINE TESTING IN HULLS */ - -// 1/32 epsilon to keep floating point happy -#define DIST_EPSILON (0.03125) -#if 1 -static inline void -visit_leaf (int num, pmtrace_t *trace) -{ - if (num != CONTENTS_SOLID) { - trace->allsolid = false; - if (num == CONTENTS_EMPTY) - trace->inopen = true; - else - trace->inwater = true; - } else - trace->startsolid = true; -} - -static inline void -fill_trace (hull_t *hull, int num, int side, - const vec3_t p1, const vec3_t p2, float p1f, float p2f, - float t1, float t2, pmtrace_t *trace) -{ - float frac; - int i; - mplane_t *plane; - - // the other side of the node is solid, this is the impact point - // put the crosspoint DIST_EPSILON pixels on the near side to guarantee - // mid is on the correct side of the plane - plane = hull->planes + hull->clipnodes[num].planenum; - if (!side) { - VectorCopy (plane->normal, trace->plane.normal); - trace->plane.dist = plane->dist; - frac = (t1 - DIST_EPSILON) / (t1 - t2); - } else { - VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); - trace->plane.dist = -plane->dist; - frac = (t1 + DIST_EPSILON) / (t1 - t2); - } - - frac = bound (0, frac, 1); - - trace->fraction = p1f + (p2f - p1f) * frac; - for (i = 0; i < 3; i++) - trace->endpos[i] = p1[i] + frac * (p2[i] - p1[i]); -} - -static inline float -calc_mid (float t1, float t2, const vec3_t p1, const vec3_t p2, - float p1f, float p2f, vec3_t mid) -{ - float frac = t1 / (t1 - t2); - int i; - - for (i=0 ; i<3 ; i++) - mid[i] = p1[i] + frac*(p2[i] - p1[i]); - return p1f + (p2f - p1f)*frac; -} - -static inline void -calc_dists (const mplane_t *plane, const vec3_t p1, const vec3_t p2, - float *t1, float *t2) -{ - if (plane->type < 3) { - *t1 = p1[plane->type] - plane->dist; - *t2 = p2[plane->type] - plane->dist; - } else { - *t1 = DotProduct (plane->normal, p1) - plane->dist; - *t2 = DotProduct (plane->normal, p2) - plane->dist; - } -} - -qboolean -PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, - const vec3_t p1, const vec3_t p2, pmtrace_t *trace) -{ - int front, back, side; - dclipnode_t *node; - float midf, t1, t2; - vec3_t mid, _p1; - - while (1) { - while (num >= 0) { - node = hull->clipnodes + num; - calc_dists (hull->planes + node->planenum, p1, p2, &t1, &t2); - - side = (t1 < 0); - if (t1 >= 0 != t2 >= 0) - break; - num = node->children[side]; - } - if (num < 0) { - visit_leaf (num, trace); - return true; - } - - midf = calc_mid (t1, t2, p1, p2, p1f, p2f, mid); - - front = node->children[side]; - if (!PM_RecursiveHullCheck (hull, front, p1f, midf, p1, mid, trace)) - return false; - - back = node->children[side ^ 1]; - if (PM_HullPointContents (hull, back, mid) == CONTENTS_SOLID) { - // got out of the solid area? - if (!trace->allsolid) - fill_trace (hull, num, side, p1, p2, p1f, p2f, - t1, t2, trace); - return false; - } - num = back; - VectorCopy (mid, _p1); - p1f = midf; - p1 = _p1; - } -} -#else -qboolean -PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, - const vec3_t p1, const vec3_t p2, pmtrace_t *trace) -{ - dclipnode_t *node; - float frac, midf, t1, t2; - int side, i; - mplane_t *plane; - vec3_t mid; - - loc0: - // 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 - } - - // 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 = DotProduct (plane->normal, p1) - plane->dist; - t2 = DotProduct (plane->normal, p2) - plane->dist; - } - - // LordHavoc: recursion optimization - if (t1 >= 0 && t2 >= 0) { - num = node->children[0]; - goto loc0; - } - if (t1 < 0 && t2 < 0) { - num = node->children[1]; - goto loc0; - } - side = (t1 < 0); - frac = t1 / (t1 - t2); - //frac = bound (0, frac, 1); // is this needed? - - midf = p1f + (p2f - p1f) * frac; - for (i = 0; i < 3; i++) - mid[i] = p1[i] + frac * (p2[i] - p1[i]); - - // move up to the node - if (!PM_RecursiveHullCheck (hull, node->children[side], - p1f, midf, p1, mid, trace)) - return false; - - if (PM_HullPointContents (hull, node->children[side ^ 1], mid) - != CONTENTS_SOLID) { - // go past the node - return PM_RecursiveHullCheck (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 { - // 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; - } - - // 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; - VectorCopy (mid, trace->endpos); - - return false; -} -#endif - /* PM_TestPlayerPosition @@ -421,21 +205,21 @@ bboxes_touch (const vec3_t min1, const vec3_t max1, } /* PM_PlayerMove */ -pmtrace_t +trace_t PM_PlayerMove (const vec3_t start, const vec3_t end) { hull_t *hull; int i, check_box, move_missed; physent_t *pe; - pmtrace_t trace, total; + trace_t trace, total; vec3_t maxs, mins, offset, start_l, end_l; vec3_t move[2]; // fill in a default trace - memset (&total, 0, sizeof (pmtrace_t)); + memset (&total, 0, sizeof (trace_t)); total.fraction = 1; - total.ent = -1; + total.ent = 0; VectorCopy (end, total.endpos); for (i = 0; i < pmove.numphysent; i++) { @@ -464,7 +248,7 @@ PM_PlayerMove (const vec3_t start, const vec3_t end) VectorSubtract (end, offset, end_l); // fill in a default trace - memset (&trace, 0, sizeof (pmtrace_t)); + memset (&trace, 0, sizeof (trace_t)); trace.fraction = 1; trace.allsolid = true; @@ -479,7 +263,7 @@ PM_PlayerMove (const vec3_t start, const vec3_t end) move[1][0] = max (start_l[0], end_l[0]); move[1][1] = max (start_l[1], end_l[1]); move[1][2] = max (start_l[2], end_l[2]); - if (!bboxes_touch (move[0], move[1], mins, maxs)) + if (!bboxes_touch (move[0], move[1], mins, maxs)) { move_missed = 1; if (PM_HullPointContents (hull, hull->firstclipnode, start_l) != CONTENTS_SOLID) { @@ -488,12 +272,12 @@ PM_PlayerMove (const vec3_t start, const vec3_t end) // is not solid, the whole trace is not solid trace.allsolid = false; } + } } if (!move_missed) { // trace a line through the appropriate clipping hull - PM_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, - start_l, end_l, &trace); + MOD_TraceLine (hull, hull->firstclipnode, start_l, end_l, &trace); } if (trace.allsolid) @@ -506,7 +290,7 @@ PM_PlayerMove (const vec3_t start, const vec3_t end) // fix trace up by the offset VectorAdd (trace.endpos, offset, trace.endpos); total = trace; - total.ent = i; + total.ent = (struct edict_s *) &pmove.physents[i]; } } diff --git a/qw/source/sv_user.c b/qw/source/sv_user.c index c277632ae..58bd232d4 100644 --- a/qw/source/sv_user.c +++ b/qw/source/sv_user.c @@ -1734,7 +1734,7 @@ SV_RunCmd (usercmd_t *ucmd, qboolean inside) // touch other objects for (i = 0; i < pmove.numtouch; i++) { - n = pmove.physents[pmove.touchindex[i]].info; + n = pmove.touchindex[i]->info; ent = EDICT_NUM (&sv_pr_state, n); if (!SVfunc (ent, touch) || (playertouch[n / 8] & (1 << (n % 8)))) continue; diff --git a/qw/source/world.c b/qw/source/world.c index d07ea7f67..a99e622f3 100644 --- a/qw/source/world.c +++ b/qw/source/world.c @@ -481,106 +481,6 @@ SV_TestEntityPosition (edict_t *ent) return NULL; } -/* LINE TESTING IN HULLS */ - -// 1/32 epsilon to keep floating point happy -#define DIST_EPSILON (0.03125) - -qboolean -SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, - const vec3_t p1, const vec3_t p2, trace_t *trace) -{ - dclipnode_t *node; - float frac, midf, t1, t2; - int side, i; - mplane_t *plane; - vec3_t mid; - - // 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 - } - - // 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 = DotProduct (plane->normal, p1) - plane->dist; - t2 = DotProduct (plane->normal, p2) - plane->dist; - } - - if (t1 >= 0 && t2 >= 0) - return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, - p2, trace); - if (t1 < 0 && t2 < 0) - return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, - p2, trace); - - side = (t1 < 0); - frac = t1 / (t1 - t2); - //frac = bound (0, frac, 1); // is this needed? - - midf = p1f + (p2f - p1f) * frac; - for (i = 0; i < 3; i++) - mid[i] = p1[i] + frac * (p2[i] - p1[i]); - - // move up to the node - if (!SV_RecursiveHullCheck (hull, node->children[side], - p1f, midf, p1, mid, trace)) - return false; - - if (SV_HullPointContents (hull, node->children[side ^ 1], mid) - != CONTENTS_SOLID) { - // go past the node - return SV_RecursiveHullCheck (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 { - // 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; - } - - // 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; - VectorCopy (mid, trace->endpos); - - return false; -} - /* SV_ClipMoveToEntity @@ -588,7 +488,7 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, eventually rotation) of the end points */ static trace_t -SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, const vec3_t start, +SV_ClipMoveToEntity (edict_t *touched, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end) { hull_t *hull; @@ -609,8 +509,7 @@ SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, const vec3_t start, VectorSubtract (end, offset, end_l); // trace a line through the apropriate clipping hull - SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, - &trace); + MOD_TraceLine (hull, hull->firstclipnode, start_l, end_l, &trace); // fix trace up by the offset if (trace.fraction != 1) @@ -675,10 +574,10 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip) } if ((int) SVfloat (touch, flags) & FL_MONSTER) - trace = SV_ClipMoveToEntity (touch, clip->passedict, clip->start, + trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end); else - trace = SV_ClipMoveToEntity (touch, clip->passedict, clip->start, + trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end); if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction) { @@ -735,7 +634,7 @@ SV_Move (const vec3_t start, const vec3_t mins, const vec3_t maxs, memset (&clip, 0, sizeof (moveclip_t)); // clip to world - clip.trace = SV_ClipMoveToEntity (sv.edicts, passedict, start, + clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end); clip.start = start;