From 5ebee4a28b4986a32774bf7dabb3274efd8e0d08 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 26 Jul 2001 04:26:54 +0000 Subject: [PATCH] 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 --- qw/include/world.h | 2 + qw/source/sv_pr_cmds.c | 88 ++++++++++++++++++++++++++++++++++++++++-- qw/source/world.c | 63 ++++++++++++++++-------------- 3 files changed, 120 insertions(+), 33 deletions(-) diff --git a/qw/include/world.h b/qw/include/world.h index 67286ff5b..b90bf8f64 100644 --- a/qw/include/world.h +++ b/qw/include/world.h @@ -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 diff --git a/qw/source/sv_pr_cmds.c b/qw/source/sv_pr_cmds.c index 505c65d6b..2a5dab84d 100644 --- a/qw/source/sv_pr_cmds.c +++ b/qw/source/sv_pr_cmds.c @@ -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 diff --git a/qw/source/world.c b/qw/source/world.c index 38f72981a..0db3a8cb1 100644 --- a/qw/source/world.c +++ b/qw/source/world.c @@ -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;