Get nq and qw world.c into sync (again:P)

This commit is contained in:
Bill Currie 2010-12-08 12:55:07 +09:00
parent e46b52a81c
commit a893d8ead3
3 changed files with 214 additions and 86 deletions

View file

@ -178,6 +178,14 @@ typedef struct client_s
#define FL_PARTIALGROUND 1024 // not all corners are valid #define FL_PARTIALGROUND 1024 // not all corners are valid
#define FL_WATERJUMP 2048 // player jumping out of water #define FL_WATERJUMP 2048 // player jumping out of water
#define FL_JUMPRELEASED 4096 // for jump debouncing #define FL_JUMPRELEASED 4096 // for jump debouncing
#define FL_FINALIZED 8192
#define FL_FINDABLE_NONSOLID 16384
#define TL_ANY_SOLID 0
#define TL_BSP_ONLY 1
// 2 used internally (MOVE_MISSILE)
#define TL_TRIGGERS 3 // scan for triggers
#define TL_EVERYTHING 4 // scan for anything
// entity effects // entity effects

View file

@ -213,6 +213,17 @@ SV_HullForEntity (edict_t *ent, const vec3_t mins, const vec3_t maxs,
model_t *model; model_t *model;
vec3_t hullmins, hullmaxs, size; vec3_t hullmins, hullmaxs, size;
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;
}
if (sv_fields.rotated_bbox != -1 if (sv_fields.rotated_bbox != -1
&& SVinteger (ent, rotated_bbox)) { && SVinteger (ent, rotated_bbox)) {
int h = SVinteger (ent, rotated_bbox) - 1; int h = SVinteger (ent, rotated_bbox) - 1;
@ -220,12 +231,18 @@ SV_HullForEntity (edict_t *ent, const vec3_t mins, const vec3_t maxs,
} if (SVfloat (ent, solid) == SOLID_BSP) { } if (SVfloat (ent, solid) == SOLID_BSP) {
// explicit hulls in the BSP model // explicit hulls in the BSP model
if (SVfloat (ent, movetype) != MOVETYPE_PUSH) if (SVfloat (ent, movetype) != MOVETYPE_PUSH)
Sys_Error ("SOLID_BSP without MOVETYPE_PUSH"); Sys_Error ("SOLID_BSP without MOVETYPE_PUSH: %d %s",
NUM_FOR_EDICT (&sv_pr_state, ent),
PR_GetString (&sv_pr_state,
SVstring (ent, classname)));
model = sv.models[(int) SVfloat (ent, modelindex)]; model = sv.models[(int) SVfloat (ent, modelindex)];
if (!model || model->type != mod_brush) if (!model || model->type != mod_brush)
Sys_Error ("SOLID_BSP with a non bsp model"); Sys_Error ("SOLID_BSP with a non bsp model: %d %s",
NUM_FOR_EDICT (&sv_pr_state, ent),
PR_GetString (&sv_pr_state,
SVstring (ent, classname)));
hull_list = model->hull_list; hull_list = model->hull_list;
} }
@ -347,8 +364,8 @@ SV_UnlinkEdict (edict_t *ent)
static void static void
SV_TouchLinks (edict_t *ent, areanode_t *node) SV_TouchLinks (edict_t *ent, areanode_t *node)
{ {
edict_t *touch;
int old_self, old_other; int old_self, old_other;
edict_t *touch;
link_t *l, *next; link_t *l, *next;
// touch linked edicts // touch linked edicts
@ -558,7 +575,6 @@ SV_TestEntityPosition (edict_t *ent)
if (trace.startsolid) if (trace.startsolid)
return sv.edicts; return sv.edicts;
return NULL; return NULL;
} }
@ -569,7 +585,7 @@ SV_TestEntityPosition (edict_t *ent)
eventually rotation) of the end points eventually rotation) of the end points
*/ */
static trace_t static trace_t
SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, const vec3_t start, SV_ClipMoveToEntity (edict_t *touched, const vec3_t start,
const vec3_t mins, const vec3_t maxs, const vec3_t end) const vec3_t mins, const vec3_t maxs, const vec3_t end)
{ {
hull_t *hull; hull_t *hull;
@ -605,73 +621,149 @@ SV_ClipMoveToEntity (edict_t *touched, edict_t *mover, const vec3_t start,
return trace; return trace;
} }
/* static inline int
SV_ClipToLinks ctl_pretest_everything (edict_t *touch, moveclip_t *clip)
Mins and maxs enclose the entire area swept by the move
*/
static void
SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
{ {
edict_t *touch; if (touch->free)
link_t *l, *next; return 0;
trace_t trace; if (!((int) SVfloat (touch, flags) & FL_FINDABLE_NONSOLID)) {
// touch linked edicts
for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) {
next = l->next;
touch = EDICT_FROM_AREA (l);
if (SVfloat (touch, solid) == SOLID_NOT) if (SVfloat (touch, solid) == SOLID_NOT)
continue; return 0;
if (SVfloat (touch, solid) == SOLID_TRIGGER)
return 0;
}
if (touch == clip->passedict) if (touch == clip->passedict)
continue; return 0;
return 1;
}
static inline int
ctl_pretest_triggers (edict_t *touch, moveclip_t *clip)
{
if (SVfloat (touch, solid) != SOLID_TRIGGER)
return 0;
if (!((int) SVfloat (touch, flags) & FL_FINDABLE_NONSOLID))
return 0;
if (touch == clip->passedict)
return 0;
return 1;
}
static inline int
ctl_pretest_other (edict_t *touch, moveclip_t *clip)
{
if (SVfloat (touch, solid) == SOLID_NOT)
return 0;
if (touch == clip->passedict)
return 0;
if (SVfloat (touch, solid) == SOLID_TRIGGER) if (SVfloat (touch, solid) == SOLID_TRIGGER)
Sys_Error ("Trigger in clipping list"); Sys_Error ("Trigger in clipping list");
if (clip->type == MOVE_NOMONSTERS if (clip->type == MOVE_NOMONSTERS && SVfloat (touch, solid) != SOLID_BSP)
&& SVfloat (touch, solid) != SOLID_BSP) return 0;
continue; return 1;
}
static inline int
ctl_touch_test (edict_t *touch, moveclip_t *clip)
{
if (clip->boxmins[0] > SVvector (touch, absmax)[0] if (clip->boxmins[0] > SVvector (touch, absmax)[0]
|| clip->boxmins[1] > SVvector (touch, absmax)[1] || clip->boxmins[1] > SVvector (touch, absmax)[1]
|| clip->boxmins[2] > SVvector (touch, absmax)[2] || clip->boxmins[2] > SVvector (touch, absmax)[2]
|| clip->boxmaxs[0] < SVvector (touch, absmin)[0] || clip->boxmaxs[0] < SVvector (touch, absmin)[0]
|| clip->boxmaxs[1] < SVvector (touch, absmin)[1] || clip->boxmaxs[1] < SVvector (touch, absmin)[1]
|| clip->boxmaxs[2] < SVvector (touch, absmin)[2]) || clip->boxmaxs[2] < SVvector (touch, absmin)[2])
continue; return 0;
if (clip->passedict != 0 && SVvector (clip->passedict, size)[0] if (clip->passedict && SVvector (clip->passedict, size)[0]
&& !SVvector (touch, size)[0]) && !SVvector (touch, size)[0])
continue; // points never interact return 0; // points never interact
// might intersect, so do an exact clip // might intersect, so do an exact clip
if (clip->trace.allsolid)
return;
if (clip->passedict) { if (clip->passedict) {
if (PROG_TO_EDICT (&sv_pr_state, SVentity (touch, owner)) if (PROG_TO_EDICT (&sv_pr_state, SVentity (touch, owner))
== clip->passedict) == clip->passedict)
continue; // don't clip against own missiles return 0; // don't clip against own missiles
if (PROG_TO_EDICT (&sv_pr_state, if (PROG_TO_EDICT (&sv_pr_state,
SVentity (clip->passedict, owner)) == touch) SVentity (clip->passedict, owner)) == touch)
continue; // don't clip against owner return 0; // don't clip against owner
} }
return 1;
}
static void
ctl_do_clip (edict_t *touch, moveclip_t *clip, trace_t *trace)
{
if ((int) SVfloat (touch, flags) & FL_MONSTER) if ((int) SVfloat (touch, flags) & FL_MONSTER)
trace = SV_ClipMoveToEntity (touch, clip->passedict, clip->start, *trace = SV_ClipMoveToEntity (touch, clip->start,
clip->mins2, clip->maxs2, clip->end); clip->mins2, clip->maxs2, clip->end);
else else
trace = SV_ClipMoveToEntity (touch, clip->passedict, clip->start, *trace = SV_ClipMoveToEntity (touch, clip->start,
clip->mins, clip->maxs, clip->end); clip->mins, clip->maxs, 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;
if (clip->trace.startsolid) { if (clip->trace.startsolid) {
clip->trace = trace; clip->trace = *trace;
clip->trace.startsolid = true; clip->trace.startsolid = true;
} else } else
clip->trace = trace; clip->trace = *trace;
} else if (trace.startsolid) } else if (trace->startsolid)
clip->trace.startsolid = true; clip->trace.startsolid = true;
}
/*
SV_ClipToLinks
Mins and maxs enclose the entire area swept by the move
*/
static void
SV_ClipToLinks (areanode_t *node, moveclip_t *clip)
{
edict_t *touch;
link_t *l, *next;
trace_t trace;
int i;
if (clip->type == TL_EVERYTHING) {
touch = NEXT_EDICT (&sv_pr_state, sv.edicts);
for (i = 1; i < sv.num_edicts; i++,
touch = NEXT_EDICT (&sv_pr_state, touch)) {
if (clip->trace.allsolid)
return;
if (!ctl_pretest_everything (touch, clip))
continue;
if (!ctl_touch_test (touch, clip))
continue;
ctl_do_clip (touch, clip, &trace);
}
} else if (clip->type == TL_TRIGGERS) {
for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) {
next = l->next;
touch = EDICT_FROM_AREA (l);
if (clip->trace.allsolid)
return;
if (!ctl_pretest_triggers (touch, clip))
continue;
if (!ctl_touch_test (touch, clip))
continue;
ctl_do_clip (touch, clip, &trace);
}
} else {
// touch linked edicts
for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) {
next = l->next;
touch = EDICT_FROM_AREA (l);
if (clip->trace.allsolid)
return;
if (!ctl_pretest_other (touch, clip))
continue;
if (!ctl_touch_test (touch, clip))
continue;
ctl_do_clip (touch, clip, &trace);
}
} }
// recurse down both sides // recurse down both sides
@ -717,8 +809,7 @@ SV_Move (const vec3_t start, const vec3_t mins, const vec3_t maxs,
memset (&clip, 0, sizeof (moveclip_t)); memset (&clip, 0, sizeof (moveclip_t));
// clip to world // clip to world
clip.trace = SV_ClipMoveToEntity (sv.edicts, passedict, start, clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end);
mins, maxs, end);
clip.start = start; clip.start = start;
clip.end = end; clip.end = end;
clip.mins = mins; clip.mins = mins;

View file

@ -208,8 +208,8 @@ hull_t *
SV_HullForEntity (edict_t *ent, const vec3_t mins, const vec3_t maxs, SV_HullForEntity (edict_t *ent, const vec3_t mins, const vec3_t maxs,
vec3_t extents, vec3_t offset) vec3_t extents, vec3_t offset)
{ {
hull_t *hull = 0;
int hull_index = 0; int hull_index = 0;
hull_t *hull = 0, **hull_list = 0;
model_t *model; model_t *model;
vec3_t hullmins, hullmaxs, size; vec3_t hullmins, hullmaxs, size;
@ -224,11 +224,10 @@ SV_HullForEntity (edict_t *ent, const vec3_t mins, const vec3_t maxs,
else else
hull_index = 2; hull_index = 2;
} }
// decide which clipping hull to use, based on the size
if (sv_fields.rotated_bbox != -1 if (sv_fields.rotated_bbox != -1
&& SVinteger (ent, rotated_bbox)) { && SVinteger (ent, rotated_bbox)) {
int h = SVinteger (ent, rotated_bbox) - 1; int h = SVinteger (ent, rotated_bbox) - 1;
hull = pf_hull_list[h]->hulls[hull_index]; hull_list = pf_hull_list[h]->hulls;
} if (SVfloat (ent, solid) == SOLID_BSP) { } if (SVfloat (ent, solid) == SOLID_BSP) {
// explicit hulls in the BSP model // explicit hulls in the BSP model
if (SVfloat (ent, movetype) != MOVETYPE_PUSH) if (SVfloat (ent, movetype) != MOVETYPE_PUSH)
@ -245,20 +244,50 @@ SV_HullForEntity (edict_t *ent, const vec3_t mins, const vec3_t maxs,
PR_GetString (&sv_pr_state, PR_GetString (&sv_pr_state,
SVstring (ent, classname))); SVstring (ent, classname)));
hull = &model->hulls[hull_index]; hull_list = model->hull_list;
}
if (hull_list) {
// decide which clipping hull to use, based on the size
VectorSubtract (maxs, mins, size);
if (extents) {
VectorScale (size, 0.5, extents);
} else {
if (size[0] < 3)
hull_index = 0;
else if (size[0] <= 32)
hull_index = 1;
else
hull_index = 2;
}
hull = hull_list[hull_index];
} }
if (hull) { if (hull) {
// calculate an offset value to center the origin // calculate an offset value to center the origin
if (extents) {
VectorAdd (extents, mins, offset);
VectorSubtract (SVvector (ent, origin), offset, offset);
} else {
VectorSubtract (hull->clip_mins, mins, offset); VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, SVvector (ent, origin), offset); VectorAdd (offset, SVvector (ent, origin), offset);
} else { // create a temp hull from bounding box sizes }
} else {
// create a temp hull from bounding box sizes
if (extents) {
VectorCopy (SVvector (ent, mins), hullmins);
VectorCopy (SVvector (ent, maxs), hullmaxs);
//FIXME broken for map models (ie, origin always 0, 0, 0)
VectorAdd (extents, mins, offset);
VectorSubtract (SVvector (ent, origin), offset, offset);
} else {
VectorSubtract (SVvector (ent, mins), maxs, hullmins); VectorSubtract (SVvector (ent, mins), maxs, hullmins);
VectorSubtract (SVvector (ent, maxs), mins, hullmaxs); VectorSubtract (SVvector (ent, maxs), mins, hullmaxs);
hull = SV_HullForBox (hullmins, hullmaxs);
VectorCopy (SVvector (ent, origin), offset); VectorCopy (SVvector (ent, origin), offset);
} }
hull = SV_HullForBox (hullmins, hullmaxs);
}
return hull; return hull;
} }
@ -568,10 +597,12 @@ SV_ClipMoveToEntity (edict_t *touched, const vec3_t start,
trace.fraction = 1; trace.fraction = 1;
trace.allsolid = true; trace.allsolid = true;
trace.isbox = 0;
VectorCopy (end, trace.endpos); VectorCopy (end, trace.endpos);
// get the clipping hull // get the clipping hull
hull = SV_HullForEntity (touched, mins, maxs, 0, offset); hull = SV_HullForEntity (touched, mins, maxs,
trace.isbox ? trace.extents : 0, offset);
VectorSubtract (start, offset, start_l); VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l); VectorSubtract (end, offset, end_l);
@ -690,7 +721,7 @@ static void
SV_ClipToLinks (areanode_t *node, moveclip_t *clip) SV_ClipToLinks (areanode_t *node, moveclip_t *clip)
{ {
edict_t *touch; edict_t *touch;
link_t *l; link_t *l, *next;
trace_t trace; trace_t trace;
int i; int i;
@ -707,8 +738,8 @@ SV_ClipToLinks (areanode_t *node, moveclip_t *clip)
ctl_do_clip (touch, clip, &trace); ctl_do_clip (touch, clip, &trace);
} }
} else if (clip->type == TL_TRIGGERS) { } else if (clip->type == TL_TRIGGERS) {
for (l = node->solid_edicts.next; for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) {
l != &node->solid_edicts; l = l->next) { next = l->next;
touch = EDICT_FROM_AREA (l); touch = EDICT_FROM_AREA (l);
if (clip->trace.allsolid) if (clip->trace.allsolid)
@ -721,8 +752,8 @@ SV_ClipToLinks (areanode_t *node, moveclip_t *clip)
} }
} else { } else {
// touch linked edicts // touch linked edicts
for (l = node->solid_edicts.next; for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) {
l != &node->solid_edicts; l = l->next) { next = l->next;
touch = EDICT_FROM_AREA (l); touch = EDICT_FROM_AREA (l);
if (clip->trace.allsolid) if (clip->trace.allsolid)
@ -745,7 +776,7 @@ SV_ClipToLinks (areanode_t *node, moveclip_t *clip)
SV_ClipToLinks (node->children[1], clip); SV_ClipToLinks (node->children[1], clip);
} }
static void static inline void
SV_MoveBounds (const vec3_t start, const vec3_t mins, const vec3_t maxs, SV_MoveBounds (const vec3_t start, const vec3_t mins, const vec3_t maxs,
const vec3_t end, vec3_t boxmins, vec3_t boxmaxs) const vec3_t end, vec3_t boxmins, vec3_t boxmaxs)
{ {
@ -778,9 +809,7 @@ SV_Move (const vec3_t start, const vec3_t mins, const vec3_t maxs,
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, clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end);
mins, maxs, end);
clip.start = start; clip.start = start;
clip.end = end; clip.end = end;
clip.mins = mins; clip.mins = mins;
@ -811,9 +840,9 @@ SV_Move (const vec3_t start, const vec3_t mins, const vec3_t maxs,
edict_t * edict_t *
SV_TestPlayerPosition (edict_t *ent, const vec3_t origin) SV_TestPlayerPosition (edict_t *ent, const vec3_t origin)
{ {
int e;
edict_t *check; edict_t *check;
hull_t *hull; hull_t *hull;
int e;
vec3_t boxmins, boxmaxs, offset; vec3_t boxmins, boxmaxs, offset;
// check world first // check world first