@vgai/engine 0.5.0-canary.20260719.0 → 0.5.0

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 (527) hide show
  1. package/dist/adapter/adapter-surface.d.ts +30 -0
  2. package/dist/adapter/adapter-surface.d.ts.map +1 -0
  3. package/dist/adapter/adapter-surface.js +18 -0
  4. package/dist/adapter/authoring.d.ts +461 -0
  5. package/dist/adapter/authoring.d.ts.map +1 -0
  6. package/dist/adapter/authoring.js +22 -0
  7. package/dist/adapter/colyseus-networking-adapter.d.ts +43 -0
  8. package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -0
  9. package/dist/adapter/colyseus-networking-adapter.js +38 -0
  10. package/dist/adapter/first-party-systems.d.ts +38 -0
  11. package/dist/adapter/first-party-systems.d.ts.map +1 -0
  12. package/dist/adapter/first-party-systems.js +77 -0
  13. package/dist/adapter/game-adapter.d.ts +133 -0
  14. package/dist/adapter/game-adapter.d.ts.map +1 -0
  15. package/dist/adapter/game-adapter.js +10 -0
  16. package/dist/adapter/host-context.d.ts +71 -0
  17. package/dist/adapter/host-context.d.ts.map +1 -0
  18. package/dist/adapter/host-context.js +16 -0
  19. package/dist/adapter/index.d.ts +22 -0
  20. package/dist/adapter/index.d.ts.map +1 -0
  21. package/dist/adapter/index.js +15 -0
  22. package/dist/adapter/ingest/game-contract.d.ts +53 -0
  23. package/dist/adapter/ingest/game-contract.d.ts.map +1 -0
  24. package/dist/adapter/ingest/game-contract.js +30 -0
  25. package/dist/adapter/ingest/overlay-applier.d.ts +118 -0
  26. package/dist/adapter/ingest/overlay-applier.d.ts.map +1 -0
  27. package/dist/adapter/ingest/overlay-applier.js +132 -0
  28. package/dist/adapter/ingest/overlay-apply.d.ts +60 -0
  29. package/dist/adapter/ingest/overlay-apply.d.ts.map +1 -0
  30. package/dist/adapter/ingest/overlay-apply.js +101 -0
  31. package/dist/adapter/ingest/overlay-file.d.ts +79 -0
  32. package/dist/adapter/ingest/overlay-file.d.ts.map +1 -0
  33. package/dist/adapter/ingest/overlay-file.js +66 -0
  34. package/dist/adapter/ingest/overlay-report.d.ts +113 -0
  35. package/dist/adapter/ingest/overlay-report.d.ts.map +1 -0
  36. package/dist/adapter/ingest/overlay-report.js +103 -0
  37. package/dist/adapter/ingest/scene-capture.d.ts +97 -0
  38. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -0
  39. package/dist/adapter/ingest/scene-capture.js +248 -0
  40. package/dist/adapter/ingest/upstream-pin.d.ts +47 -0
  41. package/dist/adapter/ingest/upstream-pin.d.ts.map +1 -0
  42. package/dist/adapter/ingest/upstream-pin.js +50 -0
  43. package/dist/adapter/loop-gate-report.d.ts +34 -0
  44. package/dist/adapter/loop-gate-report.d.ts.map +1 -0
  45. package/dist/adapter/loop-gate-report.js +37 -0
  46. package/dist/adapter/rapier-physics-adapter.d.ts +12 -0
  47. package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -0
  48. package/dist/adapter/rapier-physics-adapter.js +46 -0
  49. package/dist/adapter/system-adapter.d.ts +206 -0
  50. package/dist/adapter/system-adapter.d.ts.map +1 -0
  51. package/dist/adapter/system-adapter.js +13 -0
  52. package/dist/adapter/transform.d.ts +18 -0
  53. package/dist/adapter/transform.d.ts.map +1 -0
  54. package/dist/adapter/transform.js +1 -0
  55. package/dist/adapter/vgai-scene-game-adapter.d.ts +108 -0
  56. package/dist/adapter/vgai-scene-game-adapter.d.ts.map +1 -0
  57. package/dist/adapter/vgai-scene-game-adapter.js +762 -0
  58. package/dist/ai/navigation.d.ts +64 -0
  59. package/dist/ai/navigation.d.ts.map +1 -0
  60. package/dist/ai/navigation.js +133 -0
  61. package/dist/animation/anim-graph-types.d.ts +25 -0
  62. package/dist/animation/anim-graph-types.d.ts.map +1 -0
  63. package/dist/animation/anim-graph-types.js +1 -0
  64. package/dist/animation/animation-clock.d.ts +213 -0
  65. package/dist/animation/animation-clock.d.ts.map +1 -0
  66. package/dist/animation/animation-clock.js +301 -0
  67. package/dist/animation/blend-node.d.ts +22 -0
  68. package/dist/animation/blend-node.d.ts.map +1 -0
  69. package/dist/animation/blend-node.js +97 -0
  70. package/dist/animation/camera-ownership.d.ts +250 -0
  71. package/dist/animation/camera-ownership.d.ts.map +1 -0
  72. package/dist/animation/camera-ownership.js +169 -0
  73. package/dist/animation/cinematic-cues.d.ts +200 -0
  74. package/dist/animation/cinematic-cues.d.ts.map +1 -0
  75. package/dist/animation/cinematic-cues.js +213 -0
  76. package/dist/animation/clip-map.d.ts +12 -0
  77. package/dist/animation/clip-map.d.ts.map +1 -0
  78. package/dist/animation/clip-map.js +37 -0
  79. package/dist/animation/gsap-registration.d.ts +119 -0
  80. package/dist/animation/gsap-registration.d.ts.map +1 -0
  81. package/dist/animation/gsap-registration.js +92 -0
  82. package/dist/animation/theatre-clock-binding.d.ts +89 -0
  83. package/dist/animation/theatre-clock-binding.d.ts.map +1 -0
  84. package/dist/animation/theatre-clock-binding.js +29 -0
  85. package/dist/animation/theatre-director.d.ts +242 -0
  86. package/dist/animation/theatre-director.d.ts.map +1 -0
  87. package/dist/animation/theatre-director.js +235 -0
  88. package/dist/animation/theatre-object-binding.d.ts +305 -0
  89. package/dist/animation/theatre-object-binding.d.ts.map +1 -0
  90. package/dist/animation/theatre-object-binding.js +351 -0
  91. package/dist/animation/xstate-animation-binding.d.ts +56 -0
  92. package/dist/animation/xstate-animation-binding.d.ts.map +1 -0
  93. package/dist/animation/xstate-animation-binding.js +331 -0
  94. package/dist/animation/xstate-animation-meta.d.ts +266 -0
  95. package/dist/animation/xstate-animation-meta.d.ts.map +1 -0
  96. package/dist/animation/xstate-animation-meta.js +252 -0
  97. package/dist/assets.d.ts +26 -0
  98. package/dist/assets.d.ts.map +1 -0
  99. package/dist/assets.js +55 -0
  100. package/dist/audio/index.d.ts +4 -0
  101. package/dist/audio/index.d.ts.map +1 -0
  102. package/dist/audio/index.js +24 -0
  103. package/dist/audio/tone-clock-binding.d.ts +75 -0
  104. package/dist/audio/tone-clock-binding.d.ts.map +1 -0
  105. package/dist/audio/tone-clock-binding.js +29 -0
  106. package/dist/audio/tone-context.d.ts +114 -0
  107. package/dist/audio/tone-context.d.ts.map +1 -0
  108. package/dist/audio/tone-context.js +39 -0
  109. package/dist/audio/tone-offline-render.d.ts +90 -0
  110. package/dist/audio/tone-offline-render.d.ts.map +1 -0
  111. package/dist/audio/tone-offline-render.js +56 -0
  112. package/dist/audio/wav-encode.d.ts +38 -0
  113. package/dist/audio/wav-encode.d.ts.map +1 -0
  114. package/dist/audio/wav-encode.js +97 -0
  115. package/dist/character/cloth-sim.d.ts +179 -0
  116. package/dist/character/cloth-sim.d.ts.map +1 -0
  117. package/dist/character/cloth-sim.js +334 -0
  118. package/dist/character/spring-chain.d.ts +135 -0
  119. package/dist/character/spring-chain.d.ts.map +1 -0
  120. package/dist/character/spring-chain.js +165 -0
  121. package/dist/core/game-loop.d.ts +42 -0
  122. package/dist/core/game-loop.d.ts.map +1 -0
  123. package/dist/core/game-loop.js +167 -0
  124. package/dist/core/seeded-random.d.ts +69 -0
  125. package/dist/core/seeded-random.d.ts.map +1 -0
  126. package/dist/core/seeded-random.js +121 -0
  127. package/dist/core/system-runner.d.ts +120 -0
  128. package/dist/core/system-runner.d.ts.map +1 -0
  129. package/dist/core/system-runner.js +297 -0
  130. package/dist/core/types.d.ts +92 -0
  131. package/dist/core/types.d.ts.map +1 -0
  132. package/dist/core/types.js +25 -0
  133. package/dist/data/data-asset.d.ts +101 -0
  134. package/dist/data/data-asset.d.ts.map +1 -0
  135. package/dist/data/data-asset.js +122 -0
  136. package/dist/data/data-check-core.d.ts +110 -0
  137. package/dist/data/data-check-core.d.ts.map +1 -0
  138. package/dist/data/data-check-core.js +178 -0
  139. package/dist/data/data-ref.d.ts +79 -0
  140. package/dist/data/data-ref.d.ts.map +1 -0
  141. package/dist/data/data-ref.js +130 -0
  142. package/dist/data/vite-plugin-data.d.ts +79 -0
  143. package/dist/data/vite-plugin-data.d.ts.map +1 -0
  144. package/dist/data/vite-plugin-data.js +217 -0
  145. package/dist/dev/console-bridge.d.ts +22 -0
  146. package/dist/dev/console-bridge.d.ts.map +1 -0
  147. package/dist/dev/console-bridge.js +71 -0
  148. package/dist/dev/debug-draw.d.ts +24 -0
  149. package/dist/dev/debug-draw.d.ts.map +1 -0
  150. package/dist/dev/debug-draw.js +73 -0
  151. package/dist/dev/logger.d.ts +30 -0
  152. package/dist/dev/logger.d.ts.map +1 -0
  153. package/dist/dev/logger.js +90 -0
  154. package/dist/dev/performance-profiler.d.ts +60 -0
  155. package/dist/dev/performance-profiler.d.ts.map +1 -0
  156. package/dist/dev/performance-profiler.js +181 -0
  157. package/dist/dev/webgl-gpu-timer.d.ts +8 -0
  158. package/dist/dev/webgl-gpu-timer.d.ts.map +1 -0
  159. package/dist/dev/webgl-gpu-timer.js +52 -0
  160. package/dist/ecs/component-manager.d.ts +205 -0
  161. package/dist/ecs/component-manager.d.ts.map +1 -0
  162. package/dist/ecs/component-manager.js +706 -0
  163. package/dist/ecs/game-component.d.ts +146 -0
  164. package/dist/ecs/game-component.d.ts.map +1 -0
  165. package/dist/ecs/game-component.js +141 -0
  166. package/dist/ecs/hmr-swap-report.d.ts +53 -0
  167. package/dist/ecs/hmr-swap-report.d.ts.map +1 -0
  168. package/dist/ecs/hmr-swap-report.js +55 -0
  169. package/dist/humanoid/bake.operation.d.ts +119 -0
  170. package/dist/humanoid/bake.operation.d.ts.map +1 -0
  171. package/dist/humanoid/bake.operation.js +228 -0
  172. package/dist/humanoid/body.d.ts +101 -0
  173. package/dist/humanoid/body.d.ts.map +1 -0
  174. package/dist/humanoid/body.js +530 -0
  175. package/dist/humanoid/clips.d.ts +62 -0
  176. package/dist/humanoid/clips.d.ts.map +1 -0
  177. package/dist/humanoid/clips.js +121 -0
  178. package/dist/humanoid/compose.d.ts +75 -0
  179. package/dist/humanoid/compose.d.ts.map +1 -0
  180. package/dist/humanoid/compose.js +176 -0
  181. package/dist/humanoid/generate.d.ts +92 -0
  182. package/dist/humanoid/generate.d.ts.map +1 -0
  183. package/dist/humanoid/generate.js +124 -0
  184. package/dist/humanoid/index.d.ts +24 -0
  185. package/dist/humanoid/index.d.ts.map +1 -0
  186. package/dist/humanoid/index.js +18 -0
  187. package/dist/humanoid/schema.d.ts +35 -0
  188. package/dist/humanoid/schema.d.ts.map +1 -0
  189. package/dist/humanoid/schema.js +87 -0
  190. package/dist/humanoid/skeleton.d.ts +103 -0
  191. package/dist/humanoid/skeleton.d.ts.map +1 -0
  192. package/dist/humanoid/skeleton.js +289 -0
  193. package/dist/index.d.ts +37 -0
  194. package/dist/index.d.ts.map +1 -0
  195. package/dist/index.js +30 -0
  196. package/dist/input/input-manager.d.ts +945 -0
  197. package/dist/input/input-manager.d.ts.map +1 -0
  198. package/dist/input/input-manager.js +2207 -0
  199. package/dist/input/input-types.d.ts +174 -0
  200. package/dist/input/input-types.d.ts.map +1 -0
  201. package/dist/input/input-types.js +1 -0
  202. package/dist/input/prompt-labels.d.ts +21 -0
  203. package/dist/input/prompt-labels.d.ts.map +1 -0
  204. package/dist/input/prompt-labels.js +121 -0
  205. package/dist/input/rebind-controller.d.ts +59 -0
  206. package/dist/input/rebind-controller.d.ts.map +1 -0
  207. package/dist/input/rebind-controller.js +85 -0
  208. package/dist/input/schema.d.ts +16 -0
  209. package/dist/input/schema.d.ts.map +1 -0
  210. package/dist/input/schema.js +228 -0
  211. package/dist/loader.d.ts +43 -0
  212. package/dist/loader.d.ts.map +1 -0
  213. package/dist/loader.js +59 -0
  214. package/dist/manifest/index.d.ts +5 -0
  215. package/dist/manifest/index.d.ts.map +1 -0
  216. package/dist/manifest/index.js +8 -0
  217. package/dist/manifest/load-file.d.ts +4 -0
  218. package/dist/manifest/load-file.d.ts.map +1 -0
  219. package/dist/manifest/load-file.js +14 -0
  220. package/dist/manifest/load.d.ts +144 -0
  221. package/dist/manifest/load.d.ts.map +1 -0
  222. package/dist/manifest/load.js +273 -0
  223. package/dist/manifest/schema.d.ts +230 -0
  224. package/dist/manifest/schema.d.ts.map +1 -0
  225. package/dist/manifest/schema.js +394 -0
  226. package/dist/physics/collision-system.d.ts +41 -0
  227. package/dist/physics/collision-system.d.ts.map +1 -0
  228. package/dist/physics/collision-system.js +64 -0
  229. package/dist/physics/physics-registry.d.ts +45 -0
  230. package/dist/physics/physics-registry.d.ts.map +1 -0
  231. package/dist/physics/physics-registry.js +65 -0
  232. package/dist/physics/transform-writer.d.ts +16 -0
  233. package/dist/physics/transform-writer.d.ts.map +1 -0
  234. package/dist/physics/transform-writer.js +38 -0
  235. package/dist/physics/trigger-dispatch.d.ts +24 -0
  236. package/dist/physics/trigger-dispatch.d.ts.map +1 -0
  237. package/dist/physics/trigger-dispatch.js +80 -0
  238. package/dist/react/game-state.d.ts +156 -0
  239. package/dist/react/game-state.d.ts.map +1 -0
  240. package/dist/react/game-state.js +222 -0
  241. package/dist/react/root-adapter.d.ts +11 -0
  242. package/dist/react/root-adapter.d.ts.map +1 -0
  243. package/dist/react/root-adapter.js +41 -0
  244. package/dist/react/unmanaged-root-detector.d.ts +12 -0
  245. package/dist/react/unmanaged-root-detector.d.ts.map +1 -0
  246. package/dist/react/unmanaged-root-detector.js +45 -0
  247. package/dist/react/use-data.d.ts +60 -0
  248. package/dist/react/use-data.d.ts.map +1 -0
  249. package/dist/react/use-data.js +101 -0
  250. package/dist/react/use-selection.d.ts +75 -0
  251. package/dist/react/use-selection.d.ts.map +1 -0
  252. package/dist/react/use-selection.js +90 -0
  253. package/dist/render/auto-batcher.d.ts +34 -0
  254. package/dist/render/auto-batcher.d.ts.map +1 -0
  255. package/dist/render/auto-batcher.js +140 -0
  256. package/dist/render/render-batch-system.d.ts +33 -0
  257. package/dist/render/render-batch-system.d.ts.map +1 -0
  258. package/dist/render/render-batch-system.js +230 -0
  259. package/dist/render/render-features.d.ts +47 -0
  260. package/dist/render/render-features.d.ts.map +1 -0
  261. package/dist/render/render-features.js +105 -0
  262. package/dist/render/render-settings.d.ts +36 -0
  263. package/dist/render/render-settings.d.ts.map +1 -0
  264. package/dist/render/render-settings.js +51 -0
  265. package/dist/runtime/create-runtime.d.ts +249 -0
  266. package/dist/runtime/create-runtime.d.ts.map +1 -0
  267. package/dist/runtime/create-runtime.js +641 -0
  268. package/dist/runtime/debug-bridge.d.ts +257 -0
  269. package/dist/runtime/debug-bridge.d.ts.map +1 -0
  270. package/dist/runtime/debug-bridge.js +224 -0
  271. package/dist/runtime/debug-registry.d.ts +288 -0
  272. package/dist/runtime/debug-registry.d.ts.map +1 -0
  273. package/dist/runtime/debug-registry.js +513 -0
  274. package/dist/runtime/frame-selector-cache.d.ts +41 -0
  275. package/dist/runtime/frame-selector-cache.d.ts.map +1 -0
  276. package/dist/runtime/frame-selector-cache.js +65 -0
  277. package/dist/runtime/game.d.ts +496 -0
  278. package/dist/runtime/game.d.ts.map +1 -0
  279. package/dist/runtime/game.js +741 -0
  280. package/dist/runtime/gameplay-rng-trap.d.ts +48 -0
  281. package/dist/runtime/gameplay-rng-trap.d.ts.map +1 -0
  282. package/dist/runtime/gameplay-rng-trap.js +96 -0
  283. package/dist/runtime/input-router.d.ts +78 -0
  284. package/dist/runtime/input-router.d.ts.map +1 -0
  285. package/dist/runtime/input-router.js +171 -0
  286. package/dist/runtime/mount-game.d.ts +129 -0
  287. package/dist/runtime/mount-game.d.ts.map +1 -0
  288. package/dist/runtime/mount-game.js +152 -0
  289. package/dist/runtime/mount-manifest.d.ts +173 -0
  290. package/dist/runtime/mount-manifest.d.ts.map +1 -0
  291. package/dist/runtime/mount-manifest.js +297 -0
  292. package/dist/runtime/render-audio-control.d.ts +110 -0
  293. package/dist/runtime/render-audio-control.d.ts.map +1 -0
  294. package/dist/runtime/render-audio-control.js +111 -0
  295. package/dist/runtime/render-control.d.ts +291 -0
  296. package/dist/runtime/render-control.d.ts.map +1 -0
  297. package/dist/runtime/render-control.js +264 -0
  298. package/dist/runtime/render-seed.d.ts +57 -0
  299. package/dist/runtime/render-seed.d.ts.map +1 -0
  300. package/dist/runtime/render-seed.js +74 -0
  301. package/dist/runtime/state-bridge.d.ts +61 -0
  302. package/dist/runtime/state-bridge.d.ts.map +1 -0
  303. package/dist/runtime/state-bridge.js +63 -0
  304. package/dist/runtime/types.d.ts +253 -0
  305. package/dist/runtime/types.d.ts.map +1 -0
  306. package/dist/runtime/types.js +1 -0
  307. package/dist/scene/asset-loaders.d.ts +79 -0
  308. package/dist/scene/asset-loaders.d.ts.map +1 -0
  309. package/dist/scene/asset-loaders.js +141 -0
  310. package/dist/scene/asset-paths.d.ts +11 -0
  311. package/dist/scene/asset-paths.d.ts.map +1 -0
  312. package/dist/scene/asset-paths.js +108 -0
  313. package/dist/scene/asset-ref-check.d.ts +88 -0
  314. package/dist/scene/asset-ref-check.d.ts.map +1 -0
  315. package/dist/scene/asset-ref-check.js +214 -0
  316. package/dist/scene/asset-registry.d.ts +38 -0
  317. package/dist/scene/asset-registry.d.ts.map +1 -0
  318. package/dist/scene/asset-registry.js +66 -0
  319. package/dist/scene/collider-dimensions.d.ts +63 -0
  320. package/dist/scene/collider-dimensions.d.ts.map +1 -0
  321. package/dist/scene/collider-dimensions.js +98 -0
  322. package/dist/scene/component-registry.d.ts +22 -0
  323. package/dist/scene/component-registry.d.ts.map +1 -0
  324. package/dist/scene/component-registry.js +37 -0
  325. package/dist/scene/defaults.d.ts +252 -0
  326. package/dist/scene/defaults.d.ts.map +1 -0
  327. package/dist/scene/defaults.js +151 -0
  328. package/dist/scene/geometries/index.d.ts +8 -0
  329. package/dist/scene/geometries/index.d.ts.map +1 -0
  330. package/dist/scene/geometries/index.js +7 -0
  331. package/dist/scene/geometries/terrain.d.ts +2 -0
  332. package/dist/scene/geometries/terrain.d.ts.map +1 -0
  333. package/dist/scene/geometries/terrain.js +37 -0
  334. package/dist/scene/geometry-registry.d.ts +24 -0
  335. package/dist/scene/geometry-registry.d.ts.map +1 -0
  336. package/dist/scene/geometry-registry.js +20 -0
  337. package/dist/scene/instance-registry.d.ts +36 -0
  338. package/dist/scene/instance-registry.d.ts.map +1 -0
  339. package/dist/scene/instance-registry.js +55 -0
  340. package/dist/scene/instancers/grid.d.ts +2 -0
  341. package/dist/scene/instancers/grid.d.ts.map +1 -0
  342. package/dist/scene/instancers/grid.js +36 -0
  343. package/dist/scene/instancers/index.d.ts +8 -0
  344. package/dist/scene/instancers/index.d.ts.map +1 -0
  345. package/dist/scene/instancers/index.js +7 -0
  346. package/dist/scene/light-camera-factory.d.ts +23 -0
  347. package/dist/scene/light-camera-factory.d.ts.map +1 -0
  348. package/dist/scene/light-camera-factory.js +68 -0
  349. package/dist/scene/material-factory.d.ts +17 -0
  350. package/dist/scene/material-factory.d.ts.map +1 -0
  351. package/dist/scene/material-factory.js +197 -0
  352. package/dist/scene/material-registry.d.ts +40 -0
  353. package/dist/scene/material-registry.d.ts.map +1 -0
  354. package/dist/scene/material-registry.js +44 -0
  355. package/dist/scene/materials/index.d.ts +8 -0
  356. package/dist/scene/materials/index.d.ts.map +1 -0
  357. package/dist/scene/materials/index.js +7 -0
  358. package/dist/scene/materials/water.d.ts +2 -0
  359. package/dist/scene/materials/water.d.ts.map +1 -0
  360. package/dist/scene/materials/water.js +54 -0
  361. package/dist/scene/parse.d.ts +23 -0
  362. package/dist/scene/parse.d.ts.map +1 -0
  363. package/dist/scene/parse.js +179 -0
  364. package/dist/scene/particles-factory.d.ts +33 -0
  365. package/dist/scene/particles-factory.d.ts.map +1 -0
  366. package/dist/scene/particles-factory.js +282 -0
  367. package/dist/scene/scene-apply.d.ts +109 -0
  368. package/dist/scene/scene-apply.d.ts.map +1 -0
  369. package/dist/scene/scene-apply.js +370 -0
  370. package/dist/scene/scene-diff-schema.d.ts +285 -0
  371. package/dist/scene/scene-diff-schema.d.ts.map +1 -0
  372. package/dist/scene/scene-diff-schema.js +92 -0
  373. package/dist/scene/scene-diff-types.d.ts +40 -0
  374. package/dist/scene/scene-diff-types.d.ts.map +1 -0
  375. package/dist/scene/scene-diff-types.js +14 -0
  376. package/dist/scene/scene-loader.d.ts +167 -0
  377. package/dist/scene/scene-loader.d.ts.map +1 -0
  378. package/dist/scene/scene-loader.js +1211 -0
  379. package/dist/scene/scene-query.d.ts +11 -0
  380. package/dist/scene/scene-query.d.ts.map +1 -0
  381. package/dist/scene/scene-query.js +63 -0
  382. package/dist/scene/scene-types.d.ts +10 -0
  383. package/dist/scene/scene-types.d.ts.map +1 -0
  384. package/dist/scene/scene-types.js +8 -0
  385. package/dist/scene/scene-version.d.ts +26 -0
  386. package/dist/scene/scene-version.d.ts.map +1 -0
  387. package/dist/scene/scene-version.js +34 -0
  388. package/dist/scene/schema/animation.d.ts +8 -0
  389. package/dist/scene/schema/animation.d.ts.map +1 -0
  390. package/dist/scene/schema/animation.js +42 -0
  391. package/dist/scene/schema/audio.d.ts +13 -0
  392. package/dist/scene/schema/audio.d.ts.map +1 -0
  393. package/dist/scene/schema/audio.js +22 -0
  394. package/dist/scene/schema/camera.d.ts +28 -0
  395. package/dist/scene/schema/camera.d.ts.map +1 -0
  396. package/dist/scene/schema/camera.js +17 -0
  397. package/dist/scene/schema/collider.d.ts +40 -0
  398. package/dist/scene/schema/collider.d.ts.map +1 -0
  399. package/dist/scene/schema/collider.js +55 -0
  400. package/dist/scene/schema/entity-ref.d.ts +31 -0
  401. package/dist/scene/schema/entity-ref.d.ts.map +1 -0
  402. package/dist/scene/schema/entity-ref.js +61 -0
  403. package/dist/scene/schema/entity.d.ts +1036 -0
  404. package/dist/scene/schema/entity.d.ts.map +1 -0
  405. package/dist/scene/schema/entity.js +153 -0
  406. package/dist/scene/schema/environment.d.ts +425 -0
  407. package/dist/scene/schema/environment.d.ts.map +1 -0
  408. package/dist/scene/schema/environment.js +357 -0
  409. package/dist/scene/schema/index.d.ts +37 -0
  410. package/dist/scene/schema/index.d.ts.map +1 -0
  411. package/dist/scene/schema/index.js +19 -0
  412. package/dist/scene/schema/instances.d.ts +14 -0
  413. package/dist/scene/schema/instances.d.ts.map +1 -0
  414. package/dist/scene/schema/instances.js +28 -0
  415. package/dist/scene/schema/joint.d.ts +23 -0
  416. package/dist/scene/schema/joint.d.ts.map +1 -0
  417. package/dist/scene/schema/joint.js +23 -0
  418. package/dist/scene/schema/light.d.ts +38 -0
  419. package/dist/scene/schema/light.d.ts.map +1 -0
  420. package/dist/scene/schema/light.js +26 -0
  421. package/dist/scene/schema/material.d.ts +199 -0
  422. package/dist/scene/schema/material.d.ts.map +1 -0
  423. package/dist/scene/schema/material.js +103 -0
  424. package/dist/scene/schema/mesh.d.ts +48 -0
  425. package/dist/scene/schema/mesh.d.ts.map +1 -0
  426. package/dist/scene/schema/mesh.js +82 -0
  427. package/dist/scene/schema/particles.d.ts +2178 -0
  428. package/dist/scene/schema/particles.d.ts.map +1 -0
  429. package/dist/scene/schema/particles.js +321 -0
  430. package/dist/scene/schema/physics.d.ts +56 -0
  431. package/dist/scene/schema/physics.d.ts.map +1 -0
  432. package/dist/scene/schema/physics.js +37 -0
  433. package/dist/scene/schema/scene-file.d.ts +303 -0
  434. package/dist/scene/schema/scene-file.d.ts.map +1 -0
  435. package/dist/scene/schema/scene-file.js +256 -0
  436. package/dist/scene/schema/shadow.d.ts +28 -0
  437. package/dist/scene/schema/shadow.d.ts.map +1 -0
  438. package/dist/scene/schema/shadow.js +20 -0
  439. package/dist/scene/schema/spline.d.ts +25 -0
  440. package/dist/scene/schema/spline.d.ts.map +1 -0
  441. package/dist/scene/schema/spline.js +15 -0
  442. package/dist/scene/schema/tuples.d.ts +12 -0
  443. package/dist/scene/schema/tuples.d.ts.map +1 -0
  444. package/dist/scene/schema/tuples.js +14 -0
  445. package/dist/scene/user-data.d.ts +185 -0
  446. package/dist/scene/user-data.d.ts.map +1 -0
  447. package/dist/scene/user-data.js +144 -0
  448. package/dist/setup/setup-audio.d.ts +20 -0
  449. package/dist/setup/setup-audio.d.ts.map +1 -0
  450. package/dist/setup/setup-audio.js +41 -0
  451. package/dist/setup/setup-particles.d.ts +17 -0
  452. package/dist/setup/setup-particles.d.ts.map +1 -0
  453. package/dist/setup/setup-particles.js +16 -0
  454. package/dist/setup/setup-physics.d.ts +25 -0
  455. package/dist/setup/setup-physics.d.ts.map +1 -0
  456. package/dist/setup/setup-physics.js +51 -0
  457. package/dist/setup/setup-renderer.d.ts +69 -0
  458. package/dist/setup/setup-renderer.d.ts.map +1 -0
  459. package/dist/setup/setup-renderer.js +363 -0
  460. package/dist/tools/define-tool.d.ts +130 -0
  461. package/dist/tools/define-tool.d.ts.map +1 -0
  462. package/dist/tools/define-tool.js +96 -0
  463. package/dist/world2d/authoring-2d.d.ts +80 -0
  464. package/dist/world2d/authoring-2d.d.ts.map +1 -0
  465. package/dist/world2d/authoring-2d.js +195 -0
  466. package/dist/world2d/capture-to-scene2d.d.ts +5 -0
  467. package/dist/world2d/capture-to-scene2d.d.ts.map +1 -0
  468. package/dist/world2d/capture-to-scene2d.js +49 -0
  469. package/dist/world2d/collision-2d.d.ts +52 -0
  470. package/dist/world2d/collision-2d.d.ts.map +1 -0
  471. package/dist/world2d/collision-2d.js +70 -0
  472. package/dist/world2d/components-2d.d.ts +47 -0
  473. package/dist/world2d/components-2d.d.ts.map +1 -0
  474. package/dist/world2d/components-2d.js +77 -0
  475. package/dist/world2d/index.d.ts +34 -0
  476. package/dist/world2d/index.d.ts.map +1 -0
  477. package/dist/world2d/index.js +32 -0
  478. package/dist/world2d/ingest-iframe-2d.d.ts +82 -0
  479. package/dist/world2d/ingest-iframe-2d.d.ts.map +1 -0
  480. package/dist/world2d/ingest-iframe-2d.js +166 -0
  481. package/dist/world2d/ingest2d.d.ts +97 -0
  482. package/dist/world2d/ingest2d.d.ts.map +1 -0
  483. package/dist/world2d/ingest2d.js +40 -0
  484. package/dist/world2d/physics2d-registry.d.ts +24 -0
  485. package/dist/world2d/physics2d-registry.d.ts.map +1 -0
  486. package/dist/world2d/physics2d-registry.js +38 -0
  487. package/dist/world2d/pixi-game-adapter.d.ts +107 -0
  488. package/dist/world2d/pixi-game-adapter.d.ts.map +1 -0
  489. package/dist/world2d/pixi-game-adapter.js +210 -0
  490. package/dist/world2d/pixi-surface.d.ts +39 -0
  491. package/dist/world2d/pixi-surface.d.ts.map +1 -0
  492. package/dist/world2d/pixi-surface.js +47 -0
  493. package/dist/world2d/scene-capture-2d.d.ts +43 -0
  494. package/dist/world2d/scene-capture-2d.d.ts.map +1 -0
  495. package/dist/world2d/scene-capture-2d.js +92 -0
  496. package/dist/world2d/scene2d-loader.d.ts +27 -0
  497. package/dist/world2d/scene2d-loader.d.ts.map +1 -0
  498. package/dist/world2d/scene2d-loader.js +275 -0
  499. package/dist/world2d/schema/entity2d.d.ts +102 -0
  500. package/dist/world2d/schema/entity2d.d.ts.map +1 -0
  501. package/dist/world2d/schema/entity2d.js +119 -0
  502. package/dist/world2d/schema/physics2d.d.ts +46 -0
  503. package/dist/world2d/schema/physics2d.d.ts.map +1 -0
  504. package/dist/world2d/schema/physics2d.js +45 -0
  505. package/dist/world2d/schema/sprite.d.ts +42 -0
  506. package/dist/world2d/schema/sprite.d.ts.map +1 -0
  507. package/dist/world2d/schema/sprite.js +63 -0
  508. package/dist/world2d/schema/tilemap.d.ts +15 -0
  509. package/dist/world2d/schema/tilemap.d.ts.map +1 -0
  510. package/dist/world2d/schema/tilemap.js +19 -0
  511. package/dist/world2d/schema/tuples2d.d.ts +20 -0
  512. package/dist/world2d/schema/tuples2d.d.ts.map +1 -0
  513. package/dist/world2d/schema/tuples2d.js +19 -0
  514. package/dist/world2d/system-adapters-2d.d.ts +16 -0
  515. package/dist/world2d/system-adapters-2d.d.ts.map +1 -0
  516. package/dist/world2d/system-adapters-2d.js +37 -0
  517. package/dist/world2d/transform-writer-2d.d.ts +16 -0
  518. package/dist/world2d/transform-writer-2d.d.ts.map +1 -0
  519. package/dist/world2d/transform-writer-2d.js +22 -0
  520. package/dist/world2d/types.d.ts +59 -0
  521. package/dist/world2d/types.d.ts.map +1 -0
  522. package/dist/world2d/types.js +1 -0
  523. package/package.json +1 -1
  524. package/schemas/vgai-game.schema.json +63 -0
  525. package/src/manifest/load.ts +7 -0
  526. package/src/manifest/schema.ts +58 -0
  527. package/src/world3d-react/r3f-adapter.tsx +8 -8
@@ -0,0 +1,90 @@
1
+ import { Offline } from 'tone';
2
+ /**
3
+ * G2 — Integrate Tone with the Canonical Clock, OFFLINE-render half (spec
4
+ * §13 G2, and the G4/I6 seam it is deliberately shaped for). This module
5
+ * renders a Tone composition over an exact `[start, end)` time range to a
6
+ * real `AudioBuffer` via `Tone.Offline` — i.e. `OfflineAudioContext`, NOT a
7
+ * live real-time `AudioContext` — such that identical inputs produce
8
+ * bit-identical output samples on every call. This is what makes offline
9
+ * Tone audio safe to mux into a deterministically-rendered video (G4/I6):
10
+ * the video side already re-renders frame-by-frame from an exact clock
11
+ * position, and this is the audio side's equivalent — an exact re-render
12
+ * from an exact time range, not a live capture of whatever happened to play.
13
+ *
14
+ * ## Why this can't run in plain Node (documented, not assumed)
15
+ *
16
+ * `Tone.Offline` ultimately constructs a real `OfflineAudioContext`
17
+ * (via `standardized-audio-context`, Tone's own dependency). Node has no
18
+ * native Web Audio implementation, so `standardized-audio-context` throws
19
+ * `"Missing the native OfflineAudioContext constructor."` the moment
20
+ * `Tone.Offline(...)` is actually invoked — confirmed empirically against
21
+ * this repo's installed `tone@15.1.22` before writing this module (plain
22
+ * `import * as Tone from 'tone'` succeeds; calling `Tone.Offline(...)` in a
23
+ * Node process throws immediately). There is no lightweight polyfill in this
24
+ * repo's dependency tree, and installing a native Node Web Audio addon is
25
+ * out of scope for this unit (build-box constraints). The determinism proof
26
+ * for this module therefore runs in a REAL headless-Chromium page via
27
+ * Playwright — see `packages/engine/e2e/tests/tone-audio-g1-g2.spec.ts`
28
+ * — mirroring how I0 proved video-frame determinism. This module's own
29
+ * `packages/engine/test/audio/tone-offline-render.test.ts` covers everything
30
+ * that does NOT require a real `OfflineAudioContext` (range validation,
31
+ * synchronous pre-render cancellation) directly in Node.
32
+ *
33
+ * ## Composition contract
34
+ *
35
+ * `compose` is called by `Tone.Offline` itself, inside the offline context —
36
+ * build the SAME graph you would in real-time Tone code
37
+ * (`new Tone.Synth().toDestination()`, `context.transport.schedule(...)`,
38
+ * etc; see Tone's own `Offline` docs). Nothing about this wrapper changes
39
+ * Tone's native API surface — `compose`'s parameter is `Tone.Offline`'s own
40
+ * callback type, re-derived structurally (`Parameters<typeof Offline>[0]`)
41
+ * rather than duplicated, so this module can never drift from Tone's actual
42
+ * signature.
43
+ *
44
+ * ## Cancellation — cooperative, not a true mid-render abort
45
+ *
46
+ * The Web Audio spec gives `OfflineAudioContext` no `.close()`/cancel API
47
+ * once `startRendering()` is in flight, and neither does Tone. `signal`
48
+ * therefore provides COOPERATIVE cancellation only: if `signal` is already
49
+ * aborted before this function calls `Tone.Offline`, the render never
50
+ * starts at all (checked synchronously, before any `OfflineAudioContext` is
51
+ * created). If `signal` aborts WHILE a render is in flight, this function's
52
+ * returned promise rejects immediately with an `AbortError` — so a caller
53
+ * (e.g. a render-cancellation UI action) sees the render "stop" from its own
54
+ * perspective and never receives/uses the resulting buffer — even though
55
+ * the underlying browser-native render may keep running in the background
56
+ * until it would have finished anyway. This is an honest, documented
57
+ * limitation, not a gap: no browser API makes a stronger guarantee possible.
58
+ */
59
+ /** Tone's own `Offline` callback signature, re-derived (not re-typed) so
60
+ * this module can never drift from the real function it wraps. */
61
+ export type ToneOfflineComposeFn = Parameters<typeof Offline>[0];
62
+ export interface ToneOfflineRenderRequest {
63
+ /** Canonical/Theatre-time range start, in seconds. */
64
+ readonly start: number;
65
+ /** Canonical/Theatre-time range end, in seconds. Must be `> start`. */
66
+ readonly end: number;
67
+ /** Output sample rate. Default 44100 (CD-quality, FFmpeg's usual default). */
68
+ readonly sampleRate?: number;
69
+ /** Output channel count. Default 2 (stereo). */
70
+ readonly channels?: number;
71
+ /** Builds the Tone graph inside the offline context — Tone's native
72
+ * `Offline` callback, unmodified. Receives local time `0` at `start`. */
73
+ readonly compose: ToneOfflineComposeFn;
74
+ /** Optional cooperative-cancellation signal — see module doc above. */
75
+ readonly signal?: AbortSignal;
76
+ }
77
+ export interface ToneOfflineRenderResult {
78
+ /** The rendered PCM, as a real (native) `AudioBuffer` — `.getChannelData(n)`
79
+ * gives the Float32 samples for channel `n`, ready for a digest/RMS
80
+ * computation or (eventually, G4/I6) FFmpeg muxing. */
81
+ readonly buffer: AudioBuffer;
82
+ readonly durationSeconds: number;
83
+ readonly sampleRate: number;
84
+ readonly channels: number;
85
+ }
86
+ /** Render `request.compose`'s Tone graph offline over `[start, end)`,
87
+ * producing a deterministic `AudioBuffer`. See module doc for the
88
+ * determinism/cancellation contract. */
89
+ export declare function renderToneOffline(request: ToneOfflineRenderRequest): Promise<ToneOfflineRenderResult>;
90
+ //# sourceMappingURL=tone-offline-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tone-offline-render.d.ts","sourceRoot":"","sources":["../../src/audio/tone-offline-render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH;mEACmE;AACnE,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjE,MAAM,WAAW,wBAAwB;IACvC,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;8EAC0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACtC;;4DAEwD;IACxD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAKD;;yCAEyC;AACzC,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,CA4ClC"}
@@ -0,0 +1,56 @@
1
+ import { Offline } from 'tone';
2
+ const DEFAULT_SAMPLE_RATE = 44100;
3
+ const DEFAULT_CHANNELS = 2;
4
+ /** Render `request.compose`'s Tone graph offline over `[start, end)`,
5
+ * producing a deterministic `AudioBuffer`. See module doc for the
6
+ * determinism/cancellation contract. */
7
+ export async function renderToneOffline(request) {
8
+ const { start, end, sampleRate = DEFAULT_SAMPLE_RATE, channels = DEFAULT_CHANNELS, compose, signal, } = request;
9
+ if (!Number.isFinite(start) || !Number.isFinite(end) || end <= start) {
10
+ throw new Error(`[tone-offline-render] invalid range [${start}, ${end}) — end must be a finite number > start`);
11
+ }
12
+ if (!Number.isFinite(sampleRate) || sampleRate <= 0) {
13
+ throw new Error(`[tone-offline-render] sampleRate must be a finite number > 0, got ${sampleRate}`);
14
+ }
15
+ if (!Number.isInteger(channels) || channels <= 0) {
16
+ throw new Error(`[tone-offline-render] channels must be a positive integer, got ${channels}`);
17
+ }
18
+ // Cooperative cancellation, checked BEFORE ever constructing an
19
+ // OfflineAudioContext — an already-aborted signal must never start a
20
+ // render at all (see module doc).
21
+ if (signal?.aborted) {
22
+ throw createAbortError();
23
+ }
24
+ const durationSeconds = end - start;
25
+ const renderPromise = Offline(compose, durationSeconds, channels, sampleRate);
26
+ const toneBuffer = signal ? await raceAbort(renderPromise, signal) : await renderPromise;
27
+ const buffer = toneBuffer.get();
28
+ if (!buffer) {
29
+ throw new Error('[tone-offline-render] Tone.Offline resolved without a decoded AudioBuffer');
30
+ }
31
+ return {
32
+ buffer,
33
+ durationSeconds,
34
+ sampleRate: buffer.sampleRate,
35
+ channels: buffer.numberOfChannels,
36
+ };
37
+ }
38
+ function createAbortError() {
39
+ return new DOMException('[tone-offline-render] render canceled', 'AbortError');
40
+ }
41
+ /** Race `promise` against `signal` firing — resolves/rejects with whichever
42
+ * happens first, without altering the underlying Web Audio render (see
43
+ * module doc's "cooperative, not a true mid-render abort" section). */
44
+ function raceAbort(promise, signal) {
45
+ return new Promise((resolve, reject) => {
46
+ const onAbort = () => reject(createAbortError());
47
+ signal.addEventListener('abort', onAbort, { once: true });
48
+ promise.then((value) => {
49
+ signal.removeEventListener('abort', onAbort);
50
+ resolve(value);
51
+ }, (err) => {
52
+ signal.removeEventListener('abort', onAbort);
53
+ reject(err);
54
+ });
55
+ });
56
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Pure PCM -> 16-bit WAV encoder (spec §15 I6 "Encode and Mux", audio half —
3
+ * `docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md`). This module takes
4
+ * already-rendered Float32 channel data (e.g. `AudioBuffer.getChannelData(n)`
5
+ * from a `Tone.Offline` render, `audio/tone-offline-render.ts`) and produces
6
+ * a standard little-endian, 16-bit-PCM, interleaved RIFF/WAVE file as raw
7
+ * bytes — no `AudioBuffer`/`AudioContext` dependency, so this runs equally in
8
+ * a browser render-mode page (`runtime/render-audio-control.ts`) and in
9
+ * plain Node (this module's own `packages/engine/test/audio/wav-encode.test.ts`,
10
+ * no Playwright needed).
11
+ *
12
+ * 16-bit PCM (not 32-bit float) is the deliberate choice named by the I6 AC
13
+ * ("16-bit PCM WAV is fine") — it is universally decodable by every FFmpeg
14
+ * build without an extra format flag, keeping the video-mux step's ffmpeg
15
+ * invocation ordinary and portable.
16
+ */
17
+ export interface PcmToWavInput {
18
+ /** One `Float32Array` per channel, each sample in `[-1, 1]` (values outside
19
+ * that range are clamped, not thrown on — real synthesis can transiently
20
+ * clip). All channels must have equal length. */
21
+ readonly channelData: readonly Float32Array[];
22
+ readonly sampleRate: number;
23
+ }
24
+ /** Encode `input` as a complete little-endian, 16-bit-PCM, interleaved
25
+ * RIFF/WAVE file (44-byte canonical header + data chunk). Throws on an
26
+ * empty/mismatched channel set rather than silently producing a malformed
27
+ * file — this module's own contribution to the "fail loudly, never a
28
+ * silent no-op" convention `runtime/render-control.ts` documents. */
29
+ export declare function encodeWav16(input: PcmToWavInput): Uint8Array;
30
+ /** RMS + peak over all channels/samples — the same "non-trivial audio, not
31
+ * an all-zero buffer" sanity check `tone-audio-main.ts`'s fixture computes,
32
+ * factored out here so both that fixture and the render-audio harness can
33
+ * share one implementation instead of drifting copies. */
34
+ export declare function pcmStats(channelData: readonly Float32Array[]): {
35
+ rms: number;
36
+ peak: number;
37
+ };
38
+ //# sourceMappingURL=wav-encode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wav-encode.d.ts","sourceRoot":"","sources":["../../src/audio/wav-encode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,aAAa;IAC5B;;sDAEkD;IAClD,QAAQ,CAAC,WAAW,EAAE,SAAS,YAAY,EAAE,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAeD;;;;sEAIsE;AACtE,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAwD5D;AAED;;;2DAG2D;AAC3D,wBAAgB,QAAQ,CAAC,WAAW,EAAE,SAAS,YAAY,EAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAa5F"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Pure PCM -> 16-bit WAV encoder (spec §15 I6 "Encode and Mux", audio half —
3
+ * `docs/AI-NATIVE-AUTHORING-IMPLEMENTATION-SPEC.md`). This module takes
4
+ * already-rendered Float32 channel data (e.g. `AudioBuffer.getChannelData(n)`
5
+ * from a `Tone.Offline` render, `audio/tone-offline-render.ts`) and produces
6
+ * a standard little-endian, 16-bit-PCM, interleaved RIFF/WAVE file as raw
7
+ * bytes — no `AudioBuffer`/`AudioContext` dependency, so this runs equally in
8
+ * a browser render-mode page (`runtime/render-audio-control.ts`) and in
9
+ * plain Node (this module's own `packages/engine/test/audio/wav-encode.test.ts`,
10
+ * no Playwright needed).
11
+ *
12
+ * 16-bit PCM (not 32-bit float) is the deliberate choice named by the I6 AC
13
+ * ("16-bit PCM WAV is fine") — it is universally decodable by every FFmpeg
14
+ * build without an extra format flag, keeping the video-mux step's ffmpeg
15
+ * invocation ordinary and portable.
16
+ */
17
+ const BYTES_PER_SAMPLE = 2; // 16-bit PCM
18
+ const WAV_HEADER_BYTES = 44;
19
+ function clamp(value, lo, hi) {
20
+ return Math.min(hi, Math.max(lo, value));
21
+ }
22
+ function writeAsciiString(view, offset, text) {
23
+ for (let i = 0; i < text.length; i++) {
24
+ view.setUint8(offset + i, text.charCodeAt(i));
25
+ }
26
+ }
27
+ /** Encode `input` as a complete little-endian, 16-bit-PCM, interleaved
28
+ * RIFF/WAVE file (44-byte canonical header + data chunk). Throws on an
29
+ * empty/mismatched channel set rather than silently producing a malformed
30
+ * file — this module's own contribution to the "fail loudly, never a
31
+ * silent no-op" convention `runtime/render-control.ts` documents. */
32
+ export function encodeWav16(input) {
33
+ const { channelData, sampleRate } = input;
34
+ const numChannels = channelData.length;
35
+ if (numChannels === 0) {
36
+ throw new Error('[wav-encode] channelData must contain at least one channel');
37
+ }
38
+ if (!Number.isFinite(sampleRate) || sampleRate <= 0) {
39
+ throw new Error(`[wav-encode] sampleRate must be a finite number > 0, got ${sampleRate}`);
40
+ }
41
+ const numFrames = channelData[0]?.length ?? 0;
42
+ for (let ch = 0; ch < numChannels; ch++) {
43
+ const len = channelData[ch]?.length ?? -1;
44
+ if (len !== numFrames) {
45
+ throw new Error(`[wav-encode] channel ${ch} has length ${len}, expected ${numFrames} (all channels must match)`);
46
+ }
47
+ }
48
+ const blockAlign = numChannels * BYTES_PER_SAMPLE;
49
+ const byteRate = sampleRate * blockAlign;
50
+ const dataSize = numFrames * blockAlign;
51
+ const buffer = new ArrayBuffer(WAV_HEADER_BYTES + dataSize);
52
+ const view = new DataView(buffer);
53
+ // RIFF chunk descriptor
54
+ writeAsciiString(view, 0, 'RIFF');
55
+ view.setUint32(4, 36 + dataSize, true);
56
+ writeAsciiString(view, 8, 'WAVE');
57
+ // fmt subchunk (PCM)
58
+ writeAsciiString(view, 12, 'fmt ');
59
+ view.setUint32(16, 16, true); // subchunk size for PCM
60
+ view.setUint16(20, 1, true); // audio format 1 = PCM
61
+ view.setUint16(22, numChannels, true);
62
+ view.setUint32(24, sampleRate, true);
63
+ view.setUint32(28, byteRate, true);
64
+ view.setUint16(32, blockAlign, true);
65
+ view.setUint16(34, BYTES_PER_SAMPLE * 8, true); // bits per sample
66
+ // data subchunk
67
+ writeAsciiString(view, 36, 'data');
68
+ view.setUint32(40, dataSize, true);
69
+ let offset = WAV_HEADER_BYTES;
70
+ for (let i = 0; i < numFrames; i++) {
71
+ for (let ch = 0; ch < numChannels; ch++) {
72
+ const sample = clamp(channelData[ch]?.[i] ?? 0, -1, 1);
73
+ const intSample = Math.round(sample < 0 ? sample * 0x8000 : sample * 0x7fff);
74
+ view.setInt16(offset, intSample, true);
75
+ offset += BYTES_PER_SAMPLE;
76
+ }
77
+ }
78
+ return new Uint8Array(buffer);
79
+ }
80
+ /** RMS + peak over all channels/samples — the same "non-trivial audio, not
81
+ * an all-zero buffer" sanity check `tone-audio-main.ts`'s fixture computes,
82
+ * factored out here so both that fixture and the render-audio harness can
83
+ * share one implementation instead of drifting copies. */
84
+ export function pcmStats(channelData) {
85
+ let sumSquares = 0;
86
+ let peak = 0;
87
+ let count = 0;
88
+ for (const data of channelData) {
89
+ for (let i = 0; i < data.length; i++) {
90
+ const v = data[i] ?? 0;
91
+ sumSquares += v * v;
92
+ peak = Math.max(peak, Math.abs(v));
93
+ count++;
94
+ }
95
+ }
96
+ return { rms: count > 0 ? Math.sqrt(sumSquares / count) : 0, peak };
97
+ }
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Character primitive — Jolt soft-body cloth grids (capes, skirts, banners)
3
+ * on top of the raw `jolt-physics` WASM bindings.
4
+ *
5
+ * THIN COMPOSITION HELPER, not a wrapper (CLAUDE.md "use libraries
6
+ * directly"): every export assembles the library's own objects
7
+ * (`Jolt.SoftBodySharedSettings`, `Jolt.Body`, `Jolt.JoltInterface`) —
8
+ * nothing from the library is re-exported. This file never imports the WASM
9
+ * module itself — the caller does the async `JoltInit()` and passes the
10
+ * resolved module in, mirroring `setup-physics.ts`'s `setupPhysics(rapier:
11
+ * typeof RAPIER, ...)` pattern for Rapier. `import type Jolt from
12
+ * 'jolt-physics/wasm-compat'` below is TYPE-ONLY (erased at compile time —
13
+ * no runtime WASM import here).
14
+ *
15
+ * Sharp edges this module exists partly to contain (see the mission brief /
16
+ * `cloth-hair-bench/jolt-cloth.ts`'s header for the full discovery):
17
+ * - `Body.GetMotionProperties()` needs the `Jolt.castObject` downcast to
18
+ * `Jolt.SoftBodyMotionProperties` to reach `GetVertex`.
19
+ * - `SoftBodySharedSettings.CreateConstraints` takes a POINTER-typed
20
+ * 1-element `ArraySoftBodySharedSettingsVertexAttributes` (push_back,
21
+ * not resize+at — `.at()` on these embind vectors returns a copy).
22
+ * - Kinematic pins must set BOTH `SoftBodyVertex.mPosition` and
23
+ * `.mVelocity` (finite-differenced) every tick, or the cloth's own
24
+ * constraint solver fights a teleporting anchor.
25
+ * - NO per-frame embind allocations (reviewer finding on Phase 1's
26
+ * spike, which leaked a `new Jolt.Vec3(...)`/`new Jolt.RVec3(...)` per
27
+ * pinned vertex per frame): `tick()` below preallocates ONE `Jolt.Vec3`
28
+ * for position and ONE for velocity and reuses them via `.Set(...)` —
29
+ * embind property setters (`vertex.mPosition = tmpVec3`) copy the value
30
+ * in, so reassigning the SAME wrapper object across many vertices in one
31
+ * frame is safe. `KinematicCollider.moveTo` does the same with one
32
+ * `Jolt.RVec3` + one `Jolt.Quat` (identity, orientation is not simulated
33
+ * here) allocated once at construction.
34
+ * - CONSTRUCTION-TIME embind temporaries need `Jolt.destroy(...)` too, once
35
+ * Jolt has copied their data out (reviewer finding on Phase 2 — these
36
+ * were leaking WASM heap per build/dispose cycle even with `tick()`
37
+ * itself allocation-free). Two different lifetimes are at play:
38
+ * - Per-vertex/per-face grid temporaries (`SoftBodySharedSettingsVertex`
39
+ * + its `Float3`, `SoftBodySharedSettingsFace`, the single
40
+ * `vertexAttr`) are copied BY VALUE into `sharedSettings`'s own
41
+ * storage the instant `push_back`/the property setter runs — freed
42
+ * right there, matching the reuse-then-`Jolt.destroy()`-once pattern
43
+ * in Jolt's own `soft-body-creator.js` sample. `bodyCreation`
44
+ * (`SoftBodyCreationSettings`) is the same story: `CreateSoftBody`
45
+ * copies what it needs, so it's freed right after — same contract as
46
+ * `JoltSettings` → `JoltInterface` below.
47
+ * - `sharedSettings` itself (`SoftBodySharedSettings`) is different: it
48
+ * is REFCOUNTED (`AddRef`/`Release`/`GetRefCount` in the vendored
49
+ * typings, like `Shape`) and the body reads it every step
50
+ * (`SoftBodyMotionProperties.GetSettings()`) for face/constraint
51
+ * topology. Refcounted RefTargets are freed BY JOLT ITSELF when the
52
+ * last reference drops (Release of the final ref IS the delete) —
53
+ * so it gets NO explicit `Jolt.destroy(...)` at all: destroying
54
+ * `bodyCreation` releases the ctor's ref, and `dispose()`'s
55
+ * `DestroyBody` releases the body's (last) ref, which deletes it.
56
+ * An explicit destroy on top would be a use-after-free (empirically
57
+ * confirmed with a `GetRefCount()` probe against real Jolt WASM).
58
+ * Same rule for the collider's `Shape`: `destroy(creation)` releases
59
+ * the creation-settings ref, `DestroyBody` releases the body's —
60
+ * never destroy the shape directly.
61
+ * - The preallocated tick-loop temporaries described above (`tmpPos`/
62
+ * `tmpVel` in `buildClothGrid`, `tmpPos`/`identityQuat` in
63
+ * `buildKinematicCollider`) are plain (non-refcounted) `Vec3`/`RVec3`/
64
+ * `Quat` wrappers reused for the object's whole lifetime — freed in that
65
+ * object's own `dispose()`.
66
+ */
67
+ import type JoltNS from 'jolt-physics/wasm-compat';
68
+ import * as THREE from 'three';
69
+ /** The type of an ALREADY-INITIALIZED `jolt-physics/wasm-compat` module
70
+ * (i.e. what `await JoltInit()` resolves to) — the parameter type every
71
+ * function below takes instead of importing/initializing Jolt itself. */
72
+ export type JoltModule = typeof JoltNS;
73
+ export interface JoltWorld {
74
+ jolt: JoltModule;
75
+ joltInterface: JoltNS.JoltInterface;
76
+ physicsSystem: JoltNS.PhysicsSystem;
77
+ bodyInterface: JoltNS.BodyInterface;
78
+ /** The single "moving" object layer every body built through this world's
79
+ * helpers is placed on (cloth + kinematic colliders all collide with
80
+ * each other; nothing here needs more than one moving layer). */
81
+ movingLayer: number;
82
+ /** Advance the simulation by `dt` seconds (`options.collisionSteps` Jolt
83
+ * collision sub-steps). Position any kinematic bodies (colliders, cloth
84
+ * pins) for this frame BEFORE calling `step` — this is what
85
+ * `ClothGrid.tick` does internally. */
86
+ step(dt: number): void;
87
+ dispose(): void;
88
+ }
89
+ export interface JoltWorldOptions {
90
+ gravity?: {
91
+ x: number;
92
+ y: number;
93
+ z: number;
94
+ };
95
+ /** Jolt collision sub-steps per `step()` call. Soft-body contact has no
96
+ * CCD — a cloth vertex moving faster than its collision radius per
97
+ * collision step TUNNELS through kinematic colliders (measured live on a
98
+ * whipping cape). 2 halves the per-step travel for ~2x the (sub-ms) sim
99
+ * cost. @default 1 */
100
+ collisionSteps?: number;
101
+ }
102
+ export declare function createJoltWorld(jolt: JoltModule, options?: JoltWorldOptions): JoltWorld;
103
+ export type KinematicColliderShape = {
104
+ kind: 'sphere';
105
+ radius: number;
106
+ } | {
107
+ kind: 'capsule';
108
+ radius: number;
109
+ halfHeight: number;
110
+ };
111
+ export interface KinematicCollider {
112
+ body: JoltNS.Body;
113
+ /** Move the collider to `worldPos` (identity rotation — these fixtures
114
+ * only need translation) for tick `dt`. Call BEFORE the cloth grid's
115
+ * `tick()` for the same frame (that is what steps the Jolt world). */
116
+ moveTo(worldPos: THREE.Vector3, dt: number): void;
117
+ dispose(): void;
118
+ }
119
+ export declare function buildKinematicCollider(world: JoltWorld, shape: KinematicColliderShape): KinematicCollider;
120
+ export interface ClothPin {
121
+ row: number;
122
+ col: number;
123
+ }
124
+ export interface ClothGridOptions {
125
+ cols: number;
126
+ rows: number;
127
+ /** World-space rest position for grid vertex (row, col) — row 0 is
128
+ * conventionally the top/pinned edge, but that's a caller convention,
129
+ * not enforced here. */
130
+ restPosition(row: number, col: number): THREE.Vector3;
131
+ /** Which vertices are pinned (kinematically driven every tick, infinite
132
+ * mass). Default: every vertex in row 0. */
133
+ pins?: ClothPin[];
134
+ vertexMassKg?: number;
135
+ compliance?: number;
136
+ shearCompliance?: number;
137
+ bendCompliance?: number;
138
+ numIterations?: number;
139
+ gravityFactor?: number;
140
+ /** Collision radius of every cloth vertex (Jolt `mVertexRadius`), metres.
141
+ * The default 0 lets a pressed vertex sit exactly ON (and, under
142
+ * sustained gait-driven contact, sink INTO) a collider surface; a few cm
143
+ * here keeps the cloth standing off colliders and makes contact
144
+ * resolution far more robust against sinking. @default 0 (Jolt's own) */
145
+ vertexRadius?: number;
146
+ /** Jolt `mLinearDamping` for the soft body (higher = calmer cloth).
147
+ * @default Jolt's own default */
148
+ linearDamping?: number;
149
+ color?: number;
150
+ /** @default true */
151
+ doubleSided?: boolean;
152
+ }
153
+ export interface ClothGrid {
154
+ cols: number;
155
+ rows: number;
156
+ vertexCount: number;
157
+ /** Pin list this grid was built with, in the order `tick()`'s
158
+ * `pinTargets` must match. */
159
+ pins: ClothPin[];
160
+ mesh: THREE.Mesh;
161
+ geometry: THREE.BufferGeometry;
162
+ /** One tick: overwrite each pinned vertex's position/velocity from
163
+ * `pinTargets[i]` (world-space, matching `pins` order — velocity is
164
+ * finite-differenced against the previous call), STEP the owning
165
+ * `JoltWorld` (this is the only thing in this module that calls
166
+ * `world.step`, so build at most one `ClothGrid` per `JoltWorld` unless
167
+ * you step the world yourself and skip that side effect), then sync
168
+ * `geometry`'s `position` attribute + recompute normals from the
169
+ * simulated vertices. Position any kinematic colliders for this frame
170
+ * BEFORE calling this. */
171
+ tick(dt: number, pinTargets: readonly THREE.Vector3[]): void;
172
+ /** World-space position of every vertex, row-major (`row * cols + col`).
173
+ * Reuses `out` if given (avoids an allocation for callers sampling every
174
+ * frame, e.g. a numeric collision-clearance check). */
175
+ samplePoints(out?: THREE.Vector3[]): THREE.Vector3[];
176
+ dispose(): void;
177
+ }
178
+ export declare function buildClothGrid(world: JoltWorld, scene: THREE.Scene, options: ClothGridOptions): ClothGrid;
179
+ //# sourceMappingURL=cloth-sim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloth-sim.d.ts","sourceRoot":"","sources":["../../src/character/cloth-sim.ts"],"names":[],"mappings":"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"}