sort-of merge world.h and (mostly: Sys/Con vs SV) world.c this winds up

bringing rotated bboxes into nq :)
This commit is contained in:
Bill Currie 2001-08-27 22:16:11 +00:00
parent 3edd4550d2
commit 74dfef5cd1
7 changed files with 404 additions and 90 deletions

View file

@ -178,6 +178,8 @@ typedef struct
int pain_finished; //float
int radsuit_finished; //float
int speed; //Float
int rotated_bbox; //int
} sv_fields_t;
extern sv_fields_t sv_fields;

View file

@ -29,8 +29,9 @@
#ifndef __world_h
#define __world_h
#include "QF/qtypes.h"
#include "sv_progs.h"
#include "QF/link.h"
#include "QF/mathlib.h"
#include "QF/model.h"
typedef struct
{
@ -43,10 +44,10 @@ 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
plane_t plane; // surface normal at impact
edict_t *ent; // entity the surface is on
float fraction; // time completed, 1.0 = didn't hit anything
vec3_t endpos; // final position
plane_t plane; // surface normal at impact
struct edict_s *ent; // entity the surface is on
} trace_t;
@ -54,16 +55,31 @@ typedef struct
#define MOVE_NOMONSTERS 1
#define MOVE_MISSILE 2
typedef struct areanode_s
{
int axis; // -1 = leaf node
float dist;
struct areanode_s *children[2];
link_t trigger_edicts;
link_t solid_edicts;
} areanode_t;
#define AREA_DEPTH 4
#define AREA_NODES 32
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
void SV_UnlinkEdict (edict_t *ent);
void SV_UnlinkEdict (struct edict_s *ent);
// call before removing an entity, and before trying to move one,
// so it doesn't clip against itself
// flags ent->v.modified
void SV_LinkEdict (edict_t *ent, qboolean touch_triggers);
void SV_LinkEdict (struct edict_s *ent, qboolean touch_triggers);
// Needs to be called any time an entity changes origin, mins, maxs, or solid
// flags ent->v.modified
// sets ent->v.absmin and ent->v.absmax
@ -75,9 +91,9 @@ int SV_TruePointContents (vec3_t p);
// does not check any entities at all
// the non-true version remaps the water current contents to content_water
edict_t *SV_TestEntityPosition (edict_t *ent);
struct edict_s *SV_TestEntityPosition (struct edict_s *ent);
trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict);
trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, struct edict_s *passedict);
// mins and maxs are reletive
// if the entire move stays in a solid volume, trace.allsolid will be set
@ -90,4 +106,9 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
// passedict is explicitly excluded from clipping checks (normally NULL)
struct edict_s *SV_TestPlayerPosition (struct edict_s *ent, vec3_t origin);
int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
hull_t *SV_HullForEntity (struct edict_s *ent, vec3_t mins, vec3_t maxs, vec3_t offset);
#endif // __world_h

View file

@ -36,17 +36,19 @@
# include <strings.h>
#endif
#include "QF/clip_hull.h"
#include "QF/console.h"
#include "compat.h"
#include "QF/cvar.h"
#include "QF/sys.h"
#include "QF/cmd.h"
#include "QF/va.h"
#include "host.h"
#include "world.h"
#include "QF/msg.h"
#include "compat.h"
#include "host.h"
#include "server.h"
#include "sv_progs.h"
#include "world.h"
#define RETURN_EDICT(p, e) ((p)->pr_globals[OFS_RETURN].integer_var = EDICT_TO_PROG(p, e))
@ -1422,6 +1424,177 @@ PF_sqrt (progs_t *pr)
#endif
#define MAX_PF_HULLS 64 // FIXME make dynamic?
clip_hull_t *pf_hull_list[MAX_PF_HULLS];
static void
PF_hullpointcontents (progs_t *pr)
{
edict_t *edict = G_EDICT (pr, OFS_PARM0);
float *mins = G_VECTOR (pr, OFS_PARM1);
float *maxs = G_VECTOR (pr, OFS_PARM2);
float *point = G_VECTOR (pr, OFS_PARM3);
hull_t *hull;
vec3_t offset;
hull = SV_HullForEntity (edict, mins, maxs, offset);
VectorSubtract (point, offset, offset);
G_INT (pr, OFS_RETURN) = SV_HullPointContents (hull, 0, offset);
}
static void
PF_getboxbounds (progs_t *pr)
{
int h = G_INT (pr, OFS_PARM0) - 1;
clip_hull_t *ch;
if (h < 0 || h > MAX_PF_HULLS - 1 || !(ch = pf_hull_list[h]))
PR_RunError (pr, "PF_freeboxhull: invalid box hull handle\n");
if (G_INT (pr, OFS_PARM1)) {
VectorCopy (ch->maxs, G_VECTOR (pr, OFS_RETURN));
} else {
VectorCopy (ch->mins, G_VECTOR (pr, OFS_RETURN));
}
}
static void
PF_getboxhull (progs_t *pr)
{
clip_hull_t *ch = 0;
int i;
for (i = 0; i < MAX_PF_HULLS; i++) {
if (!pf_hull_list[i]) {
ch = MOD_Alloc_Hull (6, 6);
break;
}
}
if (ch) {
pf_hull_list[i] = ch;
G_INT (pr, OFS_RETURN) = i + 1;
for (i = 0; i < MAX_MAP_HULLS; i++)
SV_InitHull (ch->hulls[i], ch->hulls[i]->clipnodes,
ch->hulls[i]->planes);
} else {
G_INT (pr, OFS_RETURN) = 0;
}
}
static void
PF_freeboxhull (progs_t *pr)
{
int h = G_INT (pr, OFS_PARM0) - 1;
clip_hull_t *ch;
if (h < 0 || h > MAX_PF_HULLS - 1 || !(ch = pf_hull_list[h]))
PR_RunError (pr, "PF_freeboxhull: invalid box hull handle\n");
pf_hull_list[h] = 0;
MOD_Free_Hull (ch);
}
static vec_t
calc_dist (vec3_t p, vec3_t n, vec3_t *offsets)
{
vec_t d = DotProduct (p, n);
vec3_t s, v;
int i;
VectorScale (n, d, s);
for (i = 0; i < 3; i++)
if (s[i] < 0)
v[i] = offsets[0][i];
else
v[i] = offsets[1][i];
VectorAdd (p, v, v);
return DotProduct (v, n);
}
static void
PF_rotate_bbox (progs_t *pr)
{
int h = G_INT (pr, OFS_PARM0) - 1;
float *dir[3] = {
G_VECTOR (pr, OFS_PARM1),
G_VECTOR (pr, OFS_PARM2),
G_VECTOR (pr, OFS_PARM3),
};
float *mi = G_VECTOR (pr, OFS_PARM4);
float *ma = G_VECTOR (pr, OFS_PARM5);
vec3_t mins, maxs;
float *verts[6] = {maxs, mins, maxs, mins, maxs, mins};
vec3_t offsets[3][2] = {
{ { 0, 0, 0 }, { 0, 0, 0} },
{ { -16, -16, -32 }, { 16, 16, 24} },
{ { -32, -32, -64 }, { 32, 32, 24} },
};
vec3_t v[8], d;
hull_t *hull;
clip_hull_t *ch;
int i, j;
float l;
if (h < 0 || h > MAX_PF_HULLS - 1 || !(ch = pf_hull_list[h]))
PR_RunError (pr, "PF_freeboxhull: invalid box hull handle\n");
// set up the rotation matrix. the three orientation vectors form the
// columns of the rotation matrix
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
ch->axis[i][j] = dir[j][i];
}
}
// rotate the bounding box points
for (i = 0; i < 3; i++) {
mins[i] = DotProduct (ch->axis[i], mi);
maxs[i] = DotProduct (ch->axis[i], ma);
}
// find all 8 corners of the rotated box
VectorCopy (mins, v[0]);
VectorCopy (maxs, v[1]);
VectorSubtract (maxs, mins, d);
for (i = 0; i < 3; i++) {
vec3_t x;
l = DotProduct (d, dir[i]);
VectorScale (dir[i], l, x);
VectorAdd (mins, x, v[2 + i * 2]);
VectorSubtract (maxs, x, v[3 + i * 2]);
}
// now find the aligned bounding box
VectorCopy (v[0], ch->mins);
VectorCopy (v[0], ch->maxs);
for (i = 0; i < 8; i++) {
//Con_Printf ("'%0.1f %0.1f %0.1f'\n", v[i][0], v[i][1], v[i][2]);
for (j = 0; j < 3; j++) {
ch->mins[j] = min (ch->mins[j], v[i][j]);
ch->maxs[j] = max (ch->maxs[j], v[i][j]);
}
}
// set up the 3 size based hulls
for (j = 0; j < 3; j++) {
hull = ch->hulls[j];
VectorScale (offsets[j][1], -1, hull->clip_mins);
VectorScale (offsets[j][0], -1, hull->clip_maxs);
// set up the clip planes
for (i = 0; i < 6; i++) {
hull->planes[i].dist = calc_dist (verts[i], dir[i / 2], offsets[j]);
hull->planes[i].type = 4;
VectorCopy (dir[i / 2], hull->planes[i].normal);
//Con_Printf ("%f %f %f %f\n",
// hull->planes[i].dist,
// hull->planes[i].normal[0], hull->planes[i].normal[1],
// hull->planes[i].normal[2]);
}
}
}
void
PF_Fixme (progs_t *pr)
{
@ -1508,5 +1681,10 @@ SV_PR_Cmds_Init ()
PR_AddBuiltin (&sv_pr_state, "setspawnparms", PF_setspawnparms, 78); // void(entity e) setspawnparms = #78
PR_AddBuiltin (&sv_pr_state, "getboxbounds", PF_getboxbounds, 94); // vector (integer hull, integer max) getboxbounds = #94
PR_AddBuiltin (&sv_pr_state, "getboxhull", PF_getboxhull, 95); // integer () getboxhull = #95
PR_AddBuiltin (&sv_pr_state, "freeboxhull", PF_freeboxhull, 96); // void (integer hull) freeboxhull = #96
PR_AddBuiltin (&sv_pr_state, "rotate_bbox", PF_rotate_bbox, 97); // void (integer hull, vector right, vector forward, vector up, vector mins, vector maxs) rotate_bbox = #97
PR_AddBuiltin (&sv_pr_state, "checkextension", PF_checkextension, 99); // = #99
}

View file

@ -302,6 +302,8 @@ SV_LoadProgs (void)
sv_fields.light_level = ED_GetFieldIndex (&sv_pr_state, "light_level");
sv_fields.items2 = ED_GetFieldIndex (&sv_pr_state, "items2");
sv_fields.pitch_speed = ED_GetFieldIndex (&sv_pr_state, "pitch_speed");
sv_fields.rotated_bbox = ED_GetFieldIndex (&sv_pr_state, "rotated_bbox");
}
void

View file

@ -29,9 +29,18 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdio.h>
#include "QF/clip_hull.h"
#include "QF/console.h"
#include "QF/model.h"
#include "QF/crc.h"
#include "QF/sys.h"
#include "server.h"
@ -39,8 +48,8 @@
#include "world.h"
/*
entities never clip against themselves, or their owner
line of sight checks trace->crosscontent, but bullets don't
entities never clip against themselves, or their owner
line of sight checks trace->crosscontent, but bullets don't
*/
typedef struct {
@ -57,7 +66,9 @@ typedef struct {
int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
/* HULL BOXES */
/*
HULL BOXES
*/
static hull_t box_hull;
static dclipnode_t box_clipnodes[6];
@ -65,39 +76,45 @@ 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);
}
/*
SV_HullForBox
@ -117,6 +134,7 @@ SV_HullForBox (vec3_t mins, vec3_t maxs)
return &box_hull;
}
/*
SV_HullForEntity
@ -131,10 +149,27 @@ 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;
hull_t *hull = 0;
int hull_index = 0;
if ((sv_fields.rotated_bbox != -1
&& SVinteger (ent, rotated_bbox))
|| SVfloat (ent, solid) == SOLID_BSP) {
VectorSubtract (maxs, mins, size);
if (size[0] < 3)
hull_index = 0;
else if (size[0] <= 32)
hull_index = 1;
else
hull_index = 2;
}
// decide which clipping hull to use, based on the size
if (SVfloat (ent, solid) == SOLID_BSP) {
if (sv_fields.rotated_bbox != -1
&& SVinteger (ent, rotated_bbox)) {
extern clip_hull_t *pf_hull_list[];
int h = SVinteger (ent, rotated_bbox) - 1;
hull = pf_hull_list[h]->hulls[hull_index];
} if (SVfloat (ent, solid) == SOLID_BSP) {
// explicit hulls in the BSP model
if (SVfloat (ent, movetype) != MOVETYPE_PUSH)
Sys_Error ("SOLID_BSP without MOVETYPE_PUSH");
@ -144,14 +179,10 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
if (!model || model->type != mod_brush)
Sys_Error ("MOVETYPE_PUSH with a non bsp model");
VectorSubtract (maxs, mins, size);
if (size[0] < 3)
hull = &model->hulls[0];
else if (size[0] <= 32)
hull = &model->hulls[1];
else
hull = &model->hulls[2];
hull = &model->hulls[hull_index];
}
if (hull) {
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, SVvector (ent, origin), offset);
@ -166,21 +197,14 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
return hull;
}
/* ENTITY AREA CHECKING */
typedef struct areanode_s {
int axis; // -1 = leaf node
float dist;
struct areanode_s *children[2];
link_t trigger_edicts;
link_t solid_edicts;
} areanode_t;
/*
ENTITY AREA CHECKING
*/
#define AREA_DEPTH 4
#define AREA_NODES 32
areanode_t sv_areanodes[AREA_NODES];
int sv_numareanodes;
static areanode_t sv_areanodes[AREA_NODES];
static int sv_numareanodes;
areanode_t *
SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs)
@ -221,6 +245,7 @@ SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs)
return anode;
}
void
SV_ClearWorld (void)
{
@ -231,6 +256,7 @@ SV_ClearWorld (void)
SV_CreateAreaNode (0, sv.worldmodel->mins, sv.worldmodel->maxs);
}
void
SV_UnlinkEdict (edict_t *ent)
{
@ -240,6 +266,7 @@ SV_UnlinkEdict (edict_t *ent)
ent->area.prev = ent->area.next = NULL;
}
void
SV_TouchLinks (edict_t *ent, areanode_t *node)
{
@ -286,6 +313,7 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
SV_TouchLinks (ent, node->children[1]);
}
void
SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
{
@ -323,6 +351,7 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
SV_FindTouchedLeafs (ent, node->children[1]);
}
void
SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
{
@ -392,7 +421,11 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
SV_TouchLinks (ent, sv_areanodes);
}
/* POINT TESTING IN HULLS */
/*
POINT TESTING IN HULLS
*/
#ifndef USE_INTEL_ASM
int
@ -423,6 +456,7 @@ SV_HullPointContents (hull_t *hull, int num, vec3_t p)
}
#endif // !USE_INTEL_ASM
int
SV_PointContents (vec3_t p)
{
@ -434,16 +468,20 @@ SV_PointContents (vec3_t p)
return cont;
}
int
SV_TruePointContents (vec3_t p)
{
return SV_HullPointContents (&sv.worldmodel->hulls[0], 0, p);
}
/*
SV_TestEntityPosition
This could be a lot more efficient...
A small wrapper around SV_BoxInSolidEntity that never clips against the
supplied entity.
*/
edict_t *
SV_TestEntityPosition (edict_t *ent)
@ -461,11 +499,15 @@ SV_TestEntityPosition (edict_t *ent)
return NULL;
}
/* LINE TESTING IN HULLS */
/*
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, vec3_t p1,
vec3_t p2, trace_t *trace)
@ -590,6 +632,7 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
return false;
}
/*
SV_ClipMoveToEntity
@ -597,8 +640,8 @@ SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
eventually rotation) of the end points
*/
trace_t
SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
vec3_t end)
SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, vec3_t start,
vec3_t mins, vec3_t maxs, vec3_t end)
{
trace_t trace;
vec3_t offset;
@ -613,7 +656,7 @@ SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
VectorCopy (end, trace.endpos);
// get the clipping hull
hull = SV_HullForEntity (ent, mins, maxs, offset);
hull = SV_HullForEntity (touched, mins, maxs, offset);
VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l);
@ -628,11 +671,12 @@ SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
// did we clip the move?
if (trace.fraction < 1 || trace.startsolid)
trace.ent = ent;
trace.ent = touched;
return trace;
}
/*
SV_ClipToLinks
@ -685,11 +729,11 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
}
if ((int) SVfloat (touch, flags) & FL_MONSTER)
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2,
clip->maxs2, clip->end);
trace = SV_ClipMoveToEntity (touch, clip->passedict, clip->start,
clip->mins2, clip->maxs2, clip->end);
else
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins,
clip->maxs, clip->end);
trace = SV_ClipMoveToEntity (touch, clip->passedict, clip->start,
clip->mins, clip->maxs, clip->end);
if (trace.allsolid || trace.startsolid
|| trace.fraction < clip->trace.fraction) {
trace.ent = touch;
@ -712,6 +756,7 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
SV_ClipToLinks (node->children[1], clip);
}
void
SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
vec3_t boxmins, vec3_t boxmaxs)
@ -735,6 +780,7 @@ SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
#endif
}
trace_t
SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type,
edict_t *passedict)
@ -745,7 +791,7 @@ SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type,
memset (&clip, 0, sizeof (moveclip_t));
// clip to world
clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end);
clip.trace = SV_ClipMoveToEntity (sv.edicts, passedict, start, mins, maxs, end);
clip.start = start;
clip.end = end;
@ -773,3 +819,57 @@ SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type,
return clip.trace;
}
edict_t *
SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
{
hull_t *hull;
edict_t *check;
vec3_t boxmins, boxmaxs;
vec3_t offset;
int e;
// check world first
hull = &sv.worldmodel->hulls[1];
if (SV_HullPointContents (hull, hull->firstclipnode, origin) !=
CONTENTS_EMPTY) return sv.edicts;
// check all entities
VectorAdd (origin, SVvector (ent, mins), boxmins);
VectorAdd (origin, SVvector (ent, maxs), boxmaxs);
check = NEXT_EDICT (&sv_pr_state, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_pr_state, check)) {
if (check->free)
continue;
if (check == ent)
continue;
if (SVfloat (check, solid) != SOLID_BSP
&& SVfloat (check, solid) != SOLID_BBOX
&& SVfloat (check, solid) != SOLID_SLIDEBOX)
continue;
if (boxmins[0] > SVvector (check, absmax)[0]
|| boxmins[1] > SVvector (check, absmax)[1]
|| boxmins[2] > SVvector (check, absmax)[2]
|| boxmaxs[0] < SVvector (check, absmin)[0]
|| boxmaxs[1] < SVvector (check, absmin)[1]
|| boxmaxs[2] < SVvector (check, absmin)[2])
continue;
// get the clipping hull
hull = SV_HullForEntity (check, SVvector (ent, mins),
SVvector (ent, maxs), offset);
VectorSubtract (origin, offset, offset);
// test the point
if (SV_HullPointContents (hull, hull->firstclipnode, offset) !=
CONTENTS_EMPTY)
return check;
}
return NULL;
}

View file

@ -1,7 +1,7 @@
/*
world.h
(description)
@description@
Copyright (C) 1996-1997 Id Software, Inc.
@ -25,11 +25,11 @@
$Id$
*/
// world.h
#ifndef _WORLD_H
#define _WORLD_H
#ifndef __world_h
#define __world_h
#include "QF/link.h"
#include "QF/mathlib.h"
#include "QF/model.h"
@ -41,15 +41,16 @@ typedef struct
typedef struct
{
qboolean allsolid; // if true, plane is not valid
qboolean startsolid; // if true, the initial point was in a solid area
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
plane_t plane; // surface normal at impact
edict_t *ent; // entity the surface is on
float fraction; // time completed, 1.0 = didn't hit anything
vec3_t endpos; // final position
plane_t plane; // surface normal at impact
struct edict_s *ent; // entity the surface is on
} trace_t;
#define MOVE_NORMAL 0
#define MOVE_NOMONSTERS 1
#define MOVE_MISSILE 2
@ -73,24 +74,26 @@ 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
void SV_UnlinkEdict (edict_t *ent);
void SV_UnlinkEdict (struct edict_s *ent);
// call before removing an entity, and before trying to move one,
// so it doesn't clip against itself
// flags ent->v.modified
void SV_LinkEdict (edict_t *ent, qboolean touch_triggers);
void SV_LinkEdict (struct edict_s *ent, qboolean touch_triggers);
// Needs to be called any time an entity changes origin, mins, maxs, or solid
// flags ent->v.modified
// sets ent->v.absmin and ent->v.absmax
// if touchtriggers, calls prog functions for the intersected triggers
int SV_PointContents (vec3_t p);
int SV_TruePointContents (vec3_t p);
// returns the CONTENTS_* value from the world at the given point.
// does not check any entities at all
// the non-true version remaps the water current contents to content_water
edict_t *SV_TestEntityPosition (edict_t *ent);
struct edict_s *SV_TestEntityPosition (struct edict_s *ent);
trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict);
trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, struct edict_s *passedict);
// mins and maxs are reletive
// if the entire move stays in a solid volume, trace.allsolid will be set
@ -103,10 +106,9 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
// passedict is explicitly excluded from clipping checks (normally NULL)
edict_t *SV_TestPlayerPosition (edict_t *ent, vec3_t origin);
struct edict_s *SV_TestPlayerPosition (struct edict_s *ent, vec3_t origin);
int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset);
hull_t *SV_HullForEntity (struct edict_s *ent, vec3_t mins, vec3_t maxs, vec3_t offset);
#endif // _WORLD_H
#endif // __world_h

View file

@ -47,14 +47,10 @@
#include "world.h"
/*
entities never clip against themselves, or their owner
line of sight checks trace->crosscontent, but bullets don't
entities never clip against themselves, or their owner
line of sight checks trace->crosscontent, but bullets don't
*/
typedef struct {
vec3_t boxmins, boxmaxs; // enclose the test object along
// entire move
@ -67,7 +63,6 @@ typedef struct {
edict_t *passedict;
} moveclip_t;
int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
/*
@ -463,6 +458,18 @@ SV_HullPointContents (hull_t *hull, int num, vec3_t p)
int
SV_PointContents (vec3_t p)
{
int cont;
cont = SV_HullPointContents (&sv.worldmodel->hulls[0], 0, p);
if (cont <= CONTENTS_CURRENT_0 && cont >= CONTENTS_CURRENT_DOWN)
cont = CONTENTS_WATER;
return cont;
}
int
SV_TruePointContents (vec3_t p)
{
return SV_HullPointContents (&sv.worldmodel->hulls[0], 0, p);
}
@ -471,6 +478,7 @@ SV_PointContents (vec3_t p)
/*
SV_TestEntityPosition
This could be a lot more efficient...
A small wrapper around SV_BoxInSolidEntity that never clips against the
supplied entity.
*/
@ -817,8 +825,8 @@ SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
{
hull_t *hull;
edict_t *check;
vec3_t boxmins, boxmaxs;
vec3_t offset;
vec3_t boxmins, boxmaxs;
vec3_t offset;
int e;
// check world first
@ -858,7 +866,8 @@ SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
// test the point
if (SV_HullPointContents (hull, hull->firstclipnode, offset) !=
CONTENTS_EMPTY) return check;
CONTENTS_EMPTY)
return check;
}
return NULL;