/// <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)); } } } } }
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); } } } }