0

C# または XNA 用の物理プラグインがあることは知っていますが、トピックについて学ぶことができるように、独自のプラグインを作成したいと考えています。

私の問題は次のとおりです。

適切な角度と速度で弾性インパルスをキャラクターに適用しようとします。速度は正しく計算されますが、角度は正しく計算されず、結果が歪められます! 次の問題は、静止しているはずのキャラクターが震えモードになってしまうことです。問題の原因はわかっていますが、それを修正する方法がわかりません (編集: そのために貫通深度を考慮する必要がありますか?)

は最もIPhysicsObject重要な情報を継承し、Vector2[]はインデックス 0 に collisionPoint を持ち、インデックス 1 に侵入深度を持っています。

私はこれで作業しようとしましが、ええ..わかりません

    public void ElasticImpulse(IPhysicsObject Object, Vector2[] _colPos)
    {
        //this function is down below
        if (checkCollidingObjects(m_cCharacter, Object))
            return;

        //this List is like this declined:
        //public static List<IPhysicsObject[]> CollidingObjects = new List<IPhysicsObject[]>();
        //this list contains every pair of objects, that collided this frame, it is cleared after all physics and game logic is done.
        CollidingObjects.Add(new IPhysicsObject[] { m_cCharacter, Object });

        //deltavelocity is the velocity between two frames
        Vector2 v1 = Velocity - DeltaVelocity;
        float lv1 = (float)Math.Sqrt(v1.X * v1.X + v1.Y * v1.Y);
        float m1 = Mass;
        float k1 = Damping;

        Vector2 v2 = Object.Physik.Velocity - Object.Physik.DeltaVelocity;
        float lv2 = (float)Math.Sqrt(v2.X * v2.X + v2.Y * v2.Y);
        float m2 = Object.Mass;
        float k2 = Object.Physik.Damping;

        Vector2 colDir1 = _colPos[0] - m_cCharacter.Position;
        Vector2 colDir2 = _colPos[0] - Object.Position;
        colDir1.Normalize();
        colDir2.Normalize();
        Vector2 colNorm1 = new Vector2(colDir1.Y, -colDir1.X);
        Vector2 colNorm2 = new Vector2(colDir2.Y, -colDir2.X);
        float ldir1 = (float)Math.Sqrt(colNorm1.X * colNorm1.X + colNorm1.Y * colNorm1.Y);
        float ldir2 = (float)Math.Sqrt(colNorm2.X * colNorm2.X + colNorm2.Y * colNorm2.Y);

        float pi = MathHelper.Pi;
        //float angle1 = pi - ((v1.X * colNorm1.X + v2.Y * colNorm1.Y) / (lv1 * ldir1)) / v1.Length();
        float angle1 = pi - (float)Math.Acos(((v1.X * colNorm1.X + v2.Y * colNorm1.Y) / (lv1 * ldir1)) / v1.Length());
        angle1 = (float.IsNaN(angle1)) ? 0 : angle1;
        //float angle2 = pi - ((v2.X * colNorm2.X + v2.Y * colNorm2.Y) / (lv2 * ldir1)) / v2.Length();
        float angle2 = pi - (float)Math.Acos(((v2.X * colNorm2.X + v2.Y * colNorm2.Y) / (lv2 * ldir1)) / v2.Length());
        angle2 = (float.IsNaN(angle2)) ? 0 : angle2;

        //calculating the new velocities u 1/2. Got this formula out of the wiki link i posted above (took the german wiki version)
        Vector2 u1 = (m1 * v1 + m2 * v2 - (m2 * (v1 - v2) * k2)) / (m1 + m2) - v1;
        Vector2 u2 = (m1 * v1 + m2 * v2 - (m1 * (v2 - v1) * k1)) / (m1 + m2) - v2;

        //transform the new velocities by the correct angle
        Vector2 newV1 = new Vector2(
            u1.X * (float)Math.Cos(angle1) - u1.Y * (float)Math.Sin(angle1),
            u1.X * (float)Math.Sin(angle1) + u1.Y * (float)Math.Cos(angle1));
        Vector2 newV2 = new Vector2(
            u2.X * (float)Math.Cos(angle2) - u2.Y * (float)Math.Sin(angle2),
            u2.X * (float)Math.Sin(angle2) + u2.Y * (float)Math.Cos(angle2));

        newV1 = new Vector2(
            (float.IsNaN(newV1.X)) ? 0 : newV1.X,
            (float.IsNaN(newV1.Y)) ? 0 : newV1.Y);
        newV2 = new Vector2(
            (float.IsNaN(newV2.X)) ? 0 : newV2.X,
            (float.IsNaN(newV2.Y)) ? 0 : newV2.Y);
        AddForce(newV1);
        Object.Physik.AddForce(newV2);
    }

    bool checkCollidingObjects(IPhysicsObject obj1, IPhysicsObject obj2)
    {
        if (CollidingObjects.Count > 0)
        {
            int a = CollidingObjects.FindIndex(x => (x[0] == obj1 && x[1] == obj2) || 
                                                    (x[1] == obj1 && x[0] == obj2));
            return a != -1;
        }
        return false;
    }
4

0 に答える 0