rotated bounding box support. this is so totally untested it's not funny

(though it does compile). Keeps things simple and only checks touched.

.integer rotated_bbox;

ent.rotated_bbox = getboxhull ();// be sure to check for failure (0)
rotate_bbox (ent.rotated_bbox, ent.angles, ent.mins, ent.maxs);
...
freeboxhull (ent.rotated_bbox); // when freeing entity. box hulls are limited

integer () getboxhull = #95
void (integer hull) freeboxhull = #96
void (integer hull, vector angles, vector mins, vector maxs) rotate_bbox = #97
This commit is contained in:
Bill Currie 2001-07-26 04:26:54 +00:00
parent 22219fdeb0
commit 5ebee4a28b
3 changed files with 120 additions and 33 deletions

View file

@ -69,6 +69,8 @@ typedef struct areanode_s
extern areanode_t sv_areanodes[AREA_NODES];
void SV_InitHull (hull_t *hull, dclipnode_t *clipnodes, mplane_t *planes);
void SV_ClearWorld (void);
// called after the world model has been loaded, before linking any entities

View file

@ -1805,6 +1805,88 @@ PF_setinfokey (progs_t *pr)
}
#define MAX_PF_HULLS 64 // FIXME make dynamic?
static int pf_hull_list_inited;
static hull_t *pf_free_hulls;
static dclipnode_t pf_clipnodes[MAX_PF_HULLS][6];
static mplane_t pf_planes[MAX_PF_HULLS][6];
hull_t pf_hull_list[MAX_PF_HULLS];
static void
PF_getboxhull (progs_t *pr)
{
hull_t *hull = pf_free_hulls;
if (!pf_hull_list_inited) {
int i;
pf_hull_list_inited = 1;
for (i = 0; i < MAX_PF_HULLS - 1; i++)
pf_hull_list[i].clipnodes = (dclipnode_t*)&pf_hull_list[i + 1];
pf_hull_list[i].clipnodes = 0;
pf_free_hulls = pf_hull_list;
}
if (hull) {
pf_free_hulls = (hull_t*)hull->clipnodes;
SV_InitHull (hull, pf_clipnodes[hull - pf_hull_list],
pf_planes[hull - pf_hull_list]);
}
G_INT (pr, OFS_RETURN) = (hull - pf_hull_list) + 1;
}
static void
PF_freeboxhull (progs_t *pr)
{
int h = G_INT (pr, OFS_PARM0);
hull_t *hull = &pf_hull_list[h];
if (h < 1 || h > MAX_PF_HULLS
|| hull->clipnodes != pf_clipnodes[h]
|| hull->planes != pf_planes[h])
PR_RunError (pr, "PF_freeboxhull: invalid box hull handle\n");
hull->clipnodes = (dclipnode_t*)pf_free_hulls;
hull->planes = 0;
pf_free_hulls = hull;
}
static void
PF_rotate_bbox (progs_t *pr)
{
int h = G_INT (pr, OFS_PARM0);
float *angles = G_VECTOR (pr, OFS_PARM1);
float *mins = G_VECTOR (pr, OFS_PARM2);
float *maxs = G_VECTOR (pr, OFS_PARM3);
vec3_t f, r, u;
hull_t *hull = &pf_hull_list[h];
AngleVectors (angles, f, r, u);
hull->planes[0].dist = DotProduct (f, maxs);
hull->planes[0].type = 4;
VectorCopy (f, hull->planes[0].normal);
hull->planes[1].dist = DotProduct (f, mins);
hull->planes[1].type = 4;
VectorCopy (f, hull->planes[1].normal);
hull->planes[2].dist = DotProduct (r, maxs);
hull->planes[2].type = 4;
VectorCopy (r, hull->planes[2].normal);
hull->planes[3].dist = DotProduct (r, mins);
hull->planes[3].type = 4;
VectorCopy (r, hull->planes[3].normal);
hull->planes[4].dist = DotProduct (u, maxs);
hull->planes[4].type = 4;
VectorCopy (u, hull->planes[4].normal);
hull->planes[5].dist = DotProduct (u, mins);
hull->planes[5].type = 4;
VectorCopy (u, hull->planes[5].normal);
}
void
PF_Fixme (progs_t *pr)
{
@ -1924,9 +2006,9 @@ builtin_t sv_builtins[] = {
PF_Fixme, // 92
PF_Fixme, // 93
PF_Fixme, // 94
PF_Fixme, // 95
PF_Fixme, // 96
PF_Fixme, // 97
PF_getboxhull, // integer () getboxhull = #95
PF_freeboxhull, // void (integer hull) freeboxhull = #96
PF_rotate_bbox, // void (integer hull, vector angles, vector mins, vector maxs) rotate_bbox = #97
PF_checkmove, // void (vector start, vector mins, vector maxs, vector end, float type, entity passent) checkmove = #98
PF_Checkextension, // = #99
PF_strlen, // = #100

View file

@ -79,37 +79,42 @@ static mplane_t box_planes[6];
/*
SV_InitBoxHull
SV_InitHull 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
SV_InitBoxHull (void)
SV_InitHull (hull_t *hull, dclipnode_t *clipnodes, mplane_t *planes)
{
int i;
int side;
box_hull.clipnodes = box_clipnodes;
box_hull.planes = box_planes;
box_hull.firstclipnode = 0;
box_hull.lastclipnode = 5;
hull->clipnodes = clipnodes;
hull->planes = planes;
hull->firstclipnode = 0;
hull->lastclipnode = 5;
for (i = 0; i < 6; i++) {
box_clipnodes[i].planenum = i;
hull->clipnodes[i].planenum = i;
side = i & 1;
box_clipnodes[i].children[side] = CONTENTS_EMPTY;
hull->clipnodes[i].children[side] = CONTENTS_EMPTY;
if (i != 5)
box_clipnodes[i].children[side ^ 1] = i + 1;
hull->clipnodes[i].children[side ^ 1] = i + 1;
else
box_clipnodes[i].children[side ^ 1] = CONTENTS_SOLID;
hull->clipnodes[i].children[side ^ 1] = CONTENTS_SOLID;
box_planes[i].type = i >> 1;
box_planes[i].normal[i >> 1] = 1;
hull->planes[i].type = i >> 1;
hull->planes[i].normal[i >> 1] = 1;
}
}
void
SV_InitBoxHull (void)
{
SV_InitHull (&box_hull, box_clipnodes, box_planes);
}
@ -628,29 +633,27 @@ SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, vec3_t start,
VectorCopy (end, trace.endpos);
if (sv_fields.rotated_bbox != -1
&& (SVFIELD (mover, rotated_bbox, integer)
|| SVFIELD (touched, rotated_bbox, integer))) {
// get the hull
// get relative start and end locations
// rotate hull(?) and start/end locations
// run the hull check
// unrotate the trace
&& SVFIELD (touched, rotated_bbox, integer)) {
// keep things simple for now, only test against touched
extern hull_t pf_hull_list[];
hull = &pf_hull_list[SVFIELD (touched, rotated_bbox, integer) - 1];
VectorCopy (SVFIELD (touched, origin, vector), offset);
} else {
// get the clipping hull
hull = SV_HullForEntity (touched, mins, maxs, offset);
VectorSubtract (start, offset, start_l);
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);
// fix trace up by the offset
if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos);
}
VectorSubtract (start, offset, start_l);
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);
// fix trace up by the offset
if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos);
// did we clip the move?
if (trace.fraction < 1 || trace.startsolid)
trace.ent = touched;