Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
        }