Add support for rotating entities to QW.

Same as the rotating entities in NQ. Unfortunately, I have some problems
with certain entities doing really weird things during collisions. I'll
sort that out later.
This commit is contained in:
Bill Currie 2011-09-05 21:05:09 +09:00
parent 71be8510e5
commit e6e1b10c58
6 changed files with 142 additions and 18 deletions

View file

@ -40,6 +40,7 @@
#define MAX_PHYSENTS (MAX_CLIENTS + MAX_PACKET_ENTITIES)
typedef struct {
vec3_t origin;
vec3_t angles;
model_t *model; // only for bsp models
vec3_t mins, maxs; // only for non-bsp models
hull_t *hull; // hey, magic :)

View file

@ -519,6 +519,7 @@ CL_SetSolidEntities (void)
pmove.physents[0].model = cl.worldmodel;
VectorZero (pmove.physents[0].origin);
VectorZero (pmove.physents[0].angles);
pmove.physents[0].info = 0;
pmove.numphysent = 1;
@ -543,6 +544,8 @@ CL_SetSolidEntities (void)
cl.model_precache[state->modelindex];
VectorCopy (state->origin,
pmove.physents[pmove.numphysent].origin);
VectorCopy (state->angles,
pmove.physents[pmove.numphysent].angles);
pmove.numphysent++;
}
}

View file

@ -214,6 +214,9 @@ PM_PlayerMove (const vec3_t start, const vec3_t end)
trace_t trace, total;
vec3_t maxs, mins, offset, start_l, end_l;
vec3_t move[2];
vec3_t forward, right, up;
int rot = 0;
vec3_t temp;
// fill in a default trace
memset (&total, 0, sizeof (trace_t));
@ -249,6 +252,23 @@ PM_PlayerMove (const vec3_t start, const vec3_t end)
VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l);
if (1 && pe->model && pe->model->type == mod_brush
&& !VectorIsZero (pe->angles)) {
rot = 1;
AngleVectors (pe->angles, forward, right, up);
VectorNegate (right, right); // convert lhs to rhs
VectorCopy (start_l, temp);
start_l[0] = DotProduct (temp, forward);
start_l[1] = DotProduct (temp, right);
start_l[2] = DotProduct (temp, up);
VectorCopy (end_l, temp);
end_l[0] = DotProduct (temp, forward);
end_l[1] = DotProduct (temp, right);
end_l[2] = DotProduct (temp, up);
}
// fill in a default trace
memset (&trace, 0, sizeof (trace_t));
@ -289,7 +309,25 @@ PM_PlayerMove (const vec3_t start, const vec3_t end)
// did we clip the move?
if (trace.fraction < total.fraction) {
// fix trace up by the offset
// fix up trace by the offset
if (rot) {
vec_t t;
// transpose the rotation matrix to get its inverse
t = forward[1]; forward[1] = right[0]; right[0] = t;
t = forward[2]; forward[2] = up[0]; up[0] = t;
t = right[2]; right[2] = up[1]; up[1] = t;
VectorCopy (trace.endpos, temp);
trace.endpos[0] = DotProduct (temp, forward);
trace.endpos[1] = DotProduct (temp, right);
trace.endpos[2] = DotProduct (temp, up);
VectorCopy (trace.plane.normal, temp);
trace.plane.normal[0] = DotProduct (temp, forward);
trace.plane.normal[1] = DotProduct (temp, right);
trace.plane.normal[2] = DotProduct (temp, up);
}
VectorAdd (trace.endpos, offset, trace.endpos);
total = trace;
total.ent = (struct edict_s *) &pmove.physents[i];

View file

@ -398,23 +398,35 @@ SV_PushEntity (edict_t *ent, vec3_t push)
}
static qboolean
SV_Push (edict_t *pusher, vec3_t move)
SV_Push (edict_t *pusher, const vec3_t tmove, const vec3_t amove)
{
float solid_save;
int num_moved, i, e;
edict_t *check, *block;
edict_t **moved_edict;
vec3_t mins, maxs, pushorig;
vec3_t move, org, org2;
vec3_t mins, maxs, pushtorig, pushaorig;
vec3_t *moved_from;
vec3_t forward = {1, 0, 0};
vec3_t right = {0, -1, 0};
vec3_t up = {0, 0, 1};
int mark;
VectorAdd (SVvector (pusher, absmin), move, mins);
VectorAdd (SVvector (pusher, absmax), move, maxs);
VectorAdd (SVvector (pusher, absmin), tmove, mins);
VectorAdd (SVvector (pusher, absmax), tmove, maxs);
VectorCopy (SVvector (pusher, origin), pushorig);
if (!VectorIsZero (amove)) {
vec3_t a;
VectorSubtract (vec3_origin, amove, a);
AngleVectors (a, forward, right, up);
}
VectorCopy (SVvector (pusher, origin), pushtorig);
VectorCopy (SVvector (pusher, angles), pushaorig);
// move the pusher to it's final position
VectorAdd (SVvector (pusher, origin), move, SVvector (pusher, origin));
VectorAdd (SVvector (pusher, origin), tmove, SVvector (pusher, origin));
VectorAdd (SVvector (pusher, angles), amove, SVvector (pusher, angles));
SV_LinkEdict (pusher, false);
mark = Hunk_LowMark ();
@ -462,6 +474,15 @@ SV_Push (edict_t *pusher, vec3_t move)
moved_edict[num_moved] = check;
num_moved++;
// calculate destination position
VectorSubtract (SVvector (check, origin),
SVvector (pusher, origin), org);
org2[0] = DotProduct (org, forward);
org2[1] = -DotProduct (org, right);
org2[2] = DotProduct (org, up);
VectorSubtract (org2, org, move);
VectorAdd (move, tmove, move);
// try moving the contacted entity
VectorAdd (SVvector (check, origin), move, SVvector (check, origin));
block = SV_TestEntityPosition (check);
@ -490,7 +511,8 @@ SV_Push (edict_t *pusher, vec3_t move)
continue;
}
VectorCopy (pushorig, SVvector (pusher, origin));
VectorCopy (pushtorig, SVvector (pusher, origin));
VectorCopy (pushaorig, SVvector (pusher, angles));
SV_LinkEdict (pusher, false);
// if the pusher has a "blocked" function, call it
@ -501,6 +523,8 @@ SV_Push (edict_t *pusher, vec3_t move)
// move back any entities we already moved
for (i = 0; i < num_moved; i++) {
VectorCopy (moved_from[i], SVvector (moved_edict[i], origin));
VectorSubtract (SVvector (moved_edict[i], angles), amove,
SVvector (moved_edict[i], angles));
SV_LinkEdict (moved_edict[i], false);
}
Hunk_FreeToLowMark (mark);
@ -514,15 +538,18 @@ static void
SV_PushMove (edict_t *pusher, float movetime)
{
vec3_t move;
vec3_t amove;
if (VectorIsZero (SVvector (pusher, velocity))) {
if (VectorIsZero (SVvector (pusher, velocity))
&& VectorIsZero (SVvector (pusher, avelocity))) {
SVfloat (pusher, ltime) += movetime;
return;
}
VectorScale (SVvector (pusher, velocity), movetime, move);
VectorScale (SVvector (pusher, avelocity), movetime, amove);
if (SV_Push (pusher, move))
if (SV_Push (pusher, move, amove))
SVfloat (pusher, ltime) += movetime;
}
@ -560,7 +587,7 @@ SV_Physics_Pusher (edict_t *ent)
l = VectorLength (move);
if (l > (1.0 / 64.0)) {
VectorCopy (oldorg, SVvector (ent, origin));
SV_Push (ent, move);
SV_Push (ent, move, vec3_origin); //FIXME angle
}
}
}

View file

@ -1540,6 +1540,7 @@ AddLinksToPmove (areanode_t *node)
pmove.numphysent++;
VectorCopy (SVvector (check, origin), pe->origin);
VectorCopy (SVvector (check, angles), pe->angles);
pe->info = NUM_FOR_EDICT (&sv_pr_state, check);
if (sv_fields.rotated_bbox != -1

View file

@ -455,11 +455,25 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
if (ent->free)
return;
// set the abs box
VectorAdd (SVvector (ent, origin), SVvector (ent, mins),
SVvector (ent, absmin));
VectorAdd (SVvector (ent, origin), SVvector (ent, maxs),
SVvector (ent, absmax));
if (SVfloat (ent, solid) == SOLID_BSP
&& !VectorIsZero (SVvector (ent, angles)) && ent != sv.edicts) {
float m, v;
vec3_t r;
m = DotProduct (SVvector (ent, mins), SVvector (ent, mins));
v = DotProduct (SVvector (ent, maxs), SVvector (ent, maxs));
if (m < v)
m = v;
m = sqrt (m);
VectorSet (m, m, m, r);
VectorSubtract (SVvector (ent, origin), r, SVvector (ent, absmin));
VectorAdd (SVvector (ent, origin), r, SVvector (ent, absmax));
} else {
// set the abs box
VectorAdd (SVvector (ent, origin), SVvector (ent, mins),
SVvector (ent, absmin));
VectorAdd (SVvector (ent, origin), SVvector (ent, maxs),
SVvector (ent, absmax));
}
// to make items easier to pick up and allow them to be grabbed off
// of shelves, the abs sizes are expanded
@ -591,6 +605,9 @@ SV_ClipMoveToEntity (edict_t *touched, const vec3_t start,
hull_t *hull;
trace_t trace;
vec3_t offset, start_l, end_l;
vec3_t forward, right, up;
int rot = 0;
vec3_t temp;
// fill in a default trace
memset (&trace, 0, sizeof (trace_t));
@ -607,12 +624,49 @@ SV_ClipMoveToEntity (edict_t *touched, const vec3_t start,
VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l);
if (SVfloat (touched, solid) == SOLID_BSP
&& !VectorIsZero (SVvector (touched, angles))
&& touched != sv.edicts) {
rot = 1;
AngleVectors (SVvector (touched, angles), forward, right, up);
VectorNegate (right, right); // convert lhs to rhs
VectorCopy (start_l, temp);
start_l[0] = DotProduct (temp, forward);
start_l[1] = DotProduct (temp, right);
start_l[2] = DotProduct (temp, up);
VectorCopy (end_l, temp);
end_l[0] = DotProduct (temp, forward);
end_l[1] = DotProduct (temp, right);
end_l[2] = DotProduct (temp, up);
}
// trace a line through the apropriate clipping hull
MOD_TraceLine (hull, hull->firstclipnode, start_l, end_l, &trace);
// fix trace up by the offset
if (trace.fraction != 1)
// fix up trace by the rotation and offset
if (trace.fraction != 1) {
if (rot) {
vec_t t;
// transpose the rotation matrix to get its inverse
t = forward[1]; forward[1] = right[0]; right[0] = t;
t = forward[2]; forward[2] = up[0]; up[0] = t;
t = right[2]; right[2] = up[1]; up[1] = t;
VectorCopy (trace.endpos, temp);
trace.endpos[0] = DotProduct (temp, forward);
trace.endpos[1] = DotProduct (temp, right);
trace.endpos[2] = DotProduct (temp, up);
VectorCopy (trace.plane.normal, temp);
trace.plane.normal[0] = DotProduct (temp, forward);
trace.plane.normal[1] = DotProduct (temp, right);
trace.plane.normal[2] = DotProduct (temp, up);
}
VectorAdd (trace.endpos, offset, trace.endpos);
}
// did we clip the move?
if (trace.fraction < 1 || trace.startsolid)