From: lordhavoc Date: Sat, 23 Feb 2002 09:35:29 +0000 (+0000) Subject: major cleanup to pusher and SV_Move code, major fixes to pusher code (everything... X-Git-Tag: RELEASE_0_2_0_RC1~627 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=82f69d1a89085e7036f3d9524ac721b19698ec9e major cleanup to pusher and SV_Move code, major fixes to pusher code (everything should work right now) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1553 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/sv_phys.c b/sv_phys.c index f0fe0642..d4f73a31 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -206,7 +206,7 @@ int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) blocked |= 1; // floor if (!normal[2]) blocked |= 2; // step - + backoff = DotProduct (in, normal) * overbounce; for (i=0 ; i<3 ; i++) @@ -431,7 +431,6 @@ trace_t SV_PushEntity (edict_t *ent, vec3_t push, vec3_t pushangles) if (trace.ent) SV_Impact (ent, trace.ent); - return trace; } @@ -442,16 +441,18 @@ SV_PushMove ============ */ +trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end); void SV_PushMove (edict_t *pusher, float movetime) { int i, e, index; edict_t *check; float savesolid, movetime2, pushltime; - vec3_t mins, maxs, move, move1, moveangle, entorig, entang, pushorig, pushang, a, forward, left, up, org, org2; + 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], moved_fromangles[MAX_EDICTS]; model_t *pushermodel; + trace_t trace; switch ((int) pusher->v.solid) { @@ -484,33 +485,54 @@ void SV_PushMove (edict_t *pusher, float movetime) // LordHavoc: round up by a small epsilon movetime2 = movetime; // + (1.0 / 256.0); - for (i = 0;i < 3;i++) - { - move1[i] = pusher->v.velocity[i] * movetime2; - moveangle[i] = pusher->v.avelocity[i] * movetime2; - } + VectorScale(pusher->v.velocity, movetime2, move1); + VectorScale(pusher->v.avelocity, movetime2, moveangle); 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; + if (move1[i] > 0) + { + mins[i] = pushermodel->rotatedmins[i] + pusher->v.origin[i] - 1; + maxs[i] = pushermodel->rotatedmaxs[i] + move1[i] + pusher->v.origin[i] + 1; + } + else + { + mins[i] = pushermodel->rotatedmins[i] + move1[i] + pusher->v.origin[i] - 1; + maxs[i] = pushermodel->rotatedmaxs[i] + pusher->v.origin[i] + 1; + } } } 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; + if (move1[i] > 0) + { + mins[i] = pushermodel->yawmins[i] + pusher->v.origin[i] - 1; + maxs[i] = pushermodel->yawmaxs[i] + move1[i] + pusher->v.origin[i] + 1; + } + else + { + mins[i] = pushermodel->yawmins[i] + move1[i] + pusher->v.origin[i] - 1; + maxs[i] = pushermodel->yawmaxs[i] + pusher->v.origin[i] + 1; + } } } else { for (i = 0;i < 3;i++) { - mins[i] = pushermodel->normalmins[i] + move1[i] - 32; - maxs[i] = pushermodel->normalmaxs[i] + move1[i] + 32; + if (move1[i] > 0) + { + mins[i] = pushermodel->normalmins[i] + pusher->v.origin[i] - 1; + maxs[i] = pushermodel->normalmaxs[i] + move1[i] + pusher->v.origin[i] + 1; + } + else + { + mins[i] = pushermodel->normalmins[i] + move1[i] + pusher->v.origin[i] - 1; + maxs[i] = pushermodel->normalmaxs[i] + pusher->v.origin[i] + 1; + } } } @@ -547,30 +569,45 @@ void SV_PushMove (edict_t *pusher, float movetime) if (!(((int)check->v.flags & FL_ONGROUND) && PROG_TO_EDICT(check->v.groundentity) == pusher)) { if (check->v.absmin[0] >= maxs[0] - || check->v.absmin[1] >= maxs[1] - || check->v.absmin[2] >= maxs[2] || check->v.absmax[0] <= mins[0] + || check->v.absmin[1] >= maxs[1] || check->v.absmax[1] <= mins[1] + || check->v.absmin[2] >= maxs[2] || check->v.absmax[2] <= mins[2]) continue; + /* + if (forward[0] < 0.999f) // quick way to check if any rotation is used + { + 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); + //VectorSubtract(check->v.origin, move, a); + a[0] = check->v.origin[0] + (org[0] - org2[0]) - move1[0]; + a[1] = check->v.origin[1] + (org[1] - org2[1]) - move1[1]; + a[2] = check->v.origin[2] + (org[2] - org2[2]) - move1[2]; + } + else + VectorSubtract (check->v.origin, move1, a); + + trace = SV_ClipMoveToEntity (pusher, a, check->v.mins, check->v.maxs, check->v.origin); + if (trace.fraction == 1 && !trace.startsolid) + continue; + */ + trace = SV_ClipMoveToEntity (pusher, check->v.origin, check->v.mins, check->v.maxs, check->v.origin); + if (!trace.startsolid) + 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.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++; - - if (forward[0] > 0.999f) // quick way to check if any rotation is used + if (forward[0] < 0.999f) // quick way to check if any rotation is used { VectorSubtract (check->v.origin, pusher->v.origin, org); org2[0] = DotProduct (org, forward); @@ -586,13 +623,24 @@ void SV_PushMove (edict_t *pusher, float movetime) //VectorAdd(entorig, move, org2); //CL_RocketTrail2 (entorig, org2, 238, NULL); + // 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; + // try moving the contacted entity pusher->v.solid = SOLID_NOT; - SV_PushEntity (check, move, moveangle); + trace = SV_PushEntity (check, move, moveangle); pusher->v.solid = savesolid; // was SOLID_BSP // if it is still inside the pusher, block - if (SV_TestEntityPosition (check)) + // LordHavoc: cleanup - check trace.fraction and startsolid + if (/*trace.fraction != 1 || trace.startsolid || */SV_TestEntityPosition (check)) { // fail the move if (check->v.mins[0] == check->v.maxs[0]) @@ -605,31 +653,33 @@ void SV_PushMove (edict_t *pusher, float movetime) continue; } + /* VectorCopy (entorig, check->v.origin); VectorCopy (entang, check->v.angles); SV_LinkEdict (check, true); + */ VectorCopy (pushorig, pusher->v.origin); VectorCopy (pushang, pusher->v.angles); pusher->v.ltime = pushltime; SV_LinkEdict (pusher, false); - // 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 + //num_moved--; // LordHavoc: pop off check, because it was already restored for (i=0 ; iv.origin); VectorCopy (moved_fromangles[i], moved_edict[i]->v.angles); SV_LinkEdict (moved_edict[i], false); } + + // 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, ""); + } return; } } @@ -780,7 +830,7 @@ void SV_WallFriction (edict_t *ent, trace_t *trace) vec3_t forward; float d, i; vec3_t into, side; - + AngleVectors (ent->v.v_angle, forward, NULL, NULL); d = DotProduct (trace->plane.normal, forward); @@ -849,7 +899,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) //Con_DPrintf ("unstuck!\n"); return clip; } - + // go back to the original pos and try again VectorCopy (oldorg, ent->v.origin); } @@ -874,7 +924,7 @@ void SV_WalkMove (edict_t *ent) int clip; int oldonground; trace_t steptrace, downtrace; - + // // do a regular slide move unless it looks like you ran into a step // diff --git a/world.c b/world.c index fe6aba98..64a76294 100644 --- a/world.c +++ b/world.c @@ -554,7 +554,7 @@ edict_t *SV_TestEntityPosition (edict_t *ent) if (trace.startsolid) return sv.edicts; - + return NULL; } @@ -742,44 +742,36 @@ 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, start_l, end_l; - double startd[3], endd[3]; + vec3_t offset, forward, left, up; + double startd[3], endd[3], tempd[3]; 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); + VectorSubtract(start, offset, startd); + VectorSubtract(end, offset, endd); -// LordHavoc: enabling rotating bmodels // 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])) { - 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); + AngleVectorsFLU (ent->v.angles, forward, left, up); + VectorCopy(startd, tempd); + startd[0] = DotProduct (tempd, forward); + startd[1] = DotProduct (tempd, left); + startd[2] = DotProduct (tempd, up); + VectorCopy(endd, tempd); + endd[0] = DotProduct (tempd, forward); + endd[1] = DotProduct (tempd, left); + endd[2] = DotProduct (tempd, up); } - VectorCopy(start_l, startd); - VectorCopy(end_l, endd); + VectorCopy(end, trace.endpos); // trace a line through the appropriate clipping hull VectorCopy(startd, RecursiveHullCheckInfo.start); @@ -788,37 +780,30 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max RecursiveHullCheckInfo.trace = &trace; SV_RecursiveHullCheck (hull->firstclipnode, 0, 1, startd, endd); -// LordHavoc: enabling rotating bmodels - // 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])) + // if we hit, unrotate endpos and normal, and store the entity we hit + if (trace.fraction != 1) { - vec3_t a; - vec3_t forward, right, up; - vec3_t temp; - - if (trace.fraction != 1) + // 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])) { - VectorNegate (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); + VectorNegate (ent->v.angles, offset); + AngleVectorsFLU (offset, forward, left, up); + + VectorCopy (trace.endpos, tempd); + trace.endpos[0] = DotProduct (tempd, forward); + trace.endpos[1] = DotProduct (tempd, left); + trace.endpos[2] = DotProduct (tempd, up); + + VectorCopy (trace.plane.normal, tempd); + trace.plane.normal[0] = DotProduct (tempd, forward); + trace.plane.normal[1] = DotProduct (tempd, left); + trace.plane.normal[2] = DotProduct (tempd, up); } - } - -// fix trace up by the offset - if (trace.fraction != 1) + // fix offset VectorAdd (trace.endpos, offset, trace.endpos); - -// did we clip the move? - if (trace.fraction < 1 || trace.startsolid ) + trace.ent = ent; + } + else if (trace.startsolid) trace.ent = ent; return trace; @@ -839,6 +824,8 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) edict_t *touch; trace_t trace; + if (clip->trace.allsolid) + return; loc0: // touch linked edicts for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next) @@ -850,27 +837,23 @@ loc0: if (touch == clip->passedict) continue; if (touch->v.solid == SOLID_TRIGGER) - Sys_Error ("Trigger in clipping list"); + Host_Error ("Trigger in clipping list"); if (clip->type == MOVE_NOMONSTERS && touch->v.solid != SOLID_BSP) continue; if (clip->boxmins[0] > touch->v.absmax[0] - || clip->boxmins[1] > touch->v.absmax[1] - || clip->boxmins[2] > touch->v.absmax[2] || clip->boxmaxs[0] < touch->v.absmin[0] + || clip->boxmins[1] > touch->v.absmax[1] || clip->boxmaxs[1] < touch->v.absmin[1] + || clip->boxmins[2] > touch->v.absmax[2] || clip->boxmaxs[2] < touch->v.absmin[2]) continue; - if (clip->passedict != NULL && clip->passedict->v.size[0] && !touch->v.size[0]) - continue; // points never interact - - // might intersect, so do an exact clip - if (clip->trace.allsolid) - return; if (clip->passedict) { + if (clip->passedict->v.size[0] && !touch->v.size[0]) + continue; // points never interact if (PROG_TO_EDICT(touch->v.owner) == clip->passedict) continue; // don't clip against own missiles if (PROG_TO_EDICT(clip->passedict->v.owner) == touch) @@ -882,6 +865,7 @@ loc0: continue; } + // might interact, so do an exact clip if ((int)touch->v.flags & FL_MONSTER) trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end); else @@ -897,8 +881,8 @@ loc0: else clip->trace = trace; } - else if (trace.startsolid) - clip->trace.startsolid = true; + if (clip->trace.allsolid) + return; } // recurse down both sides @@ -965,9 +949,6 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e memset ( &clip, 0, sizeof ( moveclip_t ) ); -// clip to world - clip.trace = SV_ClipMoveToEntity ( sv.edicts, start, mins, maxs, end ); - clip.start = start; clip.end = end; clip.mins = mins; @@ -985,15 +966,21 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e } else { - VectorCopy (mins, clip.mins2); - VectorCopy (maxs, clip.maxs2); + VectorCopy (clip.mins, clip.mins2); + VectorCopy (clip.maxs, clip.maxs2); } -// create the bounding box of the entire move - SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); + // clip to world + clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end); -// clip to entities - SV_ClipToLinks ( sv_areanodes, &clip ); + // clip to entities + if (!clip.trace.allsolid) + { + // create the bounding box of the entire move + SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); + + SV_ClipToLinks ( sv_areanodes, &clip ); + } return clip.trace; }