mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Rotating bsp model support.
This is based on the code presented on http://forums.inside3d.com/viewtopic.php?t=2376 (and updates linked from that thread), but with modifications for hopefully supporting rotating trains (and not duplicating big fuctions). For now, only nq. qw will come after some more testing.
This commit is contained in:
parent
0e677ce0f0
commit
775f8e959b
2 changed files with 100 additions and 17 deletions
|
@ -397,24 +397,35 @@ SV_PushEntity (edict_t *ent, vec3_t push)
|
|||
}
|
||||
|
||||
static qboolean
|
||||
SV_Push (edict_t *pusher, vec3_t move)
|
||||
SV_Push (edict_t *pusher, vec3_t tmove, vec3_t amove)
|
||||
{
|
||||
float solid_save;
|
||||
int num_moved, i, e;
|
||||
edict_t *check, *block;
|
||||
edict_t **moved_edict;
|
||||
vec3_t entorig;
|
||||
vec3_t mins, maxs, pushorig;
|
||||
vec3_t entorig, 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 ();
|
||||
|
@ -460,6 +471,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
|
||||
solid_save = SVfloat (pusher, solid);
|
||||
SVfloat (pusher, solid) = SOLID_NOT;
|
||||
|
@ -468,6 +488,8 @@ SV_Push (edict_t *pusher, vec3_t move)
|
|||
|
||||
block = SV_TestEntityPosition (check);
|
||||
if (!block) {
|
||||
VectorAdd (SVvector (check, angles), amove,
|
||||
SVvector (check, angles));
|
||||
continue;
|
||||
}
|
||||
// if it is still inside the pusher, block
|
||||
|
@ -484,7 +506,8 @@ SV_Push (edict_t *pusher, vec3_t move)
|
|||
VectorCopy (entorig, SVvector (check, origin));
|
||||
SV_LinkEdict (check, true);
|
||||
|
||||
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
|
||||
|
@ -495,6 +518,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);
|
||||
|
@ -508,15 +533,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,50 @@ 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 trace up 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