mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-20 01:11:18 +00:00
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:
parent
71be8510e5
commit
e6e1b10c58
6 changed files with 142 additions and 18 deletions
|
@ -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 :)
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue