mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
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:
parent
3edd4550d2
commit
74dfef5cd1
7 changed files with 404 additions and 90 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue