HardYards/web/world/js
m3ultra 06ec4cbea2 Add 3D sail cloth sim with per-face wind and XPBD corner loads
Verlet cloth on a bilinear patch between 4 anchors, N=10 grid,
structural/shear/bend constraints, 5 relaxation iterations at a fixed
1/60 substep. Wind is applied per FACE so hypar twist genuinely sheds
load rather than being cosmetic.

Two deviations from PLAN3D worth flagging:

- Load is read from each constraint's XPBD Lagrange multiplier, not from
  FABRIC_K * leftover-stretch. After a fixed iteration count the leftover
  stretch is solver error, not fabric strain, so the naive reading came
  out ~50x hot (60 kN peaks on a 5x5 m sail). The multiplier is the real
  constraint impulse, which the statics assert confirms by balancing the
  corner reactions against the applied wind to 8%.

- Wind uses a signed square (d*|d|) rather than clamp(d)^2, so the
  leeward face is pushed too. A sail is double-sided.

The sim core deliberately does not import three.js: it runs headless
under node today, stays allocation-free in the hot loop, and replays
bit-for-bit. createSailView() pulls three in lazily for rendering.

Loads land in real newtons (~1-4 kN on a 5x5 m sail in a 34 m/s storm),
so hardware ratings are real working load limits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 21:55:37 +10:00
..
tests Add selftest harness with one suite per lane 2026-07-16 21:33:42 +10:00
camera.js Add graybox yard, third-person camera and game shell 2026-07-16 21:33:42 +10:00
contracts.js Add contracts.js: the shared integration spine 2026-07-16 21:33:42 +10:00
main.js Add graybox yard, third-person camera and game shell 2026-07-16 21:33:42 +10:00
sail.js Add 3D sail cloth sim with per-face wind and XPBD corner loads 2026-07-16 21:55:37 +10:00
sail.selftest.js Add 3D sail cloth sim with per-face wind and XPBD corner loads 2026-07-16 21:55:37 +10:00
testkit.js Add selftest harness with one suite per lane 2026-07-16 21:33:42 +10:00
world.js Add graybox yard, third-person camera and game shell 2026-07-16 21:33:42 +10:00