module

Flock::Collision::Solver2D

Warm-started sequential-impulse solver (Box2D-lite style). Each contact point carries an accumulated impulse across frames; applying it up front (warm start) and clamping the accumulated value makes stacks converge fast and rest firmly. Positional correction stays Baumgarte-style.

Constants

CORRECTION_PERCENT = 0.4_f32
PENETRATION_SLOP = 0.005_f32
RESTITUTION_THRESHOLD = 0.5_f32

Instance methods

build_constraint(i : Int32, j : Int32, key : UInt64, a : RigidBody2D, pa : Flock::Vec2, b : RigidBody2D, pb : Flock::Vec2, m : Manifold2D) : ContactConstraint2D

Precomputes the constraint geometry, effective masses and restitution bias.

Source
correct_position(pa : Flock::Vec2, inv_ma : Float32, pb : Flock::Vec2, inv_mb : Float32, m : Manifold2D, weight : Float32 = 1.0_f32) : Tuple(Flock::Vec2, Flock::Vec2)

Baumgarte positional correction: pushes centers apart along the normal, weighted by inverse mass. weight scales the correction so that when a pair's manifold has multiple contact points (each corrected separately), the summed correction stays at most ~1x (pass 1/point_count).

Source
match_cache(cached : Array(CachedImpulse2D) | Nil, point : Flock::Vec2) : Tuple(Float32, Float32)

Nearest cached impulse to point (within a small tolerance); {0,0} on miss.

Source
pair_key(a : Flock::Entity, b : Flock::Entity) : UInt64

Order-independent key for an entity pair (broadphase always yields i<j, so the A->B normal orientation is stable frame to frame).

Source
solve_constraint(a : RigidBody2D, b : RigidBody2D, c : ContactConstraint2D) : Tuple(RigidBody2D, RigidBody2D, ContactConstraint2D)

One iteration: normal impulse (with restitution bias) then friction, both via accumulated-impulse clamping.

Source
warm_start(a : RigidBody2D, b : RigidBody2D, c : ContactConstraint2D) : Tuple(RigidBody2D, RigidBody2D)

Applies the (warm-started) accumulated impulse to both bodies.

Source