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

@@ -0,0 +1,108 @@
{
"profile": "cad-full",
"path": "/?perf=1&quality=demo",
"viewport": {
"width": 1920,
"height": 1080
},
"runs": 2,
"fpsAvg": 59.9,
"fpsMin": 28.49,
"frameTimeP95Ms": 17.2,
"drawCalls": 166,
"triangles": 365218,
"heapMb": 53.82,
"renderer": "ANGLE (NVIDIA Corporation, NVIDIA GeForce GTX 1080/PCIe/SSE2, OpenGL ES 3.2)",
"physics": {
"count": 600,
"avgMs": 0.0655000012119611,
"p95Ms": 0.19999998807907104,
"maxMs": 0.9000000357627869
},
"dropsVerified": [
{
"caseId": "box_b",
"zone": "B",
"inside": true
},
{
"caseId": "lunchbox_b",
"zone": "B",
"inside": true
}
],
"device": {
"vendor": "Google Inc. (NVIDIA Corporation)",
"hardwareConcurrency": 6,
"deviceMemory": 16,
"devicePixelRatio": 1,
"viewport": {
"width": 1920,
"height": 1080
}
},
"consoleErrors": [],
"sceneLoadMs": 486.5,
"ctxLost": 0,
"modelRequests": [
"http://127.0.0.1:3101/models/sorter/conveyor-web.glb",
"http://127.0.0.1:3101/models/box-300.stl",
"http://127.0.0.1:3101/models/lunchbox.stl",
"http://127.0.0.1:3101/models/box-400.stl",
"http://127.0.0.1:3101/models/plate.stl",
"http://127.0.0.1:3101/models/bottle.stl",
"http://127.0.0.1:3101/models/pen.stl"
],
"memoryLoop": [
{
"cycle": 1,
"heapBytes": 52565544,
"dropResults": 0
},
{
"cycle": 2,
"heapBytes": 35445133,
"dropResults": 0
},
{
"cycle": 3,
"heapBytes": 65863994,
"dropResults": 0
},
{
"cycle": 4,
"heapBytes": 38948871,
"dropResults": 0
},
{
"cycle": 5,
"heapBytes": 52642098,
"dropResults": 0
},
{
"cycle": 6,
"heapBytes": 51737094,
"dropResults": 0
},
{
"cycle": 7,
"heapBytes": 58675947,
"dropResults": 0
},
{
"cycle": 8,
"heapBytes": 53790182,
"dropResults": 0
},
{
"cycle": 9,
"heapBytes": 57980834,
"dropResults": 0
},
{
"cycle": 10,
"heapBytes": 54462476,
"dropResults": 0
}
]
}

View File

@@ -0,0 +1,51 @@
{
"profile": "cad-light",
"path": "/?perf=1&quality=medium",
"viewport": {
"width": 1920,
"height": 1080
},
"runs": 2,
"fpsAvg": 59.9,
"fpsMin": 28.41,
"frameTimeP95Ms": 17.3,
"drawCalls": 112,
"triangles": 176789,
"heapMb": 30.8,
"renderer": "ANGLE (NVIDIA Corporation, NVIDIA GeForce GTX 1080/PCIe/SSE2, OpenGL ES 3.2)",
"physics": null,
"dropsVerified": [
{
"caseId": "box_b",
"zone": "B",
"inside": true
},
{
"caseId": "lunchbox_b",
"zone": "B",
"inside": true
}
],
"device": {
"vendor": "Google Inc. (NVIDIA Corporation)",
"hardwareConcurrency": 6,
"deviceMemory": 16,
"devicePixelRatio": 1,
"viewport": {
"width": 1920,
"height": 1080
}
},
"consoleErrors": [],
"sceneLoadMs": 425,
"ctxLost": 0,
"modelRequests": [
"http://127.0.0.1:3101/models/sorter/conveyor-web.glb",
"http://127.0.0.1:3101/models/box-300.stl",
"http://127.0.0.1:3101/models/lunchbox.stl",
"http://127.0.0.1:3101/models/box-400.stl",
"http://127.0.0.1:3101/models/plate.stl",
"http://127.0.0.1:3101/models/bottle.stl",
"http://127.0.0.1:3101/models/pen.stl"
]
}

View File

@@ -0,0 +1,56 @@
{
"profile": "cad-physics",
"path": "/?perf=1&quality=high",
"viewport": {
"width": 1920,
"height": 1080
},
"runs": 2,
"fpsAvg": 60.010000000000005,
"fpsMin": 31.95,
"frameTimeP95Ms": 17.299999999999997,
"drawCalls": 168,
"triangles": 365442,
"heapMb": 53.57,
"renderer": "ANGLE (NVIDIA Corporation, NVIDIA GeForce GTX 1080/PCIe/SSE2, OpenGL ES 3.2)",
"physics": {
"count": 600,
"avgMs": 0.06783333351214726,
"p95Ms": 0.19999998807907104,
"maxMs": 0.3999999761581421
},
"dropsVerified": [
{
"caseId": "box_b",
"zone": "B",
"inside": true
},
{
"caseId": "lunchbox_b",
"zone": "B",
"inside": true
}
],
"device": {
"vendor": "Google Inc. (NVIDIA Corporation)",
"hardwareConcurrency": 6,
"deviceMemory": 16,
"devicePixelRatio": 1,
"viewport": {
"width": 1920,
"height": 1080
}
},
"consoleErrors": [],
"sceneLoadMs": 553.5,
"ctxLost": 0,
"modelRequests": [
"http://127.0.0.1:3101/models/sorter/conveyor-web.glb",
"http://127.0.0.1:3101/models/box-300.stl",
"http://127.0.0.1:3101/models/lunchbox.stl",
"http://127.0.0.1:3101/models/box-400.stl",
"http://127.0.0.1:3101/models/plate.stl",
"http://127.0.0.1:3101/models/bottle.stl",
"http://127.0.0.1:3101/models/pen.stl"
]
}

View File

@@ -0,0 +1,31 @@
{
"profile": "mobile-fallback",
"path": "/",
"viewport": {
"width": 390,
"height": 844
},
"runs": 1,
"fpsAvg": null,
"fpsMin": null,
"frameTimeP95Ms": null,
"drawCalls": null,
"triangles": null,
"heapMb": null,
"renderer": null,
"physics": null,
"dropsVerified": [],
"device": null,
"consoleErrors": [],
"sceneLoadMs": 143,
"ctxLost": 0,
"modelRequests": [],
"fallback": {
"fallbackVisible": true,
"canvasCount": 0,
"ctxLost": 0,
"modelRequests": [],
"consoleErrors": [],
"sceneLoadMs": 143
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB