@aura3d/engine 4.6.1 → 4.7.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 (514) hide show
  1. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.d.ts +12 -0
  2. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.d.ts.map +1 -1
  3. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.js +26 -1
  4. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.js.map +1 -1
  5. package/dist/assets/vfx/LICENSE.md +1 -0
  6. package/dist/assets/vfx/aura-vfx-1k.png +0 -0
  7. package/dist/assets/vfx/aura-vfx-2k.png +0 -0
  8. package/dist/aura3d-cli/admission/cubeLut.d.ts +18 -0
  9. package/dist/aura3d-cli/admission/cubeLut.d.ts.map +1 -0
  10. package/dist/aura3d-cli/admission/cubeLut.js +53 -0
  11. package/dist/aura3d-cli/admission/cubeLut.js.map +1 -0
  12. package/dist/aura3d-cli/asset-core-types.d.ts +7 -4
  13. package/dist/aura3d-cli/asset-core-types.d.ts.map +1 -1
  14. package/dist/aura3d-cli/cli-help.d.ts.map +1 -1
  15. package/dist/aura3d-cli/cli-help.js +7 -4
  16. package/dist/aura3d-cli/cli-help.js.map +1 -1
  17. package/dist/aura3d-cli/cli-options.d.ts +1 -1
  18. package/dist/aura3d-cli/cli-options.d.ts.map +1 -1
  19. package/dist/aura3d-cli/cli-options.js +2 -2
  20. package/dist/aura3d-cli/cli-options.js.map +1 -1
  21. package/dist/aura3d-cli/cli.js +3 -2
  22. package/dist/aura3d-cli/cli.js.map +1 -1
  23. package/dist/aura3d-cli/commands/assets/certifyCategories.d.ts +26 -0
  24. package/dist/aura3d-cli/commands/assets/certifyCategories.d.ts.map +1 -0
  25. package/dist/aura3d-cli/commands/assets/certifyCategories.js +31 -0
  26. package/dist/aura3d-cli/commands/assets/certifyCategories.js.map +1 -0
  27. package/dist/aura3d-cli/commands/assets/optimize.d.ts +66 -0
  28. package/dist/aura3d-cli/commands/assets/optimize.d.ts.map +1 -1
  29. package/dist/aura3d-cli/commands/assets/optimize.js +270 -1
  30. package/dist/aura3d-cli/commands/assets/optimize.js.map +1 -1
  31. package/dist/aura3d-cli/commands/assets/optimizeVerb.d.ts.map +1 -1
  32. package/dist/aura3d-cli/commands/assets/optimizeVerb.js +26 -1
  33. package/dist/aura3d-cli/commands/assets/optimizeVerb.js.map +1 -1
  34. package/dist/aura3d-cli/commands/evidence/judge.d.ts +50 -1
  35. package/dist/aura3d-cli/commands/evidence/judge.d.ts.map +1 -1
  36. package/dist/aura3d-cli/commands/evidence/judge.js +154 -6
  37. package/dist/aura3d-cli/commands/evidence/judge.js.map +1 -1
  38. package/dist/aura3d-cli/commands/prd05/index.js +1 -1
  39. package/dist/aura3d-cli/commands/prd05/index.js.map +1 -1
  40. package/dist/aura3d-cli/index.d.ts.map +1 -1
  41. package/dist/aura3d-cli/index.js +25 -9
  42. package/dist/aura3d-cli/index.js.map +1 -1
  43. package/dist/aura3d-cli/look/judge.d.ts +53 -5
  44. package/dist/aura3d-cli/look/judge.d.ts.map +1 -1
  45. package/dist/aura3d-cli/look/judge.js +226 -50
  46. package/dist/aura3d-cli/look/judge.js.map +1 -1
  47. package/dist/create-aura3d/index.js +1 -1
  48. package/dist/engine/agent-api/RootRuntimeSupport.d.ts +7 -0
  49. package/dist/engine/agent-api/RootRuntimeSupport.d.ts.map +1 -1
  50. package/dist/engine/agent-api/RootRuntimeSupport.js +7 -0
  51. package/dist/engine/agent-api/RootRuntimeSupport.js.map +1 -1
  52. package/dist/engine/agent-api/app/actorAnimationHandle.d.ts +2 -0
  53. package/dist/engine/agent-api/app/actorAnimationHandle.d.ts.map +1 -1
  54. package/dist/engine/agent-api/app/actorAnimationHandle.js +149 -2
  55. package/dist/engine/agent-api/app/actorAnimationHandle.js.map +1 -1
  56. package/dist/engine/agent-api/app/createAuraApp.d.ts.map +1 -1
  57. package/dist/engine/agent-api/app/createAuraApp.js +13 -1
  58. package/dist/engine/agent-api/app/createAuraApp.js.map +1 -1
  59. package/dist/engine/agent-api/app/frameLoop.d.ts.map +1 -1
  60. package/dist/engine/agent-api/app/frameLoop.js +4 -2
  61. package/dist/engine/agent-api/app/frameLoop.js.map +1 -1
  62. package/dist/engine/agent-api/camera/layers/cinematicBars.d.ts +2 -0
  63. package/dist/engine/agent-api/camera/layers/cinematicBars.d.ts.map +1 -1
  64. package/dist/engine/agent-api/camera/layers/cinematicBars.js +4 -0
  65. package/dist/engine/agent-api/camera/layers/cinematicBars.js.map +1 -1
  66. package/dist/engine/agent-api/compiler/compileScene.d.ts +11 -1
  67. package/dist/engine/agent-api/compiler/compileScene.d.ts.map +1 -1
  68. package/dist/engine/agent-api/compiler/compileScene.js +27 -1
  69. package/dist/engine/agent-api/compiler/compileScene.js.map +1 -1
  70. package/dist/engine/agent-api/compiler/customMaterial.d.ts +16 -5
  71. package/dist/engine/agent-api/compiler/customMaterial.d.ts.map +1 -1
  72. package/dist/engine/agent-api/compiler/customMaterial.js +149 -20
  73. package/dist/engine/agent-api/compiler/customMaterial.js.map +1 -1
  74. package/dist/engine/agent-api/compiler/environment.d.ts +57 -1
  75. package/dist/engine/agent-api/compiler/environment.d.ts.map +1 -1
  76. package/dist/engine/agent-api/compiler/environment.js +170 -5
  77. package/dist/engine/agent-api/compiler/environment.js.map +1 -1
  78. package/dist/engine/agent-api/compiler/fog.js +1 -1
  79. package/dist/engine/agent-api/compiler/fog.js.map +1 -1
  80. package/dist/engine/agent-api/compiler/lights.d.ts +92 -0
  81. package/dist/engine/agent-api/compiler/lights.d.ts.map +1 -1
  82. package/dist/engine/agent-api/compiler/lights.js +358 -1
  83. package/dist/engine/agent-api/compiler/lights.js.map +1 -1
  84. package/dist/engine/agent-api/compiler/observations.d.ts +34 -0
  85. package/dist/engine/agent-api/compiler/observations.d.ts.map +1 -1
  86. package/dist/engine/agent-api/compiler/observations.js +77 -5
  87. package/dist/engine/agent-api/compiler/observations.js.map +1 -1
  88. package/dist/engine/agent-api/compiler/postprocess.d.ts +10 -0
  89. package/dist/engine/agent-api/compiler/postprocess.d.ts.map +1 -1
  90. package/dist/engine/agent-api/compiler/postprocess.js +28 -7
  91. package/dist/engine/agent-api/compiler/postprocess.js.map +1 -1
  92. package/dist/engine/agent-api/compiler/renderInput.d.ts +2 -0
  93. package/dist/engine/agent-api/compiler/renderInput.d.ts.map +1 -1
  94. package/dist/engine/agent-api/compiler/renderInput.js +15 -2
  95. package/dist/engine/agent-api/compiler/renderInput.js.map +1 -1
  96. package/dist/engine/agent-api/compiler/renderer.d.ts +6 -0
  97. package/dist/engine/agent-api/compiler/renderer.d.ts.map +1 -1
  98. package/dist/engine/agent-api/compiler/renderer.js +14 -3
  99. package/dist/engine/agent-api/compiler/renderer.js.map +1 -1
  100. package/dist/engine/agent-api/diagnostics.d.ts +16 -0
  101. package/dist/engine/agent-api/diagnostics.d.ts.map +1 -1
  102. package/dist/engine/agent-api/diagnostics.js +45 -2
  103. package/dist/engine/agent-api/diagnostics.js.map +1 -1
  104. package/dist/engine/agent-api/index.d.ts +2 -0
  105. package/dist/engine/agent-api/index.d.ts.map +1 -1
  106. package/dist/engine/agent-api/index.js +3 -0
  107. package/dist/engine/agent-api/index.js.map +1 -1
  108. package/dist/engine/agent-api/looks/lookPresets.d.ts +2 -0
  109. package/dist/engine/agent-api/looks/lookPresets.d.ts.map +1 -1
  110. package/dist/engine/agent-api/looks/lookPresets.js.map +1 -1
  111. package/dist/engine/agent-api/looks/looks.d.ts +12 -2
  112. package/dist/engine/agent-api/looks/looks.d.ts.map +1 -1
  113. package/dist/engine/agent-api/looks/looks.js +365 -65
  114. package/dist/engine/agent-api/looks/looks.js.map +1 -1
  115. package/dist/engine/agent-api/nodes/builder.d.ts +8 -0
  116. package/dist/engine/agent-api/nodes/builder.d.ts.map +1 -1
  117. package/dist/engine/agent-api/nodes/builder.js +15 -0
  118. package/dist/engine/agent-api/nodes/builder.js.map +1 -1
  119. package/dist/engine/agent-api/nodes/effects.composite.d.ts +13 -9
  120. package/dist/engine/agent-api/nodes/effects.composite.d.ts.map +1 -1
  121. package/dist/engine/agent-api/nodes/effects.d.ts +65 -14
  122. package/dist/engine/agent-api/nodes/effects.d.ts.map +1 -1
  123. package/dist/engine/agent-api/nodes/effects.js +49 -16
  124. package/dist/engine/agent-api/nodes/effects.js.map +1 -1
  125. package/dist/engine/agent-api/nodes/effects.post.d.ts +62 -5
  126. package/dist/engine/agent-api/nodes/effects.post.d.ts.map +1 -1
  127. package/dist/engine/agent-api/nodes/effects.post.js +30 -17
  128. package/dist/engine/agent-api/nodes/effects.post.js.map +1 -1
  129. package/dist/engine/agent-api/nodes/effects.toon.d.ts +65 -1
  130. package/dist/engine/agent-api/nodes/effects.toon.d.ts.map +1 -1
  131. package/dist/engine/agent-api/nodes/effects.toon.js +186 -23
  132. package/dist/engine/agent-api/nodes/effects.toon.js.map +1 -1
  133. package/dist/engine/agent-api/nodes/groups.d.ts.map +1 -1
  134. package/dist/engine/agent-api/nodes/groups.js +2 -2
  135. package/dist/engine/agent-api/nodes/groups.js.map +1 -1
  136. package/dist/engine/agent-api/nodes/instances.d.ts +130 -90
  137. package/dist/engine/agent-api/nodes/instances.d.ts.map +1 -1
  138. package/dist/engine/agent-api/nodes/instances.js +192 -48
  139. package/dist/engine/agent-api/nodes/instances.js.map +1 -1
  140. package/dist/engine/agent-api/nodes/material.d.ts +8 -1
  141. package/dist/engine/agent-api/nodes/material.d.ts.map +1 -1
  142. package/dist/engine/agent-api/nodes/material.js +82 -0
  143. package/dist/engine/agent-api/nodes/material.js.map +1 -1
  144. package/dist/engine/agent-api/nodes/outlineTargets.d.ts +16 -0
  145. package/dist/engine/agent-api/nodes/outlineTargets.d.ts.map +1 -0
  146. package/dist/engine/agent-api/nodes/outlineTargets.js +46 -0
  147. package/dist/engine/agent-api/nodes/outlineTargets.js.map +1 -0
  148. package/dist/engine/agent-api/nodes/scene.d.ts.map +1 -1
  149. package/dist/engine/agent-api/nodes/scene.js +2 -2
  150. package/dist/engine/agent-api/nodes/scene.js.map +1 -1
  151. package/dist/engine/agent-api/nodes/sky.d.ts +23 -6
  152. package/dist/engine/agent-api/nodes/sky.d.ts.map +1 -1
  153. package/dist/engine/agent-api/nodes/sky.js +2 -0
  154. package/dist/engine/agent-api/nodes/sky.js.map +1 -1
  155. package/dist/engine/agent-api/nodes/types/runtime.d.ts +28 -1
  156. package/dist/engine/agent-api/nodes/types/runtime.d.ts.map +1 -1
  157. package/dist/engine/agent-api/nodes/types.d.ts +71 -3
  158. package/dist/engine/agent-api/nodes/types.d.ts.map +1 -1
  159. package/dist/engine/agent-api/performanceEvidence.js +7 -2
  160. package/dist/engine/agent-api/performanceEvidence.js.map +1 -1
  161. package/dist/engine/agent-api/postBridge.d.ts +75 -3
  162. package/dist/engine/agent-api/postBridge.d.ts.map +1 -1
  163. package/dist/engine/agent-api/postBridge.js +436 -33
  164. package/dist/engine/agent-api/postBridge.js.map +1 -1
  165. package/dist/engine/agent-api/postPresets.d.ts +8 -4
  166. package/dist/engine/agent-api/postPresets.d.ts.map +1 -1
  167. package/dist/engine/agent-api/postPresets.js +12 -11
  168. package/dist/engine/agent-api/postPresets.js.map +1 -1
  169. package/dist/engine/agent-api/publishedUnion.d.ts +7 -4
  170. package/dist/engine/agent-api/publishedUnion.d.ts.map +1 -1
  171. package/dist/engine/agent-api/publishedUnion.js +1 -1
  172. package/dist/engine/agent-api/publishedUnion.js.map +1 -1
  173. package/dist/engine/agent-api/rendererDiagnostics.js +4 -6
  174. package/dist/engine/agent-api/rendererDiagnostics.js.map +1 -1
  175. package/dist/engine/agent-api/vfx/atmosphere-api.d.ts +2 -4
  176. package/dist/engine/agent-api/vfx/atmosphere-api.d.ts.map +1 -1
  177. package/dist/engine/agent-api/vfx/atmosphere-api.js +2 -1
  178. package/dist/engine/agent-api/vfx/atmosphere-api.js.map +1 -1
  179. package/dist/engine/agent-api/vfx/effects-api.d.ts +3 -0
  180. package/dist/engine/agent-api/vfx/effects-api.d.ts.map +1 -1
  181. package/dist/engine/agent-api/vfx/effects-api.js +337 -74
  182. package/dist/engine/agent-api/vfx/effects-api.js.map +1 -1
  183. package/dist/engine/agent-api/world/flags.d.ts +33 -3
  184. package/dist/engine/agent-api/world/flags.d.ts.map +1 -1
  185. package/dist/engine/agent-api/world/flags.js +44 -12
  186. package/dist/engine/agent-api/world/flags.js.map +1 -1
  187. package/dist/engine/agent-api/world/index.d.ts +10 -1
  188. package/dist/engine/agent-api/world/index.d.ts.map +1 -1
  189. package/dist/engine/agent-api/world/index.js +11 -2
  190. package/dist/engine/agent-api/world/index.js.map +1 -1
  191. package/dist/engine/agent-api/world/scatter.d.ts +50 -3
  192. package/dist/engine/agent-api/world/scatter.d.ts.map +1 -1
  193. package/dist/engine/agent-api/world/scatter.js +93 -7
  194. package/dist/engine/agent-api/world/scatter.js.map +1 -1
  195. package/dist/engine/agent-api/world/terrain.d.ts +8 -0
  196. package/dist/engine/agent-api/world/terrain.d.ts.map +1 -1
  197. package/dist/engine/agent-api/world/terrain.js +6 -1
  198. package/dist/engine/agent-api/world/terrain.js.map +1 -1
  199. package/dist/engine/contracts/animation.d.ts +30 -12
  200. package/dist/engine/contracts/animation.d.ts.map +1 -1
  201. package/dist/engine/contracts/animation.js +2 -0
  202. package/dist/engine/contracts/animation.js.map +1 -1
  203. package/dist/engine/contracts/art.d.ts +1 -1
  204. package/dist/engine/contracts/art.d.ts.map +1 -1
  205. package/dist/engine/contracts/atmosphere.d.ts +43 -9
  206. package/dist/engine/contracts/atmosphere.d.ts.map +1 -1
  207. package/dist/engine/contracts/atmosphere.js.map +1 -1
  208. package/dist/engine/contracts/camera.d.ts +8 -2
  209. package/dist/engine/contracts/camera.d.ts.map +1 -1
  210. package/dist/engine/contracts/camera.js +14 -3
  211. package/dist/engine/contracts/camera.js.map +1 -1
  212. package/dist/engine/contracts/effects.d.ts +83 -37
  213. package/dist/engine/contracts/effects.d.ts.map +1 -1
  214. package/dist/engine/contracts/effects.js +2 -1
  215. package/dist/engine/contracts/effects.js.map +1 -1
  216. package/dist/engine/contracts/flags.d.ts.map +1 -1
  217. package/dist/engine/contracts/flags.js +29 -4
  218. package/dist/engine/contracts/flags.js.map +1 -1
  219. package/dist/engine/contracts/lighting.d.ts +33 -1
  220. package/dist/engine/contracts/lighting.d.ts.map +1 -1
  221. package/dist/engine/contracts/lighting.js +13 -1
  222. package/dist/engine/contracts/lighting.js.map +1 -1
  223. package/dist/engine/contracts/looks.d.ts +57 -1
  224. package/dist/engine/contracts/looks.d.ts.map +1 -1
  225. package/dist/engine/contracts/looks.js.map +1 -1
  226. package/dist/engine/contracts/materials.d.ts +25 -0
  227. package/dist/engine/contracts/materials.d.ts.map +1 -1
  228. package/dist/engine/contracts/materials.js +4 -1
  229. package/dist/engine/contracts/materials.js.map +1 -1
  230. package/dist/engine/contracts/post.d.ts +14 -0
  231. package/dist/engine/contracts/post.d.ts.map +1 -1
  232. package/dist/engine/contracts/post.js +2 -0
  233. package/dist/engine/contracts/post.js.map +1 -1
  234. package/dist/engine/instances-model/CrowdKit.d.ts +231 -0
  235. package/dist/engine/instances-model/CrowdKit.d.ts.map +1 -0
  236. package/dist/engine/instances-model/CrowdKit.js +496 -0
  237. package/dist/engine/instances-model/CrowdKit.js.map +1 -0
  238. package/dist/engine/lanes/prd02.d.ts +36 -2
  239. package/dist/engine/lanes/prd02.d.ts.map +1 -1
  240. package/dist/engine/lanes/prd02.js +120 -7
  241. package/dist/engine/lanes/prd02.js.map +1 -1
  242. package/dist/engine/lanes/prd03.d.ts.map +1 -1
  243. package/dist/engine/lanes/prd03.js +9 -1
  244. package/dist/engine/lanes/prd03.js.map +1 -1
  245. package/dist/engine/lanes/prd07.d.ts.map +1 -1
  246. package/dist/engine/lanes/prd07.js +12 -7
  247. package/dist/engine/lanes/prd07.js.map +1 -1
  248. package/dist/engine/production-runtime/GlbResourceCache.d.ts +140 -0
  249. package/dist/engine/production-runtime/GlbResourceCache.d.ts.map +1 -0
  250. package/dist/engine/production-runtime/GlbResourceCache.js +237 -0
  251. package/dist/engine/production-runtime/GlbResourceCache.js.map +1 -0
  252. package/dist/engine/production-runtime/ModelMaterialOverrides.d.ts +53 -2
  253. package/dist/engine/production-runtime/ModelMaterialOverrides.d.ts.map +1 -1
  254. package/dist/engine/production-runtime/ModelMaterialOverrides.js +142 -1
  255. package/dist/engine/production-runtime/ModelMaterialOverrides.js.map +1 -1
  256. package/dist/engine/production-runtime/TypedGLBActor.d.ts +55 -0
  257. package/dist/engine/production-runtime/TypedGLBActor.d.ts.map +1 -1
  258. package/dist/engine/production-runtime/TypedGLBActor.js +205 -3
  259. package/dist/engine/production-runtime/TypedGLBActor.js.map +1 -1
  260. package/dist/engine/production-runtime/actor/ModelTextureShare.d.ts.map +1 -1
  261. package/dist/engine/production-runtime/actor/ModelTextureShare.js +5 -2
  262. package/dist/engine/production-runtime/actor/ModelTextureShare.js.map +1 -1
  263. package/dist/engine/production-runtime/actor/TypedGLBActorMaterials.d.ts.map +1 -1
  264. package/dist/engine/production-runtime/actor/TypedGLBActorMaterials.js +10 -1
  265. package/dist/engine/production-runtime/actor/TypedGLBActorMaterials.js.map +1 -1
  266. package/dist/engine/production-runtime/effects/EffectNodeLowering.d.ts +55 -0
  267. package/dist/engine/production-runtime/effects/EffectNodeLowering.d.ts.map +1 -1
  268. package/dist/engine/production-runtime/effects/EffectNodeLowering.js +71 -7
  269. package/dist/engine/production-runtime/effects/EffectNodeLowering.js.map +1 -1
  270. package/dist/engine/production-runtime/effects/FlipbookAtlas.d.ts +85 -0
  271. package/dist/engine/production-runtime/effects/FlipbookAtlas.d.ts.map +1 -1
  272. package/dist/engine/production-runtime/effects/FlipbookAtlas.js +164 -0
  273. package/dist/engine/production-runtime/effects/FlipbookAtlas.js.map +1 -1
  274. package/dist/engine/production-runtime/effects/LiveAtmosphere.d.ts +37 -6
  275. package/dist/engine/production-runtime/effects/LiveAtmosphere.d.ts.map +1 -1
  276. package/dist/engine/production-runtime/effects/LiveAtmosphere.js +93 -10
  277. package/dist/engine/production-runtime/effects/LiveAtmosphere.js.map +1 -1
  278. package/dist/engine/production-runtime/effects/ProductionEffectSystem.d.ts +71 -1
  279. package/dist/engine/production-runtime/effects/ProductionEffectSystem.d.ts.map +1 -1
  280. package/dist/engine/production-runtime/effects/ProductionEffectSystem.js +356 -6
  281. package/dist/engine/production-runtime/effects/ProductionEffectSystem.js.map +1 -1
  282. package/dist/engine/production-runtime/world/WaterRuntime.d.ts +9 -0
  283. package/dist/engine/production-runtime/world/WaterRuntime.d.ts.map +1 -1
  284. package/dist/engine/production-runtime/world/WaterRuntime.js +27 -11
  285. package/dist/engine/production-runtime/world/WaterRuntime.js.map +1 -1
  286. package/dist/engine/production-runtime/world/WorldFramePasses.d.ts +11 -1
  287. package/dist/engine/production-runtime/world/WorldFramePasses.d.ts.map +1 -1
  288. package/dist/engine/production-runtime/world/WorldFramePasses.js +37 -1
  289. package/dist/engine/production-runtime/world/WorldFramePasses.js.map +1 -1
  290. package/dist/engine/public/index.d.ts +22 -0
  291. package/dist/engine/public/index.d.ts.map +1 -1
  292. package/dist/engine/public/index.js +14 -0
  293. package/dist/engine/public/index.js.map +1 -1
  294. package/dist/game/art/define.d.ts +1 -1
  295. package/dist/game/art/define.d.ts.map +1 -1
  296. package/dist/game/art/define.js +1 -1
  297. package/dist/game/art/define.js.map +1 -1
  298. package/dist/game/fonts/register.d.ts +16 -1
  299. package/dist/game/fonts/register.d.ts.map +1 -1
  300. package/dist/game/fonts/register.js +18 -7
  301. package/dist/game/fonts/register.js.map +1 -1
  302. package/dist/game/hud/themes.d.ts +33 -8
  303. package/dist/game/hud/themes.d.ts.map +1 -1
  304. package/dist/game/hud/themes.js +125 -22
  305. package/dist/game/hud/themes.js.map +1 -1
  306. package/dist/game/index.d.ts +4 -2
  307. package/dist/game/index.d.ts.map +1 -1
  308. package/dist/game/index.js +2 -1
  309. package/dist/game/index.js.map +1 -1
  310. package/dist/game/juice/audioReactive.d.ts +42 -0
  311. package/dist/game/juice/audioReactive.d.ts.map +1 -0
  312. package/dist/game/juice/audioReactive.js +68 -0
  313. package/dist/game/juice/audioReactive.js.map +1 -0
  314. package/dist/game/styles/themes/arcade-neon.css +2 -1
  315. package/dist/game/styles/themes/fighting.css +2 -1
  316. package/dist/game/styles/themes/ink-scroll.css +15 -0
  317. package/dist/game/styles/themes/motorsport.css +2 -1
  318. package/dist/game/styles/themes/plain.css +2 -1
  319. package/dist/game/styles/themes/sci-fi-telemetry.css +2 -1
  320. package/dist/game/styles/themes/sky-expedition.css +15 -0
  321. package/dist/game/styles/themes/sports-broadcast.css +2 -1
  322. package/dist/game/styles/themes/storybook.css +15 -0
  323. package/dist/game/styles/themes/tabletop.css +2 -1
  324. package/dist/game/styles.css +3 -1
  325. package/dist/rendering/ClusteredForwardLighting.d.ts.map +1 -1
  326. package/dist/rendering/ClusteredForwardLighting.js +3 -1
  327. package/dist/rendering/ClusteredForwardLighting.js.map +1 -1
  328. package/dist/rendering/DepthPass.d.ts +25 -0
  329. package/dist/rendering/DepthPass.d.ts.map +1 -1
  330. package/dist/rendering/DepthPass.js +149 -1
  331. package/dist/rendering/DepthPass.js.map +1 -1
  332. package/dist/rendering/ForwardPass.d.ts +84 -0
  333. package/dist/rendering/ForwardPass.d.ts.map +1 -1
  334. package/dist/rendering/ForwardPass.js +236 -12
  335. package/dist/rendering/ForwardPass.js.map +1 -1
  336. package/dist/rendering/LightUniforms.d.ts +12 -0
  337. package/dist/rendering/LightUniforms.d.ts.map +1 -1
  338. package/dist/rendering/LightUniforms.js +9 -1
  339. package/dist/rendering/LightUniforms.js.map +1 -1
  340. package/dist/rendering/atmosphere/CloudLayer.d.ts +15 -0
  341. package/dist/rendering/atmosphere/CloudLayer.d.ts.map +1 -1
  342. package/dist/rendering/atmosphere/CloudLayer.js +27 -5
  343. package/dist/rendering/atmosphere/CloudLayer.js.map +1 -1
  344. package/dist/rendering/atmosphere/GradientSky.d.ts +3 -3
  345. package/dist/rendering/atmosphere/GradientSky.d.ts.map +1 -1
  346. package/dist/rendering/atmosphere/GradientSky.js +20 -9
  347. package/dist/rendering/atmosphere/GradientSky.js.map +1 -1
  348. package/dist/rendering/atmosphere/HeightFog.d.ts.map +1 -1
  349. package/dist/rendering/atmosphere/HeightFog.js +9 -0
  350. package/dist/rendering/atmosphere/HeightFog.js.map +1 -1
  351. package/dist/rendering/atmosphere/SkyBackgroundPass.d.ts +11 -0
  352. package/dist/rendering/atmosphere/SkyBackgroundPass.d.ts.map +1 -1
  353. package/dist/rendering/atmosphere/SkyBackgroundPass.js +40 -7
  354. package/dist/rendering/atmosphere/SkyBackgroundPass.js.map +1 -1
  355. package/dist/rendering/atmosphere/StarField.d.ts +21 -0
  356. package/dist/rendering/atmosphere/StarField.d.ts.map +1 -1
  357. package/dist/rendering/atmosphere/StarField.js +24 -1
  358. package/dist/rendering/atmosphere/StarField.js.map +1 -1
  359. package/dist/rendering/atmosphere/sky.glsl.d.ts.map +1 -1
  360. package/dist/rendering/atmosphere/sky.glsl.js +8 -0
  361. package/dist/rendering/atmosphere/sky.glsl.js.map +1 -1
  362. package/dist/rendering/contracts/flags.state.d.ts.map +1 -1
  363. package/dist/rendering/contracts/flags.state.js +19 -0
  364. package/dist/rendering/contracts/flags.state.js.map +1 -1
  365. package/dist/rendering/forward/Lighting.d.ts +7 -1
  366. package/dist/rendering/forward/Lighting.d.ts.map +1 -1
  367. package/dist/rendering/forward/Lighting.js +24 -1
  368. package/dist/rendering/forward/Lighting.js.map +1 -1
  369. package/dist/rendering/forward/Velocity.d.ts +8 -0
  370. package/dist/rendering/forward/Velocity.d.ts.map +1 -1
  371. package/dist/rendering/forward/Velocity.js +10 -0
  372. package/dist/rendering/forward/Velocity.js.map +1 -1
  373. package/dist/rendering/lanes/prd03.d.ts +1 -1
  374. package/dist/rendering/lanes/prd03.d.ts.map +1 -1
  375. package/dist/rendering/lanes/prd03.js +6 -1
  376. package/dist/rendering/lanes/prd03.js.map +1 -1
  377. package/dist/rendering/lanes/prd07.d.ts.map +1 -1
  378. package/dist/rendering/lanes/prd07.js +5 -2
  379. package/dist/rendering/lanes/prd07.js.map +1 -1
  380. package/dist/rendering/post/DisplayLutCache.d.ts +10 -2
  381. package/dist/rendering/post/DisplayLutCache.d.ts.map +1 -1
  382. package/dist/rendering/post/DisplayLutCache.js +15 -3
  383. package/dist/rendering/post/DisplayLutCache.js.map +1 -1
  384. package/dist/rendering/post/PostGraph.d.ts +23 -0
  385. package/dist/rendering/post/PostGraph.d.ts.map +1 -1
  386. package/dist/rendering/post/PostGraph.js.map +1 -1
  387. package/dist/rendering/post/PostQualityTiers.d.ts +36 -0
  388. package/dist/rendering/post/PostQualityTiers.d.ts.map +1 -1
  389. package/dist/rendering/post/PostQualityTiers.js +75 -0
  390. package/dist/rendering/post/PostQualityTiers.js.map +1 -1
  391. package/dist/rendering/post/chunks/velocity.glsl.d.ts +7 -0
  392. package/dist/rendering/post/chunks/velocity.glsl.d.ts.map +1 -1
  393. package/dist/rendering/post/chunks/velocity.glsl.js +12 -1
  394. package/dist/rendering/post/chunks/velocity.glsl.js.map +1 -1
  395. package/dist/rendering/post/shaders/displayGrade.glsl.d.ts +15 -1
  396. package/dist/rendering/post/shaders/displayGrade.glsl.d.ts.map +1 -1
  397. package/dist/rendering/post/shaders/displayGrade.glsl.js +26 -2
  398. package/dist/rendering/post/shaders/displayGrade.glsl.js.map +1 -1
  399. package/dist/rendering/post/shaders/dof.glsl.d.ts +11 -1
  400. package/dist/rendering/post/shaders/dof.glsl.d.ts.map +1 -1
  401. package/dist/rendering/post/shaders/dof.glsl.js +22 -0
  402. package/dist/rendering/post/shaders/dof.glsl.js.map +1 -1
  403. package/dist/rendering/post/shaders/finalize.glsl.d.ts +1 -1
  404. package/dist/rendering/post/shaders/finalize.glsl.d.ts.map +1 -1
  405. package/dist/rendering/post/shaders/finalize.glsl.js +3 -2
  406. package/dist/rendering/post/shaders/finalize.glsl.js.map +1 -1
  407. package/dist/rendering/post/shaders/godrays.glsl.d.ts +24 -1
  408. package/dist/rendering/post/shaders/godrays.glsl.d.ts.map +1 -1
  409. package/dist/rendering/post/shaders/godrays.glsl.js +45 -5
  410. package/dist/rendering/post/shaders/godrays.glsl.js.map +1 -1
  411. package/dist/rendering/post/shaders/hdrGrade.glsl.d.ts +66 -0
  412. package/dist/rendering/post/shaders/hdrGrade.glsl.d.ts.map +1 -0
  413. package/dist/rendering/post/shaders/hdrGrade.glsl.js +159 -0
  414. package/dist/rendering/post/shaders/hdrGrade.glsl.js.map +1 -0
  415. package/dist/rendering/post/shaders/ssr.glsl.d.ts +39 -0
  416. package/dist/rendering/post/shaders/ssr.glsl.d.ts.map +1 -0
  417. package/dist/rendering/post/shaders/ssr.glsl.js +163 -0
  418. package/dist/rendering/post/shaders/ssr.glsl.js.map +1 -0
  419. package/dist/rendering/post/v2Stages.d.ts +53 -0
  420. package/dist/rendering/post/v2Stages.d.ts.map +1 -1
  421. package/dist/rendering/post/v2Stages.js +314 -23
  422. package/dist/rendering/post/v2Stages.js.map +1 -1
  423. package/dist/rendering/postprocess/NativeBloomPyramid.d.ts +19 -0
  424. package/dist/rendering/postprocess/NativeBloomPyramid.d.ts.map +1 -1
  425. package/dist/rendering/postprocess/NativeBloomPyramid.js +37 -0
  426. package/dist/rendering/postprocess/NativeBloomPyramid.js.map +1 -1
  427. package/dist/rendering/program/ProgramGenerator.d.ts.map +1 -1
  428. package/dist/rendering/program/ProgramGenerator.js +12 -1
  429. package/dist/rendering/program/ProgramGenerator.js.map +1 -1
  430. package/dist/rendering/program/chunks/shadow_forward.glsl.d.ts +12 -0
  431. package/dist/rendering/program/chunks/shadow_forward.glsl.d.ts.map +1 -1
  432. package/dist/rendering/program/chunks/shadow_forward.glsl.js +57 -0
  433. package/dist/rendering/program/chunks/shadow_forward.glsl.js.map +1 -1
  434. package/dist/rendering/renderer/Background.d.ts.map +1 -1
  435. package/dist/rendering/renderer/Background.js +26 -2
  436. package/dist/rendering/renderer/Background.js.map +1 -1
  437. package/dist/rendering/renderer/FrameGraph.d.ts +8 -0
  438. package/dist/rendering/renderer/FrameGraph.d.ts.map +1 -1
  439. package/dist/rendering/renderer/FrameGraph.js +46 -7
  440. package/dist/rendering/renderer/FrameGraph.js.map +1 -1
  441. package/dist/rendering/renderer/OutlineTargets.d.ts +99 -0
  442. package/dist/rendering/renderer/OutlineTargets.d.ts.map +1 -0
  443. package/dist/rendering/renderer/OutlineTargets.js +286 -0
  444. package/dist/rendering/renderer/OutlineTargets.js.map +1 -0
  445. package/dist/rendering/renderer/PostprocessExecution.d.ts +5 -0
  446. package/dist/rendering/renderer/PostprocessExecution.d.ts.map +1 -1
  447. package/dist/rendering/renderer/PostprocessExecution.js +70 -4
  448. package/dist/rendering/renderer/PostprocessExecution.js.map +1 -1
  449. package/dist/rendering/renderer/postSkipped.d.ts +6 -0
  450. package/dist/rendering/renderer/postSkipped.d.ts.map +1 -1
  451. package/dist/rendering/renderer/postSkipped.js +8 -0
  452. package/dist/rendering/renderer/postSkipped.js.map +1 -1
  453. package/dist/rendering/shaders/chunks/author/ibl.glsl.d.ts +20 -0
  454. package/dist/rendering/shaders/chunks/author/ibl.glsl.d.ts.map +1 -0
  455. package/dist/rendering/shaders/chunks/author/ibl.glsl.js +84 -0
  456. package/dist/rendering/shaders/chunks/author/ibl.glsl.js.map +1 -0
  457. package/dist/rendering/shaders/chunks/author/index.d.ts +3 -1
  458. package/dist/rendering/shaders/chunks/author/index.d.ts.map +1 -1
  459. package/dist/rendering/shaders/chunks/author/index.js +38 -3
  460. package/dist/rendering/shaders/chunks/author/index.js.map +1 -1
  461. package/dist/rendering/shaders/chunks/author/lights.glsl.d.ts +16 -0
  462. package/dist/rendering/shaders/chunks/author/lights.glsl.d.ts.map +1 -0
  463. package/dist/rendering/shaders/chunks/author/lights.glsl.js +112 -0
  464. package/dist/rendering/shaders/chunks/author/lights.glsl.js.map +1 -0
  465. package/dist/rendering/shaders/chunks/author/shadow.glsl.d.ts +16 -2
  466. package/dist/rendering/shaders/chunks/author/shadow.glsl.d.ts.map +1 -1
  467. package/dist/rendering/shaders/chunks/author/shadow.glsl.js +46 -2
  468. package/dist/rendering/shaders/chunks/author/shadow.glsl.js.map +1 -1
  469. package/dist/rendering/shaders/chunks/instance_color_target.glsl.d.ts +34 -0
  470. package/dist/rendering/shaders/chunks/instance_color_target.glsl.d.ts.map +1 -0
  471. package/dist/rendering/shaders/chunks/instance_color_target.glsl.js +101 -0
  472. package/dist/rendering/shaders/chunks/instance_color_target.glsl.js.map +1 -0
  473. package/dist/rendering/shaders/chunks/rim.glsl.d.ts +37 -0
  474. package/dist/rendering/shaders/chunks/rim.glsl.d.ts.map +1 -0
  475. package/dist/rendering/shaders/chunks/rim.glsl.js +50 -0
  476. package/dist/rendering/shaders/chunks/rim.glsl.js.map +1 -0
  477. package/dist/rendering/shadows/Prd02ShadowBridge.d.ts +26 -3
  478. package/dist/rendering/shadows/Prd02ShadowBridge.d.ts.map +1 -1
  479. package/dist/rendering/shadows/Prd02ShadowBridge.js +134 -8
  480. package/dist/rendering/shadows/Prd02ShadowBridge.js.map +1 -1
  481. package/dist/rendering/shadows/Prd02ShadowsContributor.d.ts.map +1 -1
  482. package/dist/rendering/shadows/Prd02ShadowsContributor.js +4 -16
  483. package/dist/rendering/shadows/Prd02ShadowsContributor.js.map +1 -1
  484. package/dist/rendering/vfx/VfxAtlas.d.ts +10 -0
  485. package/dist/rendering/vfx/VfxAtlas.d.ts.map +1 -1
  486. package/dist/rendering/vfx/VfxAtlas.js +18 -3
  487. package/dist/rendering/vfx/VfxAtlas.js.map +1 -1
  488. package/dist/rendering/webgl2/LegacyPost.d.ts +9 -1
  489. package/dist/rendering/webgl2/LegacyPost.d.ts.map +1 -1
  490. package/dist/rendering/webgl2/LegacyPost.js +23 -7
  491. package/dist/rendering/webgl2/LegacyPost.js.map +1 -1
  492. package/dist/rendering/webgl2/MultiDraw.d.ts.map +1 -1
  493. package/dist/rendering/webgl2/MultiDraw.js +51 -1
  494. package/dist/rendering/webgl2/MultiDraw.js.map +1 -1
  495. package/dist/rendering/world/vegetation/WindField.d.ts.map +1 -1
  496. package/dist/rendering/world/vegetation/WindField.js +4 -1
  497. package/dist/rendering/world/vegetation/WindField.js.map +1 -1
  498. package/dist/rendering/world/water/ReflectionViewPass.d.ts.map +1 -1
  499. package/dist/rendering/world/water/ReflectionViewPass.js +12 -2
  500. package/dist/rendering/world/water/ReflectionViewPass.js.map +1 -1
  501. package/dist/rendering/world/water/SceneCopyFallback.d.ts.map +1 -1
  502. package/dist/rendering/world/water/SceneCopyFallback.js +9 -2
  503. package/dist/rendering/world/water/SceneCopyFallback.js.map +1 -1
  504. package/dist/rendering/world/water/WaterMaterial.d.ts.map +1 -1
  505. package/dist/rendering/world/water/WaterMaterial.js +8 -2
  506. package/dist/rendering/world/water/WaterMaterial.js.map +1 -1
  507. package/package.json +25 -25
  508. package/templates/cinematic-scene/package.json +2 -2
  509. package/templates/mini-game/package.json +2 -2
  510. package/templates/product-viewer/package.json +2 -2
  511. package/templates/production-asset-inspector/package.json +1 -1
  512. package/templates/production-material-studio/package.json +1 -1
  513. package/templates/production-product-configurator/package.json +1 -1
  514. package/templates/production-product-viewer/package.json +1 -1
@@ -7,7 +7,7 @@ import { Texture } from "../../../rendering/index.js";
7
7
  import { QUALITY_TIERS } from "../../../rendering/contracts/index.js";
8
8
  import { MeshParticleBatch, RibbonBatch, RibbonTrail, DecalBatch, DECAL_TIER_CAP, decalQuadGeometry, ribbonStripToDecalGeometry, PARTICLE_GPU_BUDGET_MS, ProceduralVolumeEmitter } from "../../../rendering/index.js";
9
9
  import { createEmitter, stepEmitter, writeEmitterInstances } from "./CpuEmitter.js";
10
- import { proceduralFireballSheet } from "./FlipbookAtlas.js";
10
+ import { proceduralFireballSheet, VfxSpriteTextures, vfxSpriteFrame, vfxSpritePageSize } from "./FlipbookAtlas.js";
11
11
  import { lowerEffectNode, srgbChannelToLinear } from "./EffectNodeLowering.js";
12
12
  import { EffectDiagnostics } from "./EffectDiagnostics.js";
13
13
  import { LiveAtmosphere } from "./LiveAtmosphere.js";
@@ -32,6 +32,47 @@ function flipbookTexture(fb) {
32
32
  }
33
33
  return texture;
34
34
  }
35
+ /**
36
+ * GU47 E-F: overwrite the instance `frame` slot (float 13 of the §6.2.1 layout) of every live particle with
37
+ * its sprite frame. `writeEmitterInstances` packs particle i at `i * 16`, so `state.age[i]` / `state.life[i]`
38
+ * line up; rotation and the life fade stay as the emitter wrote them.
39
+ */
40
+ export function writeSpriteFrames(state, out, live, sprite) {
41
+ const fixed = sprite.kind === "texture" ? { frames: sprite.frames, frame: sprite.frame } : sprite;
42
+ for (let i = 0; i < live; i++)
43
+ out[i * 16 + 13] = vfxSpriteFrame(fixed, state.age[i], state.life[i]);
44
+ }
45
+ /** GU47 E-F: a ribbon that samples its target every frame and drops points older than `life`. */
46
+ /** Linear blend of two RGBA colours (`t` 0: `a`, 1: `b`). */
47
+ function mixColor4(a, b, t) {
48
+ return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t, a[3] + (b[3] - a[3]) * t];
49
+ }
50
+ /** GU47 E-F: follow state of a scene `effects.trail({ target })` node (ring of maxPoints, optional life fade). */
51
+ function sceneTrailFollow(node, color) {
52
+ const ramp = node.widthOverSpeed;
53
+ return {
54
+ target: node.target,
55
+ life: typeof node.life === "number" && node.life > 0 ? node.life : Number.POSITIVE_INFINITY,
56
+ width: typeof node.width === "number" && node.width > 0 ? node.width : 0.3,
57
+ color,
58
+ ...(ramp && ramp.length >= 2 && Number.isFinite(ramp[0]) && Number.isFinite(ramp[1]) ? { widthOverSpeed: [ramp[0], ramp[1]] } : {}),
59
+ maxPoints: Math.max(2, Math.round(node.maxPoints ?? 48)),
60
+ minVertexDistance: typeof node.minVertexDistance === "number" && node.minVertexDistance >= 0 ? node.minVertexDistance : 0.05,
61
+ points: [],
62
+ following: true,
63
+ last: null,
64
+ missingNoted: false
65
+ };
66
+ }
67
+ /** Width multiplier for a point sampled at `speed` m/s under `widthOverSpeed` [min, max]. */
68
+ export function trailWidthScale(speed, ramp) {
69
+ if (!ramp)
70
+ return 1;
71
+ const [lo, hi] = ramp;
72
+ if (!(hi > lo))
73
+ return speed >= lo ? 1 : 0;
74
+ return Math.min(1, Math.max(0, (speed - lo) / (hi - lo)));
75
+ }
35
76
  function hexToRgb(c) {
36
77
  if (c.startsWith("#") && c.length === 7) {
37
78
  return [parseInt(c.slice(1, 3), 16) / 255, parseInt(c.slice(3, 5), 16) / 255, parseInt(c.slice(5, 7), 16) / 255];
@@ -255,11 +296,17 @@ export class ProductionEffectSystem {
255
296
  renderBridged = false;
256
297
  /** A renderer frame pulled the render source since the last endFrame. */
257
298
  renderSincePrevFrame = false;
299
+ /** GU47 E-F: atlas-sprite and texture-sheet textures, loaded on first use (1k page on low/medium tiers). */
300
+ sprites;
301
+ /** GU47 E-F: emitters that follow a runtime node (`attachTo`), keyed by emitter id. */
302
+ attachments = new Map();
303
+ socketScratch = new Float32Array(16);
258
304
  constructor(app, options = {}) {
259
305
  this.app = app;
260
306
  // Resolved C-27 tier wins over the explicit option's fallback: callers pass
261
307
  // app.quality.tier; "high" remains only as the unresolved default.
262
308
  this.tier = options.tier ?? app.quality?.tier ?? "high";
309
+ this.sprites = new VfxSpriteTextures(options.spriteLoader, vfxSpritePageSize(this.tier), (key, message) => this.diagnostics.note("VFX_SPRITE_UNAVAILABLE", key, `sprite texture ${key} failed to load (${message}); the batch keeps the soft-dot`), options.spritePageUrl);
263
310
  this.decals = new DecalBatch(DECAL_TIER_CAP[this.tier]);
264
311
  this.budgetCap = QUALITY_TIERS[this.tier].particleBudget;
265
312
  this.transientLights = new TransientLightPool(this.tier);
@@ -276,6 +323,9 @@ export class ProductionEffectSystem {
276
323
  return { id, age: Number((this.time - record.born).toFixed(2)), live: binding?.state.live ?? 0, emissionRate: binding?.state.desc.emissionRate ?? 0 };
277
324
  }),
278
325
  scene: [...this.emitters.keys()].filter((id) => !this.transients.has(id)),
326
+ // GU47 E-F: sprite texture load state and live trails (receipts vfx-atlas-sprites, vfx-trail).
327
+ sprites: this.spriteStatus(),
328
+ trails: [...this.trails.keys()].map((id) => ({ id, ...(this.trailInfo(id) ?? { length: 0, pointCount: 0 }) })),
279
329
  notes: this.diagnostics.report().errors
280
330
  });
281
331
  }
@@ -411,7 +461,7 @@ export class ProductionEffectSystem {
411
461
  this.walkNodes((node, visible) => {
412
462
  if (!visible || node.kind !== "effect")
413
463
  return;
414
- const lowered = lowerEffectNode(node);
464
+ const lowered = lowerEffectNode(this.placeAttached(node));
415
465
  this.diagnostics.track({
416
466
  nodeId: lowered.nodeId,
417
467
  effect: lowered.effect,
@@ -422,6 +472,7 @@ export class ProductionEffectSystem {
422
472
  });
423
473
  if (lowered.type === "emitter") {
424
474
  this.attachEmitter(lowered);
475
+ this.trackAttachment(lowered.nodeId, node);
425
476
  }
426
477
  else if (lowered.type === "volume") {
427
478
  this.attachVolume(lowered);
@@ -462,7 +513,12 @@ export class ProductionEffectSystem {
462
513
  const step = points.length > 1 ? 0.02 : 0;
463
514
  points.forEach((p, i) => trail.push([p[0] ?? 0, p[1] ?? 0, p[2] ?? 0], i * step));
464
515
  }
465
- this.trails.set(lowered.nodeId, { trail, node });
516
+ // GU47 E-F: a scene trail with a `target` (and no static `path`) follows that runtime node every frame;
517
+ // `life` fades and drops old points (absent: a ring of maxPoints). Follow state survives scene rebuilds.
518
+ const follow = node.target !== undefined && !Array.isArray(node.path)
519
+ ? this.trails.get(lowered.nodeId)?.follow ?? sceneTrailFollow(node, color)
520
+ : undefined;
521
+ this.trails.set(lowered.nodeId, { trail, node, ...(follow ? { follow } : {}) });
466
522
  }
467
523
  else if (lowered.consumer === "mesh-pass") {
468
524
  this.meshBatches.set(lowered.nodeId, seedMeshBatch(node));
@@ -578,8 +634,152 @@ export class ProductionEffectSystem {
578
634
  const binding = this.trails.get(nodeId);
579
635
  if (!binding)
580
636
  return false;
637
+ if (binding.follow) {
638
+ this.sampleTrail(binding.follow, position);
639
+ return true;
640
+ }
581
641
  return binding.trail.push(position, this.time, width, color);
582
642
  }
643
+ /**
644
+ * GU47 E-F `app.effects.trail`: a camera-facing ribbon on the RibbonBatch that follows `target` (runtime node
645
+ * id, `{ node, socket }` or a node handle; undefined: points come from `trailPush`). Points older than `life`
646
+ * seconds drop off, so the ribbon is as long as the distance the target covered in `life`. The head is
647
+ * opaque and the tail fades; `widthOverSpeed` ramps the width by the target's speed.
648
+ */
649
+ addTrail(id, target, options) {
650
+ const life = Number.isFinite(options.life) && options.life > 0 ? options.life : 0.5;
651
+ const width = Number.isFinite(options.width) && options.width > 0 ? options.width : 0.3;
652
+ // One point per frame at up to 120 Hz over the life, capped per tier.
653
+ const cap = this.tier === "low" ? 120 : 360;
654
+ const maxPoints = Math.max(8, Math.min(cap, Math.ceil(life * 120) + 2));
655
+ const minVertexDistance = options.minVertexDistance !== undefined && options.minVertexDistance >= 0 ? options.minVertexDistance : 0.05;
656
+ const color = effectColor4({ kind: "effect", color: options.color });
657
+ const trail = this.ribbons.upsertTrail({ id, maxPoints, minVertexDistance, width, color, orientation: "camera" });
658
+ const ramp = options.widthOverSpeed;
659
+ const follow = {
660
+ target,
661
+ life,
662
+ width,
663
+ color,
664
+ ...(options.colorTail !== undefined ? { colorTail: effectColor4({ kind: "effect", color: options.colorTail }) } : {}),
665
+ ...(ramp && ramp.length >= 2 && Number.isFinite(ramp[0]) && Number.isFinite(ramp[1]) ? { widthOverSpeed: [ramp[0], ramp[1]] } : {}),
666
+ maxPoints,
667
+ minVertexDistance,
668
+ points: [],
669
+ following: true,
670
+ last: null,
671
+ missingNoted: false
672
+ };
673
+ this.trails.set(id, { trail, node: { kind: "effect", effect: "trail", id }, follow, runtime: true });
674
+ if (target !== undefined) {
675
+ const at = this.resolveTarget(target);
676
+ if (at)
677
+ this.sampleTrail(follow, at);
678
+ }
679
+ return id;
680
+ }
681
+ /** GU47 E-F: live length (metres along the points) and point count of a trail, or null once it is gone. */
682
+ trailInfo(id) {
683
+ const binding = this.trails.get(id);
684
+ if (!binding)
685
+ return null;
686
+ const points = binding.follow ? binding.follow.points.map((p) => p.position) : binding.trail.getPoints().map((p) => p.position);
687
+ let length = 0;
688
+ for (let i = 1; i < points.length; i++) {
689
+ length += Math.hypot(points[i][0] - points[i - 1][0], points[i][1] - points[i - 1][1], points[i][2] - points[i - 1][2]);
690
+ }
691
+ return { length, pointCount: points.length };
692
+ }
693
+ /** GU47 pass 4: shift every live point (and the speed reference) of a trail by `offset` metres. */
694
+ translateTrail(id, offset) {
695
+ const follow = this.trails.get(id)?.follow;
696
+ const [dx, dy, dz] = offset;
697
+ if (!follow || !Number.isFinite(dx) || !Number.isFinite(dy) || !Number.isFinite(dz) || (dx === 0 && dy === 0 && dz === 0))
698
+ return;
699
+ const shift = (p) => [p[0] + dx, p[1] + dy, p[2] + dz];
700
+ for (const point of follow.points)
701
+ point.position = shift(point.position);
702
+ if (follow.last)
703
+ follow.last = { position: shift(follow.last.position), time: follow.last.time };
704
+ }
705
+ /** GU47 E-F: drop every point of a trail (it restarts from the target's next position). */
706
+ clearTrail(id) {
707
+ const binding = this.trails.get(id);
708
+ if (!binding)
709
+ return;
710
+ if (binding.follow) {
711
+ binding.follow.points.length = 0;
712
+ binding.follow.last = null;
713
+ }
714
+ binding.trail.clear();
715
+ }
716
+ /** GU47 E-F: stop following; `immediate` removes the ribbon now, otherwise it fades out over `life`. */
717
+ stopTrail(id, immediate = false) {
718
+ const binding = this.trails.get(id);
719
+ if (!binding)
720
+ return;
721
+ if (immediate || !binding.follow || !Number.isFinite(binding.follow.life)) {
722
+ binding.trail.clear();
723
+ this.ribbons.removeTrail(id);
724
+ this.trails.delete(id);
725
+ return;
726
+ }
727
+ binding.follow.following = false;
728
+ }
729
+ /** Append the target's position when it moved at least `minVertexDistance` since the last point. */
730
+ sampleTrail(follow, position) {
731
+ const p = [position[0], position[1], position[2]];
732
+ const last = follow.last;
733
+ const elapsed = last ? this.time - last.time : 0;
734
+ const speed = last && elapsed > 1e-6 ? Math.hypot(p[0] - last.position[0], p[1] - last.position[1], p[2] - last.position[2]) / elapsed : 0;
735
+ if (!last || elapsed > 1e-6 || follow.points.length === 0)
736
+ follow.last = { position: p, time: this.time };
737
+ const head = follow.points[follow.points.length - 1];
738
+ if (!head || Math.hypot(p[0] - head.position[0], p[1] - head.position[1], p[2] - head.position[2]) >= follow.minVertexDistance) {
739
+ follow.points.push({ position: p, time: this.time, speed });
740
+ while (follow.points.length > follow.maxPoints)
741
+ follow.points.shift();
742
+ }
743
+ }
744
+ /** GU47 E-F: sample every following trail, expire old points and rebuild the ribbon rings (head first). */
745
+ stepTrails() {
746
+ for (const [id, binding] of this.trails) {
747
+ const follow = binding.follow;
748
+ if (!follow)
749
+ continue;
750
+ if (follow.following && follow.target !== undefined) {
751
+ const at = this.resolveTarget(follow.target);
752
+ if (at)
753
+ this.sampleTrail(follow, at);
754
+ else if (!follow.missingNoted) {
755
+ follow.missingNoted = true;
756
+ this.diagnostics.note("VFX_ATTACH_TARGET_MISSING", id, "trail target does not resolve to a runtime node; the ribbon stops growing");
757
+ }
758
+ }
759
+ if (Number.isFinite(follow.life)) {
760
+ const cutoff = this.time - follow.life;
761
+ let drop = 0;
762
+ while (drop < follow.points.length && follow.points[drop].time < cutoff)
763
+ drop++;
764
+ if (drop > 0)
765
+ follow.points.splice(0, drop);
766
+ }
767
+ if (!follow.following && follow.points.length === 0) {
768
+ binding.trail.clear();
769
+ this.ribbons.removeTrail(id);
770
+ this.trails.delete(id);
771
+ continue;
772
+ }
773
+ binding.trail.clear();
774
+ // Newest first: the batch alpha curve 0.45·(1 − i/maxPoints) then peaks at the target and fades to the tail.
775
+ for (let i = follow.points.length - 1; i >= 0; i--) {
776
+ const point = follow.points[i];
777
+ const fade = Number.isFinite(follow.life) ? Math.max(0, 1 - (this.time - point.time) / follow.life) : 1;
778
+ const c = follow.colorTail ? mixColor4(follow.color, follow.colorTail, 1 - fade) : follow.color;
779
+ binding.trail.push(point.position, point.time, follow.width * trailWidthScale(point.speed, follow.widthOverSpeed), [c[0], c[1], c[2], c[3] * fade]);
780
+ }
781
+ }
782
+ }
583
783
  attachEmitter(lowered) {
584
784
  const state = createEmitter(lowered.emitter);
585
785
  const binding = {
@@ -603,15 +803,116 @@ export class ProductionEffectSystem {
603
803
  /** App-level switch for runtime-spawned effects (effects.burst/spawn, game effects, impact presets). The URL's `?vfx=on|off` overrides it. */
604
804
  setRuntimeEffects(mode) {
605
805
  this.runtimeEffectsApp = mode === "off" ? "off" : "on";
806
+ // GU47 E-F (floating dots): "off" drops the runtime particles that are already running too. Before, only new
807
+ // spawns were refused, so a continuous emitter started before the switch kept emitting at its spot for good.
808
+ if (this.runtimeEffects === "off")
809
+ this.clearRuntimeParticles();
810
+ }
811
+ /** GU47 E-F: remove every runtime-spawned emitter and runtime trail now (scene effects and decals stay). */
812
+ clearRuntimeParticles() {
813
+ for (const id of [...this.transients.keys()])
814
+ this.removeInstance(id);
815
+ for (const [id, binding] of [...this.trails]) {
816
+ if (binding.runtime)
817
+ this.stopTrail(id, true);
818
+ }
819
+ }
820
+ /** GU47 E-F: true while a runtime instance still has an emitter (spent one-shots are retired at once). */
821
+ instanceAlive(id) {
822
+ return this.emitters.has(id) || this.trails.has(id) || this.decalNodes.has(id);
823
+ }
824
+ /** Drop a spent runtime emitter: its batch leaves the particle pass on the next feed. */
825
+ retireEmitter(id) {
826
+ this.emitters.delete(id);
827
+ this.transients.delete(id);
828
+ this.attachments.delete(id);
829
+ this.diagnostics.untrack(id);
606
830
  }
607
831
  get runtimeEffects() {
608
832
  return this.runtimeEffectsUrl ?? this.runtimeEffectsApp;
609
833
  }
834
+ /**
835
+ * GU47 E-F: world position of an attach target: a runtime node id, `{ node, socket }` (the actor's bone
836
+ * socket when it resolves, else the node), or a node handle. Null when nothing resolves.
837
+ */
838
+ resolveTarget(target) {
839
+ let handle;
840
+ let socket;
841
+ if (typeof target === "string") {
842
+ handle = this.app.nodes?.get(target);
843
+ }
844
+ else if (typeof target === "object" && target !== null) {
845
+ const ref = target;
846
+ if (typeof ref.node === "string") {
847
+ handle = this.app.nodes?.get(ref.node);
848
+ socket = typeof ref.socket === "string" ? ref.socket : undefined;
849
+ }
850
+ else {
851
+ handle = target;
852
+ }
853
+ }
854
+ if (!handle)
855
+ return null;
856
+ if (socket !== undefined) {
857
+ const bone = handle.animation?.socket?.(socket);
858
+ if (bone?.valid) {
859
+ const m = bone.worldMatrix(this.socketScratch);
860
+ if (Number.isFinite(m[12]) && Number.isFinite(m[13]) && Number.isFinite(m[14]))
861
+ return [m[12], m[13], m[14]];
862
+ }
863
+ }
864
+ const p = typeof handle.getWorldPosition === "function" ? handle.getWorldPosition() : handle.position;
865
+ if (!p || p.length < 3 || !Number.isFinite(p[0]) || !Number.isFinite(p[1]) || !Number.isFinite(p[2]))
866
+ return null;
867
+ return [p[0], p[1], p[2]];
868
+ }
869
+ /** GU47 E-F: an `attachTo` node starts at its target (plus its `position` offset); others pass unchanged. */
870
+ placeAttached(node) {
871
+ if (node.attachTo === undefined)
872
+ return node;
873
+ const at = this.resolveTarget(node.attachTo);
874
+ if (!at)
875
+ return node;
876
+ const offset = node.position ?? [0, 0, 0];
877
+ return { ...node, position: [at[0] + offset[0], at[1] + offset[1], at[2] + offset[2]] };
878
+ }
879
+ trackAttachment(emitterId, node) {
880
+ if (node.attachTo === undefined) {
881
+ this.attachments.delete(emitterId);
882
+ return;
883
+ }
884
+ const offset = node.position ?? [0, 0, 0];
885
+ this.attachments.set(emitterId, { target: node.attachTo, offset: [offset[0], offset[1], offset[2]], missingNoted: false });
886
+ }
887
+ /** GU47 E-F: move every attached emitter's origin to its target before the sim step spawns. */
888
+ updateAttachments() {
889
+ for (const [emitterId, attachment] of this.attachments) {
890
+ const binding = this.emitters.get(emitterId);
891
+ if (!binding) {
892
+ this.attachments.delete(emitterId);
893
+ continue;
894
+ }
895
+ const at = this.resolveTarget(attachment.target);
896
+ if (!at) {
897
+ if (!attachment.missingNoted) {
898
+ attachment.missingNoted = true;
899
+ this.diagnostics.note("VFX_ATTACH_TARGET_MISSING", emitterId, "attachTo target does not resolve to a runtime node; the emitter keeps its last position");
900
+ }
901
+ continue;
902
+ }
903
+ const x = at[0] + attachment.offset[0];
904
+ const y = at[1] + attachment.offset[1];
905
+ const z = at[2] + attachment.offset[2];
906
+ const origin = binding.state.desc.origin;
907
+ if (origin[0] !== x || origin[1] !== y || origin[2] !== z)
908
+ binding.state.desc = { ...binding.state.desc, origin: [x, y, z] };
909
+ }
910
+ }
610
911
  /** Add a transient effect-instance emitter (effects.burst/spawn). */
611
912
  addInstance(nodeId, node) {
612
913
  if (this.runtimeEffects === "off")
613
914
  return nodeId;
614
- const lowered = lowerEffectNode(node);
915
+ const lowered = lowerEffectNode(this.placeAttached(node));
615
916
  this.diagnostics.track({
616
917
  nodeId,
617
918
  effect: lowered.effect,
@@ -622,6 +923,7 @@ export class ProductionEffectSystem {
622
923
  });
623
924
  if (lowered.type === "emitter") {
624
925
  this.attachEmitter({ ...lowered, nodeId });
926
+ this.trackAttachment(nodeId, node);
625
927
  this.transients.set(nodeId, { born: this.time, warned: false });
626
928
  this.lastTransientAt = this.time;
627
929
  }
@@ -636,6 +938,8 @@ export class ProductionEffectSystem {
636
938
  setInstanceOrigin(nodeId, origin) {
637
939
  const binding = this.emitters.get(nodeId);
638
940
  if (binding) {
941
+ // An explicit position wins over `attachTo`: the emitter stops following its node.
942
+ this.attachments.delete(nodeId);
639
943
  binding.state.desc = { ...binding.state.desc, origin: [origin[0] ?? 0, origin[1] ?? 0, origin[2] ?? 0] };
640
944
  return;
641
945
  }
@@ -645,6 +949,7 @@ export class ProductionEffectSystem {
645
949
  }
646
950
  removeInstance(nodeId) {
647
951
  this.transients.delete(nodeId);
952
+ this.attachments.delete(nodeId);
648
953
  const binding = this.emitters.get(nodeId);
649
954
  if (!binding) {
650
955
  this.volumes.delete(nodeId);
@@ -696,6 +1001,10 @@ export class ProductionEffectSystem {
696
1001
  // capped at 30 s of simulation per frame like createEmitter's prewarm.
697
1002
  const substeps = dt > 0 ? Math.min(Math.ceil(dt * 60 - 1e-6), 1800) : 0;
698
1003
  const h = substeps > 0 ? dt / substeps : 0;
1004
+ if (this.attachments.size > 0)
1005
+ this.updateAttachments();
1006
+ if (this.trails.size > 0)
1007
+ this.stepTrails();
699
1008
  for (const binding of this.emitters.values()) {
700
1009
  for (let s = 0; s < substeps; s++)
701
1010
  stepEmitter(binding.state, h);
@@ -759,6 +1068,12 @@ export class ProductionEffectSystem {
759
1068
  this.transients.delete(id);
760
1069
  continue;
761
1070
  }
1071
+ // GU47 E-F: a one-shot whose particles are all gone is retired now instead of idling in the system (and in
1072
+ // the frame's batch list) until the 96-slot instance pool recycles it.
1073
+ if (binding.state.live === 0 && binding.state.desc.emissionRate <= 0) {
1074
+ this.retireEmitter(id);
1075
+ continue;
1076
+ }
762
1077
  live += binding.state.live;
763
1078
  const age = this.time - record.born;
764
1079
  if (!record.warned && age > UNSTOPPED_EMITTER_SECONDS && binding.state.desc.emissionRate > 0 && binding.state.live > 0) {
@@ -812,6 +1127,9 @@ export class ProductionEffectSystem {
812
1127
  const groups = new Map();
813
1128
  for (const binding of this.emitters.values()) {
814
1129
  const live = writeEmitterInstances(binding.state, binding.scratch);
1130
+ // Flipbooks keep the frame the emitter wrote (age · frameRate); other sprite emitters get theirs here.
1131
+ if (binding.lowered.sprite && !binding.lowered.emitter.flipbook)
1132
+ writeSpriteFrames(binding.state, binding.scratch, live, binding.lowered.sprite);
815
1133
  this.frameLive.set(binding.lowered.nodeId, live);
816
1134
  const key = binding.lowered.emitter.key;
817
1135
  let group = groups.get(key);
@@ -824,12 +1142,20 @@ export class ProductionEffectSystem {
824
1142
  seenKeys.add(key);
825
1143
  const totalLive = group.parts.reduce((s, p) => s + p.live, 0);
826
1144
  const flipbook = group.first.lowered.emitter.flipbook;
1145
+ const sprite = group.first.lowered.sprite;
1146
+ // GU47 E-F: atlas sprites sample their sequence once it has loaded; until then (or after a failed load)
1147
+ // the batch draws the analytic soft-dot exactly as before.
1148
+ // A flipbook with a `texture` or built-in `sprite` samples that sheet instead of the procedural fireball.
1149
+ const spriteTexture = sprite ? this.spriteTexture(sprite) : null;
827
1150
  const desc = {
828
1151
  key,
829
1152
  capacity: group.parts.reduce((s, p) => s + p.binding.lowered.emitter.capacity, 0),
830
1153
  source: "cpu",
831
- atlas: flipbook ? flipbookTexture(flipbook) : softDotTexture(),
832
- ...(flipbook ? { atlasGrid: [flipbook.columns ?? 1, flipbook.rows ?? 1], atlasStraightAlpha: true } : {}),
1154
+ atlas: flipbook && !sprite ? flipbookTexture(flipbook) : spriteTexture ?? softDotTexture(),
1155
+ ...(flipbook && !sprite ? { atlasGrid: [flipbook.columns ?? 1, flipbook.rows ?? 1], atlasStraightAlpha: true } : {}),
1156
+ ...(sprite && spriteTexture
1157
+ ? { atlasGrid: [sprite.columns, sprite.rows], ...(sprite.kind === "texture" ? { atlasStraightAlpha: true } : {}) }
1158
+ : {}),
833
1159
  blend: group.first.lowered.batch.blend,
834
1160
  shading: group.first.lowered.batch.shading,
835
1161
  softDepth: group.first.lowered.batch.softDepth,
@@ -899,6 +1225,18 @@ export class ProductionEffectSystem {
899
1225
  }
900
1226
  }
901
1227
  }
1228
+ /** GU47 E-F: texture for a lowered sprite, or null while it loads (or after it failed). */
1229
+ spriteTexture(sprite) {
1230
+ return sprite.kind === "builtin" ? this.sprites.builtin(sprite.name) : this.sprites.texture(sprite.url);
1231
+ }
1232
+ /** GU47 E-F: load state of every sprite texture requested so far (`vfx:<name>` / `tex:<url>`). */
1233
+ spriteStatus() {
1234
+ return this.sprites.status();
1235
+ }
1236
+ /** GU47 E-F: resolves once every sprite texture requested so far has loaded or failed. */
1237
+ spritesSettled() {
1238
+ return this.sprites.settled();
1239
+ }
902
1240
  concatScratch(key, floats, parts) {
903
1241
  let buf = this.groupScratch.get(key);
904
1242
  if (!buf || buf.length < floats) {
@@ -959,8 +1297,20 @@ export class ProductionEffectSystem {
959
1297
  return;
960
1298
  this.disposed = true;
961
1299
  this.offFrame();
1300
+ // GU47 E-F: the particle pass is shared per device; leaving this system's batches in it kept the last frame's
1301
+ // particles drawing (frozen dots) for as long as the device rendered.
1302
+ if (this.lastHook)
1303
+ for (const handle of this.batchHandles.values())
1304
+ this.lastHook.removeBatch(handle);
1305
+ this.batchHandles.clear();
962
1306
  this.emitters.clear();
963
1307
  this.volumes.clear();
1308
+ this.transients.clear();
1309
+ this.attachments.clear();
1310
+ this.trails.clear();
1311
+ this.ribbons.clear();
1312
+ this.beams.clear();
1313
+ this.meshBatches.clear();
964
1314
  }
965
1315
  }
966
1316
  //# sourceMappingURL=ProductionEffectSystem.js.map