10internal sealed class CollisionResolver
12 private readonly List<ColliderInstance> _queryResults =
new();
13 private readonly ColliderRegistry _world;
18 internal event Action<ICollider, ICollider, Rectangle>? TriggerOverlap;
23 internal event Action<ICollider, ICollider, Rectangle>? SolidOverlap;
30 internal CollisionResolver(ColliderRegistry world)
32 _world = world ??
throw new ArgumentNullException(nameof(world));
38 internal void Resolve()
40 foreach (var mover
in _world.DynamicColliders)
42 if (mover.Owner is not ICollisionMovableEntity movableOwner)
45 ResolveForMover(mover, movableOwner);
49 private void ResolveForMover(ICollider mover, ICollisionMovableEntity movableOwner)
51 Rectangle rect = mover.Owner.CollisionArea;
53 var aabb = Aabb.FromRectangle(rect);
55 _world.QueryInstances(
67 foreach (var instance
in _queryResults)
69 var otherCollider = instance.Collider;
70 var otherRect = instance.BoundsWorldPx.ToRectangle();
72 if (!rect.IntersectsWith(otherRect))
83 TriggerOverlap?.Invoke(mover, otherCollider, overlap);
87 SolidOverlap?.Invoke(mover, otherCollider, overlap);
89 float centerX = rect.Left + rect.Width * 0.5f;
90 float centerY = rect.Top + rect.Height * 0.5f;
91 float otherCenterX = otherRect.Left + otherRect.Width * 0.5f;
92 float otherCenterY = otherRect.Top + otherRect.Height * 0.5f;
97 if (overlap.Width < overlap.Height)
99 dx = centerX < otherCenterX
107 dy = centerY < otherCenterY
120 if (totalDx != 0 || totalDy != 0)
122 movableOwner.TranslateWorldPx(totalDx, totalDy);
127 movableOwner.CancelVelocityComponent(hitX, hitY);
@ Rectangle
Particles are spawned uniformly within a rectangular area. This is the default distribution.
CollisionResponseType
Defines how a collider responds to collisions with other colliders.