feat: stage 2 real CAD conveyor, hybrid physics drops, mobile policy (WIP)

- CAD pipeline: conveer.FCStd -> FreeCAD headless -> conveyor-web.glb
  (555KB Draco, 42 named nodes) integrated into main scene; gates and
  rollers animated from domain state
- Domain-driven adapter sorterVisualState.ts; per-SKU visual physics
  profiles (VISUAL_PHYSICS_ESTIMATE)
- Hybrid Rapier physics: kinematic belt travel -> dynamic drop handoff
  -> verified freeze; shared collider layout (physicsWorldLayout) used
  by runtime and headless validation sim (physicsDropSim + 13 tests)
- Gravity chutes / open roll-cage front redesign (drop tuning in progress:
  4/7 routes verified headless)
- Premium industrial visual: PBR, ACES, PCFSoft shadows, Lightformer env,
  UI cleanup behind ?debug=1
- Mobile capability policy: SVG fallback / Mobile Low / full tiers,
  Telegram WebView forced to SVG, e2e stubs for weak devices
- Performance benchmarks cad-light/physics/full pass; stage2 artifacts

tsc clean. Physics drop validation for 3 SKU routes still in progress.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Даня Архипов
2026-07-29 21:05:46 +00:00
parent 394c513037
commit 40e9b18e8d
46 changed files with 5721 additions and 175 deletions

View File

@@ -100,6 +100,11 @@ test.describe('Stage 1 real models', () => {
page.on('request', (req) => {
if (MODEL_RE.test(req.url())) modelRequests.push(req.url());
});
// Stage 2 §16: fallback path is for weak devices — stub low capability.
await page.addInitScript(() => {
Object.defineProperty(navigator, 'hardwareConcurrency', { value: 4, configurable: true });
Object.defineProperty(navigator, 'deviceMemory', { value: 2, configurable: true });
});
await page.goto('/', { waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-testid="main-svg-fallback"]', { timeout: 30000 });