whitespace.

This commit is contained in:
Ragnvald Maartmann-Moe IV 2001-05-20 18:07:39 +00:00
parent a07d05e054
commit 3f816c0aa3
2 changed files with 208 additions and 353 deletions

View file

@ -1,8 +1,7 @@
/* /*
world.c world.c
@description@ world query functions
Copyright (C) 1996-1997 Id Software, Inc. Copyright (C) 1996-1997 Id Software, Inc.
@ -31,12 +30,13 @@
# include "config.h" # include "config.h"
#endif #endif
#include "world.h"
#include "QF/model.h"
#include "server.h"
#include "QF/sys.h"
#include "QF/console.h" #include "QF/console.h"
#include "QF/model.h"
#include "QF/sys.h"
#include "server.h"
#include "sv_progs.h" #include "sv_progs.h"
#include "world.h"
/* /*
@ -48,46 +48,39 @@ line of sight checks trace->crosscontent, but bullets don't
typedef struct { typedef struct {
vec3_t boxmins, boxmaxs; // enclose the test object along vec3_t boxmins, boxmaxs; // enclose the test object along
// entire move // entire move
float *mins, *maxs; // size of the moving object float *mins, *maxs; // size of the moving object
vec3_t mins2, maxs2; // size when clipping against vec3_t mins2, maxs2; // size when clipping against monsters
// mosnters
float *start, *end; float *start, *end;
trace_t trace; trace_t trace;
int type; int type;
edict_t *passedict; edict_t *passedict;
} moveclip_t; } moveclip_t;
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];
static mplane_t box_planes[6]; static mplane_t box_planes[6];
/*
===================
SV_InitBoxHull
Set up the planes and clipnodes so that the six floats of a bounding box /*
can just be stored out and get a proper hull_t structure. SV_InitBoxHull
===================
Set up the planes and clipnodes so that the six floats of a bounding box
can just be stored out and get a proper hull_t structure.
*/ */
void void
SV_InitBoxHull (void) SV_InitBoxHull (void)
{ {
int i; int i;
int side; int side;
box_hull.clipnodes = box_clipnodes; box_hull.clipnodes = box_clipnodes;
box_hull.planes = box_planes; box_hull.planes = box_planes;
@ -113,14 +106,12 @@ SV_InitBoxHull (void)
/* /*
=================== SV_HullForBox
SV_HullForBox
To keep everything totally uniform, bounding boxes are turned into small To keep everything totally uniform, bounding boxes are turned into small
BSP trees instead of being compared directly. BSP trees instead of being compared directly.
===================
*/ */
hull_t * hull_t *
SV_HullForBox (vec3_t mins, vec3_t maxs) SV_HullForBox (vec3_t mins, vec3_t maxs)
{ {
box_planes[0].dist = maxs[0]; box_planes[0].dist = maxs[0];
@ -134,27 +125,25 @@ SV_HullForBox (vec3_t mins, vec3_t maxs)
} }
/* /*
================ SV_HullForEntity
SV_HullForEntity
Returns a hull that can be used for testing or clipping an object of mins/maxs Returns a hull that can be used for testing or clipping an object of
size. mins/maxs size. Offset is filled in to contain the adjustment that must
Offset is filled in to contain the adjustment that must be added to the be added to the testing object's origin to get a point to use with the
testing object's origin to get a point to use with the returned hull. returned hull.
================
*/ */
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; model_t *model;
vec3_t size; vec3_t size;
vec3_t hullmins, hullmaxs; vec3_t hullmins, hullmaxs;
hull_t *hull; hull_t *hull;
// decide which clipping hull to use, based on the size // decide which clipping hull to use, based on the size
if (SVFIELD (ent, solid, float) == SOLID_BSP) { // explicit hulls in the BSP model if (SVFIELD (ent, solid, float) == SOLID_BSP) { // explicit hulls in the
// BSP model
if (SVFIELD (ent, movetype, float) != MOVETYPE_PUSH) if (SVFIELD (ent, movetype, float) != MOVETYPE_PUSH)
Sys_Error ("SOLID_BSP without MOVETYPE_PUSH"); Sys_Error ("SOLID_BSP without MOVETYPE_PUSH");
@ -171,12 +160,11 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
else else
hull = &model->hulls[2]; hull = &model->hulls[2];
// calculate an offset value to center the origin // calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset); VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, SVFIELD (ent, origin, vector), offset); VectorAdd (offset, SVFIELD (ent, origin, vector), offset);
} else { // create a temp hull from bounding } else { // create a temp hull from bounding
// box sizes // box sizes
VectorSubtract (SVFIELD (ent, mins, vector), maxs, hullmins); VectorSubtract (SVFIELD (ent, mins, vector), maxs, hullmins);
VectorSubtract (SVFIELD (ent, maxs, vector), mins, hullmaxs); VectorSubtract (SVFIELD (ent, maxs, vector), mins, hullmaxs);
hull = SV_HullForBox (hullmins, hullmaxs); hull = SV_HullForBox (hullmins, hullmaxs);
@ -184,16 +172,11 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
VectorCopy (SVFIELD (ent, origin, vector), offset); VectorCopy (SVFIELD (ent, origin, vector), offset);
} }
return hull; return hull;
} }
/* /*
=============================================================================== ENTITY AREA CHECKING ========================================================
ENTITY AREA CHECKING
===============================================================================
*/ */
typedef struct areanode_s { typedef struct areanode_s {
@ -210,18 +193,13 @@ typedef struct areanode_s {
static areanode_t sv_areanodes[AREA_NODES]; static areanode_t sv_areanodes[AREA_NODES];
static int sv_numareanodes; static int sv_numareanodes;
/*
===============
SV_CreateAreaNode
===============
*/
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 size;
vec3_t mins1, maxs1, mins2, maxs2; vec3_t mins1, maxs1, mins2, maxs2;
anode = &sv_areanodes[sv_numareanodes]; anode = &sv_areanodes[sv_numareanodes];
sv_numareanodes++; sv_numareanodes++;
@ -255,12 +233,7 @@ SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs)
return anode; return anode;
} }
/*
===============
SV_ClearWorld
===============
*/
void void
SV_ClearWorld (void) SV_ClearWorld (void)
{ {
@ -272,12 +245,6 @@ SV_ClearWorld (void)
} }
/*
===============
SV_UnlinkEdict
===============
*/
void void
SV_UnlinkEdict (edict_t *ent) SV_UnlinkEdict (edict_t *ent)
{ {
@ -288,11 +255,6 @@ SV_UnlinkEdict (edict_t *ent)
} }
/*
====================
SV_TouchLinks
====================
*/
void void
SV_TouchLinks (edict_t *ent, areanode_t *node) SV_TouchLinks (edict_t *ent, areanode_t *node)
{ {
@ -300,7 +262,7 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
edict_t *touch; edict_t *touch;
int old_self, old_other; int old_self, old_other;
// 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) {
next = l->next; next = l->next;
touch = EDICT_FROM_AREA (l); touch = EDICT_FROM_AREA (l);
@ -328,7 +290,7 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
*sv_globals.other = old_other; *sv_globals.other = old_other;
} }
// recurse down both sides // recurse down both sides
if (node->axis == -1) if (node->axis == -1)
return; return;
@ -339,12 +301,6 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
} }
/*
===============
SV_FindTouchedLeafs
===============
*/
void void
SV_FindTouchedLeafs (edict_t *ent, mnode_t *node) SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
{ {
@ -356,8 +312,7 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
if (node->contents == CONTENTS_SOLID) if (node->contents == CONTENTS_SOLID)
return; return;
// add an efrag if the node is a leaf // add an efrag if the node is a leaf
if (node->contents < 0) { if (node->contents < 0) {
if (ent->num_leafs == MAX_ENT_LEAFS) if (ent->num_leafs == MAX_ENT_LEAFS)
return; return;
@ -369,12 +324,12 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
ent->num_leafs++; ent->num_leafs++;
return; return;
} }
// NODE_MIXED // NODE_MIXED
splitplane = node->plane; splitplane = node->plane;
sides = BOX_ON_PLANE_SIDE (SVFIELD (ent, absmin, vector), SVFIELD (ent, absmax, vector), splitplane); sides = BOX_ON_PLANE_SIDE (SVFIELD (ent, absmin, vector), SVFIELD (ent, absmax, vector), splitplane);
// recurse down the contacted sides // recurse down the contacted sides
if (sides & 1) if (sides & 1)
SV_FindTouchedLeafs (ent, node->children[0]); SV_FindTouchedLeafs (ent, node->children[0]);
@ -382,12 +337,7 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
SV_FindTouchedLeafs (ent, node->children[1]); SV_FindTouchedLeafs (ent, node->children[1]);
} }
/*
===============
SV_LinkEdict
===============
*/
void void
SV_LinkEdict (edict_t *ent, qboolean touch_triggers) SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
{ {
@ -402,14 +352,12 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
if (ent->free) if (ent->free)
return; return;
// set the abs box // set the abs box
#ifdef QUAKE2 #ifdef QUAKE2
if (SVFIELD (ent, solid, float) == SOLID_BSP && if (SVFIELD (ent, solid, float) == SOLID_BSP &&
(SVFIELD (ent, angles, float)[0] || SVFIELD (ent, angles, float)[1] || SVFIELD (ent, angles, float)[2])) { // expand (SVFIELD (ent, angles, float)[0] || SVFIELD (ent, angles, float)[1]
// || SVFIELD (ent, angles, float)[2])) { // expand for rotation
// for
// rotation
float max, v; float max, v;
int i; int i;
@ -433,18 +381,15 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, maxs, vector), SVFIELD (ent, absmax, vector)); VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, maxs, vector), SVFIELD (ent, absmax, vector));
} }
// // to make items easier to pick up and allow them to be grabbed off
// to make items easier to pick up and allow them to be grabbed off // of shelves, the abs sizes are expanded
// of shelves, the abs sizes are expanded
//
if ((int) SVFIELD (ent, flags, float) & FL_ITEM) { if ((int) SVFIELD (ent, flags, float) & FL_ITEM) {
SVFIELD (ent, absmin, vector)[0] -= 15; SVFIELD (ent, absmin, vector)[0] -= 15;
SVFIELD (ent, absmin, vector)[1] -= 15; SVFIELD (ent, absmin, vector)[1] -= 15;
SVFIELD (ent, absmax, vector)[0] += 15; SVFIELD (ent, absmax, vector)[0] += 15;
SVFIELD (ent, absmax, vector)[1] += 15; SVFIELD (ent, absmax, vector)[1] += 15;
} else { // because movement is clipped an } else { // movement is clipped an epsilon away from actual edge, so we
// epsilon away from an actual edge, // must fully check even when bounding boxes don't quite touch
// we must fully check even when bounding boxes don't quite touch
SVFIELD (ent, absmin, vector)[0] -= 1; SVFIELD (ent, absmin, vector)[0] -= 1;
SVFIELD (ent, absmin, vector)[1] -= 1; SVFIELD (ent, absmin, vector)[1] -= 1;
SVFIELD (ent, absmin, vector)[2] -= 1; SVFIELD (ent, absmin, vector)[2] -= 1;
@ -453,7 +398,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
SVFIELD (ent, absmax, vector)[2] += 1; SVFIELD (ent, absmax, vector)[2] += 1;
} }
// link to PVS leafs // link to PVS leafs
ent->num_leafs = 0; ent->num_leafs = 0;
if (SVFIELD (ent, modelindex, float)) if (SVFIELD (ent, modelindex, float))
SV_FindTouchedLeafs (ent, sv.worldmodel->nodes); SV_FindTouchedLeafs (ent, sv.worldmodel->nodes);
@ -461,7 +406,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
if (SVFIELD (ent, solid, float) == SOLID_NOT) if (SVFIELD (ent, solid, float) == SOLID_NOT)
return; return;
// find the first node that the ent's box crosses // find the first node that the ent's box crosses
node = sv_areanodes; node = sv_areanodes;
while (1) { while (1) {
if (node->axis == -1) if (node->axis == -1)
@ -474,14 +419,13 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
break; // crosses the node break; // crosses the node
} }
// link it in // link it in
if (SVFIELD (ent, solid, float) == SOLID_TRIGGER) if (SVFIELD (ent, solid, float) == SOLID_TRIGGER)
InsertLinkBefore (&ent->area, &node->trigger_edicts); InsertLinkBefore (&ent->area, &node->trigger_edicts);
else else
InsertLinkBefore (&ent->area, &node->solid_edicts); InsertLinkBefore (&ent->area, &node->solid_edicts);
// if touch_triggers, touch all entities at this node and decend for more // if touch_triggers, touch all entities at this node and decend for more
if (touch_triggers) if (touch_triggers)
SV_TouchLinks (ent, sv_areanodes); SV_TouchLinks (ent, sv_areanodes);
} }
@ -489,25 +433,14 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
/* /*
=============================================================================== POINT TESTING IN HULLS ======================================================
POINT TESTING IN HULLS
===============================================================================
*/ */
#ifndef USE_INTEL_ASM #ifndef USE_INTEL_ASM
/*
==================
SV_HullPointContents
==================
*/
int int
SV_HullPointContents (hull_t *hull, int num, vec3_t p) SV_HullPointContents (hull_t *hull, int num, vec3_t p)
{ {
float d; float d;
dclipnode_t *node; dclipnode_t *node;
mplane_t *plane; mplane_t *plane;
@ -530,16 +463,9 @@ SV_HullPointContents (hull_t *hull, int num, vec3_t p)
return num; return num;
} }
#endif // USE_INTEL_ASM #endif // USE_INTEL_ASM
/*
==================
SV_PointContents
==================
*/
int int
SV_PointContents (vec3_t p) SV_PointContents (vec3_t p)
{ {
@ -551,29 +477,28 @@ 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
This could be a lot more efficient... This could be a lot more efficient...
============
*/ */
edict_t * edict_t *
SV_TestEntityPosition (edict_t *ent) SV_TestEntityPosition (edict_t *ent)
{ {
trace_t trace; trace_t trace;
trace = trace = SV_Move (SVFIELD (ent, origin, vector),
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector),
0, ent); SVFIELD (ent, maxs, vector),
SVFIELD (ent, origin, vector), 0, ent);
if (trace.startsolid) if (trace.startsolid)
return sv.edicts; return sv.edicts;
@ -583,22 +508,13 @@ SV_TestEntityPosition (edict_t *ent)
/* /*
=============================================================================== 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)
/*
==================
SV_RecursiveHullCheck
==================
*/
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)
@ -612,7 +528,7 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
int side; int side;
float midf; float midf;
// check for empty // check for empty
if (num < 0) { if (num < 0) {
if (num != CONTENTS_SOLID) { if (num != CONTENTS_SOLID) {
trace->allsolid = false; trace->allsolid = false;
@ -628,9 +544,7 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
if (num < hull->firstclipnode || num > hull->lastclipnode) if (num < hull->firstclipnode || num > hull->lastclipnode)
Sys_Error ("SV_RecursiveHullCheck: bad node number"); 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;
@ -644,21 +558,21 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
#if 1 #if 1
if (t1 >= 0 && t2 >= 0) if (t1 >= 0 && t2 >= 0)
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
trace); p2, trace);
if (t1 < 0 && t2 < 0) if (t1 < 0 && t2 < 0)
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
trace); p2, trace);
#else #else
if ((t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0)) if ((t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0))
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
trace); p2, trace);
if ((t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0)) if ((t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0))
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
trace); p2, trace);
#endif #endif
// put the crosspoint DIST_EPSILON pixels on the near side // put the crosspoint DIST_EPSILON pixels on the near side
if (t1 < 0) if (t1 < 0)
frac = (t1 + DIST_EPSILON) / (t1 - t2); frac = (t1 + DIST_EPSILON) / (t1 - t2);
else else
@ -674,7 +588,7 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
side = (t1 < 0); side = (t1 < 0);
// move up to the node // move up to the node
if (!SV_RecursiveHullCheck if (!SV_RecursiveHullCheck
(hull, node->children[side], p1f, midf, p1, mid, trace)) return false; (hull, node->children[side], p1f, midf, p1, mid, trace)) return false;
@ -688,16 +602,14 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
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, p2f, return SV_RecursiveHullCheck (hull, node->children[side ^ 1], midf,
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
//================== // 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;
@ -708,7 +620,7 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
while (SV_HullPointContents (hull, hull->firstclipnode, mid) while (SV_HullPointContents (hull, hull->firstclipnode, mid)
== CONTENTS_SOLID) { // shouldn't really happen, but does == CONTENTS_SOLID) { // shouldn't really happen, but does
// occasionally // occasionally
frac -= 0.1; frac -= 0.1;
if (frac < 0) { if (frac < 0) {
trace->fraction = midf; trace->fraction = midf;
@ -729,12 +641,10 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
/* /*
================== SV_ClipMoveToEntity
SV_ClipMoveToEntity
Handles selection or creation of a clipping hull, and offseting (and Handles selection or creation of a clipping hull, and offseting (and
eventually rotation) of the end points eventually rotation) of the end points
==================
*/ */
trace_t trace_t
SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
@ -745,14 +655,14 @@ SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
vec3_t start_l, end_l; vec3_t start_l, end_l;
hull_t *hull; hull_t *hull;
// fill in a default trace // fill in a default trace
memset (&trace, 0, sizeof (trace_t)); memset (&trace, 0, sizeof (trace_t));
trace.fraction = 1; trace.fraction = 1;
trace.allsolid = true; trace.allsolid = true;
VectorCopy (end, trace.endpos); VectorCopy (end, trace.endpos);
// get the clipping hull // get the clipping hull
hull = SV_HullForEntity (ent, mins, maxs, offset); hull = SV_HullForEntity (ent, mins, maxs, offset);
VectorSubtract (start, offset, start_l); VectorSubtract (start, offset, start_l);
@ -761,7 +671,8 @@ SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
#ifdef QUAKE2 #ifdef QUAKE2
// rotate start and end into the models frame of reference // rotate start and end into the models frame of reference
if (SVFIELD (ent, solid, float) == SOLID_BSP && if (SVFIELD (ent, solid, float) == SOLID_BSP &&
(SVFIELD (ent, angles, float)[0] || SVFIELD (ent, angles, float)[1] || SVFIELD (ent, angles, float)[2])) { (SVFIELD (ent, angles, float)[0] || SVFIELD (ent, angles, float)[1]
|| SVFIELD (ent, angles, float)[2])) {
vec3_t a; vec3_t a;
vec3_t forward, right, up; vec3_t forward, right, up;
vec3_t temp; vec3_t temp;
@ -780,7 +691,7 @@ SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
} }
#endif #endif
// trace a line through the apropriate clipping hull // trace a line through the apropriate clipping hull
SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l,
&trace); &trace);
@ -809,34 +720,31 @@ SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
} }
#endif #endif
// fix trace up by the offset // fix trace up by the offset
if (trace.fraction != 1) if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos); VectorAdd (trace.endpos, offset, trace.endpos);
// did we clip the move? // did we clip the move?
if (trace.fraction < 1 || trace.startsolid) if (trace.fraction < 1 || trace.startsolid)
trace.ent = ent; trace.ent = ent;
return trace; return trace;
} }
//===========================================================================
/* /*
==================== SV_ClipToLinks
SV_ClipToLinks
Mins and maxs enclose the entire area swept by the move Mins and maxs enclose the entire area swept by the move
====================
*/ */
void void
SV_ClipToLinks (areanode_t *node, moveclip_t * clip) SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
{ {
link_t *l, *next; link_t *l, *next;
edict_t *touch; edict_t *touch;
trace_t trace; trace_t trace;
// touch linked edicts // touch linked edicts
for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) { for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) {
next = l->next; next = l->next;
touch = EDICT_FROM_AREA (l); touch = EDICT_FROM_AREA (l);
@ -867,20 +775,18 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
return; return;
if (clip->passedict) { if (clip->passedict) {
if (PROG_TO_EDICT (&sv_pr_state, SVFIELD (touch, owner, entity)) == if (PROG_TO_EDICT (&sv_pr_state, SVFIELD (touch, owner, entity)) ==
clip->passedict) continue; // don't clip against own clip->passedict) continue; // don't clip against own missiles
// missiles if (PROG_TO_EDICT (&sv_pr_state,
if (PROG_TO_EDICT (&sv_pr_state, SVFIELD (clip->passedict, owner, entity)) == SVFIELD (clip->passedict, owner, entity))
touch) continue; // don't clip against owner == touch) continue; // don't clip against owner
} }
if ((int) SVFIELD (touch, flags, float) & FL_MONSTER) if ((int) SVFIELD (touch, flags, float) & FL_MONSTER)
trace = trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2,
SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end);
clip->maxs2, clip->end);
else else
trace = trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins,
SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->maxs, clip->end);
clip->end);
if (trace.allsolid || trace.startsolid if (trace.allsolid || trace.startsolid
|| trace.fraction < clip->trace.fraction) { || trace.fraction < clip->trace.fraction) {
trace.ent = touch; trace.ent = touch;
@ -893,7 +799,7 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
clip->trace.startsolid = true; clip->trace.startsolid = true;
} }
// recurse down both sides // recurse down both sides
if (node->axis == -1) if (node->axis == -1)
return; return;
@ -904,21 +810,16 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
} }
/*
==================
SV_MoveBounds
==================
*/
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)
{ {
#if 0 #if 0
// debug to test against everything // debug to test against everything
boxmins[0] = boxmins[1] = boxmins[2] = -9999; boxmins[0] = boxmins[1] = boxmins[2] = -9999;
boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999; boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999;
#else #else
int i; int i;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (end[i] > start[i]) { if (end[i] > start[i]) {
@ -932,21 +833,17 @@ SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
#endif #endif
} }
/*
==================
SV_Move
==================
*/
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; moveclip_t clip;
int i; int i;
memset (&clip, 0, sizeof (moveclip_t)); memset (&clip, 0, sizeof (moveclip_t));
// clip to world // clip to world
clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end); clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end);
clip.start = start; clip.start = start;
@ -966,11 +863,11 @@ SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type,
VectorCopy (maxs, clip.maxs2); VectorCopy (maxs, clip.maxs2);
} }
// create the bounding box of the entire move // create the bounding box of the entire move
SV_MoveBounds (start, clip.mins2, clip.maxs2, end, clip.boxmins, SV_MoveBounds (start, clip.mins2, clip.maxs2, end, clip.boxmins,
clip.boxmaxs); clip.boxmaxs);
// clip to entities // clip to entities
SV_ClipToLinks (sv_areanodes, &clip); SV_ClipToLinks (sv_areanodes, &clip);
return clip.trace; return clip.trace;

View file

@ -40,6 +40,7 @@
#include "QF/console.h" #include "QF/console.h"
#include "QF/crc.h" #include "QF/crc.h"
#include "server.h" #include "server.h"
#include "sv_progs.h" #include "sv_progs.h"
#include "world.h" #include "world.h"
@ -72,11 +73,11 @@ 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];
static mplane_t box_planes[6]; static mplane_t box_planes[6];
/* /*
SV_InitBoxHull SV_InitBoxHull
@ -86,8 +87,8 @@ static mplane_t box_planes[6];
void void
SV_InitBoxHull (void) SV_InitBoxHull (void)
{ {
int i; int i;
int side; int side;
box_hull.clipnodes = box_clipnodes; box_hull.clipnodes = box_clipnodes;
box_hull.planes = box_planes; box_hull.planes = box_planes;
@ -118,7 +119,7 @@ SV_InitBoxHull (void)
To keep everything totally uniform, bounding boxes are turned into small To keep everything totally uniform, bounding boxes are turned into small
BSP trees instead of being compared directly. BSP trees instead of being compared directly.
*/ */
hull_t * hull_t *
SV_HullForBox (vec3_t mins, vec3_t maxs) SV_HullForBox (vec3_t mins, vec3_t maxs)
{ {
box_planes[0].dist = maxs[0]; box_planes[0].dist = maxs[0];
@ -132,7 +133,6 @@ SV_HullForBox (vec3_t mins, vec3_t maxs)
} }
/* /*
SV_HullForEntity SV_HullForEntity
@ -141,15 +141,15 @@ SV_HullForBox (vec3_t mins, vec3_t maxs)
must be added to the testing object's origin to get a point to use with must be added to the testing object's origin to get a point to use with
the returned hull. the returned hull.
*/ */
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; model_t *model;
vec3_t size; vec3_t size;
vec3_t hullmins, hullmaxs; vec3_t hullmins, hullmaxs;
hull_t *hull; hull_t *hull;
// decide which clipping hull to use, based on the size // decide which clipping hull to use, based on the size
if (SVFIELD (ent, solid, float) == SOLID_BSP) { if (SVFIELD (ent, solid, float) == SOLID_BSP) {
// explicit hulls in the BSP model // explicit hulls in the BSP model
if (SVFIELD (ent, movetype, float) != MOVETYPE_PUSH) if (SVFIELD (ent, movetype, float) != MOVETYPE_PUSH)
@ -168,12 +168,10 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
else else
hull = &model->hulls[2]; hull = &model->hulls[2];
// calculate an offset value to center the origin // calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset); VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, SVFIELD (ent, origin, vector), offset); VectorAdd (offset, SVFIELD (ent, origin, vector), offset);
} else { // create a temp hull from bounding } else { // create a temp hull from bounding box sizes
// box sizes
VectorSubtract (SVFIELD (ent, mins, vector), maxs, hullmins); VectorSubtract (SVFIELD (ent, mins, vector), maxs, hullmins);
VectorSubtract (SVFIELD (ent, maxs, vector), mins, hullmaxs); VectorSubtract (SVFIELD (ent, maxs, vector), mins, hullmaxs);
hull = SV_HullForBox (hullmins, hullmaxs); hull = SV_HullForBox (hullmins, hullmaxs);
@ -181,21 +179,18 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
VectorCopy (SVFIELD (ent, origin, vector), offset); VectorCopy (SVFIELD (ent, origin, vector), 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;
/*
SV_CreateAreaNode
*/
areanode_t * areanode_t *
SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs)
{ {
@ -235,9 +230,7 @@ SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs)
return anode; return anode;
} }
/*
SV_ClearWorld
*/
void void
SV_ClearWorld (void) SV_ClearWorld (void)
{ {
@ -249,9 +242,6 @@ SV_ClearWorld (void)
} }
/*
SV_UnlinkEdict
*/
void void
SV_UnlinkEdict (edict_t *ent) SV_UnlinkEdict (edict_t *ent)
{ {
@ -262,9 +252,6 @@ SV_UnlinkEdict (edict_t *ent)
} }
/*
SV_TouchLinks
*/
void void
SV_TouchLinks (edict_t *ent, areanode_t *node) SV_TouchLinks (edict_t *ent, areanode_t *node)
{ {
@ -272,13 +259,14 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
edict_t *touch; edict_t *touch;
int old_self, old_other; int old_self, old_other;
// 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) {
next = l->next; next = l->next;
touch = EDICT_FROM_AREA (l); touch = EDICT_FROM_AREA (l);
if (touch == ent) if (touch == ent)
continue; continue;
if (!SVFIELD (touch, touch, func) || SVFIELD (touch, solid, float) != SOLID_TRIGGER) if (!SVFIELD (touch, touch, func)
|| SVFIELD (touch, solid, float) != SOLID_TRIGGER)
continue; continue;
if (SVFIELD (ent, absmin, vector)[0] > SVFIELD (touch, absmax, vector)[0] if (SVFIELD (ent, absmin, vector)[0] > SVFIELD (touch, absmax, vector)[0]
|| SVFIELD (ent, absmin, vector)[1] > SVFIELD (touch, absmax, vector)[1] || SVFIELD (ent, absmin, vector)[1] > SVFIELD (touch, absmax, vector)[1]
@ -300,7 +288,7 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
*sv_globals.other = old_other; *sv_globals.other = old_other;
} }
// recurse down both sides // recurse down both sides
if (node->axis == -1) if (node->axis == -1)
return; return;
@ -311,22 +299,18 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
} }
/*
SV_FindTouchedLeafs
*/
void void
SV_FindTouchedLeafs (edict_t *ent, mnode_t *node) SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
{ {
mplane_t *splitplane; mplane_t *splitplane;
mleaf_t *leaf; mleaf_t *leaf;
int sides; int sides;
int leafnum; int leafnum;
if (node->contents == CONTENTS_SOLID) if (node->contents == CONTENTS_SOLID)
return; return;
// add an efrag if the node is a leaf // add an efrag if the node is a leaf
if (node->contents < 0) { if (node->contents < 0) {
if (ent->num_leafs == MAX_ENT_LEAFS) if (ent->num_leafs == MAX_ENT_LEAFS)
return; return;
@ -338,12 +322,13 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
ent->num_leafs++; ent->num_leafs++;
return; return;
} }
// NODE_MIXED
// NODE_MIXED
splitplane = node->plane; splitplane = node->plane;
sides = BOX_ON_PLANE_SIDE (SVFIELD (ent, absmin, vector), SVFIELD (ent, absmax, vector), splitplane); sides = BOX_ON_PLANE_SIDE (SVFIELD (ent, absmin, vector),
SVFIELD (ent, absmax, vector), splitplane);
// recurse down the contacted sides // recurse down the contacted sides
if (sides & 1) if (sides & 1)
SV_FindTouchedLeafs (ent, node->children[0]); SV_FindTouchedLeafs (ent, node->children[0]);
@ -351,9 +336,7 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
SV_FindTouchedLeafs (ent, node->children[1]); SV_FindTouchedLeafs (ent, node->children[1]);
} }
/*
SV_LinkEdict
*/
void void
SV_LinkEdict (edict_t *ent, qboolean touch_triggers) SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
{ {
@ -368,22 +351,21 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
if (ent->free) if (ent->free)
return; return;
// set the abs box // set the abs box
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, absmin, vector)); VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector),
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, maxs, vector), SVFIELD (ent, absmax, vector)); SVFIELD (ent, absmin, vector));
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, maxs, vector),
SVFIELD (ent, absmax, vector));
// // to make items easier to pick up and allow them to be grabbed off
// to make items easier to pick up and allow them to be grabbed off // of shelves, the abs sizes are expanded
// of shelves, the abs sizes are expanded
//
if ((int) SVFIELD (ent, flags, float) & FL_ITEM) { if ((int) SVFIELD (ent, flags, float) & FL_ITEM) {
SVFIELD (ent, absmin, vector)[0] -= 15; SVFIELD (ent, absmin, vector)[0] -= 15;
SVFIELD (ent, absmin, vector)[1] -= 15; SVFIELD (ent, absmin, vector)[1] -= 15;
SVFIELD (ent, absmax, vector)[0] += 15; SVFIELD (ent, absmax, vector)[0] += 15;
SVFIELD (ent, absmax, vector)[1] += 15; SVFIELD (ent, absmax, vector)[1] += 15;
} else { // because movement is clipped an } else { // movement is clipped an epsilon away from actual edge, so we
// epsilon away from an actual edge, // must fully check even when bounding boxes don't quite touch
// we must fully check even when bounding boxes don't quite touch
SVFIELD (ent, absmin, vector)[0] -= 1; SVFIELD (ent, absmin, vector)[0] -= 1;
SVFIELD (ent, absmin, vector)[1] -= 1; SVFIELD (ent, absmin, vector)[1] -= 1;
SVFIELD (ent, absmin, vector)[2] -= 1; SVFIELD (ent, absmin, vector)[2] -= 1;
@ -392,7 +374,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
SVFIELD (ent, absmax, vector)[2] += 1; SVFIELD (ent, absmax, vector)[2] += 1;
} }
// link to PVS leafs // link to PVS leafs
ent->num_leafs = 0; ent->num_leafs = 0;
if (SVFIELD (ent, modelindex, float)) if (SVFIELD (ent, modelindex, float))
SV_FindTouchedLeafs (ent, sv.worldmodel->nodes); SV_FindTouchedLeafs (ent, sv.worldmodel->nodes);
@ -400,7 +382,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
if (SVFIELD (ent, solid, float) == SOLID_NOT) if (SVFIELD (ent, solid, float) == SOLID_NOT)
return; return;
// find the first node that the ent's box crosses // find the first node that the ent's box crosses
node = sv_areanodes; node = sv_areanodes;
while (1) { while (1) {
if (node->axis == -1) if (node->axis == -1)
@ -413,33 +395,28 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
break; // crosses the node break; // crosses the node
} }
// link it in // link it in
if (SVFIELD (ent, solid, float) == SOLID_TRIGGER) if (SVFIELD (ent, solid, float) == SOLID_TRIGGER)
InsertLinkBefore (&ent->area, &node->trigger_edicts); InsertLinkBefore (&ent->area, &node->trigger_edicts);
else else
InsertLinkBefore (&ent->area, &node->solid_edicts); InsertLinkBefore (&ent->area, &node->solid_edicts);
// if touch_triggers, touch all entities at this node and descend for more // if touch_triggers, touch all entities at this node and descend for more
if (touch_triggers) if (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
SV_HullPointContents
*/
int int
SV_HullPointContents (hull_t *hull, int num, vec3_t p) SV_HullPointContents (hull_t *hull, int num, vec3_t p)
{ {
float d; float d;
dclipnode_t *node; dclipnode_t *node;
mplane_t *plane; mplane_t *plane;
@ -462,20 +439,15 @@ SV_HullPointContents (hull_t *hull, int num, vec3_t p)
return num; return num;
} }
#endif // !USE_INTEL_ASM #endif // !USE_INTEL_ASM
/*
SV_PointContents
*/
int int
SV_PointContents (vec3_t p) SV_PointContents (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
@ -483,14 +455,14 @@ SV_PointContents (vec3_t p)
A small wrapper around SV_BoxInSolidEntity that never clips against the A small wrapper around SV_BoxInSolidEntity that never clips against the
supplied entity. supplied entity.
*/ */
edict_t * edict_t *
SV_TestEntityPosition (edict_t *ent) SV_TestEntityPosition (edict_t *ent)
{ {
trace_t trace; trace_t trace;
trace = trace = SV_Move (SVFIELD (ent, origin, vector),
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), SVFIELD (ent, origin, vector), 0, SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector),
ent); SVFIELD (ent, origin, vector), 0, ent);
if (trace.startsolid) if (trace.startsolid)
return sv.edicts; return sv.edicts;
@ -498,6 +470,7 @@ SV_TestEntityPosition (edict_t *ent)
return NULL; return NULL;
} }
/* /*
LINE TESTING IN HULLS LINE TESTING IN HULLS
*/ */
@ -505,9 +478,7 @@ SV_TestEntityPosition (edict_t *ent)
// 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)
/*
SV_RecursiveHullCheck
*/
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)
@ -521,7 +492,7 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
int side; int side;
float midf; float midf;
// check for empty // check for empty
if (num < 0) { if (num < 0) {
if (num != CONTENTS_SOLID) { if (num != CONTENTS_SOLID) {
trace->allsolid = false; trace->allsolid = false;
@ -537,9 +508,7 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
if (num < hull->firstclipnode || num > hull->lastclipnode) if (num < hull->firstclipnode || num > hull->lastclipnode)
SV_Error ("SV_RecursiveHullCheck: bad node number"); 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;
@ -553,21 +522,21 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
#if 1 #if 1
if (t1 >= 0 && t2 >= 0) if (t1 >= 0 && t2 >= 0)
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
trace); p2, trace);
if (t1 < 0 && t2 < 0) if (t1 < 0 && t2 < 0)
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
trace); p2, trace);
#else #else
if ((t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0)) if ((t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0))
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
trace); p2, trace);
if ((t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0)) if ((t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0))
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
trace); p2, trace);
#endif #endif
// put the crosspoint DIST_EPSILON pixels on the near side // put the crosspoint DIST_EPSILON pixels on the near side
if (t1 < 0) if (t1 < 0)
frac = (t1 + DIST_EPSILON) / (t1 - t2); frac = (t1 + DIST_EPSILON) / (t1 - t2);
else else
@ -583,7 +552,7 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
side = (t1 < 0); side = (t1 < 0);
// move up to the node // move up to the node
if (!SV_RecursiveHullCheck if (!SV_RecursiveHullCheck
(hull, node->children[side], p1f, midf, p1, mid, trace)) return false; (hull, node->children[side], p1f, midf, p1, mid, trace)) return false;
@ -597,16 +566,14 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
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, p2f, return SV_RecursiveHullCheck (hull, node->children[side ^ 1], midf,
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
//================== // 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;
@ -652,35 +619,34 @@ SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
vec3_t start_l, end_l; vec3_t start_l, end_l;
hull_t *hull; hull_t *hull;
// fill in a default trace // fill in a default trace
memset (&trace, 0, sizeof (trace_t)); memset (&trace, 0, sizeof (trace_t));
trace.fraction = 1; trace.fraction = 1;
trace.allsolid = true; trace.allsolid = true;
VectorCopy (end, trace.endpos); VectorCopy (end, trace.endpos);
// get the clipping hull // get the clipping hull
hull = SV_HullForEntity (ent, mins, maxs, offset); hull = SV_HullForEntity (ent, mins, maxs, offset);
VectorSubtract (start, offset, start_l); VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l); VectorSubtract (end, offset, end_l);
// trace a line through the apropriate clipping hull // trace a line through the apropriate clipping hull
SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l,
&trace); &trace);
// fix trace up by the offset // fix trace up by the offset
if (trace.fraction != 1) if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos); VectorAdd (trace.endpos, offset, trace.endpos);
// did we clip the move? // did we clip the move?
if (trace.fraction < 1 || trace.startsolid) if (trace.fraction < 1 || trace.startsolid)
trace.ent = ent; trace.ent = ent;
return trace; return trace;
} }
//===========================================================================
/* /*
SV_ClipToLinks SV_ClipToLinks
@ -694,7 +660,7 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
edict_t *touch; edict_t *touch;
trace_t trace; trace_t trace;
// touch linked edicts // touch linked edicts
for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) { for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) {
next = l->next; next = l->next;
touch = EDICT_FROM_AREA (l); touch = EDICT_FROM_AREA (l);
@ -705,7 +671,8 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
if (SVFIELD (touch, solid, float) == SOLID_TRIGGER) if (SVFIELD (touch, solid, float) == SOLID_TRIGGER)
SV_Error ("Trigger in clipping list"); SV_Error ("Trigger in clipping list");
if (clip->type == MOVE_NOMONSTERS && SVFIELD (touch, solid, float) != SOLID_BSP) if (clip->type == MOVE_NOMONSTERS && SVFIELD (touch, solid, float)
!= SOLID_BSP)
continue; continue;
if (clip->boxmins[0] > SVFIELD (touch, absmax, vector)[0] if (clip->boxmins[0] > SVFIELD (touch, absmax, vector)[0]
@ -730,13 +697,11 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
} }
if ((int) SVFIELD (touch, flags, float) & FL_MONSTER) if ((int) SVFIELD (touch, flags, float) & FL_MONSTER)
trace = trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2,
SV_ClipMoveToEntity (touch, clip->start, clip->mins2,
clip->maxs2, clip->end); clip->maxs2, clip->end);
else else
trace = trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins,
SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->maxs, clip->end);
clip->end);
if (trace.allsolid || trace.startsolid if (trace.allsolid || trace.startsolid
|| trace.fraction < clip->trace.fraction) { || trace.fraction < clip->trace.fraction) {
trace.ent = touch; trace.ent = touch;
@ -749,7 +714,7 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
clip->trace.startsolid = true; clip->trace.startsolid = true;
} }
// recurse down both sides // recurse down both sides
if (node->axis == -1) if (node->axis == -1)
return; return;
@ -760,19 +725,16 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
} }
/*
SV_MoveBounds
*/
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)
{ {
#if 0 #if 0
// debug to test against everything // debug to test against everything
boxmins[0] = boxmins[1] = boxmins[2] = -9999; boxmins[0] = boxmins[1] = boxmins[2] = -9999;
boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999; boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999;
#else #else
int i; int i;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (end[i] > start[i]) { if (end[i] > start[i]) {
@ -786,19 +748,17 @@ SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
#endif #endif
} }
/*
SV_Move
*/
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; moveclip_t clip;
int i; int i;
memset (&clip, 0, sizeof (moveclip_t)); memset (&clip, 0, sizeof (moveclip_t));
// clip to world // clip to world
clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end); clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end);
clip.start = start; clip.start = start;
@ -818,36 +778,32 @@ SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type,
VectorCopy (maxs, clip.maxs2); VectorCopy (maxs, clip.maxs2);
} }
// create the bounding box of the entire move // create the bounding box of the entire move
SV_MoveBounds (start, clip.mins2, clip.maxs2, end, clip.boxmins, SV_MoveBounds (start, clip.mins2, clip.maxs2, end, clip.boxmins,
clip.boxmaxs); clip.boxmaxs);
// clip to entities // clip to entities
SV_ClipToLinks (sv_areanodes, &clip); SV_ClipToLinks (sv_areanodes, &clip);
return clip.trace; return clip.trace;
} }
//=============================================================================
/* edict_t *
SV_TestPlayerPosition
*/
edict_t *
SV_TestPlayerPosition (edict_t *ent, vec3_t origin) SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
{ {
hull_t *hull; hull_t *hull;
edict_t *check; edict_t *check;
vec3_t boxmins, boxmaxs; vec3_t boxmins, boxmaxs;
vec3_t offset; vec3_t offset;
int e; int e;
// check world first // check world first
hull = &sv.worldmodel->hulls[1]; hull = &sv.worldmodel->hulls[1];
if (SV_HullPointContents (hull, hull->firstclipnode, origin) != if (SV_HullPointContents (hull, hull->firstclipnode, origin) !=
CONTENTS_EMPTY) return sv.edicts; CONTENTS_EMPTY) return sv.edicts;
// check all entities // check all entities
VectorAdd (origin, SVFIELD (ent, mins, vector), boxmins); VectorAdd (origin, SVFIELD (ent, mins, vector), boxmins);
VectorAdd (origin, SVFIELD (ent, maxs, vector), boxmaxs); VectorAdd (origin, SVFIELD (ent, maxs, vector), boxmaxs);
@ -855,8 +811,9 @@ SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
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 (SVFIELD (check, solid, float) != SOLID_BSP && if (SVFIELD (check, solid, float) != SOLID_BSP
SVFIELD (check, solid, float) != SOLID_BBOX && SVFIELD (check, solid, float) != SOLID_SLIDEBOX) && SVFIELD (check, solid, float) != SOLID_BBOX
&& SVFIELD (check, solid, float) != SOLID_SLIDEBOX)
continue; continue;
if (boxmins[0] > SVFIELD (check, absmax, vector)[0] if (boxmins[0] > SVFIELD (check, absmax, vector)[0]
@ -871,7 +828,8 @@ SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
continue; continue;
// get the clipping hull // get the clipping hull
hull = SV_HullForEntity (check, SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), offset); hull = SV_HullForEntity (check, SVFIELD (ent, mins, vector),
SVFIELD (ent, maxs, vector), offset);
VectorSubtract (origin, offset, offset); VectorSubtract (origin, offset, offset);