Skip to content

Phase 1 / Forge / Sequential Impulses contact solver#60

Merged
guysenpai merged 23 commits into
mainfrom
phase-1/forge/solver-sequential-impulses
Jul 24, 2026
Merged

Phase 1 / Forge / Sequential Impulses contact solver#60
guysenpai merged 23 commits into
mainfrom
phase-1/forge/solver-sequential-impulses

Conversation

@guysenpai

Copy link
Copy Markdown
Contributor

M1.1.6 — Forge 3D: Sequential Impulses contact solver

Seventh core sub-milestone of the M1.1 rigid arc — the velocity-level Sequential Impulses contact solver (Catto lineage, Box2D/Jolt tradition). The FIRST real consumer of the M1.1.3/4 contact manifolds and of the frame-stable feature_id warm-start contract. No positional bias of any kind (no Baumgarte, no split impulse); NGS position correction is M1.1.7.

Gates (all RED-first on pinnable behaviors)

  • E1Body gains friction/restitution SoA columns (dropped from BodyDescriptor since M1.1.0) + stale-safe getters + domain debug asserts; pipeline/integration.zig split into integrateVelocities/integratePositions with integrate kept as their bit-identical composition (M1.1.5 tests untouched) so the solve sits between the passes.
  • E2 — new forge_3d/rigid/ package: material combine rules, trig-free tangent basis, ContactConstraint + build (canonical broadphase pair keys → collidePair → sorted by pair key) + prepare (lever arms, world inverse inertias, normal + two independent tangent effective masses, v_n⁻ capture, true-zero inverse-mass skip).
  • E3contact_cache.zig: double-buffered sorted flat cache, full key (pair_key, subshape_id=0, feature_id), binary-search per-feature matching, hit/miss counters, beginTick/endTick. warmStart with world-space tangent reprojection onto the new basis + circular clamp.
  • E4 — Gauss-Seidel solveRange(from,to) (island-additivity seam): normal accumulated clamp λn ≥ 0 + restitution bias (approaching-only, threshold-gated, v_n⁻ captured before warm start). SolverConfig.
  • E5 — friction after the normal update per point (Jolt order): two independent tangent axes + circular (isotropic, basis-independent) clamp to μ·λn.
  • E6 — full-pipeline test harness (normative per-tick cycle, tests only), 10 acceptance scenarios + determinism (bit-exact 300 ticks) + f64 + ReleaseSafe.

Deviations from the frozen brief (recorded in the brief, ratified in review)

  1. Restitution condition |v_n⁻| > thresholdv_n⁻ < −threshold (approaching-only). The |v_n⁻| form applied a negative bias to a capture-time separating contact, under-enforcing non-penetration (Claude.ai spec defect).
  2. combineFriction @sqrt(a*b)@sqrt(a)*@sqrt(b) — identical geometric mean, finite across the whole domain (kills an inf·0 = NaN clamp path).

A KB engine-physics-forge.md spec patch is pending for both (new Open-decisions bullet in CLAUDE.md).

Flags for review

  • The harness keeps a persistent candidate-pair set (never pruned) because computePairs is moved-driven with fat-AABB hysteresis; the retention rule (retain while the FAT AABBs overlap) is normative for the M1.1.15 step()/PhysicsWorld, pinned by the small-hop regression test (pre-merge Codex P1).
  • velocity_solver.zig = 592 lines (over the 500-line Review guideline; brief-mandated single-file solver + inline tests, narrowphase.zig/broadphase.zig precedent).
  • forge_3d/root.zig exposes rigid as a namespace (pub const rigid).

Verification

  • 162/162 forge-3d tests green in f32 and -Dphysics_f64=true, debug and ReleaseSafe.
  • Full zig build test (debug + ReleaseSafe) green via the pre-push gate; zig build clean; zig fmt --check clean.
  • No benchmarks mandated (absolute perf targets land with the full step, M1.1.3/4/5 precedent).

Brief: briefs/M1.1.6-solver-sequential-impulses.md (Status → CLOSED, Execution log + Recorded deviations + Closing notes filled).

Merge strategy: squash-and-merge. Merge and tag (v0.11.6-solver-sequential-impulses) are Guy's — this PR does neither.

🤖 Generated with Claude Code

@guysenpai
guysenpai merged commit 0750ff9 into main Jul 24, 2026
16 of 18 checks passed
@guysenpai
guysenpai deleted the phase-1/forge/solver-sequential-impulses branch July 24, 2026 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant