/// <summary>
        /// Collides the given actor against all other rigidbodies and calculate the allowed velocity during this frame.
        /// </summary>
        /// <remarks>This function will immediately return if the calculated velocity becomes zero.</remarks>
        private static void CalculateActorVelocity(ActorRigidbody actor)
        {
            actor.ProcessingData.CalcVel = actor.Velocity;

            if (actor.Velocity == Vector2.Zero)
            {
                return;
            }


            foreach (var staticbody in AllStatics)
            {
                if (actor.ProcessingData.CalcVel == Vector2.Zero)
                {
                    return;
                }

                if (PhysicsMath.IsOverlapping(actor.MainCollider, staticbody.MainCollider))
                {
                    if (!PhysicsMath.IsSlidingCorner(actor.MainCollider, staticbody.MainCollider))
                    {
                        actor.ProcessingData.CalcVel = VelocityMath.IntoPlane(actor.ProcessingData.CalcVel, PhysicsMath.GetNormal(actor.MainCollider, staticbody.MainCollider));
                    }
                }
            }

            foreach (var solid in AllSolids)
            {
                foreach (var solidCollider in solid.Colliders)
                {
                    if (actor.ProcessingData.CalcVel == Vector2.Zero)
                    {
                        return;
                    }

                    if (PhysicsMath.IsOverlapping(actor.MainCollider, solidCollider))
                    {
                        if (!PhysicsMath.IsSlidingCorner(actor.MainCollider, solidCollider))
                        {
                            actor.ProcessingData.CalcVel = VelocityMath.IntoPlane(actor.ProcessingData.CalcVel, PhysicsMath.GetNormal(actor.MainCollider, solidCollider));
                        }
                    }
                }
            }
        }
Exemple #2
0
        public VelocityPair Get(Rigidbody left, Rigidbody right)
        {
            Vector2 leftVel  = left.ProcessingData.CalcVel;
            Vector2 rightVel = right.ProcessingData.CalcVel;

            //solid vs solid
            if (left is SolidRigidbody && right is SolidRigidbody)
            {
                return(VelocityMath.CollideSlide(left.MainCollider, right.MainCollider, leftVel, rightVel, 0.5f, 0.5f));
            }

            // actor vs actor
            if (left is ActorRigidbody && right is ActorRigidbody)
            {
                return(VelocityMath.CollideSlide(left.MainCollider, right.MainCollider, leftVel, rightVel, 0.5f, 0.5f));
            }

            return(new VelocityPair(leftVel, rightVel));
        }
        private static void CalculateSolidVelocity(SolidRigidbody solid)
        {
            solid.ProcessingData.CalcVel = solid.Velocity;

            if (solid.Velocity == Vector2.Zero)
            {
                return;                                             // Early exit if no velocity.
            }
            // Regional check against all static rigidbodies
            foreach (var staticbody in AllStatics)
            {
                foreach (var collider in solid.Colliders)
                {
                    if (solid.ProcessingData.CalcVel == Vector2.Zero)
                    {
                        return;
                    }

                    if (PhysicsMath.IsOverlapping(collider, staticbody.MainCollider))
                    {
                        if (!PhysicsMath.IsSlidingCorner(collider, staticbody.MainCollider))
                        {
                            solid.ProcessingData.CalcVel = VelocityMath.IntoPlane(solid.ProcessingData.CalcVel, PhysicsMath.GetNormal(collider, staticbody.MainCollider));

                            Console.WriteLine($"Solid collision against {staticbody.Entity} ({collider.LocalPosition}) to yield {solid.ProcessingData.CalcVel}");
                        }
                    }
                }
            }

            // Regional check against other solids
            foreach (var otherSolid in AllSolids)
            {
                if (solid.ProcessingData.CalcVel == Vector2.Zero)
                {
                    return;
                }

                // Skip self
                if (ReferenceEquals(solid, otherSolid))
                {
                    continue;
                }

                // Skip if other solid has already processed this solid
                if (otherSolid.ProcessingData.CheckedAgainst.Contains(solid))
                {
                    continue;
                }


                if (PhysicsMath.IsOverlapping(solid.MainCollider, otherSolid.MainCollider))
                {
                    if (!PhysicsMath.IsSlidingCorner(solid.MainCollider, otherSolid.MainCollider))
                    {
                        VelocityPair result = Ruleset.Get(solid, otherSolid);

                        Console.WriteLine($"Collided {solid.Entity} against {otherSolid.Entity} to yield {result.left} and {result.right}");

                        solid.ProcessingData.CalcVel      = result.left;
                        otherSolid.ProcessingData.CalcVel = result.right;

                        solid.ProcessingData.CheckedAgainst.Add(otherSolid);
                        otherSolid.ProcessingData.CheckedAgainst.Add(solid);
                    }
                }
            }
        }