public static void PM_StepSlideMove_( ) { Int32 bumpcount, numbumps; Single[] dir = new Single[] { 0, 0, 0 }; Single d; Int32 numplanes; Single[] primal_velocity = new Single[] { 0, 0, 0 }; Int32 i, j; trace_t trace; Single[] end = new Single[] { 0, 0, 0 }; Single time_left; numbumps = 4; Math3D.VectorCopy(pml.velocity, primal_velocity); numplanes = 0; time_left = pml.frametime; for (bumpcount = 0; bumpcount < numbumps; bumpcount++) { for (i = 0; i < 3; i++) { end[i] = pml.origin[i] + time_left * pml.velocity[i]; } trace = pm.trace.Trace(pml.origin, pm.mins, pm.maxs, end); if (trace.allsolid) { pml.velocity[2] = 0; return; } if (trace.fraction > 0) { Math3D.VectorCopy(trace.endpos, pml.origin); numplanes = 0; } if (trace.fraction == 1) { break; } if (pm.numtouch < Defines.MAXTOUCH && trace.ent != null) { pm.touchents[pm.numtouch] = trace.ent; pm.numtouch++; } time_left -= time_left * trace.fraction; if (numplanes >= SV.MAX_CLIP_PLANES) { Math3D.VectorCopy(Globals.vec3_origin, pml.velocity); break; } Math3D.VectorCopy(trace.plane.normal, planes[numplanes]); numplanes++; for (i = 0; i < numplanes; i++) { PM_ClipVelocity(pml.velocity, planes[i], pml.velocity, 1.01F); for (j = 0; j < numplanes; j++) { if (j != i) { if (Math3D.DotProduct(pml.velocity, planes[j]) < 0) { break; } } } if (j == numplanes) { break; } } if (i != numplanes) { } else { if (numplanes != 2) { Math3D.VectorCopy(Globals.vec3_origin, pml.velocity); break; } Math3D.CrossProduct(planes[0], planes[1], dir); d = Math3D.DotProduct(dir, pml.velocity); Math3D.VectorScale(dir, d, pml.velocity); } if (Math3D.DotProduct(pml.velocity, primal_velocity) <= 0) { Math3D.VectorCopy(Globals.vec3_origin, pml.velocity); break; } } if (pm.s.pm_time != 0) { Math3D.VectorCopy(primal_velocity, pml.velocity); } }
public static int SV_FlyMove(edict_t ent, float time, int mask) { edict_t hit; int bumpcount, numbumps; float[] dir = { 0.0f, 0.0f, 0.0f }; float d; int numplanes; var planes = new float[SV.MAX_CLIP_PLANES][]; float[] primal_velocity = { 0.0f, 0.0f, 0.0f }; float[] original_velocity = { 0.0f, 0.0f, 0.0f }; float[] new_velocity = { 0.0f, 0.0f, 0.0f }; int i, j; trace_t trace; float[] end = { 0.0f, 0.0f, 0.0f }; float time_left; int blocked; for (var n = 0; n < planes.Length; n++) { planes[n] = new float[3]; } numbumps = 4; blocked = 0; Math3D.VectorCopy(ent.velocity, original_velocity); Math3D.VectorCopy(ent.velocity, primal_velocity); numplanes = 0; time_left = time; ent.groundentity = null; for (bumpcount = 0; bumpcount < numbumps; bumpcount++) { for (i = 0; i < 3; i++) { end[i] = ent.s.origin[i] + time_left * ent.velocity[i]; } trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, end, ent, mask); if (trace.allsolid) { // entity is trapped in another solid Math3D.VectorCopy(Globals.vec3_origin, ent.velocity); return(3); } if (trace.fraction > 0) { // actually covered some distance Math3D.VectorCopy(trace.endpos, ent.s.origin); Math3D.VectorCopy(ent.velocity, original_velocity); numplanes = 0; } if (trace.fraction == 1) { break; // moved the entire distance } hit = trace.ent; if (trace.plane.normal[2] > 0.7) { blocked |= 1; // floor if (hit.solid == Defines.SOLID_BSP) { ent.groundentity = hit; ent.groundentity_linkcount = hit.linkcount; } } if (trace.plane.normal[2] == 0.0f) { blocked |= 2; // step } // // run the impact function // SV.SV_Impact(ent, trace); if (!ent.inuse) { break; // removed by the impact function } time_left -= time_left * trace.fraction; // cliped to another plane if (numplanes >= SV.MAX_CLIP_PLANES) { // this shouldn't // really happen Math3D.VectorCopy(Globals.vec3_origin, ent.velocity); return(3); } Math3D.VectorCopy(trace.plane.normal, planes[numplanes]); numplanes++; // // modify original_velocity so it parallels all of the clip planes // for (i = 0; i < numplanes; i++) { GameBase.ClipVelocity(original_velocity, planes[i], new_velocity, 1); for (j = 0; j < numplanes; j++) { if (j != i && !Math3D.VectorEquals(planes[i], planes[j])) { if (Math3D.DotProduct(new_velocity, planes[j]) < 0) { break; // not ok } } } if (j == numplanes) { break; } } if (i != numplanes) { // go along this plane Math3D.VectorCopy(new_velocity, ent.velocity); } else { // go along the crease if (numplanes != 2) { // gi.dprintf ("clip velocity, numplanes == // %i\n",numplanes); Math3D.VectorCopy(Globals.vec3_origin, ent.velocity); return(7); } Math3D.CrossProduct(planes[0], planes[1], dir); d = Math3D.DotProduct(dir, ent.velocity); Math3D.VectorScale(dir, d, ent.velocity); } // // if original velocity is against the original velocity, stop dead // to avoid tiny occilations in sloping corners // if (Math3D.DotProduct(ent.velocity, primal_velocity) <= 0) { Math3D.VectorCopy(Globals.vec3_origin, ent.velocity); return(blocked); } } return(blocked); }