@woosh/meep-engine 3.11.3 → 3.12.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 (401) hide show
  1. package/README.md +14 -18
  2. package/editor/SelectionVisualizer.js +127 -127
  3. package/editor/entity_world_bounds.js +27 -27
  4. package/editor/particles/rebuildParticleEmitter.js +31 -31
  5. package/editor/process/SymbolicDisplayProcess.js +1 -1
  6. package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
  7. package/editor/process/symbolic/LightSymbolicDisplay.js +172 -172
  8. package/editor/prototypeEditorShell.js +156 -156
  9. package/editor/selection/editor_pick.js +130 -130
  10. package/editor/selection/screen_rect_frustum.js +119 -119
  11. package/editor/tools/v2/TransformControls.js +971 -971
  12. package/package.json +1 -1
  13. package/src/engine/Engine.d.ts +3 -3
  14. package/src/engine/Engine.d.ts.map +1 -1
  15. package/src/engine/Engine.js +726 -726
  16. package/src/engine/EngineHarness.d.ts +1 -1
  17. package/src/engine/EngineHarness.js +590 -590
  18. package/src/engine/ecs/HIERARCHY_REVIEW.md +717 -717
  19. package/src/engine/ecs/terrain/ecs/BuildLightTexture.d.ts +1 -1
  20. package/src/engine/ecs/terrain/ecs/BuildLightTexture.js +27 -27
  21. package/src/engine/ecs/terrain/ecs/Terrain.d.ts +1 -5
  22. package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
  23. package/src/engine/ecs/terrain/ecs/Terrain.js +790 -790
  24. package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +129 -129
  25. package/src/engine/graphics/ecs/camera/camera_find_active.d.ts +1 -1
  26. package/src/engine/graphics/ecs/camera/camera_find_active.js +28 -28
  27. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +1 -1
  28. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +428 -428
  29. package/src/engine/graphics/ecs/water/Water.d.ts +1 -1
  30. package/src/engine/graphics/ecs/water/Water.js +104 -104
  31. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +1 -1
  32. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1 -1
  33. package/src/engine/graphics3/AnimationGraphSystem.d.ts +65 -0
  34. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -0
  35. package/src/engine/graphics3/AnimationGraphSystem.js +329 -0
  36. package/src/engine/graphics3/AnimationGraphSystem3.d.ts +6 -61
  37. package/src/engine/graphics3/AnimationGraphSystem3.d.ts.map +1 -1
  38. package/src/engine/graphics3/AnimationGraphSystem3.js +6 -325
  39. package/src/engine/graphics3/AnimationSystem.d.ts +76 -0
  40. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -0
  41. package/src/engine/graphics3/AnimationSystem.js +352 -0
  42. package/src/engine/graphics3/AnimationSystem3.d.ts +6 -72
  43. package/src/engine/graphics3/AnimationSystem3.d.ts.map +1 -1
  44. package/src/engine/graphics3/AnimationSystem3.js +6 -348
  45. package/src/engine/graphics3/CameraSystem.d.ts +49 -0
  46. package/src/engine/graphics3/CameraSystem.d.ts.map +1 -0
  47. package/src/engine/graphics3/CameraSystem.js +170 -0
  48. package/src/engine/graphics3/CameraSystem3.d.ts +6 -45
  49. package/src/engine/graphics3/CameraSystem3.d.ts.map +1 -1
  50. package/src/engine/graphics3/CameraSystem3.js +6 -166
  51. package/src/engine/graphics3/DebugDrawSystem.d.ts +72 -0
  52. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -0
  53. package/src/engine/graphics3/DebugDrawSystem.js +205 -0
  54. package/src/engine/graphics3/DebugDrawSystem3.d.ts +6 -68
  55. package/src/engine/graphics3/DebugDrawSystem3.d.ts.map +1 -1
  56. package/src/engine/graphics3/DebugDrawSystem3.js +6 -201
  57. package/src/engine/graphics3/DecalSystem.d.ts +81 -0
  58. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -0
  59. package/src/engine/graphics3/DecalSystem.js +441 -0
  60. package/src/engine/graphics3/DecalSystem3.d.ts +6 -77
  61. package/src/engine/graphics3/DecalSystem3.d.ts.map +1 -1
  62. package/src/engine/graphics3/DecalSystem3.js +6 -437
  63. package/src/engine/graphics3/FogOfWarSystem.d.ts +74 -0
  64. package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -0
  65. package/src/engine/graphics3/FogOfWarSystem.js +265 -0
  66. package/src/engine/graphics3/FogOfWarSystem3.d.ts +6 -70
  67. package/src/engine/graphics3/FogOfWarSystem3.d.ts.map +1 -1
  68. package/src/engine/graphics3/FogOfWarSystem3.js +6 -261
  69. package/src/engine/graphics3/GraphicsEngine.d.ts +340 -0
  70. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -0
  71. package/src/engine/graphics3/GraphicsEngine.js +790 -0
  72. package/src/engine/graphics3/GraphicsEngine3.d.ts +6 -336
  73. package/src/engine/graphics3/GraphicsEngine3.d.ts.map +1 -1
  74. package/src/engine/graphics3/GraphicsEngine3.js +6 -786
  75. package/src/engine/graphics3/HighlightSystem.d.ts +82 -0
  76. package/src/engine/graphics3/HighlightSystem.d.ts.map +1 -0
  77. package/src/engine/graphics3/HighlightSystem.js +241 -0
  78. package/src/engine/graphics3/HighlightSystem3.d.ts +6 -78
  79. package/src/engine/graphics3/HighlightSystem3.d.ts.map +1 -1
  80. package/src/engine/graphics3/HighlightSystem3.js +6 -237
  81. package/src/engine/graphics3/LightSystem.d.ts +40 -0
  82. package/src/engine/graphics3/LightSystem.d.ts.map +1 -0
  83. package/src/engine/graphics3/LightSystem.js +211 -0
  84. package/src/engine/graphics3/LightSystem3.d.ts +6 -36
  85. package/src/engine/graphics3/LightSystem3.d.ts.map +1 -1
  86. package/src/engine/graphics3/LightSystem3.js +6 -207
  87. package/src/engine/graphics3/MeshSystem.d.ts +106 -0
  88. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -0
  89. package/src/engine/graphics3/MeshSystem.js +647 -0
  90. package/src/engine/graphics3/MeshSystem3.d.ts +6 -102
  91. package/src/engine/graphics3/MeshSystem3.d.ts.map +1 -1
  92. package/src/engine/graphics3/MeshSystem3.js +6 -642
  93. package/src/engine/graphics3/ParticipatingMedia.d.ts +2 -2
  94. package/src/engine/graphics3/ParticipatingMedia.js +203 -203
  95. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts +87 -0
  96. package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -0
  97. package/src/engine/graphics3/ParticipatingMediaSystem.js +184 -0
  98. package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts +6 -83
  99. package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts.map +1 -1
  100. package/src/engine/graphics3/ParticipatingMediaSystem3.js +6 -180
  101. package/src/engine/graphics3/ParticleEmitterSystem.d.ts +76 -0
  102. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -0
  103. package/src/engine/graphics3/ParticleEmitterSystem.js +289 -0
  104. package/src/engine/graphics3/ParticleEmitterSystem3.d.ts +6 -72
  105. package/src/engine/graphics3/ParticleEmitterSystem3.d.ts.map +1 -1
  106. package/src/engine/graphics3/ParticleEmitterSystem3.js +6 -285
  107. package/src/engine/graphics3/PathDisplaySystem.d.ts +70 -0
  108. package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -0
  109. package/src/engine/graphics3/PathDisplaySystem.js +309 -0
  110. package/src/engine/graphics3/PathDisplaySystem3.d.ts +6 -66
  111. package/src/engine/graphics3/PathDisplaySystem3.d.ts.map +1 -1
  112. package/src/engine/graphics3/PathDisplaySystem3.js +6 -305
  113. package/src/engine/graphics3/Pickable.d.ts +1 -1
  114. package/src/engine/graphics3/Pickable.js +65 -65
  115. package/src/engine/graphics3/PickingQuery.d.ts +1 -1
  116. package/src/engine/graphics3/PickingQuery.js +48 -48
  117. package/src/engine/graphics3/PickingSystem.d.ts +67 -0
  118. package/src/engine/graphics3/PickingSystem.d.ts.map +1 -0
  119. package/src/engine/graphics3/PickingSystem.js +273 -0
  120. package/src/engine/graphics3/PickingSystem3.d.ts +6 -63
  121. package/src/engine/graphics3/PickingSystem3.d.ts.map +1 -1
  122. package/src/engine/graphics3/PickingSystem3.js +6 -269
  123. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +47 -0
  124. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -0
  125. package/src/engine/graphics3/ShadedGeometrySystem.js +169 -0
  126. package/src/engine/graphics3/ShadedGeometrySystem3.d.ts +6 -43
  127. package/src/engine/graphics3/ShadedGeometrySystem3.d.ts.map +1 -1
  128. package/src/engine/graphics3/ShadedGeometrySystem3.js +6 -165
  129. package/src/engine/graphics3/TerrainSystem.d.ts +80 -0
  130. package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -0
  131. package/src/engine/graphics3/TerrainSystem.js +566 -0
  132. package/src/engine/graphics3/TerrainSystem3.d.ts +6 -76
  133. package/src/engine/graphics3/TerrainSystem3.d.ts.map +1 -1
  134. package/src/engine/graphics3/TerrainSystem3.js +6 -562
  135. package/src/engine/graphics3/TooltipComponentSystem.d.ts +65 -0
  136. package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -0
  137. package/src/engine/graphics3/TooltipComponentSystem.js +328 -0
  138. package/src/engine/graphics3/TooltipComponentSystem3.d.ts +6 -61
  139. package/src/engine/graphics3/TooltipComponentSystem3.d.ts.map +1 -1
  140. package/src/engine/graphics3/TooltipComponentSystem3.js +6 -324
  141. package/src/engine/graphics3/Trail3DSystem.d.ts +73 -0
  142. package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -0
  143. package/src/engine/graphics3/Trail3DSystem.js +221 -0
  144. package/src/engine/graphics3/Trail3DSystem3.d.ts +6 -69
  145. package/src/engine/graphics3/Trail3DSystem3.d.ts.map +1 -1
  146. package/src/engine/graphics3/Trail3DSystem3.js +6 -217
  147. package/src/engine/graphics3/VolumetricLightMap.d.ts +2 -2
  148. package/src/engine/graphics3/VolumetricLightMap.js +2 -2
  149. package/src/engine/graphics3/VolumetricLightMapSystem.d.ts +98 -0
  150. package/src/engine/graphics3/VolumetricLightMapSystem.d.ts.map +1 -0
  151. package/src/engine/graphics3/VolumetricLightMapSystem.js +261 -0
  152. package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts +6 -94
  153. package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts.map +1 -1
  154. package/src/engine/graphics3/VolumetricLightMapSystem3.js +10 -261
  155. package/src/engine/graphics3/WaterSystem.d.ts +59 -0
  156. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -0
  157. package/src/engine/graphics3/WaterSystem.js +293 -0
  158. package/src/engine/graphics3/WaterSystem3.d.ts +6 -55
  159. package/src/engine/graphics3/WaterSystem3.d.ts.map +1 -1
  160. package/src/engine/graphics3/WaterSystem3.js +6 -289
  161. package/src/engine/graphics3/animation/AnimationGraphController.d.ts +1 -1
  162. package/src/engine/graphics3/animation/AnimationGraphController.js +518 -518
  163. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +1 -1
  164. package/src/engine/graphics3/animation/ClipListPlayer.js +263 -263
  165. package/src/engine/graphics3/animation/ClipPlayback.d.ts +2 -2
  166. package/src/engine/graphics3/animation/ClipPlayback.js +84 -84
  167. package/src/engine/graphics3/decal/graph_build_decal_clusters.d.ts.map +1 -1
  168. package/src/engine/graphics3/decal/graph_build_decal_clusters.js +6 -8
  169. package/src/engine/graphics3/decal/shader_cluster_assign_decals.d.ts +0 -7
  170. package/src/engine/graphics3/decal/shader_cluster_assign_decals.d.ts.map +1 -1
  171. package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +1 -1
  172. package/src/engine/graphics3/decal/shader_cull_decals_frustum.d.ts +0 -4
  173. package/src/engine/graphics3/decal/shader_cull_decals_frustum.d.ts.map +1 -1
  174. package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +1 -1
  175. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts +2 -2
  176. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts.map +1 -1
  177. package/src/engine/graphics3/highlight/pack_highlight_table.js +74 -74
  178. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +1 -1
  179. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +101 -101
  180. package/src/engine/graphics3/preview/make_model_thumbnail.d.ts +3 -3
  181. package/src/engine/graphics3/preview/make_model_thumbnail.d.ts.map +1 -1
  182. package/src/engine/graphics3/preview/make_model_thumbnail.js +48 -48
  183. package/src/engine/graphics3/shade_camera_projection_ray.d.ts +1 -1
  184. package/src/engine/graphics3/shade_camera_projection_ray.js +77 -77
  185. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts +1 -1
  186. package/src/engine/graphics3/shade_node_to_entity_composition.js +84 -84
  187. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
  188. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +0 -1
  189. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.d.ts.map +1 -1
  190. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +0 -1
  191. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
  192. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +133 -134
  193. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +202 -202
  194. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +249 -249
  195. package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSETS.js +1 -1
  196. package/src/shade/renderer/animation/pose/PosePlayback.d.ts +2 -1
  197. package/src/shade/renderer/animation/pose/PosePlayback.d.ts.map +1 -1
  198. package/src/shade/renderer/animation/pose/PosePlayback.js +2 -1
  199. package/src/shade/renderer/animation/shader_animation_apply.d.ts.map +1 -1
  200. package/src/shade/renderer/animation/shader_animation_apply.js +128 -129
  201. package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts.map +1 -1
  202. package/src/shade/renderer/animation/shader_animation_pose_resolve.js +176 -177
  203. package/src/shade/renderer/animation/shader_animation_tick.d.ts.map +1 -1
  204. package/src/shade/renderer/animation/shader_animation_tick.js +125 -126
  205. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.d.ts.map +1 -1
  206. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.js +98 -99
  207. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.d.ts.map +1 -1
  208. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.js +212 -213
  209. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts.map +1 -1
  210. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.js +120 -121
  211. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.d.ts.map +1 -1
  212. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.js +75 -76
  213. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
  214. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +371 -372
  215. package/src/shade/renderer/animation/skinning/shader_skin_matrix_prep.d.ts.map +1 -1
  216. package/src/shade/renderer/animation/skinning/shader_skin_matrix_prep.js +104 -105
  217. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts.map +1 -1
  218. package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +0 -1
  219. package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +136 -136
  220. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  221. package/src/shade/renderer/buffer/table/GPUDatabase.js +2 -3
  222. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +319 -319
  223. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts.map +1 -1
  224. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.js +41 -42
  225. package/src/shade/renderer/buffer/util/shader_buffer_intra_copy_regions.d.ts.map +1 -1
  226. package/src/shade/renderer/buffer/util/shader_buffer_intra_copy_regions.js +83 -84
  227. package/src/shade/renderer/dynamic/shader_dynamic_mesh.d.ts.map +1 -1
  228. package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +177 -170
  229. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +918 -918
  230. package/src/shade/renderer/geometry/bvh/record_blas_refit.js +4 -4
  231. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.d.ts.map +1 -1
  232. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.js +121 -122
  233. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +774 -774
  234. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts +1 -1
  235. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
  236. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +69 -70
  237. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +367 -367
  238. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +184 -184
  239. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +1115 -1115
  240. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +217 -217
  241. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
  242. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +142 -143
  243. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
  244. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +0 -1
  245. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
  246. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +140 -141
  247. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
  248. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +0 -1
  249. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
  250. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +0 -1
  251. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
  252. package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +191 -198
  253. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.d.ts +0 -6
  254. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.d.ts.map +1 -1
  255. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.js +120 -120
  256. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.d.ts +0 -4
  257. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.d.ts.map +1 -1
  258. package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.js +112 -112
  259. package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
  260. package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +4 -7
  261. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts +0 -6
  262. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts.map +1 -1
  263. package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.js +1 -1
  264. package/src/shade/renderer/lightmap/bake/raster/shader_lightmap_to_viz_buffer.js +222 -222
  265. package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_tile_composit.js +81 -81
  266. package/src/shade/renderer/material/GPUMaterialContext.js +380 -380
  267. package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
  268. package/src/shade/renderer/object_property/shader_object_property_process.d.ts.map +1 -1
  269. package/src/shade/renderer/object_property/shader_object_property_process.js +83 -84
  270. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts.map +1 -1
  271. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.js +57 -58
  272. package/src/shade/renderer/particles/prototypeParticleSystem.js +2 -3
  273. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  274. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +117 -118
  275. package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
  276. package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +77 -79
  277. package/src/shade/renderer/particles/shaders/shader_particle_render.d.ts.map +1 -1
  278. package/src/shade/renderer/particles/shaders/shader_particle_render.js +190 -183
  279. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  280. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +99 -100
  281. package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
  282. package/src/shade/renderer/particles/sort/shader_particle_sort.js +158 -161
  283. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +184 -184
  284. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +119 -119
  285. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +3 -4
  286. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.d.ts.map +1 -1
  287. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +266 -267
  288. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.d.ts.map +1 -1
  289. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +270 -271
  290. package/src/shade/renderer/postprocess/nss/shader_nss_concat.d.ts.map +1 -1
  291. package/src/shade/renderer/postprocess/nss/shader_nss_concat.js +68 -69
  292. package/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.d.ts.map +1 -1
  293. package/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.js +225 -226
  294. package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.d.ts.map +1 -1
  295. package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js +49 -50
  296. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
  297. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +291 -292
  298. package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.d.ts.map +1 -1
  299. package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +230 -231
  300. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts +16 -2
  301. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts.map +1 -1
  302. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.js +12 -12
  303. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +2 -2
  304. package/src/shade/renderer/rasterize/bucket/shader_count_meshlets_by_material.d.ts.map +1 -1
  305. package/src/shade/renderer/rasterize/bucket/shader_count_meshlets_by_material.js +68 -69
  306. package/src/shade/renderer/rasterize/bucket/shader_make_meshlet_indirect_draw_commands_by_material.d.ts.map +1 -1
  307. package/src/shade/renderer/rasterize/bucket/shader_make_meshlet_indirect_draw_commands_by_material.js +59 -60
  308. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  309. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +0 -1
  310. package/src/shade/renderer/rasterize/bucket/shader_sort_meshlets_by_material.d.ts.map +1 -1
  311. package/src/shade/renderer/rasterize/bucket/shader_sort_meshlets_by_material.js +64 -65
  312. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts.map +1 -1
  313. package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.js +168 -169
  314. package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.d.ts.map +1 -1
  315. package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.js +160 -161
  316. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  317. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +109 -110
  318. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  319. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +115 -116
  320. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_classify_bucket.d.ts.map +1 -1
  321. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_classify_bucket.js +139 -140
  322. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_count_by_rasterization_bucket.d.ts.map +1 -1
  323. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_count_by_rasterization_bucket.js +91 -92
  324. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.d.ts.map +1 -1
  325. package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.js +88 -89
  326. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
  327. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +90 -91
  328. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  329. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +65 -66
  330. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
  331. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +89 -90
  332. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts.map +1 -1
  333. package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.js +169 -170
  334. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
  335. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +89 -90
  336. package/src/shade/renderer/rasterize/expand/mesh/shader_meshes_to_meshlet_counts.d.ts.map +1 -1
  337. package/src/shade/renderer/rasterize/expand/mesh/shader_meshes_to_meshlet_counts.js +61 -62
  338. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
  339. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +153 -154
  340. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +144 -144
  341. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +88 -88
  342. package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +217 -217
  343. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +179 -179
  344. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +178 -178
  345. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +194 -194
  346. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_opaque_pass_descriptor.js +76 -76
  347. package/src/shade/renderer/restir/di/shader_restir_di_denoise.d.ts.map +1 -1
  348. package/src/shade/renderer/restir/di/shader_restir_di_denoise.js +136 -137
  349. package/src/shade/renderer/restir/di/shader_restir_di_resample.d.ts.map +1 -1
  350. package/src/shade/renderer/restir/di/shader_restir_di_resample.js +129 -130
  351. package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
  352. package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +99 -100
  353. package/src/shade/renderer/restir/di/shader_restir_di_spatial.d.ts.map +1 -1
  354. package/src/shade/renderer/restir/di/shader_restir_di_spatial.js +116 -117
  355. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +383 -383
  356. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy_naive.js +123 -123
  357. package/src/shade/renderer/scene/hierarchy/shader_nodes_record_input_positions.d.ts.map +1 -1
  358. package/src/shade/renderer/scene/hierarchy/shader_nodes_record_input_positions.js +64 -65
  359. package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy.d.ts.map +1 -1
  360. package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy.js +372 -373
  361. package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy_naive.d.ts.map +1 -1
  362. package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy_naive.js +111 -112
  363. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.d.ts.map +1 -1
  364. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js +0 -1
  365. package/src/shade/renderer/shader/ComputeShader.d.ts +24 -3
  366. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  367. package/src/shade/renderer/shader/ComputeShader.js +350 -296
  368. package/src/shade/renderer/shader/ImageShader.js +217 -217
  369. package/src/shade/renderer/shader/ShaderDescriptor.d.ts +5 -0
  370. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  371. package/src/shade/renderer/shader/ShaderDescriptor.js +20 -0
  372. package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.d.ts +47 -0
  373. package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.d.ts.map +1 -0
  374. package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.js +448 -0
  375. package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.js +3 -3
  376. package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +3 -3
  377. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +2 -2
  378. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +4 -4
  379. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.d.ts.map +1 -1
  380. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +231 -232
  381. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +1 -1
  382. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  383. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +12 -15
  384. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts +3 -2
  385. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  386. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +3 -2
  387. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts +0 -2
  388. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts.map +1 -1
  389. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js +17 -6
  390. package/src/shade/renderer/water/shader_water.js +246 -246
  391. package/src/shade/vitest.setup.mjs +1 -1
  392. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +291 -291
  393. package/src/view/minimap/Minimap.d.ts +2 -2
  394. package/src/view/minimap/Minimap.d.ts.map +1 -1
  395. package/src/view/minimap/Minimap.js +225 -225
  396. package/src/view/minimap/dom/MinimapCameraView.d.ts +3 -3
  397. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  398. package/src/view/minimap/dom/MinimapCameraView.js +206 -206
  399. package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.d.ts +0 -3
  400. package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.d.ts.map +0 -1
  401. package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.js +0 -20
@@ -0,0 +1,647 @@
1
+ import { assert } from "../../core/assert.js";
2
+ import { aabb3_array_combine } from "../../core/geom/3d/aabb/aabb3_array_combine.js";
3
+ import { SignalBinding } from "../../core/events/signal/SignalBinding.js";
4
+ import { Scene } from "../../shade/renderer/scene/Scene.js";
5
+ import { instantiate_scene_bundle } from "./instantiate_scene_bundle.js";
6
+ import {
7
+ register_instance_animation,
8
+ unregister_instance_animation
9
+ } from "./register_instance_animation.js";
10
+ import { System } from "../ecs/System.js";
11
+ import { Transform } from "../ecs/transform/Transform.js";
12
+ import { t64_copy_from_transform } from "../ecs/transform/t64_copy_from_transform.js";
13
+ import { ParentEntity } from "../ecs/parent/ParentEntity.js";
14
+ import { ShadedGeometry } from "../graphics/ecs/mesh-v2/ShadedGeometry.js";
15
+ import { SGMesh } from "../graphics/ecs/mesh-v2/aggregate/SGMesh.js";
16
+ import { shade_bundle_to_entity_composition } from "./shade_node_to_entity_composition.js";
17
+
18
+ /**
19
+ * Puts entities into Shade's scene and keeps them where the ECS says they are.
20
+ *
21
+ * **It owns the scene and tells the facade to draw it**, rather than the facade handing a graph out
22
+ * for anyone to write into — that coupling is what §2.1 retires along with `GraphicsEngine.scene`.
23
+ *
24
+ * Placement is a `Transform` copied into `Node3D.transform_local`, through
25
+ * {@link t64_copy_from_transform} because the node's transform is a `Transform64` since S2 and the
26
+ * two types stay deliberately distinct. `transform_global` is **derived** — `updateMatrices`
27
+ * recomputes it from the local transform and the parent chain — so writing it directly would be
28
+ * undone by the next refresh, and the entity is placed through the local one.
29
+ *
30
+ * What makes this affordable is S1: the scene database takes row-level updates, so moving one
31
+ * entity writes one row. Nothing here rebuilds anything.
32
+ *
33
+ * **It also hands each instance to the GPU's animation manager** ({@link update}), because it is
34
+ * what builds instances and therefore the only thing that knows when one exists. Driving those
35
+ * clips is not its business — that is the animation systems' — but a clip nothing has registered
36
+ * cannot be driven by anyone.
37
+ */
38
+ export class MeshSystem extends System {
39
+ /**
40
+ * @type {GraphicsEngine}
41
+ */
42
+ #graphics;
43
+
44
+ /**
45
+ * The scene this system writes into and the facade draws.
46
+ *
47
+ * Received rather than created: lights come from a system of their own, and both have to be
48
+ * putting content into the same scene for either to be visible.
49
+ *
50
+ * @type {Scene}
51
+ */
52
+ #scene;
53
+
54
+ /**
55
+ * Loaded model bundles, by url. A level places the same model many times over, and loading it
56
+ * once per placement would be the dominant cost of opening one.
57
+ *
58
+ * @type {Map<string, Promise<SceneBundle>>}
59
+ */
60
+ #bundles = new Map();
61
+
62
+ /**
63
+ * What each entity has in the scene, and the signal bindings keeping it in step.
64
+ *
65
+ * `instance` and `animation` are null until the model has loaded and until the GPU has been
66
+ * told about it respectively — two different waits, which is why they are two fields.
67
+ *
68
+ * @type {Map<number, {nodes: Node3D[], bindings: SignalBinding[], instance: SceneBundleInstance|null, animation: InstanceAnimationRegistration|null}>}
69
+ */
70
+ #entries = new Map();
71
+
72
+ /**
73
+ * Shade's GPU state for {@link scene}, as of the last {@link update}.
74
+ *
75
+ * Held to answer one question: has the renderer been replaced since the last frame, so that
76
+ * everything placed has to be registered again. **Which manager a particular registration
77
+ * belongs to is the registration's own to say** — it carries the context that issued it — so
78
+ * this is not consulted when ids are handed back.
79
+ *
80
+ * @type {GPUSceneContext|null}
81
+ */
82
+ #context = null;
83
+
84
+ /**
85
+ * Entries whose instance is not registered with {@link #context} — either because it has just
86
+ * loaded, or because a restart invalidated what it had.
87
+ *
88
+ * A queue rather than a scan over every entity, because this is per-frame work in a level that
89
+ * places hundreds of models and the answer is almost always "nothing to do".
90
+ *
91
+ * @type {object[]}
92
+ */
93
+ #unregistered = [];
94
+
95
+ /**
96
+ * Entities whose `SGMesh` carried no url when it was linked.
97
+ *
98
+ * `SGMesh.url` is an accessor with no change signal behind it, and the game assigns it late as a
99
+ * matter of
100
+ * course: `GeneratedArmySystem` puts the component on an army entity and fills the url in from
101
+ * a promise, once the army it generated has picked the leader whose model the army wears. So a
102
+ * url that is missing at link time is the normal path to a model rather than an edge case, and
103
+ * the only way to notice one arriving is to look again.
104
+ *
105
+ * A list rather than a scan over every entity, and it is short: it holds only what has no model
106
+ * yet, and an entry leaves it for good the moment one is asked for.
107
+ *
108
+ * @type {{entity: number, model: SGMesh, transform: Transform}[]}
109
+ */
110
+ #awaiting_url = [];
111
+
112
+ /**
113
+ * Loads a glTF into Shade's own representation. Injected rather than imported so that the
114
+ * system can be driven in a spec without a network or a device — the loader is the one genuine
115
+ * boundary here.
116
+ *
117
+ * @type {function(string): Promise<SceneBundle>}
118
+ */
119
+ #load;
120
+
121
+ /**
122
+ * @param {GraphicsEngine} graphics
123
+ * @param {Scene} scene
124
+ * @param {function(string): Promise<SceneBundle>} load
125
+ */
126
+ constructor(graphics, scene, load) {
127
+ super();
128
+
129
+ assert.defined(graphics, 'graphics');
130
+ assert.equal(scene.isScene, true, 'scene.isScene !== true');
131
+ assert.typeOf(load, 'function', 'load');
132
+
133
+ this.#graphics = graphics;
134
+ this.#scene = scene;
135
+ this.#load = load;
136
+
137
+ this.dependencies = [SGMesh, Transform];
138
+ }
139
+
140
+ /**
141
+ * @returns {Scene}
142
+ */
143
+ get scene() {
144
+ return this.#scene;
145
+ }
146
+
147
+ /**
148
+ * Visit every node of an entity's model that carries geometry.
149
+ *
150
+ * The nodes are what the scene database keys on, so anything that has to say something about a
151
+ * particular entity's meshes — which rows they occupy, which of them the visibility buffer will
152
+ * name — starts here. A grouping node is skipped, because it has no geometry and therefore no
153
+ * row of its own.
154
+ *
155
+ * @param {number} entity
156
+ * @param {function(SGMesh): void} visitor
157
+ * @returns {boolean} `false` when the entity has nothing in the scene — never seen, or still
158
+ * loading, and neither is an error
159
+ */
160
+ traverse_meshes(entity, visitor) {
161
+ const entry = this.#entries.get(entity);
162
+
163
+ if (entry === undefined) {
164
+ return false;
165
+ }
166
+
167
+ for (let i = 0; i < entry.nodes.length; i++) {
168
+ entry.nodes[i].traverse(node => {
169
+ if (node.isMesh === true) {
170
+ visitor(node);
171
+ }
172
+ });
173
+ }
174
+
175
+ this.#traverse_expanded(entry, visitor);
176
+
177
+ return true;
178
+ }
179
+
180
+ /**
181
+ * The rows of a model that became entities.
182
+ *
183
+ * Its primitives are components on descendants rather than nodes this system holds, and each one
184
+ * carries the row `ShadedGeometrySystem` put it in — so the walk is over the composition and the
185
+ * answer is the same kind of node the instance path yields. A primitive whose system has not
186
+ * linked it yet has no row and contributes nothing, which is the same "still loading" silence
187
+ * every reader here already tolerates.
188
+ *
189
+ * @param {object} entry
190
+ * @param {function(Mesh): void} visitor
191
+ */
192
+ #traverse_expanded(entry, visitor) {
193
+ const composition = entry.composition;
194
+
195
+ if (composition === null) {
196
+ return;
197
+ }
198
+
199
+ composition.traverse(node => {
200
+ const geometry = node.entity.getComponent(ShadedGeometry);
201
+
202
+ if (geometry === null || geometry === undefined) {
203
+ return;
204
+ }
205
+
206
+ if (geometry.node === null) {
207
+ return;
208
+ }
209
+
210
+ visitor(geometry.node);
211
+ });
212
+ }
213
+
214
+ /**
215
+ * The private copy of the model an entity is showing — its clips among other things, which is
216
+ * where their names and their durations come from.
217
+ *
218
+ * Handed out rather than copied because an animation driver has to know *which* instance it is
219
+ * bound to: a model swap builds a new one, and a driver still holding the old one would be
220
+ * driving nodes that left the scene. The object's identity is the only signal that says so.
221
+ *
222
+ * @param {number} entity
223
+ * @returns {SceneBundleInstance|null} `null` for an entity this system has never seen, or one
224
+ * whose model has not finished loading
225
+ */
226
+ instance_of(entity) {
227
+ const entry = this.#entries.get(entity);
228
+
229
+ if (entry === undefined) {
230
+ return null;
231
+ }
232
+
233
+ return entry.instance;
234
+ }
235
+
236
+ /**
237
+ * What the GPU's animation manager gave back for that instance — the skin and clip ids, in the
238
+ * instance's own order.
239
+ *
240
+ * Same reasoning as {@link instance_of} and a stronger version of it: these ids belong to one
241
+ * renderer, and a restart voids every one of them. The object is replaced when that happens, so
242
+ * a driver that compares it against what it bound against notices in the same frame.
243
+ *
244
+ * @param {number} entity
245
+ * @returns {InstanceAnimationRegistration|null} `null` while there is nothing registered — no
246
+ * model yet, no device yet, or a renderer restart that has not been drained
247
+ */
248
+ animation_of(entity) {
249
+ const entry = this.#entries.get(entity);
250
+
251
+ if (entry === undefined) {
252
+ return null;
253
+ }
254
+
255
+ return entry.animation;
256
+ }
257
+
258
+ /**
259
+ * Where an entity's model is, in world space.
260
+ *
261
+ * This is what makes picking possible without a second copy of the geometry: Shade already keeps
262
+ * a world bounding box per mesh, refreshed as part of the `updateMatrices` that places it, so the
263
+ * answer is a walk over what the entity has in the scene and nothing is recomputed.
264
+ *
265
+ * @param {ArrayLike<number>|number[]|Float32Array} target aabb3, order `x0,y0,z0,x1,y1,z1`
266
+ * @param {number} entity
267
+ * @returns {boolean} `false` when the entity has nothing in the scene — it may be an entity this
268
+ * system has never seen, or one whose model is still loading, and neither is an error
269
+ */
270
+ compute_world_bounds(target, entity) {
271
+ const entry = this.#entries.get(entity);
272
+
273
+ if (entry === undefined) {
274
+ return false;
275
+ }
276
+
277
+ let found = false;
278
+
279
+ /**
280
+ * @param {Mesh} node
281
+ */
282
+ const combine = node => {
283
+ const bounds = node.bounding_box;
284
+
285
+ // combining the first box with itself is how it lands in `target` — one operation
286
+ // for both cases, rather than a copy that only ever runs once
287
+ aabb3_array_combine(target, 0, found ? target : bounds, 0, bounds, 0);
288
+
289
+ found = true;
290
+ };
291
+
292
+ for (let i = 0; i < entry.nodes.length; i++) {
293
+ entry.nodes[i].traverse(node => {
294
+ if (node.isMesh !== true) {
295
+ // a grouping node carries no geometry, so it has no bounds of its own
296
+ return;
297
+ }
298
+
299
+ combine(node);
300
+ });
301
+ }
302
+
303
+ this.#traverse_expanded(entry, combine);
304
+
305
+ return found;
306
+ }
307
+
308
+ async startup(entityManager) {
309
+ this.entityManager = entityManager;
310
+
311
+ this.#graphics.set_scene(this.#scene);
312
+ }
313
+
314
+ async shutdown(entityManager) {
315
+ for (const entity of Array.from(this.#entries.keys())) {
316
+ this.#drop(entity);
317
+ }
318
+
319
+ this.#bundles.clear();
320
+
321
+ this.#context = null;
322
+ this.#unregistered.length = 0;
323
+ }
324
+
325
+ /**
326
+ * Tell the GPU about the models that have arrived since the last frame.
327
+ *
328
+ * **This is where an instance's skins and clips reach `GPUAnimationManager`** — the manager
329
+ * hangs off the scene's GPU context, which exists only while there is a device, so registration
330
+ * cannot happen where instances are built (a model loads whenever it loads, including before
331
+ * the renderer has started). Registration is documented eventually-consistent at both entry
332
+ * points, so a frame of latency here costs nothing: the ids are live immediately and the chains
333
+ * that drive deformation are built when every joint has a row.
334
+ *
335
+ * A restart is the same event seen from here: the context object changes, every id the old one
336
+ * issued is void, and everything currently placed queues up again.
337
+ *
338
+ * @param {number} time_delta_seconds
339
+ */
340
+ update(time_delta_seconds) {
341
+ this.#collect_arrived_urls();
342
+
343
+ const context = this.#graphics.scene_context(this.#scene);
344
+
345
+ if (context === null) {
346
+ // No device — before the first start, or after a stop. Nothing is registered while
347
+ // this holds, and the next context to arrive is a change like any other.
348
+ return;
349
+ }
350
+
351
+ if (context !== this.#context) {
352
+ this.#invalidate_registrations(context);
353
+ }
354
+
355
+ const waiting = this.#unregistered;
356
+
357
+ if (waiting.length === 0) {
358
+ return;
359
+ }
360
+
361
+ /*
362
+ **A throw in here does not cost one model, it costs the session.** The list is cleared after
363
+ the loop, so a registration that throws partway leaves the entries before it *already
364
+ registered* and *still queued*: the next update registers them a second time, `bind` finds
365
+ the mesh already bound to another skin, and that assertion then fires once a frame for as
366
+ long as the game runs. Meanwhile the entry that threw never gets an `animation`, so `#drop`
367
+ has nothing to give back and its skinning bindings outlive their model — which is how a
368
+ `SkinnedMesh` ends up with no meshes-table row a hundred frames later.
369
+
370
+ Seen for real: a second skinned model arriving in one frame used to overrun the meshlet
371
+ buffers while a clone was queued (fixed in `GPUMeshletManager`), and the cascade above is
372
+ what turned that one throw into a dead animation layer. Registering one entry at a time and
373
+ taking it off the list as it succeeds is the shape of the fix; what to do with an entry that
374
+ *cannot* be registered is the open question, which is why it is written down here rather
375
+ than fixed. The throw that exposed it is fixed (`ac5e430e3`); the amplifier is not, and any
376
+ future failure in registration reproduces the same cascade.
377
+ */
378
+ for (let i = 0; i < waiting.length; i++) {
379
+ const entry = waiting[i];
380
+
381
+ entry.animation = register_instance_animation(context, entry.instance);
382
+ }
383
+
384
+ waiting.length = 0;
385
+ }
386
+
387
+ /**
388
+ * Load the models of entities whose url has turned up since the last frame.
389
+ *
390
+ * Ahead of everything the device gates, because a model arrives whenever it arrives and there
391
+ * may be no renderer yet — the same bargain {@link #attach} makes with registration.
392
+ */
393
+ #collect_arrived_urls() {
394
+ const waiting = this.#awaiting_url;
395
+
396
+ for (let i = waiting.length - 1; i >= 0; i--) {
397
+ const pending = waiting[i];
398
+
399
+ if (pending.model.url === null) {
400
+ continue;
401
+ }
402
+
403
+ waiting.splice(i, 1);
404
+
405
+ this.#attach(pending.entity, pending.model.url, pending.transform);
406
+ }
407
+ }
408
+
409
+ /**
410
+ * A different renderer is drawing this scene now, so nothing that has been registered still is.
411
+ *
412
+ * @param {GPUSceneContext} context
413
+ */
414
+ #invalidate_registrations(context) {
415
+ this.#context = context;
416
+
417
+ const waiting = this.#unregistered;
418
+
419
+ waiting.length = 0;
420
+
421
+ for (const entry of this.#entries.values()) {
422
+ if (entry.instance === null) {
423
+ continue;
424
+ }
425
+
426
+ entry.animation = null;
427
+
428
+ waiting.push(entry);
429
+ }
430
+ }
431
+
432
+ /**
433
+ * @param {SGMesh} model
434
+ * @param {Transform} transform
435
+ * @param {number} entity
436
+ */
437
+ link(model, transform, entity) {
438
+ const entry = { nodes: [], bindings: [], instance: null, animation: null, composition: null };
439
+
440
+ this.#entries.set(entity, entry);
441
+
442
+ // The entity is placed the moment its transform moves, not on a poll: a transform that has
443
+ // not changed costs nothing, which is the same bargain the scene database makes downstream.
444
+ const place = () => this.#place(entity, transform);
445
+
446
+ for (const component of [transform.position, transform.rotation, transform.scale]) {
447
+ const binding = new SignalBinding(component.onChanged, place);
448
+
449
+ binding.link();
450
+
451
+ entry.bindings.push(binding);
452
+ }
453
+
454
+ if (model.url === null) {
455
+ // nothing to show yet; {@link update} watches for the url arriving
456
+ this.#awaiting_url.push({ entity, model, transform });
457
+
458
+ return;
459
+ }
460
+
461
+ this.#attach(entity, model.url, transform);
462
+ }
463
+
464
+ /**
465
+ * @param {SGMesh} model
466
+ * @param {Transform} transform
467
+ * @param {number} entity
468
+ */
469
+ unlink(model, transform, entity) {
470
+ this.#drop(entity);
471
+ }
472
+
473
+ /**
474
+ * Load the model if it has not been seen, then put a copy of it in the scene.
475
+ *
476
+ * @param {number} entity
477
+ * @param {string} url
478
+ * @param {Transform} transform
479
+ */
480
+ async #attach(entity, url, transform) {
481
+ /*
482
+ Which entry this load is for, decided before the wait rather than after it. A load is in
483
+ flight for as long as a fetch and a decode take, and the entity can leave and come back
484
+ inside that window — so asking `#entries` afterwards answers "the entry this entity has
485
+ now", which may be a different one. Attaching to that leaves the scene holding a second
486
+ model nothing owns, and its skins registered with the GPU under a record that has already
487
+ been overwritten.
488
+ */
489
+ const started_for = this.#entries.get(entity);
490
+
491
+ let bundle = this.#bundles.get(url);
492
+
493
+ if (bundle === undefined) {
494
+ bundle = this.#load(url);
495
+
496
+ this.#bundles.set(url, bundle);
497
+ }
498
+
499
+ const loaded = await bundle;
500
+
501
+ const entry = this.#entries.get(entity);
502
+
503
+ if (entry !== started_for) {
504
+ // the entity left while its model was in flight, or left and came back as another
505
+ // entry — both ordinary at level-load rates
506
+ return;
507
+ }
508
+
509
+ if (loaded.skins.length === 0 && loaded.clips.length === 0) {
510
+ this.#expand(entity, loaded, transform);
511
+
512
+ return;
513
+ }
514
+
515
+ const instance = instantiate_scene_bundle(loaded);
516
+
517
+ entry.instance = instance;
518
+
519
+ for (const node of instance.roots) {
520
+ entry.nodes.push(node);
521
+
522
+ this.#scene.add(node);
523
+ }
524
+
525
+ this.#place(entity, transform);
526
+
527
+ // The GPU hears about it on the next update rather than here: a model finishes loading
528
+ // whenever it finishes, and there may be no device to tell.
529
+ this.#unregistered.push(entry);
530
+ }
531
+
532
+ /**
533
+ * Put a model into the dataset as entities.
534
+ *
535
+ * **This is what placing a model means in an ECS** (D47): meep has no scene graph to hand a file
536
+ * to, so the file's nodes become entities — parented, named, placed, and carrying a
537
+ * `ShadedGeometry` where they draw — and `ShadedGeometrySystem` gives each of those a row.
538
+ * Nothing here touches the scene, and no copy of the model is made: the entities name the
539
+ * bundle's own geometry and material, so a model placed two hundred times is one of each.
540
+ *
541
+ * **Only a model that neither deforms nor animates comes this way.** A skinned one deforms
542
+ * against a skeleton the renderer owns and the GPU poses; an animated one has clips that drive
543
+ * the nodes of an instance, and `GPUAnimationManager` addresses those nodes rather than
544
+ * entities. Making joints entities, or moving playback onto entity transforms, are both designs
545
+ * outside this program (D47) — so anything with a skin or a clip keeps the instance path above,
546
+ * exactly as Phase 4 built it.
547
+ *
548
+ * @param {number} entity
549
+ * @param {SceneBundle} bundle
550
+ * @param {Transform} transform
551
+ */
552
+ #expand(entity, bundle, transform) {
553
+ const entry = this.#entries.get(entity);
554
+
555
+ const composition = shade_bundle_to_entity_composition(bundle);
556
+
557
+ composition.entity.add(ParentEntity.from(entity));
558
+
559
+ const follow = () => composition.transform.copy(transform);
560
+
561
+ follow();
562
+
563
+ composition.build(this.entityManager.dataset);
564
+
565
+ transform.subscribe(follow);
566
+
567
+ composition.on.destroyed.addOne(() => transform.unsubscribe(follow));
568
+
569
+ entry.composition = composition;
570
+ }
571
+
572
+ /**
573
+ * @param {number} entity
574
+ * @param {Transform} transform
575
+ */
576
+ #place(entity, transform) {
577
+ const entry = this.#entries.get(entity);
578
+
579
+ if (entry === undefined) {
580
+ return;
581
+ }
582
+
583
+ const nodes = entry.nodes;
584
+
585
+ for (let i = 0; i < nodes.length; i++) {
586
+ const node = nodes[i];
587
+
588
+ t64_copy_from_transform(node.transform_local, transform);
589
+
590
+ // recomputes transform_global down the subtree, and bumps the version the scene
591
+ // database reads to decide what to upload
592
+ node.updateMatrices();
593
+ }
594
+ }
595
+
596
+ /**
597
+ * @param {number} entity
598
+ */
599
+ #drop(entity) {
600
+ const entry = this.#entries.get(entity);
601
+
602
+ if (entry === undefined) {
603
+ return;
604
+ }
605
+
606
+ for (let i = 0; i < entry.bindings.length; i++) {
607
+ entry.bindings[i].unlink();
608
+ }
609
+
610
+ for (let i = 0; i < entry.nodes.length; i++) {
611
+ this.#scene.remove(entry.nodes[i]);
612
+ }
613
+
614
+ if (entry.composition !== null) {
615
+ // the entities the model became are the model, so they go with it
616
+ entry.composition.destroy();
617
+
618
+ entry.composition = null;
619
+ }
620
+
621
+ const waiting = this.#unregistered.indexOf(entry);
622
+
623
+ if (waiting !== -1) {
624
+ // it left before the GPU was ever told about it
625
+ this.#unregistered.splice(waiting, 1);
626
+ }
627
+
628
+ const awaiting = this.#awaiting_url.findIndex(pending => pending.entity === entity);
629
+
630
+ if (awaiting !== -1) {
631
+ // it left before it ever had a model to load
632
+ this.#awaiting_url.splice(awaiting, 1);
633
+ }
634
+
635
+ const registration = entry.animation;
636
+
637
+ if (registration !== null) {
638
+ if (this.#graphics.scene_context(this.#scene) === registration.context) {
639
+ unregister_instance_animation(registration);
640
+ }
641
+
642
+ entry.animation = null;
643
+ }
644
+
645
+ this.#entries.delete(entity);
646
+ }
647
+ }