mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-03-12 22:03:49 +00:00
baker's rotation turorial from http://forums.inside3d.com/viewtopic.php?f=12&t=2376
This commit is contained in:
parent
a3f63c8023
commit
22251acaff
2 changed files with 271 additions and 36 deletions
|
@ -568,6 +568,143 @@ void SV_PushMove (edict_t *pusher, float movetime)
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
SV_PushRotate
|
||||
|
||||
============
|
||||
*/
|
||||
void SV_PushRotate (edict_t *pusher, float movetime)
|
||||
{
|
||||
int i, e;
|
||||
edict_t *check, *block;
|
||||
vec3_t move, a, amove;
|
||||
vec3_t entorig, pushorig;
|
||||
int num_moved;
|
||||
edict_t *moved_edict[MAX_EDICTS];
|
||||
vec3_t moved_from[MAX_EDICTS];
|
||||
vec3_t org, org2;
|
||||
vec3_t forward, right, up;
|
||||
|
||||
if (!pusher->v.avelocity[0] && !pusher->v.avelocity[1] && !pusher->v.avelocity[2])
|
||||
{
|
||||
pusher->v.ltime += movetime;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
amove[i] = pusher->v.avelocity[i] * movetime;
|
||||
|
||||
VectorSubtract (vec3_origin, amove, a);
|
||||
AngleVectors (a, forward, right, up);
|
||||
|
||||
VectorCopy (pusher->v.angles, pushorig);
|
||||
|
||||
// move the pusher to it's final position
|
||||
|
||||
VectorAdd (pusher->v.angles, amove, pusher->v.angles);
|
||||
pusher->v.ltime += movetime;
|
||||
SV_LinkEdict (pusher, false);
|
||||
|
||||
|
||||
// see if any solid entities are inside the final position
|
||||
num_moved = 0;
|
||||
check = NEXT_EDICT(sv.edicts);
|
||||
for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
|
||||
{
|
||||
if (check->free)
|
||||
continue;
|
||||
if (check->v.movetype == MOVETYPE_PUSH
|
||||
|| check->v.movetype == MOVETYPE_NONE
|
||||
// || check->v.movetype == MOVETYPE_FOLLOW
|
||||
|| check->v.movetype == MOVETYPE_NOCLIP)
|
||||
continue;
|
||||
|
||||
// if the entity is standing on the pusher, it will definately be moved
|
||||
if ( ! ( ((int)check->v.flags & FL_ONGROUND)
|
||||
&& PROG_TO_EDICT(check->v.groundentity) == pusher) )
|
||||
{
|
||||
if ( check->v.absmin[0] >= pusher->v.absmax[0]
|
||||
|| check->v.absmin[1] >= pusher->v.absmax[1]
|
||||
|| check->v.absmin[2] >= pusher->v.absmax[2]
|
||||
|| check->v.absmax[0] <= pusher->v.absmin[0]
|
||||
|| check->v.absmax[1] <= pusher->v.absmin[1]
|
||||
|| check->v.absmax[2] <= pusher->v.absmin[2] )
|
||||
continue;
|
||||
|
||||
// see if the ent's bbox is inside the pusher's final position
|
||||
if (!SV_TestEntityPosition (check))
|
||||
continue;
|
||||
}
|
||||
|
||||
// remove the onground flag for non-players
|
||||
if (check->v.movetype != MOVETYPE_WALK)
|
||||
check->v.flags = (int)check->v.flags & ~FL_ONGROUND;
|
||||
|
||||
VectorCopy (check->v.origin, entorig);
|
||||
VectorCopy (check->v.origin, moved_from[num_moved]);
|
||||
moved_edict[num_moved] = check;
|
||||
num_moved++;
|
||||
|
||||
// calculate destination position
|
||||
VectorSubtract (check->v.origin, pusher->v.origin, org);
|
||||
org2[0] = DotProduct (org, forward);
|
||||
org2[1] = -DotProduct (org, right);
|
||||
org2[2] = DotProduct (org, up);
|
||||
VectorSubtract (org2, org, move);
|
||||
|
||||
// try moving the contacted entity
|
||||
pusher->v.solid = SOLID_NOT;
|
||||
SV_PushEntity (check, move);
|
||||
pusher->v.solid = SOLID_BSP;
|
||||
|
||||
// if it is still inside the pusher, block
|
||||
block = SV_TestEntityPosition (check);
|
||||
if (block)
|
||||
{ // fail the move
|
||||
if (check->v.mins[0] == check->v.maxs[0])
|
||||
continue;
|
||||
if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
|
||||
{ // corpse
|
||||
check->v.mins[0] = check->v.mins[1] = 0;
|
||||
VectorCopy (check->v.mins, check->v.maxs);
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorCopy (entorig, check->v.origin);
|
||||
SV_LinkEdict (check, true);
|
||||
|
||||
VectorCopy (pushorig, pusher->v.angles);
|
||||
SV_LinkEdict (pusher, false);
|
||||
pusher->v.ltime -= movetime;
|
||||
|
||||
// if the pusher has a "blocked" function, call it
|
||||
// otherwise, just stay in place until the obstacle is gone
|
||||
if (pusher->v.blocked)
|
||||
{
|
||||
pr_global_struct->self = EDICT_TO_PROG(pusher);
|
||||
pr_global_struct->other = EDICT_TO_PROG(check);
|
||||
PR_ExecuteProgram (pusher->v.blocked);
|
||||
}
|
||||
|
||||
// move back any entities we already moved
|
||||
for (i=0 ; i<num_moved ; i++)
|
||||
{
|
||||
VectorCopy (moved_from[i], moved_edict[i]->v.origin);
|
||||
VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles);
|
||||
SV_LinkEdict (moved_edict[i], false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorAdd (check->v.angles, amove, check->v.angles);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_Physics_Pusher
|
||||
|
@ -594,6 +731,11 @@ void SV_Physics_Pusher (edict_t *ent)
|
|||
|
||||
if (movetime)
|
||||
{
|
||||
//ROTATE START
|
||||
if ((ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2]) && ent->v.solid == SOLID_BSP)
|
||||
SV_PushRotate (ent, host_frametime);
|
||||
else
|
||||
//ROTATE END
|
||||
SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked
|
||||
}
|
||||
|
||||
|
|
|
@ -403,8 +403,40 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
|
|||
return;
|
||||
|
||||
// set the abs box
|
||||
// ROTATE START
|
||||
if (ent->v.solid == SOLID_BSP &&
|
||||
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) && ent != sv.edicts)
|
||||
{ // expand for rotation
|
||||
float max, v;
|
||||
int i;
|
||||
|
||||
max = DotProduct(ent->v.mins, ent->v.mins);
|
||||
|
||||
v = DotProduct(ent->v.maxs, ent->v.maxs);
|
||||
|
||||
if (max < v)
|
||||
|
||||
max = v;
|
||||
|
||||
max = sqrt(max);
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
|
||||
{
|
||||
|
||||
ent->v.absmin[i] = ent->v.origin[i] - max;
|
||||
|
||||
ent->v.absmax[i] = ent->v.origin[i] + max;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// ROTATE END
|
||||
VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);
|
||||
VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax);
|
||||
}
|
||||
|
||||
//
|
||||
// to make items easier to pick up and allow them to be grabbed off
|
||||
|
@ -697,44 +729,105 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec
|
|||
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_ClipMoveToEntity
|
||||
|
||||
Handles selection or creation of a clipping hull, and offseting (and
|
||||
eventually rotation) of the end points
|
||||
==================
|
||||
*/
|
||||
==================
|
||||
SV_ClipMoveToEntity
|
||||
|
||||
Handles selection or creation of a clipping hull, and offseting (and
|
||||
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)
|
||||
{
|
||||
trace_t trace;
|
||||
vec3_t offset;
|
||||
vec3_t start_l, end_l;
|
||||
hull_t *hull;
|
||||
|
||||
// fill in a default trace
|
||||
memset (&trace, 0, sizeof(trace_t));
|
||||
trace.fraction = 1;
|
||||
trace.allsolid = true;
|
||||
VectorCopy (end, trace.endpos);
|
||||
|
||||
// get the clipping hull
|
||||
hull = SV_HullForEntity (ent, mins, maxs, offset);
|
||||
|
||||
VectorSubtract (start, offset, start_l);
|
||||
VectorSubtract (end, offset, end_l);
|
||||
|
||||
// trace a line through the apropriate clipping hull
|
||||
SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace);
|
||||
|
||||
// fix trace up by the offset
|
||||
if (trace.fraction != 1)
|
||||
VectorAdd (trace.endpos, offset, trace.endpos);
|
||||
|
||||
// did we clip the move?
|
||||
if (trace.fraction < 1 || trace.startsolid )
|
||||
trace.ent = ent;
|
||||
|
||||
return trace;
|
||||
trace_t trace;
|
||||
vec3_t offset;
|
||||
vec3_t start_l, end_l;
|
||||
hull_t *hull;
|
||||
|
||||
// fill in a default trace
|
||||
memset (&trace, 0, sizeof(trace_t));
|
||||
trace.fraction = 1;
|
||||
trace.allsolid = true;
|
||||
VectorCopy (end, trace.endpos);
|
||||
|
||||
// get the clipping hull
|
||||
hull = SV_HullForEntity (ent, mins, maxs, offset);
|
||||
|
||||
VectorSubtract (start, offset, start_l);
|
||||
VectorSubtract (end, offset, end_l);
|
||||
|
||||
// ROTATE START
|
||||
// rotate start and end into the models frame of reference
|
||||
if (ent->v.solid == SOLID_BSP &&
|
||||
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) && ent != sv.edicts)
|
||||
{
|
||||
vec3_t a;
|
||||
vec3_t forward, right, up;
|
||||
vec3_t temp;
|
||||
|
||||
AngleVectors (ent->v.angles, forward, right, up);
|
||||
|
||||
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);
|
||||
}
|
||||
// ROTATE END
|
||||
|
||||
// trace a line through the apropriate clipping hull
|
||||
SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace);
|
||||
|
||||
|
||||
// ROTATE START
|
||||
// rotate endpos back to world frame of reference
|
||||
if (ent->v.solid == SOLID_BSP &&
|
||||
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) && ent != sv.edicts)
|
||||
{
|
||||
vec3_t a;
|
||||
vec3_t forward, right, up;
|
||||
vec3_t temp;
|
||||
|
||||
if (trace.fraction != 1)
|
||||
{
|
||||
VectorSubtract (vec3_origin, ent->v.angles, a);
|
||||
AngleVectors (a, forward, right, up);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// fix trace up by the offset
|
||||
VectorAdd (trace.endpos, offset, trace.endpos);
|
||||
|
||||
}
|
||||
#if 1 // Baker addition
|
||||
// Cases where not Solid BSP or no avelocity
|
||||
// Otherwise backpacks from dead monsters and such can fall through the floor
|
||||
else {
|
||||
if (trace.fraction != 1)
|
||||
VectorAdd (trace.endpos, offset, trace.endpos);
|
||||
|
||||
}
|
||||
#endif
|
||||
// ROTATE END
|
||||
|
||||
|
||||
// did we clip the move?
|
||||
if (trace.fraction < 1 || trace.startsolid )
|
||||
trace.ent = ent;
|
||||
|
||||
return trace;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
Loading…
Reference in a new issue