private static int SV_FlyMove(prog.edict_t ent, double time /*was float*/, ref world.trace_t steptrace) { int bumpcount, numbumps; double[] dir = new double[3] {0, 0, 0}; double d; int numplanes; double[][] planes = { ArrayHelpers.ExplcitDoubleArray(3), ArrayHelpers.ExplcitDoubleArray(3), ArrayHelpers.ExplcitDoubleArray(3), ArrayHelpers.ExplcitDoubleArray(3), ArrayHelpers.ExplcitDoubleArray(3) }; double[] primal_velocity = new double[3] {0, 0, 0}, original_velocity = new double[3] {0, 0, 0}, new_velocity = new double[3] {0, 0, 0}; int i, j; world.trace_t trace; double[] end = new double[3] {0, 0, 0}; double time_left; int blocked; numbumps = 4; blocked = 0; mathlib.VectorCopy(ent.v.velocity, original_velocity); mathlib.VectorCopy(ent.v.velocity, primal_velocity); numplanes = 0; time_left = time; //Debug.WriteLine("SV_FlyMove"); for (bumpcount = 0; bumpcount < numbumps; bumpcount++) { if (ent.v.velocity[0] == 0.0 && ent.v.velocity[1] == 0.0 && ent.v.velocity[2] == 0.0) break; for (i = 0; i < 3; i++) end[i] = ent.v.origin[i] + time_left * ent.v.velocity[i]; trace = world.SV_Move(ent.v.origin, ent.v.mins, ent.v.maxs, end, 0, ent); if (trace.allsolid) { //Debug.WriteLine("allsolid"); // entity is trapped in another solid mathlib.VectorCopy(mathlib.vec3_origin, ent.v.velocity); return 3; } //Debug.WriteLine(string.Format("fraction {0}", trace.fraction)); if (trace.fraction > 0) { // actually covered some distance mathlib.VectorCopy(trace.endpos, ent.v.origin); mathlib.VectorCopy(ent.v.velocity, original_velocity); numplanes = 0; } if (trace.fraction == 1.0) break; // moved the entire distance if (trace.ent == null) sys_linux.Sys_Error("SV_FlyMove: !trace.ent"); if (trace.plane.normal[2] > 0.7) { //Debug.WriteLine("trace.plane.normal[2] > 0.7"); blocked |= 1; // floor if (trace.ent.v.solid == SOLID_BSP) { ent.v.flags = (int)ent.v.flags | FL_ONGROUND; ent.v.groundentity = prog.EDICT_TO_PROG(trace.ent); } } if (!(trace.plane.normal[2] != 0.0)) { //Debug.WriteLine("!trace.plane.normal[2]"); blocked |= 2; // step if (steptrace != null) steptrace = trace; // save for player extrafriction } // // run the impact function // //Debug.WriteLine("SV_Impact"); SV_Impact(ent, trace.ent); if (ent.free) { //Debug.WriteLine("ent.fre"); break; // removed by the impact function } time_left -= time_left * trace.fraction; // cliped to another plane if (numplanes >= MAX_CLIP_PLANES) { //Debug.WriteLine("numplanes >= MAX_CLIP_PLANES"); // this shouldn't really happen mathlib.VectorCopy(mathlib.vec3_origin, ent.v.velocity); return 3; } mathlib.VectorCopy(trace.plane.normal, planes[numplanes]); numplanes++; // // modify original_velocity so it parallels all of the clip planes // for (i = 0; i < numplanes; i++) { ClipVelocity(original_velocity, planes[i], new_velocity, 1); for (j = 0; j < numplanes; j++) if (j != i) { if (mathlib.DotProduct(new_velocity, planes[j]) < 0) break; // not ok } if (j == numplanes) break; } if (i != numplanes) { // go along this plane //Debug.WriteLine("i != numplanes"); mathlib.VectorCopy(new_velocity, ent.v.velocity); } else { // go along the crease if (numplanes != 2) { // Con_Printf ("clip velocity, numplanes == %i\n",numplanes); mathlib.VectorCopy(mathlib.vec3_origin, ent.v.velocity); return 7; } mathlib.CrossProduct(planes[0], planes[1], dir); d = mathlib.DotProduct(dir, ent.v.velocity); mathlib.VectorScale(dir, d, ent.v.velocity); } // // if original velocity is against the original velocity, stop dead // to avoid tiny occilations in sloping corners // if (mathlib.DotProduct(ent.v.velocity, primal_velocity) <= 0) { //Debug.WriteLine("DotProductstuff"); mathlib.VectorCopy(mathlib.vec3_origin, ent.v.velocity); return blocked; } } return blocked; }
/* ============ SV_WallFriction ============ */ static void SV_WallFriction(prog.edict_t ent, world.trace_t trace) { double[] forward = new double[3] {0, 0, 0}, right = new double[3] {0, 0, 0}, up = new double[3] {0, 0, 0}; double d, i; double[] into = new double[3] {0, 0, 0}, side = new double[3] {0, 0, 0}; mathlib.AngleVectors(ent.v.v_angle, forward, right, up); d = mathlib.DotProduct(trace.plane.normal, forward); d += 0.5; if (d >= 0) return; // cut the tangential velocity i = mathlib.DotProduct(trace.plane.normal, ent.v.velocity); mathlib.VectorScale(trace.plane.normal, i, into); mathlib.VectorSubtract(ent.v.velocity, into, side); ent.v.velocity[0] = side[0] * (1 + d); ent.v.velocity[1] = side[1] * (1 + d); }