@woosh/meep-engine 3.23.0 → 3.24.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 (522) hide show
  1. package/editor/entity_world_bounds.d.ts +9 -3
  2. package/editor/entity_world_bounds.d.ts.map +1 -1
  3. package/editor/entity_world_bounds.js +61 -4
  4. package/package.json +1 -1
  5. package/src/core/binary/allocator/OffsetAllocator.d.ts +40 -2
  6. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  7. package/src/core/binary/allocator/OffsetAllocator.js +124 -29
  8. package/src/core/collection/map/u32_index.d.ts +83 -0
  9. package/src/core/collection/map/u32_index.d.ts.map +1 -0
  10. package/src/core/collection/map/u32_index.js +247 -0
  11. package/src/engine/asset/loaders/GLTFSceneBundleAssetLoader.d.ts +2 -2
  12. package/src/engine/asset/loaders/GLTFSceneBundleAssetLoader.js +2 -2
  13. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts +1 -2
  14. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts.map +1 -1
  15. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.js +4 -12
  16. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts +55 -0
  17. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts.map +1 -0
  18. package/src/engine/ecs/gpu/GPUStateAuthority.js +72 -0
  19. package/src/engine/ecs/gpu/GPUStateAuthorityFlags.d.ts +40 -0
  20. package/src/engine/ecs/gpu/GPUStateAuthorityFlags.d.ts.map +1 -0
  21. package/src/engine/ecs/gpu/GPUStateAuthorityFlags.js +79 -0
  22. package/src/engine/ecs/gpu/gpu_authority_assert_cpu.d.ts +18 -0
  23. package/src/engine/ecs/gpu/gpu_authority_assert_cpu.d.ts.map +1 -0
  24. package/src/engine/ecs/gpu/gpu_authority_assert_cpu.js +27 -0
  25. package/src/engine/ecs/gpu/gpu_authority_declare.d.ts +23 -0
  26. package/src/engine/ecs/gpu/gpu_authority_declare.d.ts.map +1 -0
  27. package/src/engine/ecs/gpu/gpu_authority_declare.js +39 -0
  28. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts +15 -0
  29. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts.map +1 -0
  30. package/src/engine/ecs/gpu/gpu_authority_grant.js +38 -0
  31. package/src/engine/ecs/gpu/gpu_authority_has.d.ts +18 -0
  32. package/src/engine/ecs/gpu/gpu_authority_has.d.ts.map +1 -0
  33. package/src/engine/ecs/gpu/gpu_authority_has.js +28 -0
  34. package/src/engine/ecs/gpu/gpu_authority_revoke.d.ts +24 -0
  35. package/src/engine/ecs/gpu/gpu_authority_revoke.d.ts.map +1 -0
  36. package/src/engine/ecs/gpu/gpu_authority_revoke.js +49 -0
  37. package/src/engine/ecs/ik/IKProblem.d.ts +14 -0
  38. package/src/engine/ecs/ik/IKProblem.d.ts.map +1 -1
  39. package/src/engine/ecs/ik/IKProblem.js +16 -0
  40. package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +1 -1
  41. package/src/engine/ecs/ik/InverseKinematicsSystem.js +19 -0
  42. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +2 -2
  43. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +2 -2
  44. package/src/engine/ecs/ik/ik_bone_chain.d.ts +11 -2
  45. package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +1 -1
  46. package/src/engine/ecs/ik/ik_bone_chain.js +47 -2
  47. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  48. package/src/engine/ecs/ik/ik_write_local_rotation.js +6 -0
  49. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  50. package/src/engine/ecs/speaker/VoiceSystem.js +6 -0
  51. package/src/engine/ecs/transform/T64WorldCache.d.ts +50 -0
  52. package/src/engine/ecs/transform/T64WorldCache.d.ts.map +1 -0
  53. package/src/engine/ecs/transform/T64WorldCache.js +139 -0
  54. package/src/engine/ecs/transform/t64_evaluate_world.d.ts +31 -0
  55. package/src/engine/ecs/transform/t64_evaluate_world.d.ts.map +1 -0
  56. package/src/engine/ecs/transform/t64_evaluate_world.js +126 -0
  57. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts +8 -0
  58. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  59. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +59 -30
  60. package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts.map +1 -1
  61. package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +4 -11
  62. package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.d.ts +14 -0
  63. package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.d.ts.map +1 -0
  64. package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.js +13 -0
  65. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +2 -14
  66. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts.map +1 -1
  67. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +11 -21
  68. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.d.ts +1 -0
  69. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +7 -0
  70. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts +5 -6
  71. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts.map +1 -1
  72. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.js +13 -11
  73. package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.d.ts +14 -0
  74. package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.d.ts.map +1 -0
  75. package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.js +21 -0
  76. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +1 -1
  77. package/src/engine/graphics/ecs/particles/ParticleEffect.js +1 -1
  78. package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.d.ts +1 -1
  79. package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.js +1 -1
  80. package/src/engine/graphics3/AnimationGraphSystem.js +3 -3
  81. package/src/engine/graphics3/AnimationSystem.js +2 -2
  82. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  83. package/src/engine/graphics3/DebugDrawSystem.js +2 -4
  84. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +34 -27
  85. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  86. package/src/engine/graphics3/GPUParticleEmitterSystem.js +185 -85
  87. package/src/engine/graphics3/HighlightOutlineSystem.d.ts +4 -3
  88. package/src/engine/graphics3/HighlightOutlineSystem.d.ts.map +1 -1
  89. package/src/engine/graphics3/HighlightOutlineSystem.js +7 -9
  90. package/src/engine/graphics3/LightSystem.d.ts +7 -5
  91. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  92. package/src/engine/graphics3/LightSystem.js +36 -22
  93. package/src/engine/graphics3/MeshSystem.d.ts +43 -39
  94. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  95. package/src/engine/graphics3/MeshSystem.js +324 -331
  96. package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -1
  97. package/src/engine/graphics3/PathDisplaySystem.js +2 -4
  98. package/src/engine/graphics3/PickingQuery.d.ts +15 -21
  99. package/src/engine/graphics3/PickingQuery.d.ts.map +1 -1
  100. package/src/engine/graphics3/PickingQuery.js +21 -25
  101. package/src/engine/graphics3/PickingSystem.d.ts +60 -31
  102. package/src/engine/graphics3/PickingSystem.d.ts.map +1 -1
  103. package/src/engine/graphics3/PickingSystem.js +416 -273
  104. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +22 -12
  105. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  106. package/src/engine/graphics3/ShadedGeometrySystem.js +309 -174
  107. package/src/engine/graphics3/TerrainSystem.d.ts +19 -11
  108. package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -1
  109. package/src/engine/graphics3/TerrainSystem.js +102 -53
  110. package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -1
  111. package/src/engine/graphics3/TooltipComponentSystem.js +2 -14
  112. package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -1
  113. package/src/engine/graphics3/Trail3DSystem.js +2 -4
  114. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +4 -4
  115. package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
  116. package/src/engine/graphics3/animation/ClipListPlayer.js +2 -2
  117. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts +9 -11
  118. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts.map +1 -1
  119. package/src/engine/graphics3/highlight/pack_highlight_table.js +11 -18
  120. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +4 -3
  121. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  122. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +75 -74
  123. package/src/engine/graphics3/prefab/Prefab.d.ts +130 -0
  124. package/src/engine/graphics3/prefab/Prefab.d.ts.map +1 -0
  125. package/src/engine/graphics3/prefab/Prefab.js +162 -0
  126. package/src/engine/graphics3/prefab/PrefabInstance.d.ts +72 -0
  127. package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -0
  128. package/src/engine/graphics3/prefab/PrefabInstance.js +80 -0
  129. package/src/engine/graphics3/prefab/prefab_compile.d.ts +23 -0
  130. package/src/engine/graphics3/prefab/prefab_compile.d.ts.map +1 -0
  131. package/src/engine/graphics3/prefab/prefab_compile.js +334 -0
  132. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +46 -0
  133. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -0
  134. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -0
  135. package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.d.ts +70 -0
  136. package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.d.ts.map +1 -0
  137. package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.js +210 -0
  138. package/src/engine/graphics3/prefab/prefab_place.d.ts +60 -0
  139. package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -0
  140. package/src/engine/graphics3/prefab/prefab_place.js +130 -0
  141. package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.d.ts +60 -0
  142. package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.d.ts.map +1 -0
  143. package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.js +128 -0
  144. package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts +40 -0
  145. package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts.map +1 -0
  146. package/src/engine/graphics3/prefab/prefab_skin_frame.js +116 -0
  147. package/src/engine/graphics3/preview/make_model_preview_scene.d.ts +16 -14
  148. package/src/engine/graphics3/preview/make_model_preview_scene.d.ts.map +1 -1
  149. package/src/engine/graphics3/preview/make_model_preview_scene.js +126 -154
  150. package/src/engine/graphics3/preview/make_model_thumbnail.js +1 -1
  151. package/src/engine/graphics3/register_instance_animation.d.ts +6 -6
  152. package/src/engine/graphics3/register_instance_animation.d.ts.map +1 -1
  153. package/src/engine/graphics3/register_instance_animation.js +4 -4
  154. package/src/engine/graphics3/shade_bundle_bounds.d.ts +2 -6
  155. package/src/engine/graphics3/shade_bundle_bounds.d.ts.map +1 -1
  156. package/src/engine/graphics3/shade_bundle_bounds.js +47 -55
  157. package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts +11 -18
  158. package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts.map +1 -1
  159. package/src/engine/graphics3/terrain/pack_terrain_row_table.js +48 -53
  160. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +17 -2
  161. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  162. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +284 -256
  163. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +13 -15
  164. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  165. package/src/engine/physics/cloth/ecs/ClothInstance.js +12 -14
  166. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +7 -8
  167. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
  168. package/src/engine/physics/cloth/ecs/ClothRig.js +7 -8
  169. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +5 -4
  170. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  171. package/src/engine/physics/cloth/ecs/ClothSystem.js +11 -12
  172. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +19 -23
  173. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  174. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +201 -199
  175. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  176. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +8 -0
  177. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +18 -34
  178. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
  179. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +58 -115
  180. package/src/engine/physics/cloth/playground/README.md +11 -11
  181. package/src/engine/physics/cloth/playground/garment_build.d.ts +0 -1
  182. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
  183. package/src/engine/physics/cloth/playground/garment_build.js +64 -58
  184. package/src/engine/physics/cloth/playground/garment_main.js +59 -33
  185. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  186. package/src/shade/RENDERER_CONTRACT.md +85 -53
  187. package/src/shade/device/ShadeGPUCommandContext.d.ts +23 -0
  188. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  189. package/src/shade/device/ShadeGPUCommandContext.js +36 -0
  190. package/src/shade/playground/add_random_meshes.d.ts +4 -4
  191. package/src/shade/playground/add_random_meshes.d.ts.map +1 -1
  192. package/src/shade/playground/add_random_meshes.js +20 -16
  193. package/src/shade/playground/avboit/main.d.ts +1 -0
  194. package/src/shade/playground/avboit/main.d.ts.map +1 -1
  195. package/src/shade/playground/avboit/main.js +916 -875
  196. package/src/shade/playground/basis_textures/main.d.ts.map +1 -1
  197. package/src/shade/playground/basis_textures/main.js +22 -8
  198. package/src/shade/playground/basis_textures/texture_inventory.d.ts +2 -2
  199. package/src/shade/playground/basis_textures/texture_inventory.d.ts.map +1 -1
  200. package/src/shade/playground/basis_textures/texture_inventory.js +6 -7
  201. package/src/shade/playground/ground_seam/main.d.ts.map +1 -1
  202. package/src/shade/playground/ground_seam/main.js +13 -4
  203. package/src/shade/playground/ground_seam/make_ground.d.ts +13 -4
  204. package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -1
  205. package/src/shade/playground/ground_seam/make_ground.js +21 -16
  206. package/src/shade/playground/particle_ecs/bonfire_editor.js +3 -3
  207. package/src/shade/playground/particle_system/main.js +11 -10
  208. package/src/shade/playground/particle_system/particle_prototype.d.ts +15 -10
  209. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  210. package/src/shade/playground/particle_system/particle_prototype.js +56 -15
  211. package/src/shade/playground/particle_system/particle_scene.d.ts +68 -28
  212. package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
  213. package/src/shade/playground/particle_system/particle_scene.js +149 -53
  214. package/src/shade/playground/readback_crossover/index.html +41 -0
  215. package/src/shade/playground/readback_crossover/main.d.ts +2 -0
  216. package/src/shade/playground/readback_crossover/main.d.ts.map +1 -0
  217. package/src/shade/playground/readback_crossover/main.js +372 -0
  218. package/src/shade/playground/skinned_blas_refit/README.md +11 -7
  219. package/src/shade/playground/skinned_blas_refit/add_floor.d.ts +13 -44
  220. package/src/shade/playground/skinned_blas_refit/add_floor.d.ts.map +1 -1
  221. package/src/shade/playground/skinned_blas_refit/add_floor.js +19 -59
  222. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  223. package/src/shade/playground/skinned_blas_refit/main.js +67 -58
  224. package/src/shade/playground/skinned_blas_refit/place_character.d.ts +40 -54
  225. package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
  226. package/src/shade/playground/skinned_blas_refit/place_character.js +47 -74
  227. package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts +3 -3
  228. package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts.map +1 -1
  229. package/src/shade/playground/skinned_blas_refit/sweep_views.js +4 -3
  230. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts +3 -3
  231. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts.map +1 -1
  232. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.js +11 -4
  233. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.d.ts.map +1 -1
  234. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.js +38 -9
  235. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts +3 -3
  236. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
  237. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +9 -6
  238. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts +3 -3
  239. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts.map +1 -1
  240. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +3 -3
  241. package/src/shade/playground/skinned_mesh_soup/README.md +6 -6
  242. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  243. package/src/shade/playground/skinned_mesh_soup/main.js +44 -102
  244. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts +5 -5
  245. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
  246. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +42 -33
  247. package/src/shade/playground/sponza_path_trace/main.d.ts +1 -0
  248. package/src/shade/playground/sponza_path_trace/main.d.ts.map +1 -1
  249. package/src/shade/playground/sponza_path_trace/main.js +393 -363
  250. package/src/shade/playground/ssr_reprojection/main.js +11 -9
  251. package/src/shade/playground/ssr_reprojection/scene.d.ts +15 -4
  252. package/src/shade/playground/ssr_reprojection/scene.d.ts.map +1 -1
  253. package/src/shade/playground/ssr_reprojection/scene.js +32 -11
  254. package/src/shade/playground/ssr_variance/main.js +1 -1
  255. package/src/shade/playground/ssr_variance/scene.d.ts +10 -4
  256. package/src/shade/playground/ssr_variance/scene.d.ts.map +1 -1
  257. package/src/shade/playground/ssr_variance/scene.js +39 -15
  258. package/src/shade/playground/vgeo_viewer/main.js +6 -2
  259. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  260. package/src/shade/playground/volumetrics_froxel/main.js +936 -922
  261. package/src/shade/renderer/GraphicsContext.d.ts +7 -0
  262. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  263. package/src/shade/renderer/GraphicsContext.js +11 -0
  264. package/src/shade/renderer/Renderer.d.ts +3 -2
  265. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  266. package/src/shade/renderer/Renderer.js +3 -2
  267. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +39 -47
  268. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  269. package/src/shade/renderer/animation/GPUAnimationManager.js +319 -256
  270. package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts +26 -22
  271. package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts.map +1 -1
  272. package/src/shade/renderer/animation/ShadeAnimationChannel.js +28 -23
  273. package/src/shade/renderer/animation/ShadeAnimationClip.d.ts +14 -6
  274. package/src/shade/renderer/animation/ShadeAnimationClip.d.ts.map +1 -1
  275. package/src/shade/renderer/animation/ShadeAnimationClip.js +20 -8
  276. package/src/shade/renderer/animation/Skin.d.ts +19 -19
  277. package/src/shade/renderer/animation/Skin.d.ts.map +1 -1
  278. package/src/shade/renderer/animation/Skin.js +15 -13
  279. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts +6 -5
  280. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts.map +1 -1
  281. package/src/shade/renderer/animation/pose/pose_evaluate_local.js +9 -9
  282. package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts +5 -59
  283. package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts.map +1 -1
  284. package/src/shade/renderer/animation/skin_clip_scale_conflicts.js +8 -132
  285. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +65 -62
  286. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  287. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +148 -194
  288. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.d.ts.map +1 -1
  289. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +4 -7
  290. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.d.ts +2 -2
  291. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +2 -2
  292. package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts +74 -0
  293. package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts.map +1 -0
  294. package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.js +240 -0
  295. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +14 -0
  296. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  297. package/src/shade/renderer/buffer/table/GPUDatabase.js +64 -6
  298. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts +190 -0
  299. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts.map +1 -0
  300. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.js +1323 -0
  301. package/src/shade/renderer/buffer/table/GPUPageMetadata.d.ts +10 -0
  302. package/src/shade/renderer/buffer/table/GPUPageMetadata.d.ts.map +1 -1
  303. package/src/shade/renderer/buffer/table/GPUPageMetadata.js +12 -0
  304. package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts +96 -0
  305. package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts.map +1 -0
  306. package/src/shade/renderer/buffer/table/GPUReadbackStatus.d.ts +15 -0
  307. package/src/shade/renderer/buffer/table/GPUReadbackStatus.d.ts.map +1 -0
  308. package/src/shade/renderer/buffer/table/GPUReadbackStatus.js +34 -0
  309. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +75 -7
  310. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  311. package/src/shade/renderer/buffer/table/GPUTypedTable.js +518 -135
  312. package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.d.ts +19 -0
  313. package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.d.ts.map +1 -0
  314. package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.js +18 -0
  315. package/src/shade/renderer/buffer/table/WordViews.d.ts +39 -0
  316. package/src/shade/renderer/buffer/table/WordViews.d.ts.map +1 -0
  317. package/src/shade/renderer/buffer/table/WordViews.js +62 -0
  318. package/src/shade/renderer/buffer/table/gpu_table_gather_shader.d.ts +27 -0
  319. package/src/shade/renderer/buffer/table/gpu_table_gather_shader.d.ts.map +1 -0
  320. package/src/shade/renderer/buffer/table/gpu_table_gather_shader.js +117 -0
  321. package/src/shade/renderer/buffer/table/serde/generate_record_writer.d.ts +121 -0
  322. package/src/shade/renderer/buffer/table/serde/generate_record_writer.d.ts.map +1 -0
  323. package/src/shade/renderer/buffer/table/serde/generate_record_writer.js +395 -0
  324. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  325. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +70 -20
  326. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +1 -1
  327. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  328. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +6 -5
  329. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +3 -3
  330. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  331. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +15 -11
  332. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.d.ts +1 -1
  333. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.js +4 -4
  334. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts +1 -3
  335. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts.map +1 -1
  336. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.js +5 -4
  337. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +1 -1
  338. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  339. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +1 -4
  340. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts +8 -3
  341. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts.map +1 -1
  342. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.js +19 -14
  343. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts.map +1 -1
  344. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +9 -1
  345. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts +3 -3
  346. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts.map +1 -1
  347. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.js +12 -5
  348. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +1 -1
  349. package/src/shade/renderer/light/GPULightCollection.d.ts +29 -0
  350. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  351. package/src/shade/renderer/light/GPULightCollection.js +444 -329
  352. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.d.ts.map +1 -1
  353. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.js +7 -1
  354. package/src/shade/renderer/light/LightCollection.d.ts +29 -1
  355. package/src/shade/renderer/light/LightCollection.d.ts.map +1 -1
  356. package/src/shade/renderer/light/LightCollection.js +50 -1
  357. package/src/shade/renderer/light/make_sunlight.js +2 -2
  358. package/src/shade/renderer/light/model/Light.d.ts +29 -2
  359. package/src/shade/renderer/light/model/Light.d.ts.map +1 -1
  360. package/src/shade/renderer/light/model/Light.js +30 -2
  361. package/src/shade/renderer/light/model/io/light_record_directional.d.ts +3 -1
  362. package/src/shade/renderer/light/model/io/light_record_directional.d.ts.map +1 -1
  363. package/src/shade/renderer/light/model/io/light_record_directional.js +8 -5
  364. package/src/shade/renderer/light/model/io/light_record_point.d.ts +3 -1
  365. package/src/shade/renderer/light/model/io/light_record_point.d.ts.map +1 -1
  366. package/src/shade/renderer/light/model/io/light_record_point.js +5 -2
  367. package/src/shade/renderer/light/model/io/light_record_spot.d.ts +4 -1
  368. package/src/shade/renderer/light/model/io/light_record_spot.d.ts.map +1 -1
  369. package/src/shade/renderer/light/model/io/light_record_spot.js +10 -6
  370. package/src/shade/renderer/light/place_light.d.ts +16 -0
  371. package/src/shade/renderer/light/place_light.d.ts.map +1 -0
  372. package/src/shade/renderer/light/place_light.js +36 -0
  373. package/src/shade/renderer/light/shader_refresh_light_poses.d.ts +44 -0
  374. package/src/shade/renderer/light/shader_refresh_light_poses.d.ts.map +1 -0
  375. package/src/shade/renderer/light/shader_refresh_light_poses.js +154 -0
  376. package/src/shade/renderer/lightmap/GPULightMap.js +1 -1
  377. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
  378. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +12 -14
  379. package/src/shade/renderer/loader/SceneBundle.d.ts +53 -28
  380. package/src/shade/renderer/loader/SceneBundle.d.ts.map +1 -1
  381. package/src/shade/renderer/loader/SceneBundle.js +111 -56
  382. package/src/shade/renderer/loader/SceneNode.d.ts +81 -0
  383. package/src/shade/renderer/loader/SceneNode.d.ts.map +1 -0
  384. package/src/shade/renderer/loader/SceneNode.js +114 -0
  385. package/src/shade/renderer/loader/gltf/load_gltf.d.ts +3 -2
  386. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  387. package/src/shade/renderer/loader/gltf/load_gltf.js +110 -142
  388. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  389. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.d.ts +4 -4
  390. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.d.ts.map +1 -1
  391. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.js +2 -2
  392. package/src/shade/renderer/loader/usd/load_usd.d.ts +3 -2
  393. package/src/shade/renderer/loader/usd/load_usd.d.ts.map +1 -1
  394. package/src/shade/renderer/loader/usd/load_usd.js +4 -5
  395. package/src/shade/renderer/loader/usd/usd_build_scene.d.ts +3 -3
  396. package/src/shade/renderer/loader/usd/usd_build_scene.d.ts.map +1 -1
  397. package/src/shade/renderer/loader/usd/usd_build_scene.js +47 -55
  398. package/src/shade/renderer/material/GPUMaterialManager.js +1 -1
  399. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +5 -4
  400. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  401. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +8 -15
  402. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts +15 -13
  403. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts.map +1 -1
  404. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.js +40 -21
  405. package/src/shade/renderer/particles/DESIGN.md +53 -50
  406. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +31 -17
  407. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  408. package/src/shade/renderer/particles/GPUParticleSystem.js +54 -91
  409. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +12 -11
  410. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  411. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +12 -11
  412. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +13 -19
  413. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -1
  414. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +19 -25
  415. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +34 -24
  416. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  417. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +53 -40
  418. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +1 -1
  419. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +1 -1
  420. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  421. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts.map +1 -1
  422. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.js +2 -1
  423. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.d.ts.map +1 -1
  424. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.js +5 -2
  425. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +1 -1
  426. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +1 -1
  427. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +1 -1
  428. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +1 -1
  429. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +1 -1
  430. package/src/shade/renderer/scene/DynamicMesh.d.ts +13 -4
  431. package/src/shade/renderer/scene/DynamicMesh.d.ts.map +1 -1
  432. package/src/shade/renderer/scene/DynamicMesh.js +14 -4
  433. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +38 -18
  434. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  435. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +112 -60
  436. package/src/shade/renderer/scene/GPUSceneContext.d.ts +55 -48
  437. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  438. package/src/shade/renderer/scene/GPUSceneContext.js +594 -928
  439. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +5 -5
  440. package/src/shade/renderer/scene/NODE3D_STRUCT.js +5 -5
  441. package/src/shade/renderer/scene/Node3D.d.ts +27 -8
  442. package/src/shade/renderer/scene/Node3D.d.ts.map +1 -1
  443. package/src/shade/renderer/scene/Node3DDirtyList.d.ts +59 -0
  444. package/src/shade/renderer/scene/Node3DDirtyList.d.ts.map +1 -0
  445. package/src/shade/renderer/scene/Scene.d.ts +18 -60
  446. package/src/shade/renderer/scene/Scene.d.ts.map +1 -1
  447. package/src/shade/renderer/scene/Scene.js +53 -146
  448. package/src/shade/renderer/scene/SkinnedMesh.d.ts +10 -93
  449. package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +1 -1
  450. package/src/shade/renderer/scene/bvh/StaticSceneBVH.d.ts +24 -3
  451. package/src/shade/renderer/scene/bvh/StaticSceneBVH.d.ts.map +1 -1
  452. package/src/shade/renderer/scene/bvh/StaticSceneBVH.js +53 -13
  453. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts +5 -6
  454. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts.map +1 -1
  455. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.js +5 -6
  456. package/src/shade/renderer/scene/optimization/scene_optimize.d.ts +10 -2
  457. package/src/shade/renderer/scene/optimization/scene_optimize.d.ts.map +1 -1
  458. package/src/shade/renderer/scene/optimization/scene_optimize.js +266 -230
  459. package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.d.ts +53 -0
  460. package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.d.ts.map +1 -0
  461. package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.js +144 -0
  462. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +227 -0
  463. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -0
  464. package/src/shade/renderer/scene/rows/GPUSceneRows.js +1136 -0
  465. package/src/shade/renderer/scene/rows/place_primitive.d.ts +48 -0
  466. package/src/shade/renderer/scene/rows/place_primitive.d.ts.map +1 -0
  467. package/src/shade/renderer/scene/rows/place_primitive.js +98 -0
  468. package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts +10 -8
  469. package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts.map +1 -1
  470. package/src/shade/renderer/scene/serialization/deserialize_scene.js +24 -27
  471. package/src/shade/renderer/scene/serialization/serialize_scene.d.ts +9 -2
  472. package/src/shade/renderer/scene/serialization/serialize_scene.d.ts.map +1 -1
  473. package/src/shade/renderer/scene/serialization/serialize_scene.js +25 -4
  474. package/src/shade/renderer/scene/verify_gpu_tlas_build.js +2 -2
  475. package/src/shade/renderer/shader/chunk/light/DIRECTIONAL_LIGHT_STRUCT.d.ts.map +1 -1
  476. package/src/shade/renderer/shader/chunk/light/DIRECTIONAL_LIGHT_STRUCT.js +5 -0
  477. package/src/shade/renderer/shader/chunk/light/POINT_LIGHT_STRUCT.d.ts.map +1 -1
  478. package/src/shade/renderer/shader/chunk/light/POINT_LIGHT_STRUCT.js +5 -0
  479. package/src/shade/renderer/shader/chunk/light/SPOT_LIGHT_STRUCT.d.ts.map +1 -1
  480. package/src/shade/renderer/shader/chunk/light/SPOT_LIGHT_STRUCT.js +5 -0
  481. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts +39 -0
  482. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
  483. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +112 -64
  484. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +7 -0
  485. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  486. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +1541 -1352
  487. package/src/shade/renderer/shadow/map/PointLightShadowmap.js +1 -1
  488. package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +1 -1
  489. package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +1 -1
  490. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts +29 -0
  491. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts.map +1 -0
  492. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.js +43 -0
  493. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.d.ts +13 -0
  494. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.d.ts.map +1 -0
  495. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.js +12 -0
  496. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts +49 -0
  497. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts.map +1 -0
  498. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.js +194 -0
  499. package/src/shade/renderer/shadow/map/csm_debug_draw_preview.js +1 -1
  500. package/src/shade/renderer/shadow/map/shadowmap_update_score.js +1 -1
  501. package/src/shade/renderer/shadow/ray/RTXShadows.js +1 -1
  502. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +1 -1
  503. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
  504. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +3 -1
  505. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +8 -8
  506. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  507. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +4 -3
  508. package/src/engine/graphics3/instantiate_scene_bundle.js +0 -164
  509. package/src/engine/graphics3/shade_node_to_entity_composition.js +0 -88
  510. package/src/shade/renderer/animation/compute_skin_world_bounds.js +0 -146
  511. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.js +0 -531
  512. package/src/shade/renderer/animation/pose/pose_evaluate_world.js +0 -76
  513. package/src/shade/renderer/animation/skin_bind_transform.js +0 -33
  514. package/src/shade/renderer/animation/skin_frame_defect.js +0 -132
  515. package/src/shade/renderer/animation/skin_joint_matrix.js +0 -46
  516. package/src/shade/renderer/animation/skin_normalize_mesh_frame.js +0 -216
  517. package/src/shade/renderer/scene/InstanceBatch.js +0 -235
  518. package/src/shade/renderer/scene/Mesh.js +0 -168
  519. package/src/shade/renderer/scene/Node3D.js +0 -263
  520. package/src/shade/renderer/scene/SceneNodeBinding.js +0 -56
  521. package/src/shade/renderer/scene/SkinnedMesh.js +0 -170
  522. package/src/shade/renderer/scene/TransformAuthority.js +0 -33
@@ -1,363 +1,393 @@
1
- import Vector3 from "../../../core/geom/Vector3.js";
2
- import { DEG_TO_RAD } from "../../../core/math/DEG_TO_RAD.js";
3
- import { NumericInterval } from "../../../core/math/interval/NumericInterval.js";
4
- import { seededRandom } from "../../../core/math/random/seededRandom.js";
5
- import { camera_frame_sphere } from "../../renderer/camera/camera_frame_sphere.js";
6
- import { OrbitalCameraController } from "../../renderer/camera/OrbitalCameraController.js";
7
- import { PerspectiveCamera } from "../../renderer/camera/PerspectiveCamera.js";
8
- import { create_frame_loop } from "../../renderer/create_frame_loop.js";
9
- import { BoxGeometry } from "../../renderer/geometry/BoxGeometry.js";
10
- import { make_sunlight } from "../../renderer/light/make_sunlight.js";
11
- import { StandardShadeMaterial } from "../../renderer/material/StandardShadeMaterial.js";
12
- import { load_gltf } from "../../renderer/loader/gltf/load_gltf.js";
13
- import { Renderer } from "../../renderer/Renderer.js";
14
- import { Scene } from "../../renderer/scene/Scene.js";
15
- import { load_scene_from_url } from "../../renderer/scene/serialization/deserialize_scene.js";
16
- import { add_random_meshes } from "../add_random_meshes.js";
17
- import { load_default_environment } from "../load_default_environment.js";
18
- import { make_playground_asset_manager } from "../make_playground_asset_manager.js";
19
-
20
- /**
21
- * Sponza under the path tracer, as a prototype.
22
- *
23
- * The point is the one thing no device-free tier and no readback harness can answer: what the tree
24
- * looks like when something traverses it. `AccumulatingPathTracer` binds `scene_ctx.tlas.buffer`
25
- * directly and is the traversal-heaviest consumer in the tree, so it is where a wrong child index
26
- * or a loose parent box shows up as something you can see — geometry that vanishes at a grazing
27
- * angle, or light that leaks through a wall.
28
- *
29
- * It was written to A/B the GPU TLAS build against the legacy CPU one; that comparison has been run
30
- * (`GPU_BVH_BUILD_PLAN.md` §4.6) and the legacy path is gone. What it is now is the place to notice
31
- * a regression in the tree, and — through the box-scatter control — the place to build a workload
32
- * where the TLAS is what traversal costs.
33
- *
34
- * Runs under the dev server (`npm run dev`), which is what resolves the one bare specifier the
35
- * renderer reaches for (`robust-predicates`) and what serves `test_assets/`. The panel is
36
- * hand-rolled rather than lil-gui: four checkboxes are not worth a dependency the library does not
37
- * otherwise have.
38
- */
39
-
40
- /**
41
- * Served by the dev server out of `test_assets/`, which is gitignored and unpublished. See
42
- * `test_assets/README.md` for how to put the assets there.
43
- *
44
- * glTF rather than one of the `.shade` scenes sitting next to it: `deserialize_scene` accepts
45
- * format version 2 only — deliberately, with no backward compatibility — and every exported Sponza
46
- * in the sibling repo is version 1. Re-exporting one is the fix if a `.shade` scene is wanted; the
47
- * loader below still takes one, chosen by extension.
48
- *
49
- * @type {string}
50
- */
51
- const DEFAULT_SCENE_URL = '/test_assets/Sponza/glTF/Sponza.gltf';
52
-
53
- /**
54
- * How the boxes the stress control scatters are sized, as a fraction of the scene's shortest
55
- * bounding-box span.
56
- *
57
- * Relative rather than absolute because the page loads whatever `?scene=` names and no two exports
58
- * agree on what a unit is. The two-order-of-magnitude spread between them is the point: a Morton
59
- * code sees a centroid and nothing about extent, so a mix of sizes is the case it orders worst.
60
- *
61
- * @type {NumericInterval}
62
- */
63
- const STRESS_SIZE_FRACTION = new NumericInterval(0.005, 0.4);
64
-
65
- /**
66
- * A frame-time readout, kept as a rolling mean so the number is readable rather than jittering.
67
- */
68
- class FrameTimer {
69
- #samples = new Float64Array(60);
70
- #count = 0;
71
- #cursor = 0;
72
-
73
- /**
74
- * @param {number} seconds
75
- */
76
- add(seconds) {
77
- this.#samples[this.#cursor] = seconds * 1000;
78
- this.#cursor = (this.#cursor + 1) % this.#samples.length;
79
- this.#count = Math.min(this.#count + 1, this.#samples.length);
80
- }
81
-
82
- reset() {
83
- this.#count = 0;
84
- this.#cursor = 0;
85
- }
86
-
87
- /**
88
- * @returns {number} mean frame time in milliseconds, or 0 before there is anything to average
89
- */
90
- get mean_ms() {
91
- if (this.#count === 0) {
92
- return 0;
93
- }
94
-
95
- let total = 0;
96
- for (let i = 0; i < this.#count; i++) {
97
- total += this.#samples[i];
98
- }
99
-
100
- return total / this.#count;
101
- }
102
- }
103
-
104
- /**
105
- * Populate a scene from a URL, picking the loader by extension: a glTF document comes in through
106
- * `load_gltf` and needs a light placed for it, a `.shade` scene carries its own. Either way the
107
- * camera ends up framing what arrived.
108
- *
109
- * @param {string} url
110
- * @param {Scene} scene
111
- * @param {OrbitalCameraController} controller
112
- * @returns {Promise<void>}
113
- */
114
- async function load_scene(url, scene, controller) {
115
-
116
- if (/\.gltf$|\.glb$/i.test(url)) {
117
- // glTF reads every byte through the asset framework, so it needs a manager with loaders
118
- // registered for the two types it asks for
119
- const bundle = await load_gltf(url, { assetManager: await make_playground_asset_manager() });
120
-
121
- scene.add(bundle.scenes);
122
-
123
- if (!scene.lights.elements.some(light => light.isDirectionalLight)) {
124
- // a glTF document need not carry any light at all, and Sponza does not
125
- scene.lights.add(make_sunlight({ intensity: 7.2 }));
126
- }
127
- } else {
128
- await load_scene_from_url(url, scene);
129
- }
130
-
131
- const bounds = scene.instances.bounding_box;
132
-
133
- const radius = Math.hypot(bounds.width, bounds.height, bounds.depth) * 0.5;
134
-
135
- camera_frame_sphere(
136
- controller,
137
- radius,
138
- new Vector3(bounds.centerX, bounds.centerY, bounds.centerZ)
139
- );
140
-
141
- controller.movement_speed_scale = Math.max(bounds.width, bounds.height, bounds.depth) * 0.1;
142
- }
143
-
144
- /**
145
- * Stand the prototype up. Called by the page rather than run on import, so that nothing here
146
- * touches the DOM until there is one.
147
- *
148
- * @returns {Promise<void>}
149
- */
150
- export async function start() {
151
-
152
- const element = id => document.getElementById(id);
153
-
154
- const status_element = element('status');
155
- const stats_element = element('stats');
156
-
157
- /**
158
- * @param {string} text
159
- * @param {string} [kind]
160
- */
161
- function set_status(text, kind = '') {
162
- status_element.textContent = text;
163
- status_element.className = kind;
164
- }
165
-
166
- const canvas = element('view');
167
-
168
- const context = canvas.getContext('webgpu');
169
-
170
- if (context === null) {
171
- set_status('no WebGPU context — this browser has none, or the page is not a secure context', 'fail');
172
- return;
173
- }
174
-
175
- const renderer = new Renderer();
176
-
177
- set_status('acquiring a device…');
178
-
179
- await renderer.initialize({ context });
180
-
181
- if (!renderer.graphics.device.features.has('subgroups')) {
182
- // Not fatal for rasterization, but the GPU TLAS build takes subgroup builtins in the sort's
183
- // scatter and in the extraction pass, so the A/B has only one usable side here.
184
- set_status('device has no `subgroups` — the GPU TLAS path will fail; use the CPU side of the A/B', 'warn');
185
- }
186
-
187
- const camera = new PerspectiveCamera();
188
-
189
- camera.transform.setTranslation(0, 2, -5);
190
- camera.transform.lookAt(Vector3.zero);
191
-
192
- camera.near = 0.1;
193
- camera.far = 200;
194
- camera.fov = 72 * DEG_TO_RAD;
195
- camera.aspect = renderer.aspect_ratio;
196
-
197
- const scene = new Scene();
198
-
199
- // document.body rather than the canvas: the controller starts a keyboard device, and only a
200
- // focusable element can receive key events — body carries tabindex for exactly that.
201
- const controller = new OrbitalCameraController(camera, document.body);
202
-
203
- // handy from the console
204
- globalThis.renderer = renderer;
205
- globalThis.scene = scene;
206
- globalThis.camera = camera;
207
-
208
- // ---- controls -------------------------------------------------------------------------
209
-
210
- const frame_timer = new FrameTimer();
211
-
212
- let paused = false;
213
-
214
- element('path_tracing').addEventListener('change', event => {
215
- renderer.feature_path_tracing_enabled = event.target.checked;
216
-
217
- // Two temporal filters over one image is nonsense; the tracer accumulates on its own.
218
- if (event.target.checked) {
219
- element('taa').checked = false;
220
- renderer.feature_taa_enabled = false;
221
- }
222
-
223
- renderer.indicate_view_change();
224
- frame_timer.reset();
225
- });
226
-
227
- element('taa').addEventListener('change', event => {
228
- renderer.feature_taa_enabled = event.target.checked;
229
- renderer.indicate_view_change();
230
- });
231
-
232
- element('pause').addEventListener('click', () => {
233
- paused = !paused;
234
- element('pause').textContent = paused ? 'Resume' : 'Pause';
235
- });
236
-
237
- element('reset_accumulation').addEventListener('click', () => {
238
- renderer.path_tracer.clear_history = true;
239
- renderer.indicate_view_change();
240
- frame_timer.reset();
241
- });
242
-
243
- // Built once and shared across clicks: a geometry per click would be a BLAS per click, which
244
- // is the opposite of what this control is for. One generator likewise, so a second click
245
- // scatters new boxes rather than laying the same ones down again.
246
- const stress_geometry = new BoxGeometry(1, 1, 1);
247
- const stress_material = new StandardShadeMaterial();
248
- const stress_random = seededRandom(12345);
249
-
250
- element('stress').addEventListener('click', () => {
251
- const count = Math.max(1, Number.parseInt(element('stress_count').value, 10) || 0);
252
-
253
- const bounds = scene.instances.bounding_box;
254
-
255
- const shortest_span = Math.min(bounds.width, bounds.height, bounds.depth);
256
-
257
- add_random_meshes({
258
- batch: scene.instances,
259
- geometries: [stress_geometry],
260
- materials: [stress_material],
261
- count,
262
- region: bounds,
263
- geometry_scale_range: new NumericInterval(
264
- shortest_span * STRESS_SIZE_FRACTION.min,
265
- shortest_span * STRESS_SIZE_FRACTION.max
266
- ),
267
- random: stress_random
268
- });
269
-
270
- renderer.path_tracer.clear_history = true;
271
- renderer.indicate_view_change();
272
- frame_timer.reset();
273
-
274
- set_status(`added ${count} boxes — ${scene.instances.instances.length} instances`, 'pass');
275
- });
276
-
277
- // ---- the scene ------------------------------------------------------------------------
278
-
279
- const url = new URLSearchParams(location.search).get('scene') ?? DEFAULT_SCENE_URL;
280
-
281
- const url_input = element('scene_url');
282
-
283
- url_input.value = url;
284
-
285
- // A Scene has no teardown, so changing scenes reloads the page rather than trying to empty one
286
- // in place.
287
- function load_url(next) {
288
- const parameters = new URLSearchParams(location.search);
289
-
290
- parameters.set('scene', next);
291
-
292
- location.search = parameters.toString();
293
- }
294
-
295
- element('load').addEventListener('click', () => load_url(url_input.value.trim()));
296
-
297
- url_input.addEventListener('keydown', event => {
298
- if (event.key === 'Enter') {
299
- load_url(url_input.value.trim());
300
- }
301
- });
302
-
303
- set_status(`loading ${url} …`);
304
-
305
- try {
306
- await load_scene(url, scene, controller);
307
- } catch (error) {
308
- set_status(
309
- `could not load the scene (${error.message}). Put the assets under test_assets/ — `
310
- + `see test_assets/README.md — or type a reachable URL above and press Load.`,
311
- 'fail'
312
- );
313
- console.error(error);
314
- return;
315
- }
316
-
317
- // Image-based lighting if a sky is there, and nothing said about it if not: the scene renders
318
- // either way, and a missing optional asset is not a reason to show a failure. The helper warns
319
- // and resolves false rather than rejecting.
320
- load_default_environment(scene).then(applied => {
321
- if (applied) {
322
- renderer.indicate_view_change();
323
- }
324
- });
325
-
326
- // the controller's keyboard device listens on body, and only a focused element gets key events
327
- document.body.focus();
328
-
329
- set_status(`loaded — ${scene.instances.instances.length} instances`, 'pass');
330
-
331
- renderer.indicate_view_change();
332
-
333
- // ---- frame loop -----------------------------------------------------------------------
334
-
335
- const FRAME_RATE_LIMIT = 60;
336
-
337
- create_frame_loop(time_delta_s => {
338
- const width = window.innerWidth;
339
- const height = window.innerHeight;
340
-
341
- renderer.resize(width, height);
342
- renderer.pixel_ratio = window.devicePixelRatio;
343
- camera.aspect = width / height;
344
-
345
- controller.update();
346
-
347
- if (paused) {
348
- return;
349
- }
350
-
351
- renderer.render(camera, scene, time_delta_s);
352
-
353
- frame_timer.add(time_delta_s);
354
-
355
- const instances = scene.instances.instances.length;
356
- const mean = frame_timer.mean_ms;
357
-
358
- stats_element.textContent =
359
- `${mean.toFixed(1)} ms · ${mean > 0 ? (1000 / mean).toFixed(0) : '0'} fps · `
360
- + `${instances} instances`
361
- + `${renderer.feature_path_tracing_enabled ? ' · path traced' : ''}`;
362
- }, FRAME_RATE_LIMIT);
363
- }
1
+ import Vector3 from "../../../core/geom/Vector3.js";
2
+ import { DEG_TO_RAD } from "../../../core/math/DEG_TO_RAD.js";
3
+ import { NumericInterval } from "../../../core/math/interval/NumericInterval.js";
4
+ import { seededRandom } from "../../../core/math/random/seededRandom.js";
5
+ import { camera_frame_sphere } from "../../renderer/camera/camera_frame_sphere.js";
6
+ import { OrbitalCameraController } from "../../renderer/camera/OrbitalCameraController.js";
7
+ import { PerspectiveCamera } from "../../renderer/camera/PerspectiveCamera.js";
8
+ import { create_frame_loop } from "../../renderer/create_frame_loop.js";
9
+ import { BoxGeometry } from "../../renderer/geometry/BoxGeometry.js";
10
+ import { make_sunlight } from "../../renderer/light/make_sunlight.js";
11
+ import { place_light } from "../../renderer/light/place_light.js";
12
+ import { EntityComponentDataset } from "../../../engine/ecs/EntityComponentDataset.js";
13
+ import { StandardShadeMaterial } from "../../renderer/material/StandardShadeMaterial.js";
14
+ import { load_gltf } from "../../renderer/loader/gltf/load_gltf.js";
15
+ import { Renderer } from "../../renderer/Renderer.js";
16
+ import { Scene } from "../../renderer/scene/Scene.js";
17
+ import { load_scene_from_url } from "../../renderer/scene/serialization/deserialize_scene.js";
18
+ import { add_random_meshes } from "../add_random_meshes.js";
19
+ import { load_default_environment } from "../load_default_environment.js";
20
+ import { make_playground_asset_manager } from "../make_playground_asset_manager.js";
21
+ import { AABB3 } from "../../../core/geom/3d/aabb/AABB3.js";
22
+ import { Transform64 } from "../../../engine/ecs/transform/Transform64.js";
23
+ import { prefab_compile } from "../../../engine/graphics3/prefab/prefab_compile.js";
24
+ import { prefab_place } from "../../../engine/graphics3/prefab/prefab_place.js";
25
+ import { shade_bundle_bounds } from "../../../engine/graphics3/shade_bundle_bounds.js";
26
+
27
+ /**
28
+ * Sponza under the path tracer, as a prototype.
29
+ *
30
+ * The point is the one thing no device-free tier and no readback harness can answer: what the tree
31
+ * looks like when something traverses it. `AccumulatingPathTracer` binds `scene_ctx.tlas.buffer`
32
+ * directly and is the traversal-heaviest consumer in the tree, so it is where a wrong child index
33
+ * or a loose parent box shows up as something you can see — geometry that vanishes at a grazing
34
+ * angle, or light that leaks through a wall.
35
+ *
36
+ * It was written to A/B the GPU TLAS build against the legacy CPU one; that comparison has been run
37
+ * (`GPU_BVH_BUILD_PLAN.md` §4.6) and the legacy path is gone. What it is now is the place to notice
38
+ * a regression in the tree, and — through the box-scatter control — the place to build a workload
39
+ * where the TLAS is what traversal costs.
40
+ *
41
+ * Runs under the dev server (`npm run dev`), which is what resolves the one bare specifier the
42
+ * renderer reaches for (`robust-predicates`) and what serves `test_assets/`. The panel is
43
+ * hand-rolled rather than lil-gui: four checkboxes are not worth a dependency the library does not
44
+ * otherwise have.
45
+ */
46
+
47
+ /**
48
+ * Served by the dev server out of `test_assets/`, which is gitignored and unpublished. See
49
+ * `test_assets/README.md` for how to put the assets there.
50
+ *
51
+ * glTF rather than one of the `.shade` scenes sitting next to it: `deserialize_scene` accepts
52
+ * format version 2 only — deliberately, with no backward compatibility — and every exported Sponza
53
+ * in the sibling repo is version 1. Re-exporting one is the fix if a `.shade` scene is wanted; the
54
+ * loader below still takes one, chosen by extension.
55
+ *
56
+ * @type {string}
57
+ */
58
+ const DEFAULT_SCENE_URL = '/test_assets/Sponza/glTF/Sponza.gltf';
59
+
60
+ /**
61
+ * How the boxes the stress control scatters are sized, as a fraction of the scene's shortest
62
+ * bounding-box span.
63
+ *
64
+ * Relative rather than absolute because the page loads whatever `?scene=` names and no two exports
65
+ * agree on what a unit is. The two-order-of-magnitude spread between them is the point: a Morton
66
+ * code sees a centroid and nothing about extent, so a mix of sizes is the case it orders worst.
67
+ *
68
+ * @type {NumericInterval}
69
+ */
70
+ const STRESS_SIZE_FRACTION = new NumericInterval(0.005, 0.4);
71
+
72
+ /**
73
+ * A frame-time readout, kept as a rolling mean so the number is readable rather than jittering.
74
+ */
75
+ class FrameTimer {
76
+ #samples = new Float64Array(60);
77
+ #count = 0;
78
+ #cursor = 0;
79
+
80
+ /**
81
+ * @param {number} seconds
82
+ */
83
+ add(seconds) {
84
+ this.#samples[this.#cursor] = seconds * 1000;
85
+ this.#cursor = (this.#cursor + 1) % this.#samples.length;
86
+ this.#count = Math.min(this.#count + 1, this.#samples.length);
87
+ }
88
+
89
+ reset() {
90
+ this.#count = 0;
91
+ this.#cursor = 0;
92
+ }
93
+
94
+ /**
95
+ * @returns {number} mean frame time in milliseconds, or 0 before there is anything to average
96
+ */
97
+ get mean_ms() {
98
+ if (this.#count === 0) {
99
+ return 0;
100
+ }
101
+
102
+ let total = 0;
103
+ for (let i = 0; i < this.#count; i++) {
104
+ total += this.#samples[i];
105
+ }
106
+
107
+ return total / this.#count;
108
+ }
109
+ }
110
+
111
+ /** how many primitives the loaded model placed — the boxes the stress button adds are on the batch, counted apart */
112
+ let drawn = 0;
113
+
114
+ /** how many stress boxes the button has scattered — primitives at rows of their own */
115
+ let boxes = 0;
116
+
117
+ /** the box the loaded model occupies, which the stress boxes are scattered through */
118
+ const scene_bounds = new AABB3();
119
+
120
+ /**
121
+ * @typedef {import("../../renderer/loader/SceneBundle.js").SceneBundle} SceneBundle
122
+ */
123
+
124
+ /**
125
+ * Populate a scene from a URL, picking the loader by extension: a glTF document comes in through
126
+ * `load_gltf` and needs a light placed for it, a `.shade` scene carries its own. Either way the
127
+ * camera ends up framing what arrived.
128
+ *
129
+ * @param {string} url
130
+ * @param {Scene} scene
131
+ * @param {OrbitalCameraController} controller
132
+ * @returns {Promise<void>}
133
+ */
134
+ async function load_scene(url, scene, controller) {
135
+ /** @type {SceneBundle} */
136
+ let bundle;
137
+
138
+ if (/\.gltf$|\.glb$/i.test(url)) {
139
+ // glTF reads every byte through the asset framework, so it needs a manager with loaders
140
+ // registered for the two types it asks for
141
+ bundle = await load_gltf(url, { assetManager: await make_playground_asset_manager() });
142
+
143
+ if (!scene.lights.elements.some(light => light.isDirectionalLight)) {
144
+ // a glTF document need not carry any light at all, and Sponza does not
145
+ place_light(scene, make_sunlight({ intensity: 7.2 }));
146
+ }
147
+ } else {
148
+ // the file's lights and environment go to the scene; its meshes come back as a model
149
+ bundle = await load_scene_from_url(url, scene);
150
+ }
151
+
152
+ const placed = prefab_place(renderer.scenes.obtain(scene), scene.dataset, prefab_compile(bundle), new Transform64());
153
+
154
+ drawn = placed.drawn;
155
+
156
+ const bounds = new AABB3();
157
+
158
+ shade_bundle_bounds(bounds, bundle);
159
+ scene_bounds.copy(bounds);
160
+
161
+ const radius = Math.hypot(bounds.width, bounds.height, bounds.depth) * 0.5;
162
+
163
+ camera_frame_sphere(
164
+ controller,
165
+ radius,
166
+ new Vector3(bounds.centerX, bounds.centerY, bounds.centerZ)
167
+ );
168
+
169
+ controller.movement_speed_scale = Math.max(bounds.width, bounds.height, bounds.depth) * 0.1;
170
+ }
171
+
172
+ /**
173
+ * Stand the prototype up. Called by the page rather than run on import, so that nothing here
174
+ * touches the DOM until there is one.
175
+ *
176
+ * @returns {Promise<void>}
177
+ */
178
+ export async function start() {
179
+
180
+ const element = id => document.getElementById(id);
181
+
182
+ const status_element = element('status');
183
+ const stats_element = element('stats');
184
+
185
+ /**
186
+ * @param {string} text
187
+ * @param {string} [kind]
188
+ */
189
+ function set_status(text, kind = '') {
190
+ status_element.textContent = text;
191
+ status_element.className = kind;
192
+ }
193
+
194
+ const canvas = element('view');
195
+
196
+ const context = canvas.getContext('webgpu');
197
+
198
+ if (context === null) {
199
+ set_status('no WebGPU context — this browser has none, or the page is not a secure context', 'fail');
200
+ return;
201
+ }
202
+
203
+ const renderer = new Renderer();
204
+
205
+ set_status('acquiring a device…');
206
+
207
+ await renderer.initialize({ context });
208
+
209
+ if (!renderer.graphics.device.features.has('subgroups')) {
210
+ // Not fatal for rasterization, but the GPU TLAS build takes subgroup builtins in the sort's
211
+ // scatter and in the extraction pass, so the A/B has only one usable side here.
212
+ set_status('device has no `subgroups` — the GPU TLAS path will fail; use the CPU side of the A/B', 'warn');
213
+ }
214
+
215
+ const camera = new PerspectiveCamera();
216
+
217
+ camera.transform.setTranslation(0, 2, -5);
218
+ camera.transform.lookAt(Vector3.zero);
219
+
220
+ camera.near = 0.1;
221
+ camera.far = 200;
222
+ camera.fov = 72 * DEG_TO_RAD;
223
+ camera.aspect = renderer.aspect_ratio;
224
+
225
+ const scene = new Scene();
226
+
227
+ // the sun stands at an entity, so the scene names a dataset for it
228
+ scene.dataset = new EntityComponentDataset();
229
+
230
+ // document.body rather than the canvas: the controller starts a keyboard device, and only a
231
+ // focusable element can receive key events — body carries tabindex for exactly that.
232
+ const controller = new OrbitalCameraController(camera, document.body);
233
+
234
+ // handy from the console
235
+ globalThis.renderer = renderer;
236
+ globalThis.scene = scene;
237
+ globalThis.camera = camera;
238
+
239
+ // ---- controls -------------------------------------------------------------------------
240
+
241
+ const frame_timer = new FrameTimer();
242
+
243
+ let paused = false;
244
+
245
+ element('path_tracing').addEventListener('change', event => {
246
+ renderer.feature_path_tracing_enabled = event.target.checked;
247
+
248
+ // Two temporal filters over one image is nonsense; the tracer accumulates on its own.
249
+ if (event.target.checked) {
250
+ element('taa').checked = false;
251
+ renderer.feature_taa_enabled = false;
252
+ }
253
+
254
+ renderer.indicate_view_change();
255
+ frame_timer.reset();
256
+ });
257
+
258
+ element('taa').addEventListener('change', event => {
259
+ renderer.feature_taa_enabled = event.target.checked;
260
+ renderer.indicate_view_change();
261
+ });
262
+
263
+ element('pause').addEventListener('click', () => {
264
+ paused = !paused;
265
+ element('pause').textContent = paused ? 'Resume' : 'Pause';
266
+ });
267
+
268
+ element('reset_accumulation').addEventListener('click', () => {
269
+ renderer.path_tracer.clear_history = true;
270
+ renderer.indicate_view_change();
271
+ frame_timer.reset();
272
+ });
273
+
274
+ // Built once and shared across clicks: a geometry per click would be a BLAS per click, which
275
+ // is the opposite of what this control is for. One generator likewise, so a second click
276
+ // scatters new boxes rather than laying the same ones down again.
277
+ const stress_geometry = new BoxGeometry(1, 1, 1);
278
+ const stress_material = new StandardShadeMaterial();
279
+ const stress_random = seededRandom(12345);
280
+
281
+ element('stress').addEventListener('click', () => {
282
+ const count = Math.max(1, Number.parseInt(element('stress_count').value, 10) || 0);
283
+
284
+ const bounds = scene_bounds;
285
+ const shortest_span = Math.min(bounds.width, bounds.height, bounds.depth);
286
+
287
+ boxes += add_random_meshes({
288
+ scene_context: renderer.scenes.obtain(scene),
289
+ geometries: [stress_geometry],
290
+ materials: [stress_material],
291
+ count,
292
+ region: bounds,
293
+ geometry_scale_range: new NumericInterval(
294
+ shortest_span * STRESS_SIZE_FRACTION.min,
295
+ shortest_span * STRESS_SIZE_FRACTION.max
296
+ ),
297
+ random: stress_random
298
+ }).length;
299
+
300
+ renderer.path_tracer.clear_history = true;
301
+ renderer.indicate_view_change();
302
+ frame_timer.reset();
303
+
304
+ set_status(`added ${count} boxes — ${drawn + boxes} instances`, 'pass');
305
+ });
306
+
307
+ // ---- the scene ------------------------------------------------------------------------
308
+
309
+ const url = new URLSearchParams(location.search).get('scene') ?? DEFAULT_SCENE_URL;
310
+
311
+ const url_input = element('scene_url');
312
+
313
+ url_input.value = url;
314
+
315
+ // A Scene has no teardown, so changing scenes reloads the page rather than trying to empty one
316
+ // in place.
317
+ function load_url(next) {
318
+ const parameters = new URLSearchParams(location.search);
319
+
320
+ parameters.set('scene', next);
321
+
322
+ location.search = parameters.toString();
323
+ }
324
+
325
+ element('load').addEventListener('click', () => load_url(url_input.value.trim()));
326
+
327
+ url_input.addEventListener('keydown', event => {
328
+ if (event.key === 'Enter') {
329
+ load_url(url_input.value.trim());
330
+ }
331
+ });
332
+
333
+ set_status(`loading ${url} …`);
334
+
335
+ try {
336
+ await load_scene(url, scene, controller);
337
+ } catch (error) {
338
+ set_status(
339
+ `could not load the scene (${error.message}). Put the assets under test_assets/ — `
340
+ + `see test_assets/README.md — or type a reachable URL above and press Load.`,
341
+ 'fail'
342
+ );
343
+ console.error(error);
344
+ return;
345
+ }
346
+
347
+ // Image-based lighting if a sky is there, and nothing said about it if not: the scene renders
348
+ // either way, and a missing optional asset is not a reason to show a failure. The helper warns
349
+ // and resolves false rather than rejecting.
350
+ load_default_environment(scene).then(applied => {
351
+ if (applied) {
352
+ renderer.indicate_view_change();
353
+ }
354
+ });
355
+
356
+ // the controller's keyboard device listens on body, and only a focused element gets key events
357
+ document.body.focus();
358
+
359
+ set_status(`loaded — ${drawn} instances`, 'pass');
360
+
361
+ renderer.indicate_view_change();
362
+
363
+ // ---- frame loop -----------------------------------------------------------------------
364
+
365
+ const FRAME_RATE_LIMIT = 60;
366
+
367
+ create_frame_loop(time_delta_s => {
368
+ const width = window.innerWidth;
369
+ const height = window.innerHeight;
370
+
371
+ renderer.resize(width, height);
372
+ renderer.pixel_ratio = window.devicePixelRatio;
373
+ camera.aspect = width / height;
374
+
375
+ controller.update();
376
+
377
+ if (paused) {
378
+ return;
379
+ }
380
+
381
+ renderer.render(camera, scene, time_delta_s);
382
+
383
+ frame_timer.add(time_delta_s);
384
+
385
+ const instances = drawn + boxes;
386
+ const mean = frame_timer.mean_ms;
387
+
388
+ stats_element.textContent =
389
+ `${mean.toFixed(1)} ms · ${mean > 0 ? (1000 / mean).toFixed(0) : '0'} fps · `
390
+ + `${instances} instances`
391
+ + `${renderer.feature_path_tracing_enabled ? ' · path traced' : ''}`;
392
+ }, FRAME_RATE_LIMIT);
393
+ }