@aura3d/engine 1.4.5 → 1.5.1

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 (513) hide show
  1. package/README.md +95 -29
  2. package/dist/animation/Retargeting.d.ts +12 -0
  3. package/dist/animation/Retargeting.d.ts.map +1 -0
  4. package/dist/animation/Retargeting.js +19 -0
  5. package/dist/animation/Retargeting.js.map +1 -0
  6. package/dist/assets/GLTFLoader.d.ts +4 -0
  7. package/dist/assets/GLTFLoader.d.ts.map +1 -1
  8. package/dist/assets/GLTFLoader.js +39 -4
  9. package/dist/assets/GLTFLoader.js.map +1 -1
  10. package/dist/assets/GLTFRenderResources.d.ts +16 -0
  11. package/dist/assets/GLTFRenderResources.d.ts.map +1 -1
  12. package/dist/assets/GLTFRenderResources.js +42 -2
  13. package/dist/assets/GLTFRenderResources.js.map +1 -1
  14. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.d.ts +6 -0
  15. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.d.ts.map +1 -1
  16. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.js +2 -1
  17. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.js.map +1 -1
  18. package/dist/assets/index.d.ts +0 -1
  19. package/dist/assets/index.d.ts.map +1 -1
  20. package/dist/assets/index.js +0 -1
  21. package/dist/assets/index.js.map +1 -1
  22. package/dist/assets/loaders/index.d.ts +0 -1
  23. package/dist/assets/loaders/index.d.ts.map +1 -1
  24. package/dist/assets/loaders/index.js +0 -1
  25. package/dist/assets/loaders/index.js.map +1 -1
  26. package/dist/aura3d-cli/asset-intent.d.ts +148 -0
  27. package/dist/aura3d-cli/asset-intent.d.ts.map +1 -0
  28. package/dist/aura3d-cli/asset-intent.js +145 -0
  29. package/dist/aura3d-cli/asset-intent.js.map +1 -0
  30. package/dist/aura3d-cli/asset-role-admission.d.ts +174 -0
  31. package/dist/aura3d-cli/asset-role-admission.d.ts.map +1 -0
  32. package/dist/aura3d-cli/asset-role-admission.js +381 -0
  33. package/dist/aura3d-cli/asset-role-admission.js.map +1 -0
  34. package/dist/aura3d-cli/asset-screening-effects.d.ts +95 -0
  35. package/dist/aura3d-cli/asset-screening-effects.d.ts.map +1 -0
  36. package/dist/aura3d-cli/asset-screening-effects.js +321 -0
  37. package/dist/aura3d-cli/asset-screening-effects.js.map +1 -0
  38. package/dist/aura3d-cli/asset-screening-pipeline.d.ts +132 -0
  39. package/dist/aura3d-cli/asset-screening-pipeline.d.ts.map +1 -0
  40. package/dist/aura3d-cli/asset-screening-pipeline.js +277 -0
  41. package/dist/aura3d-cli/asset-screening-pipeline.js.map +1 -0
  42. package/dist/aura3d-cli/cartoon-asset-profiles.d.ts +15 -0
  43. package/dist/aura3d-cli/cartoon-asset-profiles.d.ts.map +1 -0
  44. package/dist/aura3d-cli/cartoon-asset-profiles.js +46 -0
  45. package/dist/aura3d-cli/cartoon-asset-profiles.js.map +1 -0
  46. package/dist/aura3d-cli/cli-help.js +1 -1
  47. package/dist/aura3d-cli/cli.js +16 -2
  48. package/dist/aura3d-cli/cli.js.map +1 -1
  49. package/dist/aura3d-cli/index.d.ts +8 -0
  50. package/dist/aura3d-cli/index.d.ts.map +1 -1
  51. package/dist/aura3d-cli/index.js +390 -17
  52. package/dist/aura3d-cli/index.js.map +1 -1
  53. package/dist/aura3d-cli/pull-bridge/search.d.ts +4 -0
  54. package/dist/aura3d-cli/pull-bridge/search.d.ts.map +1 -1
  55. package/dist/aura3d-cli/pull-bridge/search.js +22 -0
  56. package/dist/aura3d-cli/pull-bridge/search.js.map +1 -1
  57. package/dist/aura3d-cli/pull-bridge.d.ts +20 -5
  58. package/dist/aura3d-cli/pull-bridge.d.ts.map +1 -1
  59. package/dist/aura3d-cli/pull-bridge.js +38 -1
  60. package/dist/aura3d-cli/pull-bridge.js.map +1 -1
  61. package/dist/controls/ControlState.d.ts +1 -1
  62. package/dist/controls/ControlState.d.ts.map +1 -1
  63. package/dist/controls/DragControls.d.ts +21 -1
  64. package/dist/controls/DragControls.d.ts.map +1 -1
  65. package/dist/controls/DragControls.js +24 -2
  66. package/dist/controls/DragControls.js.map +1 -1
  67. package/dist/controls/FirstPersonControls.d.ts +10 -1
  68. package/dist/controls/FirstPersonControls.d.ts.map +1 -1
  69. package/dist/controls/FirstPersonControls.js +18 -2
  70. package/dist/controls/FirstPersonControls.js.map +1 -1
  71. package/dist/controls/FlyControls.d.ts +42 -0
  72. package/dist/controls/FlyControls.d.ts.map +1 -1
  73. package/dist/controls/FlyControls.js +106 -3
  74. package/dist/controls/FlyControls.js.map +1 -1
  75. package/dist/controls/MapControls.d.ts +13 -0
  76. package/dist/controls/MapControls.d.ts.map +1 -1
  77. package/dist/controls/MapControls.js +40 -2
  78. package/dist/controls/MapControls.js.map +1 -1
  79. package/dist/controls/OrbitControls.d.ts +54 -0
  80. package/dist/controls/OrbitControls.d.ts.map +1 -1
  81. package/dist/controls/OrbitControls.js +133 -0
  82. package/dist/controls/OrbitControls.js.map +1 -1
  83. package/dist/controls/PointerLockControls.d.ts +12 -5
  84. package/dist/controls/PointerLockControls.d.ts.map +1 -1
  85. package/dist/controls/PointerLockControls.js +30 -11
  86. package/dist/controls/PointerLockControls.js.map +1 -1
  87. package/dist/controls/SelectionManager.d.ts +22 -1
  88. package/dist/controls/SelectionManager.d.ts.map +1 -1
  89. package/dist/controls/SelectionManager.js +64 -6
  90. package/dist/controls/SelectionManager.js.map +1 -1
  91. package/dist/controls/TransformControls.d.ts +135 -1
  92. package/dist/controls/TransformControls.d.ts.map +1 -1
  93. package/dist/controls/TransformControls.js +534 -10
  94. package/dist/controls/TransformControls.js.map +1 -1
  95. package/dist/controls/index.d.ts +7 -2
  96. package/dist/controls/index.d.ts.map +1 -1
  97. package/dist/controls/index.js +1 -1
  98. package/dist/controls/index.js.map +1 -1
  99. package/dist/create-aura3d/showcase-spec-game-geometry-extractor.d.ts +2 -0
  100. package/dist/create-aura3d/showcase-spec-game-geometry-extractor.d.ts.map +1 -1
  101. package/dist/create-aura3d/showcase-spec-game-geometry-extractor.js +769 -42
  102. package/dist/create-aura3d/showcase-spec-game-geometry-extractor.js.map +1 -1
  103. package/dist/create-aura3d/showcase-spec-game-template-evidence.d.ts.map +1 -1
  104. package/dist/create-aura3d/showcase-spec-game-template-evidence.js +22 -2
  105. package/dist/create-aura3d/showcase-spec-game-template-evidence.js.map +1 -1
  106. package/dist/create-aura3d/showcase-spec-replacement-candidates.js +26 -0
  107. package/dist/create-aura3d/showcase-spec-replacement-candidates.js.map +1 -1
  108. package/dist/ecs/components/MeshComponent.d.ts +5 -2
  109. package/dist/ecs/components/MeshComponent.d.ts.map +1 -1
  110. package/dist/ecs/components/MeshComponent.js.map +1 -1
  111. package/dist/editor-runtime/CartoonSceneEditor.d.ts +111 -0
  112. package/dist/editor-runtime/CartoonSceneEditor.d.ts.map +1 -0
  113. package/dist/editor-runtime/CartoonSceneEditor.js +285 -0
  114. package/dist/editor-runtime/CartoonSceneEditor.js.map +1 -0
  115. package/dist/editor-runtime/InteractiveTransformGizmo.d.ts +142 -0
  116. package/dist/editor-runtime/InteractiveTransformGizmo.d.ts.map +1 -0
  117. package/dist/editor-runtime/InteractiveTransformGizmo.js +468 -0
  118. package/dist/editor-runtime/InteractiveTransformGizmo.js.map +1 -0
  119. package/dist/editor-runtime/index.d.ts +2 -0
  120. package/dist/editor-runtime/index.d.ts.map +1 -1
  121. package/dist/editor-runtime/index.js +1 -0
  122. package/dist/editor-runtime/index.js.map +1 -1
  123. package/dist/engine/agent-api/ApplicationKits.d.ts +307 -0
  124. package/dist/engine/agent-api/ApplicationKits.d.ts.map +1 -0
  125. package/dist/engine/agent-api/ApplicationKits.js +650 -0
  126. package/dist/engine/agent-api/ApplicationKits.js.map +1 -0
  127. package/dist/engine/agent-api/CartoonAssetManifest.d.ts +50 -0
  128. package/dist/engine/agent-api/CartoonAssetManifest.d.ts.map +1 -0
  129. package/dist/engine/agent-api/CartoonAssetManifest.js +65 -0
  130. package/dist/engine/agent-api/CartoonAssetManifest.js.map +1 -0
  131. package/dist/engine/agent-api/CartoonDirector.d.ts +120 -0
  132. package/dist/engine/agent-api/CartoonDirector.d.ts.map +1 -0
  133. package/dist/engine/agent-api/CartoonDirector.js +432 -0
  134. package/dist/engine/agent-api/CartoonDirector.js.map +1 -0
  135. package/dist/engine/agent-api/CartoonEpisodePackage.d.ts +51 -0
  136. package/dist/engine/agent-api/CartoonEpisodePackage.d.ts.map +1 -0
  137. package/dist/engine/agent-api/CartoonEpisodePackage.js +79 -0
  138. package/dist/engine/agent-api/CartoonEpisodePackage.js.map +1 -0
  139. package/dist/engine/agent-api/CartoonMotionQuality.d.ts +83 -0
  140. package/dist/engine/agent-api/CartoonMotionQuality.d.ts.map +1 -0
  141. package/dist/engine/agent-api/CartoonMotionQuality.js +128 -0
  142. package/dist/engine/agent-api/CartoonMotionQuality.js.map +1 -0
  143. package/dist/engine/agent-api/CartoonPerformance.d.ts +150 -0
  144. package/dist/engine/agent-api/CartoonPerformance.d.ts.map +1 -0
  145. package/dist/engine/agent-api/CartoonPerformance.js +345 -0
  146. package/dist/engine/agent-api/CartoonPerformance.js.map +1 -0
  147. package/dist/engine/agent-api/CartoonRenderQueue.d.ts +143 -0
  148. package/dist/engine/agent-api/CartoonRenderQueue.d.ts.map +1 -0
  149. package/dist/engine/agent-api/CartoonRenderQueue.js +410 -0
  150. package/dist/engine/agent-api/CartoonRenderQueue.js.map +1 -0
  151. package/dist/engine/agent-api/CartoonRouteProof.d.ts +112 -0
  152. package/dist/engine/agent-api/CartoonRouteProof.d.ts.map +1 -0
  153. package/dist/engine/agent-api/CartoonRouteProof.js +127 -0
  154. package/dist/engine/agent-api/CartoonRouteProof.js.map +1 -0
  155. package/dist/engine/agent-api/CombatFrameData.d.ts +210 -0
  156. package/dist/engine/agent-api/CombatFrameData.d.ts.map +1 -0
  157. package/dist/engine/agent-api/CombatFrameData.js +324 -0
  158. package/dist/engine/agent-api/CombatFrameData.js.map +1 -0
  159. package/dist/engine/agent-api/FocusSelection.d.ts +186 -0
  160. package/dist/engine/agent-api/FocusSelection.d.ts.map +1 -0
  161. package/dist/engine/agent-api/FocusSelection.js +436 -0
  162. package/dist/engine/agent-api/FocusSelection.js.map +1 -0
  163. package/dist/engine/agent-api/GameEvidence.d.ts +1 -0
  164. package/dist/engine/agent-api/GameEvidence.d.ts.map +1 -1
  165. package/dist/engine/agent-api/GameEvidence.js +1 -0
  166. package/dist/engine/agent-api/GameEvidence.js.map +1 -1
  167. package/dist/engine/agent-api/GameGenreKits.d.ts +43 -1
  168. package/dist/engine/agent-api/GameGenreKits.d.ts.map +1 -1
  169. package/dist/engine/agent-api/GameGenreKits.js +79 -13
  170. package/dist/engine/agent-api/GameGenreKits.js.map +1 -1
  171. package/dist/engine/agent-api/GameRuntime.d.ts +1 -0
  172. package/dist/engine/agent-api/GameRuntime.d.ts.map +1 -1
  173. package/dist/engine/agent-api/GameRuntime.js +1 -0
  174. package/dist/engine/agent-api/GameRuntime.js.map +1 -1
  175. package/dist/engine/agent-api/GameSceneGeometryBindings.d.ts +22 -0
  176. package/dist/engine/agent-api/GameSceneGeometryBindings.d.ts.map +1 -1
  177. package/dist/engine/agent-api/GameSceneGeometryBindings.js +9 -0
  178. package/dist/engine/agent-api/GameSceneGeometryBindings.js.map +1 -1
  179. package/dist/engine/agent-api/LayeredSceneComposition.d.ts +295 -0
  180. package/dist/engine/agent-api/LayeredSceneComposition.d.ts.map +1 -0
  181. package/dist/engine/agent-api/LayeredSceneComposition.js +387 -0
  182. package/dist/engine/agent-api/LayeredSceneComposition.js.map +1 -0
  183. package/dist/engine/agent-api/PlatformerMotion.d.ts +177 -0
  184. package/dist/engine/agent-api/PlatformerMotion.d.ts.map +1 -0
  185. package/dist/engine/agent-api/PlatformerMotion.js +207 -0
  186. package/dist/engine/agent-api/PlatformerMotion.js.map +1 -0
  187. package/dist/engine/agent-api/SceneGroundingUtils.d.ts +62 -0
  188. package/dist/engine/agent-api/SceneGroundingUtils.d.ts.map +1 -1
  189. package/dist/engine/agent-api/SceneGroundingUtils.js +37 -0
  190. package/dist/engine/agent-api/SceneGroundingUtils.js.map +1 -1
  191. package/dist/engine/agent-api/SceneQueries.d.ts +124 -0
  192. package/dist/engine/agent-api/SceneQueries.d.ts.map +1 -0
  193. package/dist/engine/agent-api/SceneQueries.js +221 -0
  194. package/dist/engine/agent-api/SceneQueries.js.map +1 -0
  195. package/dist/engine/agent-api/SpatialAnchoring.d.ts +232 -0
  196. package/dist/engine/agent-api/SpatialAnchoring.d.ts.map +1 -0
  197. package/dist/engine/agent-api/SpatialAnchoring.js +348 -0
  198. package/dist/engine/agent-api/SpatialAnchoring.js.map +1 -0
  199. package/dist/engine/agent-api/SubjectFramingUtils.d.ts +127 -0
  200. package/dist/engine/agent-api/SubjectFramingUtils.d.ts.map +1 -0
  201. package/dist/engine/agent-api/SubjectFramingUtils.js +126 -0
  202. package/dist/engine/agent-api/SubjectFramingUtils.js.map +1 -0
  203. package/dist/engine/agent-api/TouchControlBinding.d.ts +81 -0
  204. package/dist/engine/agent-api/TouchControlBinding.d.ts.map +1 -0
  205. package/dist/engine/agent-api/TouchControlBinding.js +116 -0
  206. package/dist/engine/agent-api/TouchControlBinding.js.map +1 -0
  207. package/dist/engine/agent-api/VehicleChassis.d.ts +192 -0
  208. package/dist/engine/agent-api/VehicleChassis.d.ts.map +1 -0
  209. package/dist/engine/agent-api/VehicleChassis.js +322 -0
  210. package/dist/engine/agent-api/VehicleChassis.js.map +1 -0
  211. package/dist/engine/agent-api/VehicleDriverAi.d.ts +123 -0
  212. package/dist/engine/agent-api/VehicleDriverAi.d.ts.map +1 -0
  213. package/dist/engine/agent-api/VehicleDriverAi.js +217 -0
  214. package/dist/engine/agent-api/VehicleDriverAi.js.map +1 -0
  215. package/dist/engine/agent-api/WorldLabelRenderer.d.ts +146 -0
  216. package/dist/engine/agent-api/WorldLabelRenderer.d.ts.map +1 -0
  217. package/dist/engine/agent-api/WorldLabelRenderer.js +331 -0
  218. package/dist/engine/agent-api/WorldLabelRenderer.js.map +1 -0
  219. package/dist/engine/agent-api/index.d.ts +69 -0
  220. package/dist/engine/agent-api/index.d.ts.map +1 -1
  221. package/dist/engine/agent-api/index.js +633 -75
  222. package/dist/engine/agent-api/index.js.map +1 -1
  223. package/dist/engine/agent-api/product-viewer-runtime.d.ts.map +1 -1
  224. package/dist/engine/production-runtime/GameRenderPreset.d.ts +32 -0
  225. package/dist/engine/production-runtime/GameRenderPreset.d.ts.map +1 -1
  226. package/dist/engine/production-runtime/GameRenderPreset.js +37 -2
  227. package/dist/engine/production-runtime/GameRenderPreset.js.map +1 -1
  228. package/dist/engine/production-runtime/TypedGLBActor.d.ts +8 -0
  229. package/dist/engine/production-runtime/TypedGLBActor.d.ts.map +1 -1
  230. package/dist/engine/production-runtime/TypedGLBActor.js +2 -1
  231. package/dist/engine/production-runtime/TypedGLBActor.js.map +1 -1
  232. package/dist/input/controls/PointerLockControls.d.ts +1 -1
  233. package/dist/input/controls/PointerLockControls.d.ts.map +1 -1
  234. package/dist/input/controls/PointerLockControls.js +12 -0
  235. package/dist/input/controls/PointerLockControls.js.map +1 -1
  236. package/dist/physics/Collider.d.ts +1 -1
  237. package/dist/physics/Collider.d.ts.map +1 -1
  238. package/dist/physics/Collider.js +2 -2
  239. package/dist/physics/Collider.js.map +1 -1
  240. package/dist/physics/CollisionEvents.d.ts +1 -0
  241. package/dist/physics/CollisionEvents.d.ts.map +1 -1
  242. package/dist/physics/CollisionEvents.js.map +1 -1
  243. package/dist/physics/NarrowPhase.d.ts +11 -0
  244. package/dist/physics/NarrowPhase.d.ts.map +1 -0
  245. package/dist/physics/NarrowPhase.js +565 -0
  246. package/dist/physics/NarrowPhase.js.map +1 -0
  247. package/dist/physics/PhysicsDebugDraw.js +19 -1
  248. package/dist/physics/PhysicsDebugDraw.js.map +1 -1
  249. package/dist/physics/PhysicsWorld.d.ts +43 -0
  250. package/dist/physics/PhysicsWorld.d.ts.map +1 -1
  251. package/dist/physics/PhysicsWorld.js +305 -30
  252. package/dist/physics/PhysicsWorld.js.map +1 -1
  253. package/dist/physics/RigidBody.d.ts +8 -1
  254. package/dist/physics/RigidBody.d.ts.map +1 -1
  255. package/dist/physics/RigidBody.js +32 -5
  256. package/dist/physics/RigidBody.js.map +1 -1
  257. package/dist/physics/Shape.d.ts +16 -2
  258. package/dist/physics/Shape.d.ts.map +1 -1
  259. package/dist/physics/Shape.js +93 -31
  260. package/dist/physics/Shape.js.map +1 -1
  261. package/dist/physics/TimeOfImpact.d.ts +15 -0
  262. package/dist/physics/TimeOfImpact.d.ts.map +1 -0
  263. package/dist/physics/TimeOfImpact.js +81 -0
  264. package/dist/physics/TimeOfImpact.js.map +1 -0
  265. package/dist/physics/index.d.ts +2 -0
  266. package/dist/physics/index.d.ts.map +1 -1
  267. package/dist/physics/index.js +2 -0
  268. package/dist/physics/index.js.map +1 -1
  269. package/dist/rendering/CascadedShadowMaps.d.ts +9 -1
  270. package/dist/rendering/CascadedShadowMaps.d.ts.map +1 -1
  271. package/dist/rendering/CascadedShadowMaps.js +68 -0
  272. package/dist/rendering/CascadedShadowMaps.js.map +1 -1
  273. package/dist/rendering/ClusteredForwardLighting.d.ts +28 -0
  274. package/dist/rendering/ClusteredForwardLighting.d.ts.map +1 -0
  275. package/dist/rendering/ClusteredForwardLighting.js +156 -0
  276. package/dist/rendering/ClusteredForwardLighting.js.map +1 -0
  277. package/dist/rendering/DepthPass.d.ts +14 -1
  278. package/dist/rendering/DepthPass.d.ts.map +1 -1
  279. package/dist/rendering/DepthPass.js +19 -4
  280. package/dist/rendering/DepthPass.js.map +1 -1
  281. package/dist/rendering/EnvironmentMapResources.d.ts +59 -1
  282. package/dist/rendering/EnvironmentMapResources.d.ts.map +1 -1
  283. package/dist/rendering/EnvironmentMapResources.js +140 -100
  284. package/dist/rendering/EnvironmentMapResources.js.map +1 -1
  285. package/dist/rendering/EnvironmentPlatform.d.ts +3 -2
  286. package/dist/rendering/EnvironmentPlatform.d.ts.map +1 -1
  287. package/dist/rendering/EnvironmentPlatform.js +99 -44
  288. package/dist/rendering/EnvironmentPlatform.js.map +1 -1
  289. package/dist/rendering/ForwardPass.d.ts +37 -0
  290. package/dist/rendering/ForwardPass.d.ts.map +1 -1
  291. package/dist/rendering/ForwardPass.js +234 -7
  292. package/dist/rendering/ForwardPass.js.map +1 -1
  293. package/dist/rendering/Geometry.d.ts +19 -0
  294. package/dist/rendering/Geometry.d.ts.map +1 -1
  295. package/dist/rendering/Geometry.js +64 -0
  296. package/dist/rendering/Geometry.js.map +1 -1
  297. package/dist/rendering/IBL.d.ts.map +1 -1
  298. package/dist/rendering/IBL.js +0 -1
  299. package/dist/rendering/IBL.js.map +1 -1
  300. package/dist/rendering/LightCollector.d.ts +5 -1
  301. package/dist/rendering/LightCollector.d.ts.map +1 -1
  302. package/dist/rendering/LightCollector.js +16 -3
  303. package/dist/rendering/LightCollector.js.map +1 -1
  304. package/dist/rendering/LightUniforms.d.ts +26 -1
  305. package/dist/rendering/LightUniforms.d.ts.map +1 -1
  306. package/dist/rendering/LightUniforms.js +140 -8
  307. package/dist/rendering/LightUniforms.js.map +1 -1
  308. package/dist/rendering/LightingRig.d.ts +77 -0
  309. package/dist/rendering/LightingRig.d.ts.map +1 -1
  310. package/dist/rendering/LightingRig.js +100 -11
  311. package/dist/rendering/LightingRig.js.map +1 -1
  312. package/dist/rendering/MeshConsolidation.d.ts +63 -0
  313. package/dist/rendering/MeshConsolidation.d.ts.map +1 -0
  314. package/dist/rendering/MeshConsolidation.js +251 -0
  315. package/dist/rendering/MeshConsolidation.js.map +1 -0
  316. package/dist/rendering/PMREM.d.ts +13 -1
  317. package/dist/rendering/PMREM.d.ts.map +1 -1
  318. package/dist/rendering/PMREM.js +18 -4
  319. package/dist/rendering/PMREM.js.map +1 -1
  320. package/dist/rendering/PostProcessPass.d.ts +24 -2
  321. package/dist/rendering/PostProcessPass.d.ts.map +1 -1
  322. package/dist/rendering/PostProcessPass.js +136 -18
  323. package/dist/rendering/PostProcessPass.js.map +1 -1
  324. package/dist/rendering/PrimitiveSubmissionAudit.d.ts +195 -0
  325. package/dist/rendering/PrimitiveSubmissionAudit.d.ts.map +1 -0
  326. package/dist/rendering/PrimitiveSubmissionAudit.js +280 -0
  327. package/dist/rendering/PrimitiveSubmissionAudit.js.map +1 -0
  328. package/dist/rendering/ProductTurntableFixtures.d.ts.map +1 -1
  329. package/dist/rendering/ProductTurntableFixtures.js +93 -13
  330. package/dist/rendering/ProductTurntableFixtures.js.map +1 -1
  331. package/dist/rendering/ReflectionProbe.d.ts +59 -0
  332. package/dist/rendering/ReflectionProbe.d.ts.map +1 -1
  333. package/dist/rendering/ReflectionProbe.js +224 -0
  334. package/dist/rendering/ReflectionProbe.js.map +1 -1
  335. package/dist/rendering/ReflectionSurfaces.d.ts +4 -2
  336. package/dist/rendering/ReflectionSurfaces.d.ts.map +1 -1
  337. package/dist/rendering/ReflectionSurfaces.js +13 -8
  338. package/dist/rendering/ReflectionSurfaces.js.map +1 -1
  339. package/dist/rendering/RenderBackend.d.ts +1 -1
  340. package/dist/rendering/RenderBackend.d.ts.map +1 -1
  341. package/dist/rendering/RenderBackend.js +5 -1
  342. package/dist/rendering/RenderBackend.js.map +1 -1
  343. package/dist/rendering/RenderDevice.d.ts +13 -2
  344. package/dist/rendering/RenderDevice.d.ts.map +1 -1
  345. package/dist/rendering/RenderDevice.js +5 -2
  346. package/dist/rendering/RenderDevice.js.map +1 -1
  347. package/dist/rendering/Renderer.d.ts +41 -1
  348. package/dist/rendering/Renderer.d.ts.map +1 -1
  349. package/dist/rendering/Renderer.js +406 -61
  350. package/dist/rendering/Renderer.js.map +1 -1
  351. package/dist/rendering/RendererPostprocessPlan.d.ts +10 -3
  352. package/dist/rendering/RendererPostprocessPlan.d.ts.map +1 -1
  353. package/dist/rendering/RendererPostprocessPlan.js +25 -5
  354. package/dist/rendering/RendererPostprocessPlan.js.map +1 -1
  355. package/dist/rendering/RendererVisualPipelineReport.d.ts +3 -2
  356. package/dist/rendering/RendererVisualPipelineReport.d.ts.map +1 -1
  357. package/dist/rendering/RendererVisualPipelineReport.js +2 -0
  358. package/dist/rendering/RendererVisualPipelineReport.js.map +1 -1
  359. package/dist/rendering/ScreenSpaceLineMaterial.d.ts +34 -0
  360. package/dist/rendering/ScreenSpaceLineMaterial.d.ts.map +1 -0
  361. package/dist/rendering/ScreenSpaceLineMaterial.js +93 -0
  362. package/dist/rendering/ScreenSpaceLineMaterial.js.map +1 -0
  363. package/dist/rendering/ShaderChunks.d.ts +7 -0
  364. package/dist/rendering/ShaderChunks.d.ts.map +1 -1
  365. package/dist/rendering/ShaderChunks.js +137 -0
  366. package/dist/rendering/ShaderChunks.js.map +1 -1
  367. package/dist/rendering/ShaderLibrary.d.ts +17 -0
  368. package/dist/rendering/ShaderLibrary.d.ts.map +1 -1
  369. package/dist/rendering/ShaderLibrary.js +940 -98
  370. package/dist/rendering/ShaderLibrary.js.map +1 -1
  371. package/dist/rendering/ShadowPass.d.ts +10 -0
  372. package/dist/rendering/ShadowPass.d.ts.map +1 -1
  373. package/dist/rendering/ShadowPass.js +8 -1
  374. package/dist/rendering/ShadowPass.js.map +1 -1
  375. package/dist/rendering/SkinnedLitMaterial.d.ts +6 -0
  376. package/dist/rendering/SkinnedLitMaterial.d.ts.map +1 -1
  377. package/dist/rendering/SkinnedLitMaterial.js +22 -8
  378. package/dist/rendering/SkinnedLitMaterial.js.map +1 -1
  379. package/dist/rendering/SkinnedUnlitMaterial.d.ts +8 -0
  380. package/dist/rendering/SkinnedUnlitMaterial.d.ts.map +1 -1
  381. package/dist/rendering/SkinnedUnlitMaterial.js +26 -9
  382. package/dist/rendering/SkinnedUnlitMaterial.js.map +1 -1
  383. package/dist/rendering/SpecularPrefilter.d.ts +42 -0
  384. package/dist/rendering/SpecularPrefilter.d.ts.map +1 -0
  385. package/dist/rendering/SpecularPrefilter.js +480 -0
  386. package/dist/rendering/SpecularPrefilter.js.map +1 -0
  387. package/dist/rendering/TerrainFixtures.d.ts +24 -0
  388. package/dist/rendering/TerrainFixtures.d.ts.map +1 -1
  389. package/dist/rendering/TerrainFixtures.js +96 -0
  390. package/dist/rendering/TerrainFixtures.js.map +1 -1
  391. package/dist/rendering/Texture.d.ts +7 -0
  392. package/dist/rendering/Texture.d.ts.map +1 -1
  393. package/dist/rendering/Texture.js +9 -0
  394. package/dist/rendering/Texture.js.map +1 -1
  395. package/dist/rendering/VertexFormat.d.ts +34 -1
  396. package/dist/rendering/VertexFormat.d.ts.map +1 -1
  397. package/dist/rendering/VertexFormat.js +61 -0
  398. package/dist/rendering/VertexFormat.js.map +1 -1
  399. package/dist/rendering/WebGL2Device.d.ts +48 -0
  400. package/dist/rendering/WebGL2Device.d.ts.map +1 -1
  401. package/dist/rendering/WebGL2Device.js +1298 -44
  402. package/dist/rendering/WebGL2Device.js.map +1 -1
  403. package/dist/rendering/WebGPUDevice.d.ts +7 -2
  404. package/dist/rendering/WebGPUDevice.d.ts.map +1 -1
  405. package/dist/rendering/WebGPUDevice.js +111 -17
  406. package/dist/rendering/WebGPUDevice.js.map +1 -1
  407. package/dist/rendering/WebGPUSkinningLimits.d.ts +14 -0
  408. package/dist/rendering/WebGPUSkinningLimits.d.ts.map +1 -0
  409. package/dist/rendering/WebGPUSkinningLimits.js +14 -0
  410. package/dist/rendering/WebGPUSkinningLimits.js.map +1 -0
  411. package/dist/rendering/cartoon/CartoonMaterialStyle.d.ts +19 -0
  412. package/dist/rendering/cartoon/CartoonMaterialStyle.d.ts.map +1 -0
  413. package/dist/rendering/cartoon/CartoonMaterialStyle.js +13 -0
  414. package/dist/rendering/cartoon/CartoonMaterialStyle.js.map +1 -0
  415. package/dist/rendering/cartoon/CartoonRenderPreset.d.ts +36 -0
  416. package/dist/rendering/cartoon/CartoonRenderPreset.d.ts.map +1 -0
  417. package/dist/rendering/cartoon/CartoonRenderPreset.js +23 -0
  418. package/dist/rendering/cartoon/CartoonRenderPreset.js.map +1 -0
  419. package/dist/rendering/cartoon/CartoonToonMaterial.d.ts +130 -0
  420. package/dist/rendering/cartoon/CartoonToonMaterial.d.ts.map +1 -0
  421. package/dist/rendering/cartoon/CartoonToonMaterial.js +303 -0
  422. package/dist/rendering/cartoon/CartoonToonMaterial.js.map +1 -0
  423. package/dist/rendering/cartoon/CartoonVisualQuality.d.ts +28 -0
  424. package/dist/rendering/cartoon/CartoonVisualQuality.d.ts.map +1 -0
  425. package/dist/rendering/cartoon/CartoonVisualQuality.js +39 -0
  426. package/dist/rendering/cartoon/CartoonVisualQuality.js.map +1 -0
  427. package/dist/rendering/cartoon/applyCartoonRenderPreset.d.ts +79 -0
  428. package/dist/rendering/cartoon/applyCartoonRenderPreset.d.ts.map +1 -0
  429. package/dist/rendering/cartoon/applyCartoonRenderPreset.js +88 -0
  430. package/dist/rendering/cartoon/applyCartoonRenderPreset.js.map +1 -0
  431. package/dist/rendering/cartoon/index.d.ts +6 -0
  432. package/dist/rendering/cartoon/index.d.ts.map +1 -0
  433. package/dist/rendering/cartoon/index.js +6 -0
  434. package/dist/rendering/cartoon/index.js.map +1 -0
  435. package/dist/rendering/index.d.ts +26 -15
  436. package/dist/rendering/index.d.ts.map +1 -1
  437. package/dist/rendering/index.js +15 -9
  438. package/dist/rendering/index.js.map +1 -1
  439. package/dist/rendering/postprocess/NativeLdrEffectLuts.d.ts +93 -0
  440. package/dist/rendering/postprocess/NativeLdrEffectLuts.d.ts.map +1 -0
  441. package/dist/rendering/postprocess/NativeLdrEffectLuts.js +202 -0
  442. package/dist/rendering/postprocess/NativeLdrEffectLuts.js.map +1 -0
  443. package/dist/rendering/production-runtime/PBRHDRPipeline.d.ts.map +1 -1
  444. package/dist/rendering/production-runtime/PBRHDRPipeline.js +3 -0
  445. package/dist/rendering/production-runtime/PBRHDRPipeline.js.map +1 -1
  446. package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts +1 -0
  447. package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts.map +1 -1
  448. package/dist/rendering/production-runtime/ProductionRendererTypes.js.map +1 -1
  449. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.d.ts.map +1 -1
  450. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js +5 -3
  451. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js.map +1 -1
  452. package/dist/rendering/production-runtime/ProductionWebGPURenderer.d.ts.map +1 -1
  453. package/dist/rendering/production-runtime/ProductionWebGPURenderer.js +9 -5
  454. package/dist/rendering/production-runtime/ProductionWebGPURenderer.js.map +1 -1
  455. package/dist/rendering/production-runtime/TransmissionBackdropCapture.d.ts +5 -0
  456. package/dist/rendering/production-runtime/TransmissionBackdropCapture.d.ts.map +1 -1
  457. package/dist/rendering/production-runtime/TransmissionBackdropCapture.js +40 -0
  458. package/dist/rendering/production-runtime/TransmissionBackdropCapture.js.map +1 -1
  459. package/dist/rendering/production-runtime/environment/HDRLoader.d.ts +6 -0
  460. package/dist/rendering/production-runtime/environment/HDRLoader.d.ts.map +1 -1
  461. package/dist/rendering/production-runtime/environment/HDRLoader.js +19 -0
  462. package/dist/rendering/production-runtime/environment/HDRLoader.js.map +1 -1
  463. package/dist/rendering/production-runtime/index.d.ts +3 -1
  464. package/dist/rendering/production-runtime/index.d.ts.map +1 -1
  465. package/dist/rendering/production-runtime/index.js +1 -0
  466. package/dist/rendering/production-runtime/index.js.map +1 -1
  467. package/dist/scene/Light.d.ts +1 -1
  468. package/dist/scene/Light.d.ts.map +1 -1
  469. package/dist/scene/RectAreaLight.d.ts +22 -0
  470. package/dist/scene/RectAreaLight.d.ts.map +1 -0
  471. package/dist/scene/RectAreaLight.js +46 -0
  472. package/dist/scene/RectAreaLight.js.map +1 -0
  473. package/dist/scene/Scene.d.ts +6 -1
  474. package/dist/scene/Scene.d.ts.map +1 -1
  475. package/dist/scene/Scene.js +8 -1
  476. package/dist/scene/Scene.js.map +1 -1
  477. package/dist/scene/SceneSerializer.d.ts +3 -1
  478. package/dist/scene/SceneSerializer.d.ts.map +1 -1
  479. package/dist/scene/SceneSerializer.js +14 -7
  480. package/dist/scene/SceneSerializer.js.map +1 -1
  481. package/dist/scene/index.d.ts +1 -0
  482. package/dist/scene/index.d.ts.map +1 -1
  483. package/dist/scene/index.js +1 -0
  484. package/dist/scene/index.js.map +1 -1
  485. package/dist/scripting/CartoonNodeCategories.d.ts +3 -0
  486. package/dist/scripting/CartoonNodeCategories.d.ts.map +1 -0
  487. package/dist/scripting/CartoonNodeCategories.js +9 -0
  488. package/dist/scripting/CartoonNodeCategories.js.map +1 -0
  489. package/dist/scripting/CartoonVisualNodes.d.ts +3 -0
  490. package/dist/scripting/CartoonVisualNodes.d.ts.map +1 -0
  491. package/dist/scripting/CartoonVisualNodes.js +41 -0
  492. package/dist/scripting/CartoonVisualNodes.js.map +1 -0
  493. package/package.json +131 -114
  494. package/templates/production-asset-inspector/README.md +5 -0
  495. package/templates/production-asset-inspector/asset-manifest.json +9 -0
  496. package/templates/production-asset-inspector/index.html +2 -0
  497. package/templates/production-asset-inspector/package.json +17 -0
  498. package/templates/production-asset-inspector/src/main.ts +16 -0
  499. package/templates/production-material-studio/README.md +5 -0
  500. package/templates/production-material-studio/asset-manifest.json +9 -0
  501. package/templates/production-material-studio/index.html +2 -0
  502. package/templates/production-material-studio/package.json +17 -0
  503. package/templates/production-material-studio/src/main.ts +16 -0
  504. package/templates/production-product-configurator/README.md +5 -0
  505. package/templates/production-product-configurator/asset-manifest.json +9 -0
  506. package/templates/production-product-configurator/index.html +2 -0
  507. package/templates/production-product-configurator/package.json +17 -0
  508. package/templates/production-product-configurator/src/main.ts +16 -0
  509. package/templates/production-product-viewer/README.md +7 -0
  510. package/templates/production-product-viewer/asset-manifest.json +8 -0
  511. package/templates/production-product-viewer/index.html +26 -0
  512. package/templates/production-product-viewer/package.json +17 -0
  513. package/templates/production-product-viewer/src/main.ts +70 -0
@@ -1,8 +1,18 @@
1
1
  import { PhysicsDebugDraw, PhysicsStepper, PhysicsWorld, ScenePhysicsBridge, Shape as PhysicsShapeFactory } from "../../physics/index.js";
2
2
  import { createExternalParityEnvironmentLighting, Geometry, IndexBuffer, PBRMaterial, ProductionRuntimeRenderer, VertexBuffer, VertexFormat } from "../../rendering/index.js";
3
- import { DirectionalLight } from "../../scene/index.js";
3
+ import { DirectionalLight, PointLight, SpotLight } from "../../scene/index.js";
4
4
  import { createTypedGLBActor } from "../production-runtime/TypedGLBActor.js";
5
5
  import { AURA_NORMALIZED_MODEL_MAX_DIMENSION, boundsFromAsset, boundsHeight, boundsMaxDimension, boundsSize } from "./SceneGroundingUtils.js";
6
+ import { createWorldLabelLayer } from "./WorldLabelRenderer.js";
7
+ export * from "./SpatialAnchoring.js";
8
+ export * from "./FocusSelection.js";
9
+ export * from "./WorldLabelRenderer.js";
10
+ export * from "./VehicleChassis.js";
11
+ export * from "./VehicleDriverAi.js";
12
+ export * from "./PlatformerMotion.js";
13
+ export * from "./CombatFrameData.js";
14
+ export * from "./SceneQueries.js";
15
+ export * from "./ApplicationKits.js";
6
16
  export * from "./FrameEncoder.js";
7
17
  export * from "./BrowserFrameCaptureAdapter.js";
8
18
  export * from "./MediaRecorderFrameEncoder.js";
@@ -35,6 +45,9 @@ export * from "./CloudRenderAdapter.js";
35
45
  export * from "./BatchEpisodeRenderer.js";
36
46
  export * from "./AnimationAssetManifest.js";
37
47
  export * from "./SceneGroundingUtils.js";
48
+ export * from "./SubjectFramingUtils.js";
49
+ export * from "./LayeredSceneComposition.js";
50
+ export * from "./TouchControlBinding.js";
38
51
  export * from "./AssetLibraryBrowser.js";
39
52
  export * from "./DialogueAlignment.js";
40
53
  export * from "./PerformancePoseEditor.js";
@@ -98,6 +111,9 @@ export * from "./AnimationPerformance.js";
98
111
  export * from "./AnimationRenderQueue.js";
99
112
  export * from "./AnimationAssetManifest.js";
100
113
  export * from "./SceneGroundingUtils.js";
114
+ export * from "./SubjectFramingUtils.js";
115
+ export * from "./LayeredSceneComposition.js";
116
+ export * from "./TouchControlBinding.js";
101
117
  export * from "./AssetLibraryBrowser.js";
102
118
  const auraAssetRefBrand = Symbol("AuraAssetRef");
103
119
  export function defineAuraAssets(definitions) {
@@ -1735,7 +1751,17 @@ function createRendererDiagnosticReport(snapshot, runtime, rendererOptions) {
1735
1751
  antiBlowout: bloom?.antiBlowout ?? true
1736
1752
  },
1737
1753
  shadows: {
1738
- enabled: true,
1754
+ // Never a source-authored `true`. When the runtime is mounted this is the
1755
+ // device-observed shadow-map state; when it is not mounted the scene has
1756
+ // only requested shadows and nothing has been proven yet.
1757
+ enabled: runtime?.mounted ? Boolean(runtime.shadow?.mapSampled) : false,
1758
+ requested: runtime?.shadow?.requested ?? false,
1759
+ mapRendered: runtime?.shadow?.mapRendered ?? false,
1760
+ mapSampled: runtime?.shadow?.mapSampled ?? false,
1761
+ mapSize: runtime?.shadow?.mapSize,
1762
+ label: runtime?.shadow?.label,
1763
+ nativeShadowMapBindings: runtime?.shadow?.nativeShadowMapBindings ?? 0,
1764
+ shadowRenderTargetsAllocated: runtime?.shadow?.shadowRenderTargetsAllocated ?? 0,
1739
1765
  contactShadows,
1740
1766
  mapType: "pcf-soft"
1741
1767
  },
@@ -4325,7 +4351,12 @@ export function createGamePlatformerPresentationSurfaceNodes(options) {
4325
4351
  const point = options.sceneBinding.toScenePoint(checkpoint, 0.02);
4326
4352
  nodes.push(primitives.box({
4327
4353
  name: `scene-bound platformer checkpoint ${checkpoint.id}`,
4328
- material: material.emissive({ color: "#d7f9ff", emissive: "#a6f4ff", emissiveIntensity: 0.48, roughness: 0.4 })
4354
+ material: material.emissive({
4355
+ color: options.checkpointColor ?? "#d7f9ff",
4356
+ emissive: options.checkpointColor ?? "#a6f4ff",
4357
+ emissiveIntensity: 0.48,
4358
+ roughness: 0.4
4359
+ })
4329
4360
  })
4330
4361
  .position(point[0], point[1], point[2] + (isGameLevel ? 0.29 : 0.19))
4331
4362
  .scale([0.026, 0.22, 0.034])
@@ -7052,6 +7083,66 @@ function isRenderableModelNode(node) {
7052
7083
  function isWebGLRenderableNode(node) {
7053
7084
  return isRenderableModelNode(node) || node.kind === "primitive";
7054
7085
  }
7086
+ /**
7087
+ * Translate scene label nodes into world-anchored labels for the label layer.
7088
+ *
7089
+ * `labels.callout(...)` and friends previously reached the scene snapshot and were
7090
+ * counted by evidence but drawn only by the canvas2d fallback. Every route with a
7091
+ * typed GLB takes the production WebGL2 path, so every production callout was
7092
+ * silently dropped. This is the bridge that makes the public label API real in the
7093
+ * path public routes actually use.
7094
+ */
7095
+ function worldLabelsFromSnapshot(snapshot, runtimeNodes) {
7096
+ const labelNodes = groups.flatten(snapshot.nodes).filter((node) => node.kind === "label");
7097
+ return labelNodes.map((node, index) => {
7098
+ const runtimeId = node.runtime?.id;
7099
+ const runtimeSnapshot = runtimeId ? runtimeNodes?.get(runtimeId)?.snapshot() : undefined;
7100
+ if (runtimeSnapshot?.visible === false) {
7101
+ return {
7102
+ id: node.name ?? `${node.label}-${index + 1}`,
7103
+ text: node.text,
7104
+ anchor: [0, 0, 0],
7105
+ offscreenPolicy: "hide"
7106
+ };
7107
+ }
7108
+ const position = (runtimeSnapshot?.position ?? node.position ?? labelDefaultPosition(node));
7109
+ const anchor = node.anchorWorldPosition ?? position;
7110
+ // Screen offset is derived from the gap between the label box and its anchor,
7111
+ // projected as a vertical nudge. A label that requests no separate anchor sits
7112
+ // directly on its own position.
7113
+ const separated = node.anchorWorldPosition !== undefined;
7114
+ return {
7115
+ id: node.name ?? `${node.label}-${index + 1}`,
7116
+ text: node.text,
7117
+ anchor: [position[0], position[1], position[2]],
7118
+ leaderAnchor: [anchor[0], anchor[1], anchor[2]],
7119
+ screenOffset: separated ? [0, 0] : [0, -26],
7120
+ color: typeof node.color === "string" ? node.color : undefined,
7121
+ background: typeof node.background === "string" ? node.background : undefined,
7122
+ // `size` is authored in world units for scene labels; map it onto a legible
7123
+ // pixel range rather than using it directly as a font size.
7124
+ fontSize: Math.max(11, Math.min(26, Math.round((node.size ?? 0.34) * 46))),
7125
+ leader: node.leader === true,
7126
+ offscreenPolicy: node.offscreenPolicy ?? (node.label === "hud" ? "draw" : "clamp"),
7127
+ ...(node.label === "hud" && node.screenAnchor ? { screenAnchor: node.screenAnchor } : {}),
7128
+ ...(node.label === "hud" && !node.screenAnchor ? { screenAnchor: "top-left" } : {})
7129
+ };
7130
+ });
7131
+ }
7132
+ /**
7133
+ * Mount the world-label layer for a canvas, if the scene has any label nodes.
7134
+ *
7135
+ * Returns `undefined` in headless or label-free scenes so nothing is created that
7136
+ * would then need disposing.
7137
+ */
7138
+ function createSceneLabelLayer(canvas, snapshot) {
7139
+ if (!canvas || typeof document === "undefined")
7140
+ return undefined;
7141
+ const hasLabels = groups.flatten(snapshot.nodes).some((node) => node.kind === "label");
7142
+ if (!hasLabels)
7143
+ return undefined;
7144
+ return createWorldLabelLayer({ container: canvas.parentElement ?? document.body, canvas });
7145
+ }
7055
7146
  async function startProductionRender(canvas, snapshot, diagnosticsState, options, overlay, beforeRender, isPaused = () => false, runtimeNodes) {
7056
7147
  const renderableNode = snapshot.nodes.find(isWebGLRenderableNode);
7057
7148
  if (!renderableNode) {
@@ -7060,6 +7151,7 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
7060
7151
  const renderer = await createProductionSceneRenderer(canvas, snapshot, options.renderer, runtimeNodes);
7061
7152
  diagnosticsState.renderer = renderer.diagnostics;
7062
7153
  const continuousRender = shouldContinuouslyRender(snapshot);
7154
+ const labelLayer = createSceneLabelLayer(canvas, snapshot);
7063
7155
  let disposed = false;
7064
7156
  let animationHandle = 0;
7065
7157
  let lastTime = 0;
@@ -7077,6 +7169,13 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
7077
7169
  diagnosticsState.renderSize = [canvas.width, canvas.height];
7078
7170
  diagnosticsState.evidence = collectAuraSceneEvidence(snapshot);
7079
7171
  diagnosticsState.renderer = renderer.diagnostics;
7172
+ if (labelLayer) {
7173
+ // Reproject every frame against the renderer's own camera so labels track
7174
+ // their anchors while the camera moves.
7175
+ labelLayer.setLabels(worldLabelsFromSnapshot(snapshot, runtimeNodes));
7176
+ labelLayer.update(renderer.viewProjection(time));
7177
+ diagnosticsState.labels = labelLayer.snapshot();
7178
+ }
7080
7179
  overlay?.update();
7081
7180
  if (continuousRender && options.autoStart !== false && typeof requestAnimationFrame !== "undefined") {
7082
7181
  animationHandle = requestAnimationFrame(renderFrame);
@@ -7091,6 +7190,7 @@ async function startProductionRender(canvas, snapshot, diagnosticsState, options
7091
7190
  disposed = true;
7092
7191
  if (animationHandle && typeof cancelAnimationFrame !== "undefined")
7093
7192
  cancelAnimationFrame(animationHandle);
7193
+ labelLayer?.dispose();
7094
7194
  renderer.dispose();
7095
7195
  }
7096
7196
  };
@@ -7131,38 +7231,7 @@ async function createProductionSceneRenderer(canvas, snapshot, rendererOptions,
7131
7231
  ], runtimeNodes);
7132
7232
  }
7133
7233
  }
7134
- const PRODUCTION_RUNTIME_POSTPROCESS = {
7135
- targetFormat: "rgba8",
7136
- toneMapping: {
7137
- exposure: 1.14,
7138
- whitePoint: 1.18,
7139
- operator: "filmic",
7140
- inputColorSpace: "linear",
7141
- outputColorSpace: "srgb"
7142
- },
7143
- colorGrade: {
7144
- contrast: 1.1,
7145
- saturation: 1.06,
7146
- vibrance: 0.12,
7147
- vignette: 0.08,
7148
- sharpening: 0.24
7149
- },
7150
- fxaa: {
7151
- edgeThreshold: 0.08,
7152
- subpixelBlend: 0.55
7153
- }
7154
- };
7155
- const PRODUCTION_RUNTIME_SHADOWS = {
7156
- enabled: true,
7157
- size: 1024,
7158
- bias: 0.0014,
7159
- strength: 0.28,
7160
- pcfRadius: 1.2,
7161
- pcfSamples: 9,
7162
- filter: "pcf",
7163
- label: "aura3d-root-production-shadow-map"
7164
- };
7165
- let cachedProductionRuntimeLights;
7234
+ let cachedProductionRuntimeFallbackLights;
7166
7235
  function createProductionRuntimeEnvironment(snapshot) {
7167
7236
  const names = groups.flatten(snapshot.nodes).map((node) => "name" in node ? node.name?.toLowerCase() ?? "" : "");
7168
7237
  const category = resolveRendererSceneCategory(snapshot, names);
@@ -7179,11 +7248,149 @@ function createProductionRuntimeEnvironment(snapshot) {
7179
7248
  lighting: bundle.lighting
7180
7249
  };
7181
7250
  }
7182
- function createProductionRuntimePostprocess() {
7183
- return PRODUCTION_RUNTIME_POSTPROCESS;
7251
+ /**
7252
+ * Translates a public `effects.fog(...)` node into renderer forward-pass fog.
7253
+ *
7254
+ * Without this the root bridge never set `environmentFog`, so `effects.fog()` was
7255
+ * accepted by the scene builder, reported as `fog.enabled` in diagnostics, and
7256
+ * changed exactly zero pixels through `createAuraApp`. Returning `false` when no
7257
+ * fog node is authored keeps the unfogged path unchanged.
7258
+ */
7259
+ function createProductionRuntimeEnvironmentFog(snapshot) {
7260
+ const fog = groups.flatten(snapshot.nodes).find((node) => node.kind === "effect" && node.effect === "fog");
7261
+ if (!fog)
7262
+ return false;
7263
+ const density = clampNumber(fog.density ?? 0.12, 0, 1);
7264
+ const intensity = clampNumber(fog.intensity ?? 0.5, 0, 1);
7265
+ const color = colorToRgb(fog.color ?? "#9fb7d9");
7266
+ return {
7267
+ // Exponential-squared reads as depth haze rather than a hard linear band, which
7268
+ // matches what the public helper documents.
7269
+ mode: "exponential-squared",
7270
+ color: [color[0], color[1], color[2]],
7271
+ near: 1,
7272
+ far: 60,
7273
+ density,
7274
+ maxOpacity: clampNumber(0.25 + intensity * 0.55, 0, 0.92)
7275
+ };
7184
7276
  }
7185
- function createProductionRuntimeShadowOptions() {
7186
- return PRODUCTION_RUNTIME_SHADOWS;
7277
+ function createProductionRuntimePostprocess(snapshot) {
7278
+ const nodes = groups.flatten(snapshot.nodes);
7279
+ const names = nodes.map((node) => "name" in node ? node.name?.toLowerCase() ?? "" : "");
7280
+ const category = resolveRendererSceneCategory(snapshot, names);
7281
+ const authoredBloom = nodes.find((node) => node.kind === "effect" && node.effect === "bloom");
7282
+ const emissiveSubjects = nodes.filter((node) => {
7283
+ if (!("material" in node) || !node.material)
7284
+ return false;
7285
+ return Boolean(node.material.emissive) && (node.material.emissiveIntensity ?? 1) > 0;
7286
+ }).length;
7287
+ const darkScene = ["neon", "city-night", "space", "game"].includes(category);
7288
+ const bloomRequested = Boolean(authoredBloom) || (darkScene && emissiveSubjects > 0);
7289
+ // Root previously advertised `ssao` in `requestedPasses` whenever a scene added
7290
+ // effects.ambientOcclusion() or effects.contactOcclusion(), but never submitted
7291
+ // an `ssao` option to the renderer. The advertised pass could therefore never
7292
+ // run, and `ambientOcclusionPass` was permanently false. Submit the real option
7293
+ // so the request and the rendered pass agree.
7294
+ const authoredAmbientOcclusion = nodes.find((node) => node.kind === "effect" && node.effect === "ambient-occlusion");
7295
+ const authoredContactOcclusion = nodes.find((node) => node.kind === "effect" && node.effect === "contact-occlusion");
7296
+ const authoredOcclusion = authoredAmbientOcclusion ?? authoredContactOcclusion;
7297
+ const exposure = category === "city-day" ? 1.02
7298
+ : category === "material" || category === "product" ? 1.08
7299
+ : category === "space" ? 1.18
7300
+ : 1.12;
7301
+ const saturation = category === "material" || category === "product" ? 1.01
7302
+ : category === "city-day" ? 1.04
7303
+ : 1.1;
7304
+ return {
7305
+ targetFormat: "rgba8",
7306
+ ...(bloomRequested ? {
7307
+ bloom: {
7308
+ threshold: clampNumber(authoredBloom?.threshold ?? (darkScene ? 0.68 : 0.78), 0, 1),
7309
+ intensity: clampNumber(authoredBloom?.intensity ?? Math.min(0.5, 0.24 + emissiveSubjects * 0.035), 0, 2),
7310
+ radius: Math.max(1, Math.min(4, Math.round(authoredBloom?.radius ?? (category === "space" ? 3 : 2))))
7311
+ }
7312
+ } : {}),
7313
+ ...(authoredOcclusion ? {
7314
+ ssao: {
7315
+ // The renderer's SSAO radius is an integer sample-kernel size in pixels
7316
+ // (1-8), while the public effect `radius` is a world-space extent whose
7317
+ // default is 0.42. Passing the authored value straight through threw
7318
+ // "SSAO radius must be an integer in [1, 8]" and left the route with zero
7319
+ // draw calls, so it is mapped onto the kernel range instead.
7320
+ radius: Math.max(1, Math.min(8, Math.round((authoredOcclusion.radius ?? 0.42) * 8))),
7321
+ intensity: clampNumber(authoredOcclusion.intensity ?? 0.32, 0, 1),
7322
+ bias: 0.025
7323
+ }
7324
+ } : {}),
7325
+ toneMapping: {
7326
+ exposure,
7327
+ whitePoint: category === "city-day" ? 1.28 : 1.18,
7328
+ operator: "filmic",
7329
+ inputColorSpace: "linear",
7330
+ outputColorSpace: "srgb"
7331
+ },
7332
+ colorGrade: {
7333
+ contrast: category === "material" || category === "product" ? 1.06 : 1.1,
7334
+ saturation,
7335
+ vibrance: darkScene ? 0.14 : 0.06,
7336
+ vignette: category === "game" || category === "neon" ? 0.1 : 0.04,
7337
+ sharpening: category === "material" || category === "product" ? 0.28 : 0.2
7338
+ },
7339
+ fxaa: {
7340
+ edgeThreshold: category === "game" ? 0.07 : 0.09,
7341
+ subpixelBlend: category === "material" || category === "product" ? 0.48 : 0.58
7342
+ }
7343
+ };
7344
+ }
7345
+ function createProductionRuntimeShadowOptions(snapshot, collectedLights) {
7346
+ const nodes = groups.flatten(snapshot.nodes);
7347
+ const names = nodes.map((node) => "name" in node ? node.name?.toLowerCase() ?? "" : "");
7348
+ const category = resolveRendererSceneCategory(snapshot, names);
7349
+ const sceneRadius = nodes.reduce((radius, node) => {
7350
+ const position = "position" in node && Array.isArray(node.position)
7351
+ ? node.position
7352
+ : [0, 0, 0];
7353
+ const nodeScale = "scale" in node ? node.scale : undefined;
7354
+ const scale = typeof nodeScale === "number"
7355
+ ? Math.abs(nodeScale)
7356
+ : Array.isArray(nodeScale) ? Math.max(...nodeScale.map(Math.abs)) : 1;
7357
+ return Math.max(radius, Math.hypot(...position) + scale);
7358
+ }, 1);
7359
+ const shadowCaster = collectedLights.find((light) => light.castsShadow);
7360
+ const size = sceneRadius > 30 ? 4096 : sceneRadius > 10 ? 2048 : 1024;
7361
+ const texelWorldSize = (sceneRadius * 2) / size;
7362
+ return {
7363
+ enabled: Boolean(shadowCaster),
7364
+ size,
7365
+ bias: clampNumber(texelWorldSize * 0.55, 0.00035, 0.004),
7366
+ strength: category === "city-day" ? 0.38
7367
+ : category === "material" || category === "product" ? 0.24
7368
+ : 0.32,
7369
+ pcfRadius: size >= 2048 ? 1.5 : 1.2,
7370
+ pcfSamples: size >= 2048 ? 16 : 9,
7371
+ filter: "pcf",
7372
+ label: `aura3d-root-production-${category}-${size}px-shadow-map`
7373
+ };
7374
+ }
7375
+ /**
7376
+ * Device-observed shadow state. `requested` comes from the submitted shadow
7377
+ * options, but `mapRendered`/`mapSampled` come only from what the device
7378
+ * actually did: a shadow depth target has to exist and a shader has to bind and
7379
+ * sample it. This is what stops the root report from publishing an unconditional
7380
+ * `shadows.enabled: true`.
7381
+ */
7382
+ function createProductionRuntimeShadowObservation(shadowOptions, diagnostics) {
7383
+ const nativeShadowMapBindings = diagnostics.nativeShadowMapBindings ?? 0;
7384
+ const mapRendered = Boolean(shadowOptions.enabled) && (diagnostics.shadowRenderTargetsAllocated ?? 0) > 0;
7385
+ return {
7386
+ requested: Boolean(shadowOptions.enabled),
7387
+ mapRendered,
7388
+ mapSampled: mapRendered && nativeShadowMapBindings > 0,
7389
+ mapSize: shadowOptions.size,
7390
+ label: shadowOptions.label,
7391
+ nativeShadowMapBindings,
7392
+ shadowRenderTargetsAllocated: diagnostics.shadowRenderTargetsAllocated ?? 0
7393
+ };
7187
7394
  }
7188
7395
  function createProductionRuntimePostprocessObservation(diagnostics) {
7189
7396
  const actualPasses = diagnostics.postprocessPassNames ?? [];
@@ -7199,22 +7406,150 @@ function createProductionRuntimePostprocessObservation(diagnostics) {
7199
7406
  fallbackPasses: pixelBacked ? [] : ["direct-render"]
7200
7407
  };
7201
7408
  }
7202
- function createProductionRuntimeCollectedLights() {
7203
- if (cachedProductionRuntimeLights)
7204
- return cachedProductionRuntimeLights;
7205
- const key = new DirectionalLight("aura3d-root-production-key-shadow");
7206
- const fill = new DirectionalLight("aura3d-root-production-fill");
7207
- const rim = new DirectionalLight("aura3d-root-production-rim");
7208
- key.castsShadow = true;
7209
- key.color = [1, 0.94, 0.82];
7210
- key.intensity = 2.6;
7211
- fill.color = [0.52, 0.64, 0.9];
7212
- fill.intensity = 0.64;
7213
- rim.color = [0.88, 0.94, 1];
7214
- rim.intensity = 0.88;
7215
- cachedProductionRuntimeLights = [
7409
+ function createProductionRuntimeCollectedLights(snapshot) {
7410
+ const authoredLights = groups.flatten(snapshot.nodes).filter((node) => node.kind === "light");
7411
+ const descriptors = authoredLights.flatMap((node, index) => createProductionRuntimeLightDescriptors(node, index));
7412
+ if (descriptors.length === 0)
7413
+ return createProductionRuntimeFallbackLights();
7414
+ const shadowCasterIndex = descriptors.reduce((selected, descriptor, index) => {
7415
+ if (selected < 0)
7416
+ return index;
7417
+ const current = descriptors[selected];
7418
+ if (descriptor.shadowPriority !== current.shadowPriority) {
7419
+ return descriptor.shadowPriority > current.shadowPriority ? index : selected;
7420
+ }
7421
+ return descriptor.intensity > current.intensity ? index : selected;
7422
+ }, -1);
7423
+ return descriptors.map((descriptor, index) => createProductionRuntimeCollectedLight(descriptor, index === shadowCasterIndex));
7424
+ }
7425
+ function createProductionRuntimeLightDescriptors(node, authoredIndex) {
7426
+ const name = node.name?.trim() || `aura-authored-${node.light}-${authoredIndex + 1}`;
7427
+ const color = colorToRgb(node.color ?? "#ffffff");
7428
+ const intensity = nonNegativeFinite(node.intensity);
7429
+ const position = productionRuntimeLightPosition(node);
7430
+ const direction = productionRuntimeLightDirection(node, position);
7431
+ if (node.light === "ambient") {
7432
+ // CollectedLight intentionally represents direct lights only. Ambient light remains
7433
+ // environment-lighting intent and does not masquerade as a directional light.
7434
+ return [];
7435
+ }
7436
+ if (node.light === "directional") {
7437
+ return [{
7438
+ kind: "directional",
7439
+ name,
7440
+ color,
7441
+ intensity,
7442
+ position,
7443
+ direction,
7444
+ range: 0,
7445
+ spotAngle: 0,
7446
+ penumbra: 0,
7447
+ shadowPriority: 3,
7448
+ authoredLight: node.light
7449
+ }];
7450
+ }
7451
+ if (node.light === "point") {
7452
+ return [{
7453
+ kind: "point",
7454
+ name,
7455
+ color,
7456
+ intensity,
7457
+ position,
7458
+ direction,
7459
+ range: 10 * productionRuntimeLightMaxScale(node.scale),
7460
+ spotAngle: 0,
7461
+ penumbra: 0,
7462
+ shadowPriority: 1,
7463
+ authoredLight: node.light
7464
+ }];
7465
+ }
7466
+ if (node.light === "studio") {
7467
+ return createProductionRuntimeStudioLightDescriptors(node, name, color, intensity, position);
7468
+ }
7469
+ const width = positiveFinite(node.width, node.light === "softbox" ? 2.4 : 2.2)
7470
+ * productionRuntimeLightAxisScale(node.scale, 0);
7471
+ const height = positiveFinite(node.height, node.light === "softbox" ? 1.6 : 1.2)
7472
+ * productionRuntimeLightAxisScale(node.scale, 1);
7473
+ const target = node.lookAt ?? [0, 0.75, 0];
7474
+ const targetDistance = Math.max(0.001, distance3(position, target));
7475
+ const halfDiagonal = Math.hypot(width, height) / 2;
7476
+ return [{
7477
+ kind: "spot",
7478
+ name: `${name}-${node.light}-spot-proxy`,
7479
+ color,
7480
+ intensity,
7481
+ position,
7482
+ direction,
7483
+ range: Math.max(1, targetDistance + halfDiagonal * 2),
7484
+ spotAngle: clampNumber(Math.atan2(halfDiagonal, targetDistance), 0.08, Math.PI / 2 - 0.01),
7485
+ penumbra: node.light === "softbox" ? 0.78 : 0.42,
7486
+ shadowPriority: 2,
7487
+ authoredLight: node.light,
7488
+ authoredWidth: width,
7489
+ authoredHeight: height
7490
+ }];
7491
+ }
7492
+ function createProductionRuntimeStudioLightDescriptors(node, name, color, intensity, position) {
7493
+ const target = node.lookAt ?? [0, 0.75, 0];
7494
+ const fillPosition = [
7495
+ position[0] === 0 ? 3.2 : -position[0],
7496
+ Math.max(1, position[1] * 0.72),
7497
+ position[2] * 0.58
7498
+ ];
7499
+ const rimPosition = [
7500
+ position[0] * 0.2,
7501
+ Math.max(1, position[1] * 0.88),
7502
+ position[2] === 0 ? -3.6 : -Math.abs(position[2])
7503
+ ];
7504
+ return [
7216
7505
  {
7217
7506
  kind: "directional",
7507
+ name: `${name}-key`,
7508
+ color,
7509
+ intensity,
7510
+ position,
7511
+ direction: productionRuntimeLightDirection(node, position),
7512
+ range: 0,
7513
+ spotAngle: 0,
7514
+ penumbra: 0,
7515
+ shadowPriority: 3,
7516
+ authoredLight: node.light
7517
+ },
7518
+ {
7519
+ kind: "directional",
7520
+ name: `${name}-fill`,
7521
+ color: multiplyRgb(color, [0.62, 0.72, 1]),
7522
+ intensity: intensity * 0.32,
7523
+ position: fillPosition,
7524
+ direction: normalizedDirection(fillPosition, target),
7525
+ range: 0,
7526
+ spotAngle: 0,
7527
+ penumbra: 0,
7528
+ shadowPriority: 0,
7529
+ authoredLight: node.light
7530
+ },
7531
+ {
7532
+ kind: "directional",
7533
+ name: `${name}-rim`,
7534
+ color: multiplyRgb(color, [0.84, 0.92, 1]),
7535
+ intensity: intensity * 0.54,
7536
+ position: rimPosition,
7537
+ direction: normalizedDirection(rimPosition, target),
7538
+ range: 0,
7539
+ spotAngle: 0,
7540
+ penumbra: 0,
7541
+ shadowPriority: 0,
7542
+ authoredLight: node.light
7543
+ }
7544
+ ];
7545
+ }
7546
+ function createProductionRuntimeFallbackLights() {
7547
+ if (cachedProductionRuntimeFallbackLights)
7548
+ return cachedProductionRuntimeFallbackLights;
7549
+ const descriptors = [
7550
+ {
7551
+ kind: "directional",
7552
+ name: "aura3d-root-production-fallback-key-shadow",
7218
7553
  color: [1, 0.94, 0.82],
7219
7554
  intensity: 2.6,
7220
7555
  position: [0, 0, 0],
@@ -7222,12 +7557,12 @@ function createProductionRuntimeCollectedLights() {
7222
7557
  range: 0,
7223
7558
  spotAngle: 0,
7224
7559
  penumbra: 0,
7225
- castsShadow: true,
7226
- layerMask: 0xffffffff,
7227
- source: key
7560
+ shadowPriority: 3,
7561
+ authoredLight: "fallback"
7228
7562
  },
7229
7563
  {
7230
7564
  kind: "directional",
7565
+ name: "aura3d-root-production-fallback-fill",
7231
7566
  color: [0.52, 0.64, 0.9],
7232
7567
  intensity: 0.64,
7233
7568
  position: [0, 0, 0],
@@ -7235,12 +7570,12 @@ function createProductionRuntimeCollectedLights() {
7235
7570
  range: 0,
7236
7571
  spotAngle: 0,
7237
7572
  penumbra: 0,
7238
- castsShadow: false,
7239
- layerMask: 0xffffffff,
7240
- source: fill
7573
+ shadowPriority: 0,
7574
+ authoredLight: "fallback"
7241
7575
  },
7242
7576
  {
7243
7577
  kind: "directional",
7578
+ name: "aura3d-root-production-fallback-rim",
7244
7579
  color: [0.88, 0.94, 1],
7245
7580
  intensity: 0.88,
7246
7581
  position: [0, 0, 0],
@@ -7248,12 +7583,120 @@ function createProductionRuntimeCollectedLights() {
7248
7583
  range: 0,
7249
7584
  spotAngle: 0,
7250
7585
  penumbra: 0,
7251
- castsShadow: false,
7252
- layerMask: 0xffffffff,
7253
- source: rim
7586
+ shadowPriority: 0,
7587
+ authoredLight: "fallback"
7254
7588
  }
7255
7589
  ];
7256
- return cachedProductionRuntimeLights;
7590
+ cachedProductionRuntimeFallbackLights = descriptors.map((descriptor, index) => createProductionRuntimeCollectedLight(descriptor, index === 0));
7591
+ return cachedProductionRuntimeFallbackLights;
7592
+ }
7593
+ function createProductionRuntimeCollectedLight(descriptor, castsShadow) {
7594
+ const source = descriptor.kind === "directional"
7595
+ ? new DirectionalLight(descriptor.name)
7596
+ : descriptor.kind === "point"
7597
+ ? new PointLight(descriptor.name)
7598
+ : new SpotLight(descriptor.name);
7599
+ source.color = [...descriptor.color];
7600
+ source.intensity = descriptor.intensity;
7601
+ source.castsShadow = castsShadow;
7602
+ source.layerMask = 0xffffffff;
7603
+ source.userData.aura3dAuthoredLight = descriptor.authoredLight;
7604
+ if (descriptor.authoredWidth !== undefined)
7605
+ source.userData.aura3dAuthoredWidth = descriptor.authoredWidth;
7606
+ if (descriptor.authoredHeight !== undefined)
7607
+ source.userData.aura3dAuthoredHeight = descriptor.authoredHeight;
7608
+ source.transform.setPosition(...descriptor.position);
7609
+ if (source instanceof PointLight || source instanceof SpotLight) {
7610
+ source.range = Math.max(0.001, descriptor.range);
7611
+ }
7612
+ if (source instanceof SpotLight) {
7613
+ source.angle = clampNumber(descriptor.spotAngle, 0.001, Math.PI / 2 - 0.001);
7614
+ source.penumbra = clampNumber(descriptor.penumbra, 0, 1);
7615
+ }
7616
+ if (!(source instanceof PointLight)) {
7617
+ const rotation = quaternionFromForwardDirection(descriptor.direction);
7618
+ source.transform.setRotation(...rotation);
7619
+ }
7620
+ source.updateWorldTransform(true);
7621
+ return {
7622
+ kind: descriptor.kind,
7623
+ color: descriptor.color,
7624
+ intensity: descriptor.intensity,
7625
+ position: descriptor.position,
7626
+ direction: normalize3(descriptor.direction),
7627
+ range: descriptor.range,
7628
+ spotAngle: descriptor.spotAngle,
7629
+ penumbra: descriptor.penumbra,
7630
+ castsShadow,
7631
+ layerMask: 0xffffffff,
7632
+ source
7633
+ };
7634
+ }
7635
+ function productionRuntimeLightPosition(node) {
7636
+ const fallback = node.light === "directional" ? [3, 4, 3]
7637
+ : node.light === "point" ? [2, 2.5, 1.5]
7638
+ : node.light === "studio" ? [0, 3, 4]
7639
+ : node.light === "softbox" ? [-2.2, 2.4, 2.2]
7640
+ : node.light === "rect" ? [0, 2.6, 1.8]
7641
+ : [0, 0, 0];
7642
+ const position = node.position ?? fallback;
7643
+ return position.map((component, index) => Number.isFinite(component) ? component : fallback[index]);
7644
+ }
7645
+ function productionRuntimeLightDirection(node, position) {
7646
+ if (node.lookAt) {
7647
+ const direction = normalizedDirection(position, node.lookAt);
7648
+ if (length3(direction) > 0)
7649
+ return direction;
7650
+ }
7651
+ if (node.rotation) {
7652
+ const matrix = rotationXYZ(node.rotation);
7653
+ return normalize3([-matrix[8], -matrix[9], -matrix[10]]);
7654
+ }
7655
+ if (length3(position) > 0.000001)
7656
+ return normalize3([-position[0], -position[1], -position[2]]);
7657
+ return [0, -1, 0];
7658
+ }
7659
+ function quaternionFromForwardDirection(direction) {
7660
+ const target = normalize3(direction);
7661
+ const dot = clampNumber(-target[2], -1, 1);
7662
+ if (dot > 0.999999)
7663
+ return [0, 0, 0, 1];
7664
+ if (dot < -0.999999)
7665
+ return [0, 1, 0, 0];
7666
+ const quaternion = [target[1], -target[0], 0, 1 + dot];
7667
+ const length = Math.hypot(...quaternion) || 1;
7668
+ return [
7669
+ quaternion[0] / length,
7670
+ quaternion[1] / length,
7671
+ quaternion[2] / length,
7672
+ quaternion[3] / length
7673
+ ];
7674
+ }
7675
+ function normalizedDirection(from, to) {
7676
+ const direction = [to[0] - from[0], to[1] - from[1], to[2] - from[2]];
7677
+ return length3(direction) > 0.000001 ? normalize3(direction) : [0, -1, 0];
7678
+ }
7679
+ function length3(value) {
7680
+ return Math.hypot(value[0], value[1], value[2]);
7681
+ }
7682
+ function productionRuntimeLightMaxScale(scale) {
7683
+ return Math.max(productionRuntimeLightAxisScale(scale, 0), productionRuntimeLightAxisScale(scale, 1), productionRuntimeLightAxisScale(scale, 2));
7684
+ }
7685
+ function productionRuntimeLightAxisScale(scale, axis) {
7686
+ const value = typeof scale === "number" ? scale : scale?.[axis] ?? 1;
7687
+ return positiveFinite(Math.abs(value), 1);
7688
+ }
7689
+ function nonNegativeFinite(value) {
7690
+ return Number.isFinite(value) ? Math.max(0, value) : 0;
7691
+ }
7692
+ function positiveFinite(value, fallback) {
7693
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback;
7694
+ }
7695
+ function clampNumber(value, min, max) {
7696
+ return Math.max(min, Math.min(max, Number.isFinite(value) ? value : min));
7697
+ }
7698
+ function multiplyRgb(color, tint) {
7699
+ return [color[0] * tint[0], color[1] * tint[1], color[2] * tint[2]];
7257
7700
  }
7258
7701
  async function createProductionRuntimeSceneRenderer(canvas, snapshot, rendererOptions, runtimeNodes) {
7259
7702
  const flattened = groups.flatten(snapshot.nodes);
@@ -7283,10 +7726,16 @@ async function createProductionRuntimeSceneRenderer(canvas, snapshot, rendererOp
7283
7726
  let latestFeatures = productionRenderer.getFeatures();
7284
7727
  const runtimeWarnings = new Set();
7285
7728
  const productionEnvironment = createProductionRuntimeEnvironment(snapshot);
7729
+ const productionRuntimeLights = createProductionRuntimeCollectedLights(snapshot);
7730
+ const authoredLightNodes = flattened.filter((node) => node.kind === "light");
7731
+ const authoredDirectLightNodes = authoredLightNodes.filter((node) => node.light !== "ambient");
7732
+ const authoredAmbientLightCount = authoredLightNodes.length - authoredDirectLightNodes.length;
7733
+ const authoredAreaProxyCount = authoredDirectLightNodes.filter((node) => node.light === "rect" || node.light === "softbox").length;
7286
7734
  const buildDiagnostics = () => createRendererDiagnosticReport(snapshot, {
7287
7735
  mounted: true,
7288
7736
  backend: "production-runtime",
7289
7737
  postprocess: createProductionRuntimePostprocessObservation(latestDeviceDiagnostics),
7738
+ shadow: createProductionRuntimeShadowObservation(createProductionRuntimeShadowOptions(snapshot, productionRuntimeLights), latestDeviceDiagnostics),
7290
7739
  environment: {
7291
7740
  enabled: true,
7292
7741
  preset: productionEnvironment.preset,
@@ -7295,6 +7744,15 @@ async function createProductionRuntimeSceneRenderer(canvas, snapshot, rendererOp
7295
7744
  },
7296
7745
  warnings: [
7297
7746
  `Production runtime bridge active with ${actorEntries.length} typed GLB actor${actorEntries.length === 1 ? "" : "s"} and ${primitiveEntries.length} Aura primitive${primitiveEntries.length === 1 ? "" : "s"} on ${productionRenderer.backend}.`,
7747
+ ...(authoredDirectLightNodes.length === 0
7748
+ ? ["Production runtime direct-light fallback active: the scene has no authored directional, point, studio, rect, or softbox light."]
7749
+ : [`Production runtime derived ${productionRuntimeLights.length} collected direct light${productionRuntimeLights.length === 1 ? "" : "s"} from ${authoredDirectLightNodes.length} authored scene light${authoredDirectLightNodes.length === 1 ? "" : "s"}.`]),
7750
+ ...(authoredAmbientLightCount > 0
7751
+ ? [`${authoredAmbientLightCount} authored ambient light${authoredAmbientLightCount === 1 ? "" : "s"} remain environment-lighting intent and are not mislabeled as direct CollectedLight entries.`]
7752
+ : []),
7753
+ ...(authoredAreaProxyCount > 0
7754
+ ? [`${authoredAreaProxyCount} authored rect/softbox light${authoredAreaProxyCount === 1 ? "" : "s"} use bounded spot-light proxies whose cone and range derive from authored width and height; this does not claim physical area-light shading.`]
7755
+ : []),
7298
7756
  ...(flattened.some((node) => node.kind === "effect")
7299
7757
  ? ["Effect nodes are requested in the scene graph; production bridge diagnostics report them, but unsupported postprocess/effect passes remain non-pixel-backed until the runtime feature reports support."]
7300
7758
  : []),
@@ -7314,12 +7772,15 @@ async function createProductionRuntimeSceneRenderer(canvas, snapshot, rendererOp
7314
7772
  },
7315
7773
  render(time) {
7316
7774
  runtimeWarnings.clear();
7317
- const input = createProductionRuntimeRendererInput(snapshot, canvas, actorEntries, primitiveEntries, time, runtimeNodes, runtimeWarnings, productionEnvironment.lighting);
7775
+ const input = createProductionRuntimeRendererInput(snapshot, canvas, actorEntries, primitiveEntries, time, runtimeNodes, runtimeWarnings, productionEnvironment.lighting, productionRuntimeLights);
7318
7776
  const result = productionRenderer.renderInteractiveFrame(input);
7319
7777
  latestDeviceDiagnostics = result.diagnostics;
7320
7778
  latestFeatures = result.features;
7321
7779
  return latestDeviceDiagnostics.drawCalls;
7322
7780
  },
7781
+ viewProjection(time) {
7782
+ return createViewProjection(snapshot, canvas.width / Math.max(1, canvas.height), time, runtimeNodes);
7783
+ },
7323
7784
  dispose() {
7324
7785
  productionRenderer.dispose();
7325
7786
  for (const { actor } of actorEntries)
@@ -7331,7 +7792,7 @@ async function createProductionRuntimeSceneRenderer(canvas, snapshot, rendererOp
7331
7792
  }
7332
7793
  };
7333
7794
  }
7334
- function createProductionRuntimeRendererInput(snapshot, canvas, actorEntries, primitiveEntries, time, runtimeNodes, runtimeWarnings, environmentLighting) {
7795
+ function createProductionRuntimeRendererInput(snapshot, canvas, actorEntries, primitiveEntries, time, runtimeNodes, runtimeWarnings, environmentLighting, collectedLights) {
7335
7796
  const items = [];
7336
7797
  for (const entry of actorEntries) {
7337
7798
  const currentState = resolveProductionActorRuntimeState(entry, runtimeNodes);
@@ -7340,7 +7801,7 @@ function createProductionRuntimeRendererInput(snapshot, canvas, actorEntries, pr
7340
7801
  continue;
7341
7802
  applyProductionActorAnimation(entry, currentNode, currentState.animationBinding, time, runtimeWarnings);
7342
7803
  applyProductionActorMorphTargets(entry, currentState.morphTargets, runtimeWarnings);
7343
- const modelMatrix = [...createModelMatrix(currentNode, boundsFromAuraAsset(currentNode.asset), shouldNormalizeModelNode(currentNode), time)];
7804
+ const modelMatrix = [...createModelMatrix(currentNode, productionActorModelBounds(currentNode.asset, entry.actor), shouldNormalizeModelNode(currentNode), time)];
7344
7805
  const actorItems = entry.actor.collectRenderItems({ modelMatrix });
7345
7806
  items.push(...actorItems);
7346
7807
  attachProductionActorEvidence(currentNode, entry.actor, actorItems, runtimeNodes);
@@ -7362,12 +7823,13 @@ function createProductionRuntimeRendererInput(snapshot, canvas, actorEntries, pr
7362
7823
  const source = {
7363
7824
  collectRenderItems: () => items,
7364
7825
  cameraPolicy: "require",
7365
- staticBatching: false,
7366
- frustumCulling: false,
7367
- collectedLights: createProductionRuntimeCollectedLights(),
7826
+ staticBatching: true,
7827
+ frustumCulling: true,
7828
+ collectedLights,
7368
7829
  environmentLighting,
7369
- postprocess: createProductionRuntimePostprocess(),
7370
- shadow: createProductionRuntimeShadowOptions(),
7830
+ postprocess: createProductionRuntimePostprocess(snapshot),
7831
+ shadow: createProductionRuntimeShadowOptions(snapshot, collectedLights),
7832
+ environmentFog: createProductionRuntimeEnvironmentFog(snapshot),
7371
7833
  cameraPosition
7372
7834
  };
7373
7835
  const cameraLike = { viewProjectionMatrix };
@@ -7564,6 +8026,74 @@ function createProductionRuntimeMetadata(actorEntries) {
7564
8026
  function sumProductionMetadata(metadata, key) {
7565
8027
  return metadata.reduce((total, item) => total + item[key], 0);
7566
8028
  }
8029
+ /**
8030
+ * Bounds used to size a typed model in the production bridge.
8031
+ *
8032
+ * Order matters and is deliberate:
8033
+ *
8034
+ * 1. The actor's actually-loaded GLB bounds. These are what the geometry really
8035
+ * occupies, so the bridge stays correct even if a manifest is stale or was written
8036
+ * by an older CLI. Preferring metadata here once caused whole levels to disappear:
8037
+ * a world recorded with an ~8x-too-small X extent was sized far too large and
8038
+ * frustum-culled out of frame.
8039
+ * 2. Manifest `boundsMetadata` min/max, when loaded bounds are unavailable.
8040
+ * 3. The flat `bounds` size triple, only if neither is available. This assumes a
8041
+ * min-Y-at-zero box that the mesh may not match, so it is a last resort.
8042
+ *
8043
+ * `camera.frameAsset` is synchronous and can only read manifest metadata, so framing
8044
+ * and rendering agree only while the manifest matches the geometry. Both are correct
8045
+ * as of the scene-space bounds fix and manifest regeneration;
8046
+ * `auraProductionBoundsProbes()` records any per-asset disagreement at runtime so a
8047
+ * future divergence is observable rather than silent.
8048
+ */
8049
+ function productionActorModelBounds(asset, actor) {
8050
+ const loaded = typedGLBActorLoadedBounds(actor);
8051
+ const metadataBounds = asset.metadata?.boundsMetadata;
8052
+ const metadataMin = vec3FromReadonly(metadataBounds?.min);
8053
+ const metadataMax = vec3FromReadonly(metadataBounds?.max);
8054
+ if (loaded) {
8055
+ if (metadataMin && metadataMax) {
8056
+ productionBoundsProbes.set(asset.id, {
8057
+ assetId: asset.id,
8058
+ metadata: { min: metadataMin, max: metadataMax },
8059
+ loaded: { min: [...loaded.min], max: [...loaded.max] }
8060
+ });
8061
+ }
8062
+ return loaded;
8063
+ }
8064
+ if (metadataMin && metadataMax)
8065
+ return { min: metadataMin, max: metadataMax };
8066
+ return boundsFromAuraAsset(asset);
8067
+ }
8068
+ const productionBoundsProbes = new Map();
8069
+ /**
8070
+ * Diagnostic: manifest `boundsMetadata` versus the bounds actually computed from the
8071
+ * loaded GLB, per typed asset routed through the production bridge.
8072
+ *
8073
+ * The bridge sizes models from loaded bounds because those are what the geometry
8074
+ * really occupies. This accessor exists so a disagreement with manifest metadata —
8075
+ * which `camera.frameAsset` must use, being synchronous — is observable instead of
8076
+ * silently producing mismatched framing.
8077
+ */
8078
+ export function auraProductionBoundsProbes() {
8079
+ return [...productionBoundsProbes.values()];
8080
+ }
8081
+ /**
8082
+ * Real bounds of the loaded GLB scene, as computed from its geometry. Returns
8083
+ * undefined when the actor cannot supply them, so callers fall back to manifest
8084
+ * metadata rather than silently using a zeroed box.
8085
+ */
8086
+ function typedGLBActorLoadedBounds(actor) {
8087
+ const bounds = actor.pipeline?.resources?.bounds;
8088
+ const min = vec3FromReadonly(bounds?.min);
8089
+ const max = vec3FromReadonly(bounds?.max);
8090
+ if (!min || !max)
8091
+ return undefined;
8092
+ // A degenerate box would produce a divide-by-near-zero fit scale.
8093
+ if (max[0] - min[0] <= 0 && max[1] - min[1] <= 0 && max[2] - min[2] <= 0)
8094
+ return undefined;
8095
+ return { min, max };
8096
+ }
7567
8097
  function boundsFromAuraAsset(asset) {
7568
8098
  const metadataBounds = asset.metadata?.boundsMetadata;
7569
8099
  const metadataMin = vec3FromReadonly(metadataBounds?.min);
@@ -7963,6 +8493,9 @@ async function createWebGLSceneRenderer(canvas, snapshot, rendererOptions, runti
7963
8493
  }
7964
8494
  return drawCalls;
7965
8495
  },
8496
+ viewProjection(time) {
8497
+ return createViewProjection(snapshot, canvas.width / Math.max(1, canvas.height), time, runtimeNodes);
8498
+ },
7966
8499
  dispose() {
7967
8500
  for (const modelEntry of models) {
7968
8501
  const textures = new Set();
@@ -8858,7 +9391,13 @@ function createPlaneGeometry() {
8858
9391
  0, 1, 0,
8859
9392
  0, 1, 0
8860
9393
  ]),
8861
- indices: new Uint16Array([0, 1, 2, 0, 2, 3]),
9394
+ // Counter-clockwise when viewed from +Y, so the triangle winding agrees with
9395
+ // the [0, 1, 0] vertex normals. The previous [0, 1, 2, 0, 2, 3] order wound
9396
+ // the opposite way: its geometric normal was [0, -1, 0], so `gl_FrontFacing`
9397
+ // was false for a camera above the plane and the two-sided shader flipped the
9398
+ // up-normal downward. The plane then faced away from every overhead light and
9399
+ // received no direct lighting or visible cast shadows.
9400
+ indices: new Uint16Array([0, 2, 1, 0, 3, 2]),
8862
9401
  bounds: { min: [-0.5, 0, -0.5], max: [0.5, 0, 0.5] }
8863
9402
  };
8864
9403
  }
@@ -9542,6 +10081,23 @@ function appendCanvas(target) {
9542
10081
  target.append(canvas);
9543
10082
  return canvas;
9544
10083
  }
10084
+ /**
10085
+ * `resize: false` means "do not take over sizing", not "render at the HTML
10086
+ * default backing store". A canvas element always reports `width === 300` and
10087
+ * `height === 150` until something assigns them, so a truthiness check on those
10088
+ * properties can never tell an author-chosen size from the spec default. Only an
10089
+ * explicit `width`/`height` attribute, or a backing store that was already
10090
+ * assigned to something other than the default pair, counts as author intent.
10091
+ */
10092
+ function hasAuthoredBackingStore(canvas) {
10093
+ if (canvas.dataset.aura3dCanvas === "true")
10094
+ return false;
10095
+ if (canvas.hasAttribute("width") || canvas.hasAttribute("height"))
10096
+ return true;
10097
+ return canvas.width !== DEFAULT_CANVAS_BACKING_WIDTH || canvas.height !== DEFAULT_CANVAS_BACKING_HEIGHT;
10098
+ }
10099
+ const DEFAULT_CANVAS_BACKING_WIDTH = 300;
10100
+ const DEFAULT_CANVAS_BACKING_HEIGHT = 150;
9545
10101
  function applyDefaultCanvasMountLayout(target) {
9546
10102
  if (typeof window === "undefined")
9547
10103
  return;
@@ -9571,8 +10127,9 @@ function configureCanvas(canvas, pixelRatio, resize) {
9571
10127
  canvas.style.height = `${cssHeight}px`;
9572
10128
  const width = Math.max(320, Math.round(cssWidth * pixelRatio));
9573
10129
  const height = Math.max(220, Math.round(cssHeight * pixelRatio));
9574
- canvas.width = resize ? width : canvas.width || width;
9575
- canvas.height = resize ? height : canvas.height || height;
10130
+ const keepAuthoredSize = !resize && hasAuthoredBackingStore(canvas);
10131
+ canvas.width = keepAuthoredSize ? canvas.width : width;
10132
+ canvas.height = keepAuthoredSize ? canvas.height : height;
9576
10133
  }
9577
10134
  function validateSceneAssets(snapshot, assets) {
9578
10135
  for (const node of snapshot.nodes) {
@@ -9638,7 +10195,8 @@ function snapshotDiagnostics(value) {
9638
10195
  evidence: value.evidence,
9639
10196
  renderer: value.renderer,
9640
10197
  warnings: [...value.warnings],
9641
- errors: [...value.errors]
10198
+ errors: [...value.errors],
10199
+ ...(value.labels ? { labels: value.labels } : {})
9642
10200
  };
9643
10201
  }
9644
10202
  function collectGeneratedCodeWarnings(snapshot) {