@vgai/engine 0.5.21 → 0.5.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/README.md +6 -3
  2. package/dist/adapter/adapter-module.d.ts.map +1 -1
  3. package/dist/adapter/adapter-module.js +2 -4
  4. package/dist/adapter/adapter-surface.d.ts +1 -1
  5. package/dist/adapter/adapter-surface.js +1 -1
  6. package/dist/adapter/authoring.d.ts +19 -21
  7. package/dist/adapter/authoring.d.ts.map +1 -1
  8. package/dist/adapter/authoring.js +2 -2
  9. package/dist/adapter/binding.d.ts +341 -0
  10. package/dist/adapter/binding.d.ts.map +1 -0
  11. package/dist/adapter/binding.js +148 -0
  12. package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -1
  13. package/dist/adapter/colyseus-networking-adapter.js +23 -4
  14. package/dist/adapter/entrypoint-selection-readers.d.ts +24 -0
  15. package/dist/adapter/entrypoint-selection-readers.d.ts.map +1 -0
  16. package/dist/adapter/entrypoint-selection-readers.js +63 -0
  17. package/dist/adapter/entrypoint-selection-source.d.ts.map +1 -1
  18. package/dist/adapter/entrypoint-selection-source.js +1 -44
  19. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
  20. package/dist/adapter/finders/scenes-from-entrypoint-selection.js +1 -52
  21. package/dist/adapter/host-context.d.ts +46 -15
  22. package/dist/adapter/host-context.d.ts.map +1 -1
  23. package/dist/adapter/host-context.js +2 -9
  24. package/dist/adapter/index.d.ts +11 -12
  25. package/dist/adapter/index.d.ts.map +1 -1
  26. package/dist/adapter/index.js +9 -10
  27. package/dist/adapter/ingest/game-contract.d.ts +0 -3
  28. package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
  29. package/dist/adapter/ingest/game-contract.js +0 -3
  30. package/dist/adapter/ingest/scene-capture.d.ts +19 -23
  31. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
  32. package/dist/adapter/ingest/scene-capture.js +143 -17
  33. package/dist/adapter/ingest/visible-capture-window.d.ts +34 -0
  34. package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
  35. package/dist/adapter/manifest-interpreter.d.ts +59 -0
  36. package/dist/adapter/manifest-interpreter.d.ts.map +1 -0
  37. package/dist/adapter/manifest-interpreter.js +50 -0
  38. package/dist/adapter/native-debug-module.d.ts +71 -3
  39. package/dist/adapter/native-debug-module.d.ts.map +1 -1
  40. package/dist/adapter/native-debug-module.js +146 -10
  41. package/dist/adapter/rapier-physics-adapter.d.ts +31 -1
  42. package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -1
  43. package/dist/adapter/rapier-physics-adapter.js +50 -36
  44. package/dist/adapter/renderer-config.d.ts +3 -3
  45. package/dist/adapter/renderer-config.js +3 -3
  46. package/dist/adapter/root-adapter.d.ts +7 -7
  47. package/dist/adapter/root-adapter.js +4 -4
  48. package/dist/adapter/system-adapter.d.ts +45 -7
  49. package/dist/adapter/system-adapter.d.ts.map +1 -1
  50. package/dist/adapter/system-seam-contract.d.ts +3 -3
  51. package/dist/adapter/system-seam-contract.js +3 -3
  52. package/dist/adapter/system-slot.d.ts +168 -0
  53. package/dist/adapter/system-slot.d.ts.map +1 -0
  54. package/dist/adapter/system-slot.js +229 -0
  55. package/dist/adapter/transform.d.ts +11 -1
  56. package/dist/adapter/transform.d.ts.map +1 -1
  57. package/dist/ai/navigation.d.ts +17 -1
  58. package/dist/ai/navigation.d.ts.map +1 -1
  59. package/dist/ai/navigation.js +26 -5
  60. package/dist/animation/anim-graph-types.d.ts +11 -3
  61. package/dist/animation/anim-graph-types.d.ts.map +1 -1
  62. package/dist/animation/theatre-clock-binding.d.ts +4 -4
  63. package/dist/animation/theatre-clock-binding.js +4 -4
  64. package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
  65. package/dist/animation/xstate-animation-binding.js +2 -2
  66. package/dist/animation/xstate-animation-meta.d.ts +13 -0
  67. package/dist/animation/xstate-animation-meta.d.ts.map +1 -1
  68. package/dist/animation/xstate-animation-meta.js +14 -0
  69. package/dist/asset-formats/index.d.ts +4 -7
  70. package/dist/asset-formats/index.d.ts.map +1 -1
  71. package/dist/asset-formats/index.js +4 -7
  72. package/dist/asset-formats/render-env.d.ts +5 -8
  73. package/dist/asset-formats/render-env.d.ts.map +1 -1
  74. package/dist/asset-formats/render-env.js +3 -6
  75. package/dist/asset-parse-error.d.ts +2 -5
  76. package/dist/asset-parse-error.d.ts.map +1 -1
  77. package/dist/asset-parse-error.js +2 -5
  78. package/dist/audio/bus-mixer.d.ts +101 -0
  79. package/dist/audio/bus-mixer.d.ts.map +1 -0
  80. package/dist/audio/bus-mixer.js +115 -0
  81. package/dist/canvas-react/index.d.ts +5 -12
  82. package/dist/canvas-react/index.d.ts.map +1 -1
  83. package/dist/canvas-react/index.js +5 -12
  84. package/dist/canvas-react/pixi-react-root-factory.d.ts +34 -21
  85. package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -1
  86. package/dist/canvas-react/pixi-react-root-factory.js +274 -36
  87. package/dist/core/countdown-timer.d.ts +118 -0
  88. package/dist/core/countdown-timer.d.ts.map +1 -0
  89. package/dist/core/countdown-timer.js +137 -0
  90. package/dist/core/deferred-commands.d.ts +127 -0
  91. package/dist/core/deferred-commands.d.ts.map +1 -0
  92. package/dist/core/deferred-commands.js +132 -0
  93. package/dist/core/frame-pacing.d.ts +1 -1
  94. package/dist/core/frame-pacing.js +2 -2
  95. package/dist/core/game-loop.d.ts +1 -3
  96. package/dist/core/game-loop.d.ts.map +1 -1
  97. package/dist/core/game-loop.js +1 -3
  98. package/dist/core/seeded-random.d.ts +1 -1
  99. package/dist/core/sim-clock.d.ts +19 -8
  100. package/dist/core/sim-clock.d.ts.map +1 -1
  101. package/dist/core/sim-clock.js +18 -7
  102. package/dist/core/types.d.ts +1 -3
  103. package/dist/core/types.d.ts.map +1 -1
  104. package/dist/defaults.d.ts +6 -14
  105. package/dist/defaults.d.ts.map +1 -1
  106. package/dist/defaults.js +6 -14
  107. package/dist/dev/instruments.d.ts +38 -11
  108. package/dist/dev/instruments.d.ts.map +1 -1
  109. package/dist/dev/instruments.js +81 -11
  110. package/dist/dev/register-render-vitals.d.ts +1 -4
  111. package/dist/dev/register-render-vitals.d.ts.map +1 -1
  112. package/dist/dev/register-render-vitals.js +1 -4
  113. package/dist/dev/render-debug-adapter.d.ts +2 -3
  114. package/dist/dev/render-debug-adapter.d.ts.map +1 -1
  115. package/dist/dev/render-debug-adapter.js +2 -3
  116. package/dist/dev/render-vitals.d.ts +3 -3
  117. package/dist/dev/render-vitals.js +3 -3
  118. package/dist/dev/webgl-frame-capture.d.ts +1 -1
  119. package/dist/dev/webgl-frame-capture.js +1 -1
  120. package/dist/index.d.ts +2 -5
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +2 -4
  123. package/dist/input/host-pointer.d.ts +122 -0
  124. package/dist/input/host-pointer.d.ts.map +1 -0
  125. package/dist/input/host-pointer.js +160 -0
  126. package/dist/input/input-manager.d.ts +33 -5
  127. package/dist/input/input-manager.d.ts.map +1 -1
  128. package/dist/input/input-manager.js +48 -13
  129. package/dist/input/rebind-controller.d.ts.map +1 -1
  130. package/dist/input/rebind-controller.js +6 -8
  131. package/dist/input/schema.d.ts.map +1 -1
  132. package/dist/input/schema.js +56 -28
  133. package/dist/manifest/filename.d.ts.map +1 -1
  134. package/dist/manifest/filename.js +8 -12
  135. package/dist/manifest/load.d.ts +10 -10
  136. package/dist/manifest/load.d.ts.map +1 -1
  137. package/dist/manifest/load.js +9 -6
  138. package/dist/manifest/schema.d.ts +17 -21
  139. package/dist/manifest/schema.d.ts.map +1 -1
  140. package/dist/manifest/schema.js +45 -35
  141. package/dist/physics/collider-dimensions.d.ts +8 -12
  142. package/dist/physics/collider-dimensions.d.ts.map +1 -1
  143. package/dist/physics/collider-dimensions.js +8 -12
  144. package/dist/pixi/scene-capture.d.ts +11 -13
  145. package/dist/pixi/scene-capture.d.ts.map +1 -1
  146. package/dist/react/world-state.d.ts +1 -1
  147. package/dist/react/world-state.d.ts.map +1 -1
  148. package/dist/render/directional-shadow-fit.d.ts +88 -0
  149. package/dist/render/directional-shadow-fit.d.ts.map +1 -0
  150. package/dist/render/directional-shadow-fit.js +133 -0
  151. package/dist/render/environment-capture.d.ts +68 -0
  152. package/dist/render/environment-capture.d.ts.map +1 -0
  153. package/dist/render/environment-capture.js +90 -0
  154. package/dist/render/ibl-override-material.d.ts +97 -0
  155. package/dist/render/ibl-override-material.d.ts.map +1 -0
  156. package/dist/render/ibl-override-material.js +114 -0
  157. package/dist/render/light-camera-factory.d.ts +5 -7
  158. package/dist/render/light-camera-factory.d.ts.map +1 -1
  159. package/dist/render/light-camera-factory.js +8 -11
  160. package/dist/render/material-factory.js +1 -1
  161. package/dist/render/render-batch-system.d.ts.map +1 -1
  162. package/dist/render/render-features.d.ts +17 -6
  163. package/dist/render/render-features.d.ts.map +1 -1
  164. package/dist/render/render-features.js +0 -28
  165. package/dist/runtime/create-runtime.d.ts +34 -25
  166. package/dist/runtime/create-runtime.d.ts.map +1 -1
  167. package/dist/runtime/create-runtime.js +218 -93
  168. package/dist/runtime/debug-registry.d.ts +77 -8
  169. package/dist/runtime/debug-registry.d.ts.map +1 -1
  170. package/dist/runtime/debug-registry.js +3 -3
  171. package/dist/runtime/dev-build.d.ts +2 -2
  172. package/dist/runtime/dev-build.js +2 -2
  173. package/dist/runtime/game-input-seams.d.ts +51 -0
  174. package/dist/runtime/game-input-seams.d.ts.map +1 -0
  175. package/dist/runtime/game-input-seams.js +86 -0
  176. package/dist/runtime/game.d.ts +104 -40
  177. package/dist/runtime/game.d.ts.map +1 -1
  178. package/dist/runtime/game.js +119 -61
  179. package/dist/runtime/mount-game.d.ts +0 -16
  180. package/dist/runtime/mount-game.d.ts.map +1 -1
  181. package/dist/runtime/mount-game.js +26 -41
  182. package/dist/runtime/mount-manifest.d.ts +22 -14
  183. package/dist/runtime/mount-manifest.d.ts.map +1 -1
  184. package/dist/runtime/mount-manifest.js +22 -20
  185. package/dist/runtime/playtest.d.ts +22 -0
  186. package/dist/runtime/playtest.d.ts.map +1 -0
  187. package/dist/runtime/playtest.js +12 -0
  188. package/dist/runtime/state-bridge.d.ts +2 -3
  189. package/dist/runtime/state-bridge.d.ts.map +1 -1
  190. package/dist/runtime/state-bridge.js +1 -0
  191. package/dist/setup/setup-audio.d.ts +12 -0
  192. package/dist/setup/setup-audio.d.ts.map +1 -1
  193. package/dist/setup/setup-audio.js +9 -10
  194. package/dist/setup/setup-renderer.d.ts +2 -25
  195. package/dist/setup/setup-renderer.d.ts.map +1 -1
  196. package/dist/setup/setup-renderer.js +2 -31
  197. package/dist/world3d-react/index.d.ts +15 -25
  198. package/dist/world3d-react/index.d.ts.map +1 -1
  199. package/dist/world3d-react/index.js +15 -25
  200. package/dist/world3d-react/r3f-root-factory.d.ts +28 -34
  201. package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
  202. package/dist/world3d-react/r3f-root-factory.js +403 -57
  203. package/dist/world3d-react/rapier-physics-bridge.d.ts +30 -17
  204. package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
  205. package/dist/world3d-react/rapier-physics-bridge.js +143 -58
  206. package/package.json +1 -1
  207. package/schemas/engine-capabilities.json +16 -14
  208. package/schemas/vgai-project.schema.json +35 -26
  209. package/src/adapter/adapter-module.ts +2 -4
  210. package/src/adapter/adapter-surface.ts +1 -1
  211. package/src/adapter/authoring.ts +19 -21
  212. package/src/adapter/binding.ts +468 -0
  213. package/src/adapter/colyseus-networking-adapter.ts +20 -5
  214. package/src/adapter/entrypoint-selection-readers.ts +66 -0
  215. package/src/adapter/entrypoint-selection-source.ts +1 -40
  216. package/src/adapter/finders/scenes-from-entrypoint-selection.ts +1 -48
  217. package/src/adapter/host-context.ts +45 -15
  218. package/src/adapter/index.ts +23 -11
  219. package/src/adapter/ingest/game-contract.ts +0 -3
  220. package/src/adapter/ingest/scene-capture.ts +190 -39
  221. package/src/adapter/ingest/visible-capture-window.ts +35 -0
  222. package/src/adapter/manifest-interpreter.ts +64 -0
  223. package/src/adapter/native-debug-module.ts +248 -15
  224. package/src/adapter/rapier-physics-adapter.ts +76 -20
  225. package/src/adapter/renderer-config.ts +3 -3
  226. package/src/adapter/root-adapter.ts +7 -7
  227. package/src/adapter/system-adapter.ts +43 -8
  228. package/src/adapter/system-seam-contract.ts +3 -3
  229. package/src/adapter/system-slot.ts +291 -0
  230. package/src/adapter/transform.ts +18 -1
  231. package/src/ai/navigation.ts +30 -3
  232. package/src/animation/anim-graph-types.ts +11 -3
  233. package/src/animation/theatre-clock-binding.ts +4 -4
  234. package/src/animation/xstate-animation-binding.ts +2 -2
  235. package/src/animation/xstate-animation-meta.ts +16 -0
  236. package/src/asset-formats/index.ts +4 -7
  237. package/src/asset-formats/render-env.ts +3 -6
  238. package/src/asset-parse-error.ts +2 -5
  239. package/src/audio/bus-mixer.ts +161 -0
  240. package/src/canvas-react/index.ts +5 -21
  241. package/src/canvas-react/pixi-react-root-factory.tsx +301 -39
  242. package/src/core/countdown-timer.ts +188 -0
  243. package/src/core/deferred-commands.ts +174 -0
  244. package/src/core/frame-pacing.ts +2 -2
  245. package/src/core/game-loop.ts +1 -3
  246. package/src/core/seeded-random.ts +1 -1
  247. package/src/core/sim-clock.ts +19 -8
  248. package/src/core/types.ts +1 -3
  249. package/src/defaults.ts +6 -14
  250. package/src/dev/instruments.ts +108 -11
  251. package/src/dev/register-render-vitals.ts +1 -4
  252. package/src/dev/render-debug-adapter.ts +2 -3
  253. package/src/dev/render-vitals.ts +3 -3
  254. package/src/dev/webgl-frame-capture.ts +1 -1
  255. package/src/index.ts +2 -5
  256. package/src/input/host-pointer.ts +230 -0
  257. package/src/input/input-manager.ts +49 -13
  258. package/src/input/input-types.ts +1 -1
  259. package/src/input/rebind-controller.ts +6 -8
  260. package/src/input/schema.ts +216 -188
  261. package/src/manifest/filename.ts +8 -12
  262. package/src/manifest/load.ts +17 -13
  263. package/src/manifest/schema.ts +55 -47
  264. package/src/physics/collider-dimensions.ts +8 -12
  265. package/src/pixi/scene-capture.ts +12 -15
  266. package/src/react/world-state.tsx +1 -1
  267. package/src/render/directional-shadow-fit.ts +156 -0
  268. package/src/render/environment-capture.ts +102 -0
  269. package/src/render/ibl-override-material.ts +170 -0
  270. package/src/render/light-camera-factory.ts +8 -11
  271. package/src/render/material-factory.ts +1 -1
  272. package/src/render/render-batch-system.ts +14 -6
  273. package/src/render/render-features.ts +17 -35
  274. package/src/runtime/create-runtime.ts +270 -108
  275. package/src/runtime/debug-registry.ts +84 -8
  276. package/src/runtime/dev-build.ts +2 -2
  277. package/src/runtime/game-input-seams.ts +108 -0
  278. package/src/runtime/game.ts +231 -85
  279. package/src/runtime/mount-game.ts +31 -57
  280. package/src/runtime/mount-manifest.ts +47 -36
  281. package/src/runtime/playtest.ts +22 -0
  282. package/src/runtime/state-bridge.ts +3 -3
  283. package/src/setup/setup-audio.ts +21 -11
  284. package/src/setup/setup-renderer.ts +2 -61
  285. package/src/world3d-react/index.ts +15 -31
  286. package/src/world3d-react/r3f-root-factory.tsx +451 -60
  287. package/src/world3d-react/rapier-physics-bridge.tsx +154 -58
  288. package/dist/adapter/setup-three-root-adapter.d.ts +0 -86
  289. package/dist/adapter/setup-three-root-adapter.d.ts.map +0 -1
  290. package/dist/adapter/setup-three-root-adapter.js +0 -908
  291. package/dist/animation/clip-map.d.ts +0 -12
  292. package/dist/animation/clip-map.d.ts.map +0 -1
  293. package/dist/animation/clip-map.js +0 -31
  294. package/dist/asset-registry.d.ts +0 -38
  295. package/dist/asset-registry.d.ts.map +0 -1
  296. package/dist/asset-registry.js +0 -66
  297. package/dist/canvas-react/engine-bridge.d.ts +0 -45
  298. package/dist/canvas-react/engine-bridge.d.ts.map +0 -1
  299. package/dist/canvas-react/engine-bridge.js +0 -45
  300. package/dist/canvas-react/pixi-react-adapter.d.ts +0 -77
  301. package/dist/canvas-react/pixi-react-adapter.d.ts.map +0 -1
  302. package/dist/canvas-react/pixi-react-adapter.js +0 -294
  303. package/dist/canvas-react/world-context.d.ts +0 -98
  304. package/dist/canvas-react/world-context.d.ts.map +0 -1
  305. package/dist/canvas-react/world-context.js +0 -173
  306. package/dist/dev/debug-draw.d.ts +0 -24
  307. package/dist/dev/debug-draw.d.ts.map +0 -1
  308. package/dist/dev/debug-draw.js +0 -73
  309. package/dist/render/auto-batcher.d.ts +0 -34
  310. package/dist/render/auto-batcher.d.ts.map +0 -1
  311. package/dist/render/auto-batcher.js +0 -140
  312. package/dist/render/lod.d.ts +0 -13
  313. package/dist/render/lod.d.ts.map +0 -1
  314. package/dist/render/lod.js +0 -16
  315. package/dist/runtime/types.d.ts +0 -303
  316. package/dist/runtime/types.d.ts.map +0 -1
  317. package/dist/runtime/types.js +0 -1
  318. package/dist/world3d-react/engine-bridge.d.ts +0 -47
  319. package/dist/world3d-react/engine-bridge.d.ts.map +0 -1
  320. package/dist/world3d-react/engine-bridge.js +0 -73
  321. package/dist/world3d-react/r3f-adapter.d.ts +0 -58
  322. package/dist/world3d-react/r3f-adapter.d.ts.map +0 -1
  323. package/dist/world3d-react/r3f-adapter.js +0 -634
  324. package/dist/world3d-react/world-context.d.ts +0 -182
  325. package/dist/world3d-react/world-context.d.ts.map +0 -1
  326. package/dist/world3d-react/world-context.js +0 -235
  327. package/src/adapter/setup-three-root-adapter.ts +0 -1032
  328. package/src/animation/clip-map.ts +0 -34
  329. package/src/asset-registry.ts +0 -89
  330. package/src/canvas-react/engine-bridge.ts +0 -59
  331. package/src/canvas-react/pixi-react-adapter.tsx +0 -356
  332. package/src/canvas-react/world-context.ts +0 -253
  333. package/src/dev/debug-draw.ts +0 -80
  334. package/src/render/auto-batcher.ts +0 -168
  335. package/src/render/lod.ts +0 -17
  336. package/src/runtime/types.ts +0 -328
  337. package/src/world3d-react/engine-bridge.ts +0 -86
  338. package/src/world3d-react/r3f-adapter.tsx +0 -717
  339. package/src/world3d-react/world-context.ts +0 -358
@@ -1,98 +0,0 @@
1
- /**
2
- * `createCanvasRootContext` — the ENGINE runtime a canvas world owns, split out
3
- * of `./pixi-react-adapter.tsx` so it stays react-free and headlessly
4
- * unit-testable (`test/canvas-react-context-parity.test.tsx`).
5
- *
6
- * This is the canvas surface's answer to the same question
7
- * `world3d-react/world-context.ts` answers for three: what does a component
8
- * inside the world tree reach when it asks the engine for something?
9
- *
10
- * 1. **`ctx.debug` / `ctx.random` / `ctx.game` / `ctx.roots` are wired** from
11
- * the ONE game-scoped registry (`getDebugRegistry(host.game)`), so a
12
- * component's effect can `ctx.debug.registerStateProvider(...)` and be
13
- * visible to `vgai eval`/the editor's debug panels.
14
- * 2. **`ctx.input` is the game-owned `InputManager` when a Game hosts the
15
- * root** (`host.game.input` — the
16
- * same instance every sibling root shares), and this module registers the
17
- * per-world debug-registry seams (`setVirtualInputTarget`/
18
- * `setInputActionsSource`/`setInputTraceSource`) that make `game.input.*`
19
- * (the bot-input doctrine) resolve instead of throwing
20
- * `DEBUG_INPUT_UNAVAILABLE`. The project's input map loads through
21
- * `Game.loadInputMap` (the game-owned, load-once path every root shares).
22
- * A missing/unparseable map degrades LOUDLY without failing the mount — a
23
- * canvas world with no declared actions is legal. A bare/foreign mount
24
- * receives `null`, visibly in the type, rather than a throwing getter.
25
- * 3. **Absent subsystems are absent from the type.** A canvas world builds no
26
- * THREE scene/camera, Rapier world, composer, first-party audio/particles/
27
- * debug-draw, or Three-flavoured `AssetCache`. Its explicit
28
- * {@link CanvasGameContext} cannot name those fields, so misuse fails at
29
- * the call site during typechecking instead of from a throwing getter at
30
- * runtime.
31
- *
32
- * The Pixi handles themselves are deliberately NOT re-exposed here: a component
33
- * reaches the live `Application` (and therefore `app.stage`, `app.renderer`,
34
- * `app.ticker`) through `@pixi/react`'s own `useApplication()`, and its assets
35
- * through Pixi's own `Assets`. Re-publishing them on `ctx` would be a wrapper
36
- * standing between the author and the library.
37
- */
38
- import type { Application } from 'pixi.js';
39
- import type { CanvasHostContext } from '../adapter';
40
- import type { SystemAdapters } from '../adapter/system-adapter';
41
- import type { SimClock } from '../core/sim-clock';
42
- import { createSystemRunner } from '../core/system-runner';
43
- import type { ComponentContextBase } from '../runtime/types';
44
- /** The conventional input-map location every scaffolded project ships. Shared
45
- * verbatim with the three lane — a project has ONE input map, whatever surface
46
- * reads it. */
47
- export declare const DEFAULT_INPUT_MAP_PATH = "/inputmaps/default.inputmap.json";
48
- export interface CanvasRootContextOptions {
49
- /** World id — provenance for every debug-registry registration (matches the
50
- * manifest root id). */
51
- readonly id: string;
52
- /**
53
- * Input map to load through `Game.loadInputMap` (game-owned, load-once —
54
- * several roots asking for the SAME path share one load; competing paths
55
- * throw there). Defaults to {@link DEFAULT_INPUT_MAP_PATH}. Pass `null` to
56
- * skip loading (a world with no actions). Ignored when no `host.game` is
57
- * present.
58
- */
59
- readonly inputMapPath?: string | null | undefined;
60
- }
61
- /** The engine services a Canvas component genuinely receives. Pixi's own
62
- * `useApplication()` and `Assets` remain the doors to rendering and assets.
63
- * `disposeAfter` is excluded because it accepts a `THREE.Object3D`; Canvas
64
- * code schedules `displayObject.destroy()` with `clock.after()` instead. */
65
- export type CanvasGameContext = ComponentContextBase & {
66
- readonly clock: Omit<SimClock, 'disposeAfter'>;
67
- };
68
- /** What {@link createCanvasRootContext} returns — the engine runtime one canvas
69
- * world owns, plus the wiring hooks the adapter's `mount()` drives. */
70
- export interface CanvasRootRuntime {
71
- /** The explicit Canvas context this world's components read through
72
- * `useGameContext`. See {@link CanvasGameContext}. */
73
- readonly ctx: CanvasGameContext;
74
- /** The world-local phase runner `mount().update(dt)` ticks. */
75
- readonly systems: ReturnType<typeof createSystemRunner>;
76
- /** The mounted world's `SystemAdapters` bag (`mounted.systems`) —
77
- * `ctx.registerSystemAdapter` writes into it; `debug` is pre-seeded. */
78
- readonly systemAdapters: SystemAdapters;
79
- /** Resolves once the input map load settles (immediately when skipped).
80
- * Never rejects — a failed load reports loudly and resolves. */
81
- readonly inputMapReady: Promise<void>;
82
- /** Backfill the live `Application` once `@pixi/react` has initialized it —
83
- * before any tick can run. Read back via {@link CanvasRootRuntime.app}. */
84
- setApplication(app: Application): void;
85
- /** The live `Application`, or `null` before the first commit resolves it. */
86
- readonly app: Application | null;
87
- /** Strip this world's debug registrations (scoped, so sibling roots and
88
- * react-door registrations are untouched when a Game hosts this world) and
89
- * dispose a clock this mount created. */
90
- dispose(): void;
91
- }
92
- /**
93
- * Build the engine runtime for one canvas world from a `CanvasHostContext`.
94
- * React-free on purpose: everything here is plain engine wiring the adapter
95
- * threads into the `@pixi/react` tree through `EngineBridge`.
96
- */
97
- export declare function createCanvasRootContext(host: CanvasHostContext, options: CanvasRootContextOptions): CanvasRootRuntime;
98
- //# sourceMappingURL=world-context.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"world-context.d.ts","sourceRoot":"","sources":["../../src/canvas-react/world-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAMhE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;gBAEgB;AAChB,eAAO,MAAM,sBAAsB,qCAAqC,CAAC;AAEzE,MAAM,WAAW,wBAAwB;IACvC;6BACyB;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACnD;AAED;;;4EAG4E;AAC5E,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG;IACrD,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;CAChD,CAAC;AAEF;wEACwE;AACxE,MAAM,WAAW,iBAAiB;IAChC;2DACuD;IACvD,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;IACxD;6EACyE;IACzE,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC;qEACiE;IACjE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC;gFAC4E;IAC5E,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACvC,6EAA6E;IAC7E,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC;;8CAE0C;IAC1C,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,wBAAwB,GAChC,iBAAiB,CAwInB"}
@@ -1,173 +0,0 @@
1
- /**
2
- * `createCanvasRootContext` — the ENGINE runtime a canvas world owns, split out
3
- * of `./pixi-react-adapter.tsx` so it stays react-free and headlessly
4
- * unit-testable (`test/canvas-react-context-parity.test.tsx`).
5
- *
6
- * This is the canvas surface's answer to the same question
7
- * `world3d-react/world-context.ts` answers for three: what does a component
8
- * inside the world tree reach when it asks the engine for something?
9
- *
10
- * 1. **`ctx.debug` / `ctx.random` / `ctx.game` / `ctx.roots` are wired** from
11
- * the ONE game-scoped registry (`getDebugRegistry(host.game)`), so a
12
- * component's effect can `ctx.debug.registerStateProvider(...)` and be
13
- * visible to `vgai eval`/the editor's debug panels.
14
- * 2. **`ctx.input` is the game-owned `InputManager` when a Game hosts the
15
- * root** (`host.game.input` — the
16
- * same instance every sibling root shares), and this module registers the
17
- * per-world debug-registry seams (`setVirtualInputTarget`/
18
- * `setInputActionsSource`/`setInputTraceSource`) that make `game.input.*`
19
- * (the bot-input doctrine) resolve instead of throwing
20
- * `DEBUG_INPUT_UNAVAILABLE`. The project's input map loads through
21
- * `Game.loadInputMap` (the game-owned, load-once path every root shares).
22
- * A missing/unparseable map degrades LOUDLY without failing the mount — a
23
- * canvas world with no declared actions is legal. A bare/foreign mount
24
- * receives `null`, visibly in the type, rather than a throwing getter.
25
- * 3. **Absent subsystems are absent from the type.** A canvas world builds no
26
- * THREE scene/camera, Rapier world, composer, first-party audio/particles/
27
- * debug-draw, or Three-flavoured `AssetCache`. Its explicit
28
- * {@link CanvasGameContext} cannot name those fields, so misuse fails at
29
- * the call site during typechecking instead of from a throwing getter at
30
- * runtime.
31
- *
32
- * The Pixi handles themselves are deliberately NOT re-exposed here: a component
33
- * reaches the live `Application` (and therefore `app.stage`, `app.renderer`,
34
- * `app.ticker`) through `@pixi/react`'s own `useApplication()`, and its assets
35
- * through Pixi's own `Assets`. Re-publishing them on `ctx` would be a wrapper
36
- * standing between the author and the library.
37
- */
38
- import { createSeededRandom, DEFAULT_SEEDED_RANDOM_SEED, getSeededRandom, } from '../core/seeded-random';
39
- import { createSimClock, getSimClock } from '../core/sim-clock';
40
- import { createSystemRunner } from '../core/system-runner';
41
- import { createDebugRegistry, getDebugRegistry, } from '../runtime/debug-registry';
42
- /** The conventional input-map location every scaffolded project ships. Shared
43
- * verbatim with the three lane — a project has ONE input map, whatever surface
44
- * reads it. */
45
- export const DEFAULT_INPUT_MAP_PATH = '/inputmaps/default.inputmap.json';
46
- /**
47
- * Build the engine runtime for one canvas world from a `CanvasHostContext`.
48
- * React-free on purpose: everything here is plain engine wiring the adapter
49
- * threads into the `@pixi/react` tree through `EngineBridge`.
50
- */
51
- export function createCanvasRootContext(host, options) {
52
- const { id, inputMapPath = DEFAULT_INPUT_MAP_PATH } = options;
53
- // Same observer threading as the three lane — this world's phases show up
54
- // under the shared game profiler when hosted.
55
- const systems = createSystemRunner(host.game?.profiler.systemObserver, 'canvas');
56
- // The mounted world's adapter surface (`mounted.systems`) — declared before
57
- // ctx so `ctx.registerSystemAdapter` can close over it (a game-owned
58
- // capability like networking registers here from component code).
59
- const systemAdapters = {};
60
- let app = null;
61
- const ctxRaw = {
62
- systems,
63
- input: host.game?.input ?? null,
64
- registerSystemAdapter: (kind, adapter) => {
65
- // biome-ignore lint/suspicious/noExplicitAny: same per-key record write the three lane performs; correct by construction
66
- systemAdapters[kind] = adapter;
67
- host.game?.notifySystemAdaptersChanged();
68
- },
69
- };
70
- const ctx = ctxRaw;
71
- if (host.game) {
72
- ctx.game = host.game;
73
- ctx.roots = host.game.roots;
74
- ctx.playtest = host.game.playtest ?? null;
75
- }
76
- // --- ctx.debug — the ONE registry per Game root, shared across every world
77
- // mounted onto it; a bare mount with no Game shell gets a private,
78
- // mount-local registry instead. ---
79
- const debugRegistry = (host.game ? getDebugRegistry(host.game) : null) ??
80
- createDebugRegistry({ getTick: () => 0, getSimT: () => 0 });
81
- systemAdapters.debug = debugRegistry.adapter;
82
- ctx.debug = debugRegistry.forRoot(id);
83
- ctx.random =
84
- (host.game ? getSeededRandom(host.game) : null) ??
85
- createSeededRandom(DEFAULT_SEEDED_RANDOM_SEED);
86
- // --- ctx.clock — a REAL value, never a throwing getter: every world has a
87
- // sim clock. A bare mount with no Game shell gets a private, mount-local one.
88
- // `SimClock.disposeAfter` takes a THREE.Object3D, so the mount-local
89
- // fallback's disposer is a loud refusal rather than a fabricated no-op: a
90
- // canvas world's debris is a `PIXI.Container`, destroyed with its own
91
- // `container.destroy()`.
92
- const gameClock = host.game ? getSimClock(host.game) : null;
93
- const clock = gameClock ??
94
- createSimClock({
95
- dispose: () => {
96
- throw new Error(`canvas world "${id}": clock.disposeAfter() disposes a THREE.Object3D and has no ` +
97
- 'meaning in a canvas world — destroy a display object with its own ' +
98
- '`container.destroy({ children: true })`, scheduled with `clock.after(seconds, ...)`.');
99
- },
100
- });
101
- ctxRaw['clock'] = clock;
102
- // --- ctx.input + the debug-registry input seams — the game-owned
103
- // InputManager, polled by the game-scoped runner each frame; this world
104
- // registers the per-world seams so `game.input.*` (virtual input) and the
105
- // built-in `input.actions`/`input.trace` providers resolve to it. ---
106
- let inputMapReady = Promise.resolve();
107
- if (host.game) {
108
- const game = host.game;
109
- const input = game.input;
110
- debugRegistry.setInputActionsSource(id, () => input.actionNames().map((name) => ({ name, valueType: input.getActionValueType(name) })));
111
- debugRegistry.setInputTraceSource(id, () => {
112
- const raw = input.getInputTrace();
113
- return {
114
- version: raw.version,
115
- seed: getSeededRandom(game)?.seed ?? null,
116
- fixedDt: game.loop.fixedDt,
117
- ticks: raw.ticks,
118
- };
119
- });
120
- debugRegistry.setVirtualInputTarget(id, {
121
- setVirtualAction: (action, value) => input.setVirtualAction(action, value),
122
- tapVirtualAction: (action) => input.tapVirtualAction(action),
123
- clearVirtualActions: () => input.clearVirtualActions(),
124
- scheduleActionAtTick: (tick, action, value) => input.scheduleActionAtTick(tick, action, value),
125
- startInputRecording: () => input.startInputRecording(),
126
- stopInputRecording: () => input.stopInputRecording(),
127
- isInputRecording: () => input.isInputRecording(),
128
- injectAxis: (sourceId, value) => input.injectAxis(sourceId, value),
129
- injectVector2: (sourceId, value) => input.injectVector2(sourceId, value),
130
- injectPointerDelta: (sourceId, delta) => input.injectPointerDelta(sourceId, delta),
131
- injectPointerPosition: (sourceId, value) => input.injectPointerPosition(sourceId, value),
132
- });
133
- if (!host.headless && inputMapPath !== null) {
134
- // Load-once through the game-owned path (competing paths across roots
135
- // throw THERE, loudly). A FAILED load must not fail this mount: a canvas
136
- // world with no declared actions is legal. It degrades loudly instead.
137
- inputMapReady = game.loadInputMap(inputMapPath).catch((err) => {
138
- // biome-ignore lint/suspicious/noConsole: deliberate loud degrade — the documented alternative to failing the mount
139
- console.error(`canvas world "${id}": failed to load input map "${inputMapPath}" — declared input ` +
140
- 'actions and `game.input.*` (bot/virtual input) will not work until a valid map ' +
141
- 'loads. Ship one at the conventional path or pass `inputMapPath` to ' +
142
- `createPixiReactAdapter (null to opt out). Cause: ${err instanceof Error ? err.message : String(err)}`);
143
- });
144
- }
145
- }
146
- return {
147
- ctx,
148
- systems,
149
- systemAdapters,
150
- inputMapReady,
151
- get app() {
152
- return app;
153
- },
154
- setApplication(next) {
155
- app = next;
156
- },
157
- dispose() {
158
- // Same ownership rule the three lane follows: dispose ONLY a clock this
159
- // mount created. The game-scoped one belongs to `GameInternal.dispose()`
160
- // — killing it here would freeze sim time and cancel every SIBLING
161
- // world's timers.
162
- if (!gameClock)
163
- clock.dispose();
164
- app = null;
165
- // Scoped strip when a Game hosts this world (sibling roots stay live);
166
- // a bare standalone mount owns its private registry and clears it all.
167
- if (host.game)
168
- debugRegistry.strip(id);
169
- else
170
- debugRegistry.strip();
171
- },
172
- };
173
- }
@@ -1,24 +0,0 @@
1
- import * as THREE from 'three';
2
- /**
3
- * Debug drawing utilities for development.
4
- *
5
- * Draw lines, spheres, boxes, and arrows for visualizing
6
- * physics colliders, raycasts, AI paths, etc.
7
- *
8
- * All debug objects are added to a dedicated group that can be toggled.
9
- */
10
- export declare function createDebugDraw(scene: THREE.Scene): {
11
- /** Draw a line between two points */
12
- line(from: THREE.Vector3, to: THREE.Vector3, color?: number): THREE.Line<THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>, THREE.LineBasicMaterial, THREE.Object3DEventMap>;
13
- /** Draw a wireframe sphere at a position */
14
- sphere(center: THREE.Vector3, radius?: number, color?: number): THREE.Mesh<THREE.SphereGeometry, THREE.MeshBasicMaterial, THREE.Object3DEventMap>;
15
- /** Draw a wireframe box */
16
- box(center: THREE.Vector3, size: THREE.Vector3, color?: number): THREE.Mesh<THREE.BoxGeometry, THREE.MeshBasicMaterial, THREE.Object3DEventMap>;
17
- /** Draw an arrow (direction indicator) */
18
- arrow(origin: THREE.Vector3, direction: THREE.Vector3, length?: number, color?: number): THREE.ArrowHelper;
19
- /** Clear all debug drawings */
20
- clear(): void;
21
- /** Toggle debug draw visibility */
22
- visible: boolean;
23
- };
24
- //# sourceMappingURL=debug-draw.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"debug-draw.d.ts","sourceRoot":"","sources":["../../src/dev/debug-draw.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK;IAM9C,qCAAqC;eAC1B,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC,OAAO;IAQ3C,4CAA4C;mBAC7B,KAAK,CAAC,OAAO;IAS5B,2BAA2B;gBACf,KAAK,CAAC,OAAO,QAAQ,KAAK,CAAC,OAAO;IAS9C,0CAA0C;kBAC5B,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,OAAO;IAQrD,+BAA+B;;IAgB/B,mCAAmC;aACpB,OAAO;EAQzB"}
@@ -1,73 +0,0 @@
1
- import * as THREE from 'three';
2
- /**
3
- * Debug drawing utilities for development.
4
- *
5
- * Draw lines, spheres, boxes, and arrows for visualizing
6
- * physics colliders, raycasts, AI paths, etc.
7
- *
8
- * All debug objects are added to a dedicated group that can be toggled.
9
- */
10
- export function createDebugDraw(scene) {
11
- const group = new THREE.Group();
12
- group.name = 'debug-draw';
13
- scene.add(group);
14
- return {
15
- /** Draw a line between two points */
16
- line(from, to, color = 0x00ff00) {
17
- const geometry = new THREE.BufferGeometry().setFromPoints([from, to]);
18
- const material = new THREE.LineBasicMaterial({ color });
19
- const line = new THREE.Line(geometry, material);
20
- group.add(line);
21
- return line;
22
- },
23
- /** Draw a wireframe sphere at a position */
24
- sphere(center, radius = 0.1, color = 0xff0000) {
25
- const geo = new THREE.SphereGeometry(radius, 8, 8);
26
- const mat = new THREE.MeshBasicMaterial({ color, wireframe: true });
27
- const mesh = new THREE.Mesh(geo, mat);
28
- mesh.position.copy(center);
29
- group.add(mesh);
30
- return mesh;
31
- },
32
- /** Draw a wireframe box */
33
- box(center, size, color = 0x00ffff) {
34
- const geo = new THREE.BoxGeometry(size.x, size.y, size.z);
35
- const mat = new THREE.MeshBasicMaterial({ color, wireframe: true });
36
- const mesh = new THREE.Mesh(geo, mat);
37
- mesh.position.copy(center);
38
- group.add(mesh);
39
- return mesh;
40
- },
41
- /** Draw an arrow (direction indicator) */
42
- arrow(origin, direction, length = 1, color = 0xffff00) {
43
- // Clone before normalize() — never mutate the caller's vector.
44
- const dir = direction.clone().normalize();
45
- const arrow = new THREE.ArrowHelper(dir, origin, length, color);
46
- group.add(arrow);
47
- return arrow;
48
- },
49
- /** Clear all debug drawings */
50
- clear() {
51
- while (group.children.length > 0) {
52
- const child = group.children[0];
53
- group.remove(child);
54
- if (child instanceof THREE.Mesh || child instanceof THREE.Line) {
55
- // Mesh, Line and LineSegments all own geometry + material.
56
- child.geometry.dispose();
57
- child.material.dispose();
58
- }
59
- else if (child instanceof THREE.ArrowHelper) {
60
- // ArrowHelper owns a line + cone; dispose() frees both.
61
- child.dispose();
62
- }
63
- }
64
- },
65
- /** Toggle debug draw visibility */
66
- set visible(v) {
67
- group.visible = v;
68
- },
69
- get visible() {
70
- return group.visible;
71
- },
72
- };
73
- }
@@ -1,34 +0,0 @@
1
- import * as THREE from 'three';
2
- export declare class AutoBatcher {
3
- /** Root the batcher owns under the scene (instanced meshes when on, entities when off). */
4
- readonly root: THREE.Group<THREE.Object3DEventMap>;
5
- private entities;
6
- private batches;
7
- private enabled;
8
- /** Indices of entities whose transform changed since last sync. */
9
- private dirty;
10
- private touchedBatches;
11
- private indexOf;
12
- private optOut;
13
- private batchOf;
14
- private membersOf;
15
- constructor(parent: THREE.Object3D, enabled?: boolean);
16
- /** Register an entity (a Mesh) as the logical handle. Call build() after adding. */
17
- add(entity: THREE.Mesh, optOut?: boolean): void;
18
- /** Mark an entity moved this frame (dirty-tracking input). */
19
- markMoved(entity: THREE.Mesh): void;
20
- /** (Re)build the render representation for the current enabled state. */
21
- build(): void;
22
- /** Apply the dirty set to the instance buffers. Cheap when few moved. */
23
- sync(): void;
24
- /** Live toggle: rebuilds the representation (one-time cost, not per-frame). */
25
- setEnabled(on: boolean): void;
26
- isEnabled(): boolean;
27
- /** Map a raycast hit on a batch back to the logical entity (editor/gameplay picking). */
28
- resolvePick(intersection: THREE.Intersection): THREE.Mesh | null;
29
- /** Per-frame draw-call count this batcher contributes (for stats). */
30
- get drawCallCount(): number;
31
- private get optOutCount();
32
- private clearRoot;
33
- }
34
- //# sourceMappingURL=auto-batcher.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-batcher.d.ts","sourceRoot":"","sources":["../../src/render/auto-batcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgC/B,qBAAa,WAAW;IACtB,2FAA2F;IAC3F,QAAQ,CAAC,IAAI,sCAAqB;IAElC,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAAU;IACzB,mEAAmE;IACnE,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,cAAc,CAAoB;IAG1C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,OAAO,CAAkE;IACjF,OAAO,CAAC,SAAS,CAAoD;gBAEzD,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,UAAO;IAMlD,oFAAoF;IACpF,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,UAAQ,GAAG,IAAI;IAM7C,8DAA8D;IAC9D,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,GAAG,IAAI;IAKnC,yEAAyE;IACzE,KAAK,IAAI,IAAI;IAuCb,yEAAyE;IACzE,IAAI,IAAI,IAAI;IAmBZ,+EAA+E;IAC/E,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI;IAM7B,SAAS,IAAI,OAAO;IAIpB,yFAAyF;IACzF,WAAW,CAAC,YAAY,EAAE,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,GAAG,IAAI;IAShE,sEAAsE;IACtE,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,OAAO,KAAK,WAAW,GAItB;IAED,OAAO,CAAC,SAAS;CAOlB"}
@@ -1,140 +0,0 @@
1
- import * as THREE from 'three';
2
- const SIG = (m) => {
3
- const mat = Array.isArray(m.material) ? m.material[0] : m.material;
4
- return `${m.geometry.uuid}|${mat.uuid}`;
5
- };
6
- export class AutoBatcher {
7
- /** Root the batcher owns under the scene (instanced meshes when on, entities when off). */
8
- root = new THREE.Group();
9
- entities = [];
10
- batches = new Map();
11
- enabled;
12
- /** Indices of entities whose transform changed since last sync. */
13
- dirty = new Set();
14
- touchedBatches = new Set();
15
- // Per-mesh bookkeeping is kept in WeakMaps, NOT on userData (the typed userData
16
- // registry is reserved for documented engine keys — see user-data.ts).
17
- indexOf = new WeakMap();
18
- optOut = new WeakSet();
19
- batchOf = new WeakMap();
20
- membersOf = new WeakMap();
21
- constructor(parent, enabled = true) {
22
- this.enabled = enabled;
23
- this.root.name = 'AutoBatcher';
24
- parent.add(this.root);
25
- }
26
- /** Register an entity (a Mesh) as the logical handle. Call build() after adding. */
27
- add(entity, optOut = false) {
28
- this.indexOf.set(entity, this.entities.length);
29
- if (optOut)
30
- this.optOut.add(entity);
31
- this.entities.push(entity);
32
- }
33
- /** Mark an entity moved this frame (dirty-tracking input). */
34
- markMoved(entity) {
35
- const i = this.indexOf.get(entity);
36
- if (i !== undefined)
37
- this.dirty.add(i);
38
- }
39
- /** (Re)build the render representation for the current enabled state. */
40
- build() {
41
- this.clearRoot();
42
- this.batches.clear();
43
- if (!this.enabled) {
44
- for (const e of this.entities)
45
- this.root.add(e);
46
- return;
47
- }
48
- const m = new THREE.Matrix4();
49
- // group eligible entities; opt-outs render individually
50
- const groups = new Map();
51
- for (const e of this.entities) {
52
- if (this.optOut.has(e)) {
53
- this.root.add(e);
54
- continue;
55
- }
56
- const key = SIG(e);
57
- const arr = groups.get(key) ?? [];
58
- arr.push(e);
59
- groups.set(key, arr);
60
- }
61
- for (const [key, members] of groups) {
62
- const proto = members[0];
63
- const mat = Array.isArray(proto.material) ? proto.material[0] : proto.material;
64
- const inst = new THREE.InstancedMesh(proto.geometry, mat, members.length);
65
- inst.frustumCulled = false;
66
- for (let i = 0; i < members.length; i++) {
67
- const e = members[i];
68
- e.updateMatrix();
69
- m.copy(e.matrix);
70
- inst.setMatrixAt(i, m);
71
- this.batchOf.set(e, { key, localIndex: i });
72
- }
73
- inst.instanceMatrix.needsUpdate = true;
74
- this.membersOf.set(inst, members); // localIndex → entity (picking)
75
- this.root.add(inst);
76
- this.batches.set(key, { key, instanced: inst, members });
77
- }
78
- }
79
- /** Apply the dirty set to the instance buffers. Cheap when few moved. */
80
- sync() {
81
- if (!this.enabled)
82
- return;
83
- const m = new THREE.Matrix4();
84
- this.touchedBatches.clear();
85
- for (const i of this.dirty) {
86
- const e = this.entities[i];
87
- const info = this.batchOf.get(e);
88
- if (!info)
89
- continue; // opt-out or not batched
90
- const batch = this.batches.get(info.key);
91
- if (!batch)
92
- continue;
93
- e.updateMatrix();
94
- m.copy(e.matrix);
95
- batch.instanced.setMatrixAt(info.localIndex, m);
96
- this.touchedBatches.add(batch);
97
- }
98
- for (const b of this.touchedBatches)
99
- b.instanced.instanceMatrix.needsUpdate = true;
100
- this.dirty.clear();
101
- }
102
- /** Live toggle: rebuilds the representation (one-time cost, not per-frame). */
103
- setEnabled(on) {
104
- if (on === this.enabled)
105
- return;
106
- this.enabled = on;
107
- this.build();
108
- }
109
- isEnabled() {
110
- return this.enabled;
111
- }
112
- /** Map a raycast hit on a batch back to the logical entity (editor/gameplay picking). */
113
- resolvePick(intersection) {
114
- const obj = intersection.object;
115
- if (obj.isInstancedMesh && intersection.instanceId != null) {
116
- const members = this.membersOf.get(obj);
117
- return members?.[intersection.instanceId] ?? null;
118
- }
119
- return obj instanceof THREE.Mesh ? obj : null;
120
- }
121
- /** Per-frame draw-call count this batcher contributes (for stats). */
122
- get drawCallCount() {
123
- return this.enabled ? this.batches.size + this.optOutCount : this.entities.length;
124
- }
125
- get optOutCount() {
126
- let n = 0;
127
- for (const e of this.entities)
128
- if (this.optOut.has(e))
129
- n++;
130
- return n;
131
- }
132
- clearRoot() {
133
- for (let i = this.root.children.length - 1; i >= 0; i--) {
134
- const c = this.root.children[i];
135
- this.root.remove(c);
136
- if (c.isInstancedMesh)
137
- c.dispose();
138
- }
139
- }
140
- }
@@ -1,13 +0,0 @@
1
- import type * as THREE from 'three';
2
- /**
3
- * Per-frame LOD tick. `THREE.LOD` only swaps its active level when
4
- * `.update(camera)` runs, so every `THREE.LOD` in the scene graph needs this
5
- * called once a frame. Wired into the runtime's `preRender` system in
6
- * `adapter/setup-three-root-adapter.ts`.
7
- *
8
- * Format-neutral: it matches THREE's own `isLOD` marker and knows nothing about
9
- * how the LOD was built. Formerly `@engine/scene/scene-loader`'s
10
- * `updateSceneLODs`, relocated here when WO-8 deleted the `.vscn` scene loader.
11
- */
12
- export declare function updateSceneLODs(scene: THREE.Object3D, camera: THREE.Camera): void;
13
- //# sourceMappingURL=lod.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lod.d.ts","sourceRoot":"","sources":["../../src/render/lod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAIjF"}
@@ -1,16 +0,0 @@
1
- /**
2
- * Per-frame LOD tick. `THREE.LOD` only swaps its active level when
3
- * `.update(camera)` runs, so every `THREE.LOD` in the scene graph needs this
4
- * called once a frame. Wired into the runtime's `preRender` system in
5
- * `adapter/setup-three-root-adapter.ts`.
6
- *
7
- * Format-neutral: it matches THREE's own `isLOD` marker and knows nothing about
8
- * how the LOD was built. Formerly `@engine/scene/scene-loader`'s
9
- * `updateSceneLODs`, relocated here when WO-8 deleted the `.vscn` scene loader.
10
- */
11
- export function updateSceneLODs(scene, camera) {
12
- scene.traverse((o) => {
13
- if (o.isLOD)
14
- o.update(camera);
15
- });
16
- }