From 79364be7e78057695411165ed1e3a7119f0d55ff Mon Sep 17 00:00:00 2001 From: lordhavoc Date: Fri, 15 Feb 2002 21:19:04 +0000 Subject: [PATCH] fixed rotating+moving pushers (teleport ball in end.bsp), cleaned up code a lot double precision RecursiveHullCheck git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1514 d7cf8633-e32d-0410-b094-e92efae38249 --- sv_phys.c | 316 ++++++++++++++++++------------------------------------ world.c | 298 +++----------------------------------------------- 2 files changed, 120 insertions(+), 494 deletions(-) diff --git a/sv_phys.c b/sv_phys.c index 855abe16..f0fe0642 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -172,7 +172,7 @@ void SV_Impact (edict_t *e1, edict_t *e2) pr_global_struct->other = EDICT_TO_PROG(e2); PR_ExecuteProgram (e1->v.touch, ""); } - + if (e2->v.touch && e2->v.solid != SOLID_NOT) { pr_global_struct->self = EDICT_TO_PROG(e2); @@ -233,10 +233,7 @@ Returns the clipflags if the velocity was modified (hit something solid) If steptrace is not NULL, the trace of any vertical wall hit will be stored ============ */ -// LordHavoc: increased from 5 to 20, to partially fix angled corner sticking -// (example - start.bsp hall to e4, leading to the pool there are two -// angled corners, which you could get stuck on, now they are just a one -// frame hiccup) +// LordHavoc: increased from 5 to 20 #define MAX_CLIP_PLANES 20 int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) { @@ -251,9 +248,9 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) vec3_t end; float time_left; int blocked; - + numbumps = 4; - + blocked = 0; VectorCopy (ent->v.velocity, original_velocity); VectorCopy (ent->v.velocity, primal_velocity); @@ -313,9 +310,9 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) if (ent->free) break; // removed by the impact function - + time_left -= time_left * trace.fraction; - + // cliped to another plane if (numplanes >= MAX_CLIP_PLANES) { // this shouldn't really happen @@ -341,7 +338,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) if (j == numplanes) break; } - + if (i != numplanes) { // go along this plane VectorCopy (new_velocity, ent->v.velocity); @@ -412,11 +409,11 @@ SV_PushEntity Does not change the entities velocity at all ============ */ -trace_t SV_PushEntity (edict_t *ent, vec3_t push) +trace_t SV_PushEntity (edict_t *ent, vec3_t push, vec3_t pushangles) { trace_t trace; vec3_t end; - + VectorAdd (ent->v.origin, push, end); if (ent->v.movetype == MOVETYPE_FLYMISSILE) @@ -425,16 +422,18 @@ trace_t SV_PushEntity (edict_t *ent, vec3_t push) // only clip against bmodels trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent); else - trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent); - + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent); + VectorCopy (trace.endpos, ent->v.origin); + // FIXME: turn players specially + ent->v.angles[1] += trace.fraction * pushangles[1]; SV_LinkEdict (ent, true); if (trace.ent) - SV_Impact (ent, trace.ent); + SV_Impact (ent, trace.ent); return trace; -} +} /* @@ -445,14 +444,14 @@ SV_PushMove */ void SV_PushMove (edict_t *pusher, float movetime) { - int i, e; + int i, e, index; edict_t *check; - vec3_t mins, maxs, move; - vec3_t entorig, pushorig; + float savesolid, movetime2, pushltime; + vec3_t mins, maxs, move, move1, moveangle, entorig, entang, pushorig, pushang, a, forward, left, up, org, org2; int num_moved; edict_t *moved_edict[MAX_EDICTS]; - vec3_t moved_from[MAX_EDICTS]; - float savesolid; + vec3_t moved_from[MAX_EDICTS], moved_fromangles[MAX_EDICTS]; + model_t *pushermodel; switch ((int) pusher->v.solid) { @@ -466,33 +465,70 @@ void SV_PushMove (edict_t *pusher, float movetime) case SOLID_NOT: case SOLID_TRIGGER: VectorMA (pusher->v.origin, movetime, pusher->v.velocity, pusher->v.origin); + VectorMA (pusher->v.angles, movetime, pusher->v.avelocity, pusher->v.angles); pusher->v.ltime += movetime; SV_LinkEdict (pusher, false); return; default: Host_Error("SV_PushMove: unrecognized solid type %f\n", pusher->v.solid); } - if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2]) + if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2] && !pusher->v.avelocity[0] && !pusher->v.avelocity[1] && !pusher->v.avelocity[2]) { pusher->v.ltime += movetime; return; } - - for (i=0 ; i<3 ; i++) + index = (int) pusher->v.modelindex; + if (index < 1 || index >= MAX_MODELS) + Host_Error("SV_PushMove: invalid modelindex %f\n", pusher->v.modelindex); + pushermodel = sv.models[index]; + + // LordHavoc: round up by a small epsilon + movetime2 = movetime; // + (1.0 / 256.0); + for (i = 0;i < 3;i++) { - move[i] = pusher->v.velocity[i] * movetime; - mins[i] = pusher->v.absmin[i] + move[i]; - maxs[i] = pusher->v.absmax[i] + move[i]; + move1[i] = pusher->v.velocity[i] * movetime2; + moveangle[i] = pusher->v.avelocity[i] * movetime2; + } + if (moveangle[0] || moveangle[2]) + { + for (i = 0;i < 3;i++) + { + mins[i] = pushermodel->rotatedmins[i] + move1[i] - 32; + maxs[i] = pushermodel->rotatedmaxs[i] + move1[i] + 32; + } + } + else if (moveangle[1]) + { + for (i = 0;i < 3;i++) + { + mins[i] = pushermodel->yawmins[i] + move1[i] - 32; + maxs[i] = pushermodel->yawmaxs[i] + move1[i] + 32; + } + } + else + { + for (i = 0;i < 3;i++) + { + mins[i] = pushermodel->normalmins[i] + move1[i] - 32; + maxs[i] = pushermodel->normalmaxs[i] + move1[i] + 32; + } } + VectorNegate (moveangle, a); + AngleVectorsFLU (a, forward, left, up); + VectorCopy (pusher->v.origin, pushorig); - + VectorCopy (pusher->v.angles, pushang); + pushltime = pusher->v.ltime; + // move the pusher to it's final position - VectorAdd (pusher->v.origin, move, pusher->v.origin); + VectorMA (pusher->v.origin, movetime, pusher->v.velocity, pusher->v.origin); + VectorMA (pusher->v.angles, movetime, pusher->v.avelocity, pusher->v.angles); pusher->v.ltime += movetime; SV_LinkEdict (pusher, false); + savesolid = pusher->v.solid; // see if any solid entities are inside the final position num_moved = 0; @@ -526,198 +562,57 @@ void SV_PushMove (edict_t *pusher, float movetime) // 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.angles, entang); VectorCopy (check->v.origin, moved_from[num_moved]); + VectorCopy (check->v.angles, moved_fromangles[num_moved]); moved_edict[num_moved] = check; num_moved++; - // LordHavoc: pusher fixes (teleport train bug, etc) - savesolid = pusher->v.solid; - if (savesolid == SOLID_BSP || savesolid == SOLID_BBOX || savesolid == SOLID_SLIDEBOX) + if (forward[0] > 0.999f) // quick way to check if any rotation is used { - // try moving the contacted entity - pusher->v.solid = SOLID_NOT; - SV_PushEntity (check, move); - pusher->v.solid = savesolid; // was SOLID_BSP - - // if it is still inside the pusher, block - if (SV_TestEntityPosition (check)) - { // 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.origin); - 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 - num_moved--; // LordHavoc: pop off check, because it was already restored - for (i=0 ; iv.origin); - SV_LinkEdict (moved_edict[i], false); - } - return; - } + VectorSubtract (check->v.origin, pusher->v.origin, org); + org2[0] = DotProduct (org, forward); + org2[1] = DotProduct (org, left); + org2[2] = DotProduct (org, up); + VectorSubtract (org2, org, move); + VectorAdd (move, move1, move); } - } - - -} - -/* -============ -SV_PushRotate - -============ -*/ -void SV_PushRotate (edict_t *pusher, float movetime) -{ - int i, e; - edict_t *check; - vec3_t move, a, amove; - vec3_t entorigin, entangles, pushorigin, pushangles; - int num_moved; - edict_t *moved_edict[MAX_EDICTS]; - vec3_t moved_from[MAX_EDICTS]; - vec3_t angled_from[MAX_EDICTS]; - vec3_t org, org2; - vec3_t forward, right, up; - float savesolid; - - switch ((int) pusher->v.solid) - { - // LordHavoc: valid pusher types - case SOLID_BSP: - case SOLID_BBOX: - case SOLID_SLIDEBOX: - case SOLID_CORPSE: // LordHavoc: this would be weird... - break; - // LordHavoc: no collisions - case SOLID_NOT: - case SOLID_TRIGGER: - VectorMA (pusher->v.angles, movetime, pusher->v.avelocity, pusher->v.angles); - pusher->v.ltime += movetime; - SV_LinkEdict (pusher, false); - return; - default: - Host_Error("SV_PushRotate: unrecognized solid type %f\n", pusher->v.solid); - } - 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; - - VectorNegate (amove, a); - AngleVectors (a, forward, right, up); - - VectorCopy (pusher->v.origin, pushorigin); - VectorCopy (pusher->v.angles, pushangles); - -// 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 ; efree) - 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, entorigin); - VectorCopy (check->v.origin, moved_from[num_moved]); - VectorCopy (check->v.angles, entangles); - VectorCopy (check->v.angles, angled_from[num_moved]); - moved_edict[num_moved] = check; - num_moved++; + else + VectorCopy (move1, move); - // 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); + // LordHavoc: debugging + //VectorAdd(entorig, move, org2); + //CL_RocketTrail2 (entorig, org2, 238, NULL); - // try moving the contacted entity - savesolid = pusher->v.solid; // LordHavoc: restore to correct solid type + // try moving the contacted entity pusher->v.solid = SOLID_NOT; - SV_PushEntity (check, move); - pusher->v.solid = savesolid; // LordHavoc: restore to correct solid type + SV_PushEntity (check, move, moveangle); + pusher->v.solid = savesolid; // was SOLID_BSP - VectorAdd (check->v.angles, amove, check->v.angles); - - // if it is still inside the pusher, block + // if it is still inside the pusher, block if (SV_TestEntityPosition (check)) - { // fail the move + { + // 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 + { + // corpse check->v.mins[0] = check->v.mins[1] = 0; VectorCopy (check->v.mins, check->v.maxs); continue; } - - VectorCopy (entorigin, check->v.origin); - VectorCopy (entangles, check->v.angles); + + VectorCopy (entorig, check->v.origin); + VectorCopy (entang, check->v.angles); SV_LinkEdict (check, true); - VectorCopy (pushorigin, pusher->v.origin); - VectorCopy (pushangles, pusher->v.angles); + VectorCopy (pushorig, pusher->v.origin); + VectorCopy (pushang, pusher->v.angles); + pusher->v.ltime = pushltime; 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) @@ -726,13 +621,13 @@ void SV_PushRotate (edict_t *pusher, float movetime) pr_global_struct->other = EDICT_TO_PROG(check); PR_ExecuteProgram (pusher->v.blocked, ""); } - - // move back any entities we already moved + + // move back any entities we already moved num_moved--; // LordHavoc: pop off check, because it was already restored for (i=0 ; iv.origin); - VectorCopy (angled_from[i], moved_edict[i]->v.angles); + VectorCopy (moved_fromangles[i], moved_edict[i]->v.angles); SV_LinkEdict (moved_edict[i], false); } return; @@ -765,13 +660,8 @@ void SV_Physics_Pusher (edict_t *ent) movetime = sv.frametime; if (movetime) - { - if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2]) - SV_PushRotate (ent, movetime); - else - SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked - } - + SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked + if (thinktime > oldltime && thinktime <= ent->v.ltime) { ent->v.nextthink = 0; @@ -945,7 +835,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) case 7: dir[0] = -2; dir[1] = -2; break; } - SV_PushEntity (ent, dir); + SV_PushEntity (ent, dir, vec3_origin); // retry the original move ent->v.velocity[0] = oldvel[0]; @@ -1025,7 +915,7 @@ void SV_WalkMove (edict_t *ent) downmove[2] = -STEPSIZE + oldvel[2]*sv.frametime; // move up - SV_PushEntity (ent, upmove); // FIXME: don't link? + SV_PushEntity (ent, upmove, vec3_origin); // FIXME: don't link? // move forward ent->v.velocity[0] = oldvel[0]; @@ -1049,7 +939,7 @@ void SV_WalkMove (edict_t *ent) SV_WallFriction (ent, &steptrace); // move down - downtrace = SV_PushEntity (ent, downmove); // FIXME: don't link? + downtrace = SV_PushEntity (ent, downmove, vec3_origin); // FIXME: don't link? if (downtrace.plane.normal[2] > 0.7) { @@ -1319,7 +1209,7 @@ void SV_Physics_Toss (edict_t *ent) // move origin VectorScale (ent->v.velocity, sv.frametime, move); - trace = SV_PushEntity (ent, move); + trace = SV_PushEntity (ent, move, vec3_origin); if (trace.fraction == 1) return; if (ent->free) diff --git a/world.c b/world.c index 5880c7cf..fe6aba98 100644 --- a/world.c +++ b/world.c @@ -568,8 +568,7 @@ LINE TESTING IN HULLS */ // 1/32 epsilon to keep floating point happy -//#define DIST_EPSILON (0.03125) -#define DIST_EPSILON (0.125) +#define DIST_EPSILON (0.03125) #define HULLCHECKSTATE_EMPTY 0 #define HULLCHECKSTATE_SOLID 1 @@ -614,7 +613,7 @@ void SV_RecursiveHullCheck_Impact (mplane_t *plane, int side) } frac = t1 / (t1 - t2); - frac = bound(0.0f, frac, 1.0f); + frac = bound(0.0f, frac, 1.0); RHC.trace->fraction = frac; RHC.trace->endpos[0] = RHC.start[0] + frac * RHC.dist[0]; @@ -622,17 +621,16 @@ void SV_RecursiveHullCheck_Impact (mplane_t *plane, int side) RHC.trace->endpos[2] = RHC.start[2] + frac * RHC.dist[2]; } -int SV_RecursiveHullCheck (int num, float p1f, float p2f, vec3_t p1, vec3_t p2) +int SV_RecursiveHullCheck (int num, double p1f, double p2f, double p1[3], double p2[3]) { dclipnode_t *node; - vec3_t mid; int side; - float midf; + double midf, mid[3]; // LordHavoc: FIXME: this is not thread safe... if threading matters here, // remove the static prefixes static int ret; static mplane_t *plane; - static float t1, t2, frac; + static double t1, t2, frac; // LordHavoc: a goto! everyone flee in terror... :) loc0: @@ -712,7 +710,7 @@ loc0: } frac = t1 / (t1 - t2); - frac = bound(0.0f, frac, 1.0f); + frac = bound(0.0f, frac, 1.0); midf = p1f + ((p2f - p1f) * frac); mid[0] = RHC.start[0] + midf * RHC.dist[0]; @@ -733,271 +731,6 @@ loc0: return HULLCHECKSTATE_DONE; } -/* -qboolean SV_RecursiveHullCheckContentBoundary (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace) -{ - dclipnode_t *node; - mplane_t *plane; - float t1, t2; - float frac; - int i; - vec3_t mid; - int side; - float midf; - - // LordHavoc: a goto! everyone flee in terror... :) -loc0: -// check for empty - if (num < 0) - { - if (num != trace->startcontents) - trace->startsolid = true; - else - trace->allsolid = false; - return true; // empty - } - -// find the point distances - node = hull->clipnodes + num; - plane = hull->planes + node->planenum; - - if (plane->type < 3) - { - t1 = p1[plane->type] - plane->dist; - t2 = p2[plane->type] - plane->dist; - } - else - { - t1 = DotProduct (plane->normal, p1) - plane->dist; - t2 = DotProduct (plane->normal, p2) - plane->dist; - } - - // LordHavoc: rearranged the side/frac code - // LordHavoc: recursion optimization - if (t1 >= 0) - { - if (t2 >= 0) - { - num = node->children[0]; - goto loc0; - } - // put the crosspoint DIST_EPSILON pixels on the near side - side = 0; - } - else - { - if (t2 < 0) - { - num = node->children[1]; - goto loc0; - } - // put the crosspoint DIST_EPSILON pixels on the near side - side = 1; - } - - frac = t1 / (t1 - t2); - frac = bound(0.0f, frac, 1.0f); - - midf = p1f + ((p2f - p1f) * frac); - mid[0] = p1[0] + ((p2[0] - p1[0]) * frac); - mid[1] = p1[1] + ((p2[1] - p1[1]) * frac); - mid[2] = p1[2] + ((p2[2] - p1[2]) * frac); - -// move up to the node - if (!SV_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) ) - return false; - -*/ - /* -#ifdef PARANOID - if (SV_HullPointContents (pm_hullmodel, mid, node->children[side]) != trace->startcontents) - { - Con_Printf ("mid PointInHullSolid\n"); - return false; - } -#endif - */ -/* - - // LordHavoc: warning to the clumsy, this recursion can not be optimized because mid would need to be duplicated on a stack - if (SV_HullPointContents (hull, node->children[side^1], mid) == trace->startcontents) -// go past the node - return SV_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace); - - if (trace->allsolid) - return false; // never got out of the solid area - -//================== -// the other side of the node is solid, this is the impact point -//================== - if (!side) - { - VectorCopy (plane->normal, trace->plane.normal); - trace->plane.dist = plane->dist; - } - else - { - VectorNegate (plane->normal, trace->plane.normal); - trace->plane.dist = -plane->dist; - } - -*/ - /* - while (SV_HullPointContents (hull, hull->firstclipnode, mid) != trace->startcontents) - { - // shouldn't really happen, but does occasionally - frac -= 0.1; - if (frac < 0) - { - trace->fraction = midf; - VectorCopy (mid, trace->endpos); - Con_DPrintf ("backup past 0\n"); - return false; - } - midf = p1f + (p2f - p1f)*frac; - mid[0] = p1[0] + frac*(p2[0] - p1[0]); - mid[1] = p1[1] + frac*(p2[1] - p1[1]); - mid[2] = p1[2] + frac*(p2[2] - p1[2]); - } - */ -/* - - frac = t1; - if (side) - frac += DIST_EPSILON; - else - frac -= DIST_EPSILON; - - frac /= (t1 - t2); - frac = bound(0.0f, frac, 1.0f); - - trace->fraction = p1f + (p2f - p1f)*frac; - trace->endpos[0] = p1[0] + frac*(p2[0] - p1[0]); - trace->endpos[1] = p1[1] + frac*(p2[1] - p1[1]); - trace->endpos[2] = p1[2] + frac*(p2[2] - p1[2]); - - return false; -} -*/ - -/* -// FIXME: this is broken and I'm not interested in figuring out what is broken about it right now -qboolean SV_TestLine (hull_t *hull, int num, vec3_t p1, vec3_t p2) -{ - dclipnode_t *node; - mplane_t *plane; - float t1, t2, frac; - vec3_t mid; - int side; - -loc0: -// check for empty - if (num < 0) - return num != CONTENTS_SOLID; - - if (num < hull->firstclipnode || num > hull->lastclipnode) - Sys_Error ("SV_RecursiveHullCheck: bad node number"); - -// -// find the point distances -// - node = hull->clipnodes + num; - if (node->children[0] < 0) - { - if (node->children[0] == CONTENTS_SOLID) - return false; - if (node->children[1] < 0) - return node->children[1] != CONTENTS_SOLID; - } - else if (node->children[1] == CONTENTS_SOLID) - return false; - - plane = hull->planes + node->planenum; - - if (plane->type < 3) - { - t1 = p1[plane->type] - plane->dist; - t2 = p2[plane->type] - plane->dist; - } - else - { - t1 = DotProduct (plane->normal, p1) - plane->dist; - t2 = DotProduct (plane->normal, p2) - plane->dist; - } - - if (t1 >= 0) - { - if (t2 >= 0) - { - num = node->children[0]; - goto loc0; - } - side = 0; - } - else - { - if (t2 < 0) - { - num = node->children[1]; - goto loc0; - } - side = 1; - } - - if (node->children[side] < 0) - { - if (node->children[side] == CONTENTS_SOLID) - return false; - - if (node->children[!side] < 0) - return node->children[!side] != CONTENTS_SOLID; - else - { - frac = t1 / (t1 - t2); - frac = bound(0, frac, 1); - - mid[0] = p1[0] + frac*(p2[0] - p1[0]); - mid[1] = p1[1] + frac*(p2[1] - p1[1]); - mid[2] = p1[2] + frac*(p2[2] - p1[2]); - - return SV_TestLine(hull, node->children[!side], mid, p2); - } - } - else - { - if (node->children[!side] < 0) - { - if (node->children[!side] == CONTENTS_SOLID) - return false; - - frac = t1 / (t1 - t2); - frac = bound(0, frac, 1); - - mid[0] = p1[0] + frac*(p2[0] - p1[0]); - mid[1] = p1[1] + frac*(p2[1] - p1[1]); - mid[2] = p1[2] + frac*(p2[2] - p1[2]); - - return SV_TestLine(hull, node->children[side], p1, mid); - } - else - { - frac = t1 / (t1 - t2); - frac = bound(0, frac, 1); - - mid[0] = p1[0] + frac*(p2[0] - p1[0]); - mid[1] = p1[1] + frac*(p2[1] - p1[1]); - mid[2] = p1[2] + frac*(p2[2] - p1[2]); - - if (SV_TestLine(hull, node->children[side], p1, mid)) - return SV_TestLine(hull, node->children[!side], mid, p2); - else - return false; - } - } -} -*/ - - /* ================== SV_ClipMoveToEntity @@ -1008,10 +741,10 @@ 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; + trace_t trace; + vec3_t offset, start_l, end_l; + double startd[3], endd[3]; + hull_t *hull; // fill in a default trace memset (&trace, 0, sizeof(trace_t)); @@ -1045,12 +778,15 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max end_l[2] = DotProduct (temp, up); } + VectorCopy(start_l, startd); + VectorCopy(end_l, endd); + // trace a line through the appropriate clipping hull - VectorCopy(start_l, RecursiveHullCheckInfo.start); - VectorSubtract(end_l, start_l, RecursiveHullCheckInfo.dist); + VectorCopy(startd, RecursiveHullCheckInfo.start); + VectorSubtract(endd, startd, RecursiveHullCheckInfo.dist); RecursiveHullCheckInfo.hull = hull; RecursiveHullCheckInfo.trace = &trace; - SV_RecursiveHullCheck (hull->firstclipnode, 0, 1, start_l, end_l); + SV_RecursiveHullCheck (hull->firstclipnode, 0, 1, startd, endd); // LordHavoc: enabling rotating bmodels // rotate endpos back to world frame of reference @@ -1200,7 +936,7 @@ boxmins[0] = boxmins[1] = boxmins[2] = -9999; boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999; #else int i; - + for (i=0 ; i<3 ; i++) { if (end[i] > start[i]) -- 2.39.2