Esempio n. 1
0
        internal void ResolveCircleAABBSimple()
        {
            // TODO Circle AABB
            Shapes.Circle BA = (BodyA.shape is Shapes.Circle) ? BodyA.shape as Shapes.Circle : BodyB.shape as Shapes.Circle;
            Shapes.AABB   BB = (BodyA.shape is Shapes.Circle) ? BodyB.shape as Shapes.AABB : BodyA.shape as Shapes.AABB;

            Vector3 dN    = Vector3.Normalize(BA.lastOverlap_delta);
            float   theta = (float)Math.Atan(dN.Z / dN.X);

            float length = BB.LengthAtAngle(theta);

            // Time to move the circle and the aabb away from each other along the normal
            // Calculate a new center of mass for the system, and offset them both their radii away from this center of mass, along the normal, based on their mass percentage of the system
            float   dR     = length + BA.Radius;
            float   tM     = BodyA.Mass + BodyB.Mass;
            float   mA     = BodyA.Mass / tM;
            float   mB     = BodyB.Mass / tM;
            Vector3 newCOM = BodyA.transform.Position * mA + BodyB.transform.Position * mB;

            BodyA.transform.parent.Position = newCOM - (dN * dR * (1 - mA));
            BodyB.transform.parent.Position = newCOM + (dN * dR * (1 - mB));

            // Calculate the resulting velocities based on the restitution scalars for both bodies
            if (BodyA.Velocity.LengthSquared() + BodyB.Velocity.LengthSquared() > 0)
            {
                float projection = (2 * (Vector3.Dot(BodyA.Velocity * BodyA.Restitution, dN) - Vector3.Dot(BodyB.Velocity * BodyB.Restitution, dN))) / (tM);

                if (BodyA.shape is Shapes.AABB)
                {
                    BodyA.Velocity = BodyA.Velocity - projection * BodyA.Mass * dN;

                    if (Math.Abs(dN.X) > Math.Abs(dN.Y))
                    {
                        BodyB.Velocity = new Vector3(-BodyB.Velocity.X, BodyB.Velocity.Y, BodyB.Velocity.Z);
                    }
                    else
                    {
                        BodyB.Velocity = new Vector3(BodyB.Velocity.X, BodyB.Velocity.Y, -BodyB.Velocity.Z);
                    }
                }
                else
                {
                    BodyB.Velocity = BodyB.Velocity + projection * BodyB.Mass * dN;

                    if (Math.Abs(dN.X) > Math.Abs(dN.Y))
                    {
                        BodyA.Velocity = new Vector3(-BodyA.Velocity.X, BodyA.Velocity.Y, BodyA.Velocity.Z);
                    }
                    else
                    {
                        BodyA.Velocity = new Vector3(BodyA.Velocity.X, BodyA.Velocity.Y, -BodyA.Velocity.Z);
                    }
                }
            }
        }
Esempio n. 2
0
        internal void ResolveCircleAABBStatic(PhysicsBody2D BodyS, PhysicsBody2D BodyD)
        {
            // TODO Circle AABB
            Shapes.Circle BA = (BodyS.shape is Shapes.Circle) ? BodyS.shape as Shapes.Circle : BodyD.shape as Shapes.Circle;
            Shapes.AABB   BB = (BodyS.shape is Shapes.Circle) ? BodyD.shape as Shapes.AABB : BodyS.shape as Shapes.AABB;

            // Might as well normalize the delta while we are at it
            Vector3 dN     = Vector3.Normalize(BA.lastOverlap_delta);
            float   theta  = (float)Math.Atan(dN.Z / dN.X);
            float   length = BB.LengthAtAngle(theta);

            // Time to move the circle and the aabb away from each other along the normal
            // Calculate a new center of mass for the system, and offset them both their radii away from this center of mass, along the normal, based on their mass percentage of the system
            float dR = length + BA.Radius;

            BodyD.transform.parent.Position = BodyS.transform.Position + (dN * dR);

            if (BodyB.Velocity.LengthSquared() > 0 && Vector3.Dot(Vector3.Normalize(BodyB.Velocity), dN) > 0)
            {
                float projection = 2 * -Vector3.Dot(BodyB.Velocity * MathHelper.Min(BodyB.Restitution, BodyA.Restitution), dN);

                if (BodyA.shape is Shapes.AABB)
                {
                    if (Math.Abs(dN.X) > Math.Abs(dN.Y))
                    {
                        BodyB.Velocity = new Vector3(-BodyB.Velocity.X, BodyB.Velocity.Y, BodyB.Velocity.Z);
                    }
                    else
                    {
                        BodyB.Velocity = new Vector3(BodyB.Velocity.X, BodyB.Velocity.Y, -BodyB.Velocity.Z);
                    }
                }
                else
                {
                    BodyB.Velocity = BodyB.Velocity + projection * BodyB.Mass * dN;
                }
            }
        }