@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,40 +1,116 @@
1
1
  import { assert } from "../../core/assert.js";
2
2
  import { aabb3_array_combine } from "../../core/geom/3d/aabb/aabb3_array_combine.js";
3
- import { SignalBinding } from "../../core/events/signal/SignalBinding.js";
3
+ import { aabb3_matrix4_project } from "../../core/geom/3d/aabb/aabb3_matrix4_project.js";
4
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
5
  import { System } from "../ecs/System.js";
11
6
  import { Transform64 } from "../ecs/transform/Transform64.js";
12
- import { ParentEntity } from "../ecs/parent/ParentEntity.js";
7
+ import { TRANSFORM64_EVENT_CHANGE } from "../ecs/transform/TRANSFORM64_EVENT_CHANGE.js";
8
+ import { TRANSFORM_ATTACHMENT_EVENT_CHANGE } from "../ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js";
13
9
  import { ShadedGeometry } from "../graphics/ecs/mesh-v2/ShadedGeometry.js";
14
10
  import { SGMesh } from "../graphics/ecs/mesh-v2/aggregate/SGMesh.js";
15
- import { shade_bundle_to_entity_composition } from "./shade_node_to_entity_composition.js";
16
- import { TRANSFORM64_EVENT_CHANGE } from "../ecs/transform/TRANSFORM64_EVENT_CHANGE.js";
17
- import { t64_announce_change } from "../ecs/transform/t64_announce_change.js";
11
+ import { prefab_compile } from "./prefab/prefab_compile.js";
12
+ import { prefab_instance_destroy, prefab_instantiate } from "./prefab/prefab_instantiate.js";
13
+ import {
14
+ register_instance_animation,
15
+ unregister_instance_animation
16
+ } from "./register_instance_animation.js";
18
17
 
19
18
  /**
20
- * Puts entities into Shade's scene and keeps them where the ECS says they are.
19
+ * @typedef {import("../../shade/renderer/scene/GPUSceneContext.js").GPUSceneContext} GPUSceneContext
20
+ * @typedef {import("../../shade/renderer/loader/SceneBundle.js").SceneBundle} SceneBundle
21
+ * @typedef {import("./prefab/Prefab.js").Prefab} Prefab
22
+ * @typedef {import("./prefab/PrefabInstance.js").PrefabInstance} PrefabInstance
23
+ * @typedef {import("./register_instance_animation.js").InstanceAnimationRegistration} InstanceAnimationRegistration
24
+ * @typedef {import("./GraphicsEngine.js").GraphicsEngine} GraphicsEngine
25
+ */
26
+
27
+ /**
28
+ * What {@link MeshSystem.mesh_entities_of} answers for an entity with nothing in the scene.
21
29
  *
22
- * **It owns the scene and tells the facade to draw it**, rather than the facade handing a graph out
23
- * for anyone to write into — that coupling is what §2.1 retires along with `GraphicsEngine.scene`.
30
+ * @type {Int32Array}
31
+ */
32
+ const NO_ENTITIES = new Int32Array(0);
33
+
34
+ const SCRATCH_BOUNDS = new Float32Array(6);
35
+
36
+ /**
37
+ * What one entity has: its model, once loaded, as entities; the ids the GPU issued for the model's
38
+ * skins; and what is listening on its behalf.
39
+ */
40
+ class Entry {
41
+ /**
42
+ * @type {number}
43
+ */
44
+ entity = -1;
45
+
46
+ /**
47
+ * @type {SGMesh}
48
+ */
49
+ model = null;
50
+
51
+ /**
52
+ * @type {Transform64}
53
+ */
54
+ transform = null;
55
+
56
+ /**
57
+ * The model as entities, or null until it has loaded.
58
+ *
59
+ * @type {PrefabInstance|null}
60
+ */
61
+ instance = null;
62
+
63
+ /**
64
+ * What the GPU gave back for the instance's skins, or null while there is nothing registered —
65
+ * no model yet, no device yet, or a renderer restart that has not been drained.
66
+ *
67
+ * @type {InstanceAnimationRegistration|null}
68
+ */
69
+ animation = null;
70
+
71
+ /**
72
+ * The GPU context the instance's entities hold their rows in, or null while they hold none.
73
+ *
74
+ * @type {GPUSceneContext|null}
75
+ */
76
+ context = null;
77
+
78
+ /**
79
+ * Fires when the placing entity's world transform moves.
80
+ *
81
+ * @type {function(): void}
82
+ */
83
+ on_moved = null;
84
+
85
+ /**
86
+ * One per entity of the instance, firing when that entity's offset from its parent moves —
87
+ * a joint an IK solver, a ragdoll or a cloth wrote.
88
+ *
89
+ * @type {Map<number, function(): void>}
90
+ */
91
+ on_offset_moved = new Map();
92
+ }
93
+
94
+ /**
95
+ * Puts models into the scene as entities, and keeps their rows where the entities say.
24
96
  *
25
- * Placement is a `Transform` copied into `Node3D.transform_local`, through
26
- * {@link t64_copy_from_transform} because the node's transform is a `Transform64` since S2 and the
27
- * two types stay deliberately distinct. `transform_global` is **derived** — `updateMatrices`
28
- * recomputes it from the local transform and the parent chain — so writing it directly would be
29
- * undone by the next refresh, and the entity is placed through the local one.
97
+ * **A model is a prefab, and a placement is entities.** A loaded bundle is compiled once per url
98
+ * ({@link prefab_compile}) and spawned once per entity that wears it
99
+ * ({@link prefab_instantiate}): every node of the file becomes an entity attached to its parent's,
100
+ * named, drawing where it draws, with the placing entity as the root. What used to be a private
101
+ * copy of a node tree per placement is the dataset's own hierarchy, addressable by every system —
102
+ * IK finds a foot by name, cloth seeds from joints, gameplay asks where a socket is — and the
103
+ * renderer's tables are indexed by those entities, at `entity + 1`.
30
104
  *
31
- * What makes this affordable is S1: the scene database takes row-level updates, so moving one
32
- * entity writes one row. Nothing here rebuilds anything.
105
+ * **It owns the scene and tells the facade to draw it**, rather than the facade handing a graph out
106
+ * for anyone to write into.
33
107
  *
34
- * **It also hands each instance to the GPU's animation manager** ({@link update}), because it is
35
- * what builds instances and therefore the only thing that knows when one exists. Driving those
36
- * clips is not its business — that is the animation systems' — but a clip nothing has registered
37
- * cannot be driven by anyone.
108
+ * **Rows need a device, and registration does too.** A model loads whenever it loads, and there
109
+ * may be no renderer yet; {@link update} attaches every instance's entities to the scene's GPU
110
+ * context when one arrives, registers its skins with the animation manager, and does both again
111
+ * after a renderer restart. Driving the clips is not this system's business — that is the
112
+ * animation systems' — but a clip nothing has registered cannot be driven by anyone, which is why
113
+ * the instance is handed out ({@link instance_of}) rather than kept.
38
114
  */
39
115
  export class MeshSystem extends System {
40
116
  /**
@@ -43,53 +119,43 @@ export class MeshSystem extends System {
43
119
  #graphics;
44
120
 
45
121
  /**
46
- * The scene this system writes into and the facade draws.
47
- *
48
- * Received rather than created: lights come from a system of their own, and both have to be
49
- * putting content into the same scene for either to be visible.
122
+ * The scene this system writes into and the facade draws. Received rather than created: lights
123
+ * come from a system of their own, and both have to be putting content into the same scene for
124
+ * either to be visible.
50
125
  *
51
126
  * @type {Scene}
52
127
  */
53
128
  #scene;
54
129
 
55
130
  /**
56
- * Loaded model bundles, by url. A level places the same model many times over, and loading it
57
- * once per placement would be the dominant cost of opening one.
131
+ * Loaded and compiled models, by url. A level places the same model many times over, and
132
+ * loading it once per placement would be the dominant cost of opening one; compiling it once
133
+ * per placement would be the next.
58
134
  *
59
- * @type {Map<string, Promise<SceneBundle>>}
135
+ * @type {Map<string, Promise<Prefab>>}
60
136
  */
61
- #bundles = new Map();
137
+ #models = new Map();
62
138
 
63
139
  /**
64
- * What each entity has in the scene, and the signal bindings keeping it in step.
65
- *
66
- * `instance` and `animation` are null until the model has loaded and until the GPU has been
67
- * told about it respectively — two different waits, which is why they are two fields.
68
- *
69
- * @type {Map<number, {nodes: Node3D[], bindings: SignalBinding[], instance: SceneBundleInstance|null, animation: InstanceAnimationRegistration|null}>}
140
+ * @type {Map<number, Entry>}
70
141
  */
71
142
  #entries = new Map();
72
143
 
73
144
  /**
74
- * Shade's GPU state for {@link scene}, as of the last {@link update}.
75
- *
76
- * Held to answer one question: has the renderer been replaced since the last frame, so that
77
- * everything placed has to be registered again. **Which manager a particular registration
78
- * belongs to is the registration's own to say** — it carries the context that issued it — so
79
- * this is not consulted when ids are handed back.
145
+ * Shade's GPU state for {@link scene}, as of the last {@link update}. Held to answer one
146
+ * question: has the renderer been replaced since the last frame, so that everything placed has
147
+ * to be attached and registered again.
80
148
  *
81
149
  * @type {GPUSceneContext|null}
82
150
  */
83
151
  #context = null;
84
152
 
85
153
  /**
86
- * Entries whose instance is not registered with {@link #context} — either because it has just
87
- * loaded, or because a restart invalidated what it had.
88
- *
89
- * A queue rather than a scan over every entity, because this is per-frame work in a level that
90
- * places hundreds of models and the answer is almost always "nothing to do".
154
+ * Entries whose instance is not attached to {@link #context} — either because it has just
155
+ * loaded, or because a restart invalidated what it had. A queue rather than a scan over every
156
+ * entity, because this is per-frame work and the answer is almost always "nothing to do".
91
157
  *
92
- * @type {object[]}
158
+ * @type {Entry[]}
93
159
  */
94
160
  #unregistered = [];
95
161
 
@@ -97,16 +163,12 @@ export class MeshSystem extends System {
97
163
  * Entities whose `SGMesh` carried no url when it was linked.
98
164
  *
99
165
  * `SGMesh.url` is an accessor with no change signal behind it, and the game assigns it late as a
100
- * matter of
101
- * course: `GeneratedArmySystem` puts the component on an army entity and fills the url in from
102
- * a promise, once the army it generated has picked the leader whose model the army wears. So a
103
- * url that is missing at link time is the normal path to a model rather than an edge case, and
104
- * the only way to notice one arriving is to look again.
166
+ * matter of course: `GeneratedArmySystem` puts the component on an army entity and fills the
167
+ * url in from a promise, once the army it generated has picked the leader whose model the army
168
+ * wears. So a url that is missing at link time is the normal path to a model rather than an
169
+ * edge case, and the only way to notice one arriving is to look again.
105
170
  *
106
- * A list rather than a scan over every entity, and it is short: it holds only what has no model
107
- * yet, and an entry leaves it for good the moment one is asked for.
108
- *
109
- * @type {{entity: number, model: SGMesh, transform: Transform}[]}
171
+ * @type {Entry[]}
110
172
  */
111
173
  #awaiting_url = [];
112
174
 
@@ -146,82 +208,15 @@ export class MeshSystem extends System {
146
208
  }
147
209
 
148
210
  /**
149
- * Visit every node of an entity's model that carries geometry.
150
- *
151
- * The nodes are what the scene database keys on, so anything that has to say something about a
152
- * particular entity's meshes — which rows they occupy, which of them the visibility buffer will
153
- * name — starts here. A grouping node is skipped, because it has no geometry and therefore no
154
- * row of its own.
155
- *
156
- * @param {number} entity
157
- * @param {function(SGMesh): void} visitor
158
- * @returns {boolean} `false` when the entity has nothing in the scene — never seen, or still
159
- * loading, and neither is an error
160
- */
161
- traverse_meshes(entity, visitor) {
162
- const entry = this.#entries.get(entity);
163
-
164
- if (entry === undefined) {
165
- return false;
166
- }
167
-
168
- for (let i = 0; i < entry.nodes.length; i++) {
169
- entry.nodes[i].traverse(node => {
170
- if (node.isMesh === true) {
171
- visitor(node);
172
- }
173
- });
174
- }
175
-
176
- this.#traverse_expanded(entry, visitor);
177
-
178
- return true;
179
- }
180
-
181
- /**
182
- * The rows of a model that became entities.
183
- *
184
- * Its primitives are components on descendants rather than nodes this system holds, and each one
185
- * carries the row `ShadedGeometrySystem` put it in — so the walk is over the composition and the
186
- * answer is the same kind of node the instance path yields. A primitive whose system has not
187
- * linked it yet has no row and contributes nothing, which is the same "still loading" silence
188
- * every reader here already tolerates.
189
- *
190
- * @param {object} entry
191
- * @param {function(Mesh): void} visitor
192
- */
193
- #traverse_expanded(entry, visitor) {
194
- const composition = entry.composition;
195
-
196
- if (composition === null) {
197
- return;
198
- }
199
-
200
- composition.traverse(node => {
201
- const geometry = node.entity.getComponent(ShadedGeometry);
202
-
203
- if (geometry === null || geometry === undefined) {
204
- return;
205
- }
206
-
207
- if (geometry.node === null) {
208
- return;
209
- }
210
-
211
- visitor(geometry.node);
212
- });
213
- }
214
-
215
- /**
216
- * The private copy of the model an entity is showing — its clips among other things, which is
217
- * where their names and their durations come from.
211
+ * The model an entity is showing, as entities: its skins and clips addressed to them, and its
212
+ * nodes by name.
218
213
  *
219
214
  * Handed out rather than copied because an animation driver has to know *which* instance it is
220
215
  * bound to: a model swap builds a new one, and a driver still holding the old one would be
221
- * driving nodes that left the scene. The object's identity is the only signal that says so.
216
+ * driving entities that have gone. The object's identity is the only signal that says so.
222
217
  *
223
218
  * @param {number} entity
224
- * @returns {SceneBundleInstance|null} `null` for an entity this system has never seen, or one
219
+ * @returns {PrefabInstance|null} `null` for an entity this system has never seen, or one
225
220
  * whose model has not finished loading
226
221
  */
227
222
  instance_of(entity) {
@@ -235,7 +230,7 @@ export class MeshSystem extends System {
235
230
  }
236
231
 
237
232
  /**
238
- * What the GPU's animation manager gave back for that instance — the skin and clip ids, in the
233
+ * What the GPU's animation manager gave back for that instance — the skin ids, in the
239
234
  * instance's own order.
240
235
  *
241
236
  * Same reasoning as {@link instance_of} and a stronger version of it: these ids belong to one
@@ -257,11 +252,31 @@ export class MeshSystem extends System {
257
252
  }
258
253
 
259
254
  /**
260
- * Where an entity's model is, in world space.
255
+ * The entities of an entity's model that draw — one per primitive of the file. Each holds the
256
+ * `meshes` row `entity + 1`, which is what the visibility buffer writes for every pixel it
257
+ * covers; anything that has to say something about a particular model's meshes starts here.
261
258
  *
262
- * This is what makes picking possible without a second copy of the geometry: Shade already keeps
263
- * a world bounding box per mesh, refreshed as part of the `updateMatrices` that places it, so the
264
- * answer is a walk over what the entity has in the scene and nothing is recomputed.
259
+ * @param {number} entity
260
+ * @returns {Int32Array} empty for an entity with nothing in the scene — never seen, or still
261
+ * loading, and neither is an error. Not to be kept: a model swap replaces it
262
+ */
263
+ mesh_entities_of(entity) {
264
+ const entry = this.#entries.get(entity);
265
+
266
+ if (entry === undefined || entry.instance === null) {
267
+ return NO_ENTITIES;
268
+ }
269
+
270
+ return entry.instance.mesh_entities;
271
+ }
272
+
273
+ /**
274
+ * Where an entity's model is, in world space: the union of its primitives' geometry bounds
275
+ * under their own entities' world transforms — which the ECS composes, so this answers with no
276
+ * device and with no frame of latency, from what the simulation knows. The box the renderer
277
+ * culls by is derived on the GPU from the same and is not consulted.
278
+ *
279
+ * A skinned primitive answers at its rest pose, under the frame its skin deforms in.
265
280
  *
266
281
  * @param {ArrayLike<number>|number[]|Float32Array} target aabb3, order `x0,y0,z0,x1,y1,z1`
267
282
  * @param {number} entity
@@ -271,45 +286,57 @@ export class MeshSystem extends System {
271
286
  compute_world_bounds(target, entity) {
272
287
  const entry = this.#entries.get(entity);
273
288
 
274
- if (entry === undefined) {
289
+ if (entry === undefined || entry.instance === null) {
275
290
  return false;
276
291
  }
277
292
 
293
+ const dataset = this.entityManager.dataset;
294
+ const primitives = entry.instance.mesh_entities;
295
+
278
296
  let found = false;
279
297
 
280
- /**
281
- * @param {Mesh} node
282
- */
283
- const combine = node => {
284
- const bounds = node.bounding_box;
298
+ for (let i = 0; i < primitives.length; i++) {
299
+ const primitive = primitives[i];
300
+
301
+ if (!dataset.entityExists(primitive)) {
302
+ continue;
303
+ }
304
+
305
+ const geometry = dataset.getComponent(primitive, ShadedGeometry);
306
+ const world = dataset.getComponent(primitive, Transform64);
307
+
308
+ if (geometry === undefined || world === undefined || geometry.geometry === null) {
309
+ continue;
310
+ }
311
+
312
+ // a Transform64's matrix starts at element 0, so it is its own mat4 argument
313
+ aabb3_matrix4_project(SCRATCH_BOUNDS, geometry.geometry.bounding_box, world);
285
314
 
286
315
  // combining the first box with itself is how it lands in `target` — one operation
287
316
  // for both cases, rather than a copy that only ever runs once
288
- aabb3_array_combine(target, 0, found ? target : bounds, 0, bounds, 0);
317
+ aabb3_array_combine(target, 0, found ? target : SCRATCH_BOUNDS, 0, SCRATCH_BOUNDS, 0);
289
318
 
290
319
  found = true;
291
- };
292
-
293
- for (let i = 0; i < entry.nodes.length; i++) {
294
- entry.nodes[i].traverse(node => {
295
- if (node.isMesh !== true) {
296
- // a grouping node carries no geometry, so it has no bounds of its own
297
- return;
298
- }
299
-
300
- combine(node);
301
- });
302
320
  }
303
321
 
304
- this.#traverse_expanded(entry, combine);
305
-
306
322
  return found;
307
323
  }
308
324
 
309
325
  async startup(entityManager) {
310
326
  this.entityManager = entityManager;
311
327
 
312
- this.#graphics.set_scene(this.#scene);
328
+ // the scene's rows are this dataset's entities; the first system to place one says so
329
+ const dataset = entityManager.dataset;
330
+ const scene = this.#scene;
331
+
332
+ assert.ok(
333
+ scene.dataset === null || scene.dataset === undefined || scene.dataset === dataset,
334
+ 'the scene is bound to another dataset'
335
+ );
336
+
337
+ scene.dataset = dataset;
338
+
339
+ this.#graphics.set_scene(scene);
313
340
  }
314
341
 
315
342
  async shutdown(entityManager) {
@@ -317,24 +344,24 @@ export class MeshSystem extends System {
317
344
  this.#drop(entity);
318
345
  }
319
346
 
320
- this.#bundles.clear();
347
+ this.#models.clear();
321
348
 
322
349
  this.#context = null;
323
350
  this.#unregistered.length = 0;
324
351
  }
325
352
 
326
353
  /**
327
- * Tell the GPU about the models that have arrived since the last frame.
354
+ * Tell the GPU about the models that have arrived since the last frame: their entities take
355
+ * their rows, and their skins reach `GPUAnimationManager`.
328
356
  *
329
- * **This is where an instance's skins and clips reach `GPUAnimationManager`** — the manager
330
- * hangs off the scene's GPU context, which exists only while there is a device, so registration
331
- * cannot happen where instances are built (a model loads whenever it loads, including before
332
- * the renderer has started). Registration is documented eventually-consistent at both entry
333
- * points, so a frame of latency here costs nothing: the ids are live immediately and the chains
334
- * that drive deformation are built when every joint has a row.
357
+ * The manager hangs off the scene's GPU context, which exists only while there is a device, so
358
+ * neither can happen where instances are built (a model loads whenever it loads, including
359
+ * before the renderer has started). Registration is documented eventually-consistent at both
360
+ * entry points, so a frame of latency here costs nothing: the ids are live immediately and the
361
+ * chains that drive deformation are built when every joint has its row.
335
362
  *
336
- * A restart is the same event seen from here: the context object changes, every id the old one
337
- * issued is void, and everything currently placed queues up again.
363
+ * A restart is the same event seen from here: the context object changes, every id and every
364
+ * row the old one issued is void, and everything currently placed queues up again.
338
365
  *
339
366
  * @param {number} time_delta_seconds
340
367
  */
@@ -363,23 +390,13 @@ export class MeshSystem extends System {
363
390
  **A throw in here does not cost one model, it costs the session.** The list is cleared after
364
391
  the loop, so a registration that throws partway leaves the entries before it *already
365
392
  registered* and *still queued*: the next update registers them a second time, `bind` finds
366
- the mesh already bound to another skin, and that assertion then fires once a frame for as
367
- long as the game runs. Meanwhile the entry that threw never gets an `animation`, so `#drop`
368
- has nothing to give back and its skinning bindings outlive their model — which is how a
369
- `SkinnedMesh` ends up with no meshes-table row a hundred frames later.
370
-
371
- Seen for real: a second skinned model arriving in one frame used to overrun the meshlet
372
- buffers while a clone was queued (fixed in `GPUMeshletManager`), and the cascade above is
373
- what turned that one throw into a dead animation layer. Registering one entry at a time and
374
- taking it off the list as it succeeds is the shape of the fix; what to do with an entry that
375
- *cannot* be registered is the open question, which is why it is written down here rather
376
- than fixed. The throw that exposed it is fixed (`ac5e430e3`); the amplifier is not, and any
377
- future failure in registration reproduces the same cascade.
393
+ the entity already bound to another skin, and that assertion then fires once a frame for as
394
+ long as the game runs. Registering one entry at a time and taking it off the list as it
395
+ succeeds is the shape of the fix; what to do with an entry that *cannot* be registered is
396
+ the open question, which is why it is written down here rather than fixed.
378
397
  */
379
398
  for (let i = 0; i < waiting.length; i++) {
380
- const entry = waiting[i];
381
-
382
- entry.animation = register_instance_animation(context, entry.instance);
399
+ this.#register(waiting[i], context);
383
400
  }
384
401
 
385
402
  waiting.length = 0;
@@ -395,15 +412,15 @@ export class MeshSystem extends System {
395
412
  const waiting = this.#awaiting_url;
396
413
 
397
414
  for (let i = waiting.length - 1; i >= 0; i--) {
398
- const pending = waiting[i];
415
+ const entry = waiting[i];
399
416
 
400
- if (pending.model.url === null) {
417
+ if (entry.model.url === null) {
401
418
  continue;
402
419
  }
403
420
 
404
421
  waiting.splice(i, 1);
405
422
 
406
- this.#attach(pending.entity, pending.model.url, pending.transform);
423
+ this.#attach(entry, entry.model.url);
407
424
  }
408
425
  }
409
426
 
@@ -425,41 +442,69 @@ export class MeshSystem extends System {
425
442
  }
426
443
 
427
444
  entry.animation = null;
445
+ entry.context = null;
428
446
 
429
447
  waiting.push(entry);
430
448
  }
431
449
  }
432
450
 
451
+ /**
452
+ * Give an instance's entities their rows in a context, and its skins to the animation manager.
453
+ *
454
+ * Every entity of the model takes a `transforms` row — a joint composes on the GPU, a grouping
455
+ * node is what its children compose under — and the placing entity takes one too, so the whole
456
+ * hierarchy composes from it. The primitives' `meshes` rows are `ShadedGeometrySystem`'s.
457
+ *
458
+ * @param {Entry} entry
459
+ * @param {GPUSceneContext} context
460
+ */
461
+ #register(entry, context) {
462
+ const rows = context.rows;
463
+ const entities = entry.instance.entities;
464
+
465
+ for (let i = 0; i < entities.length; i++) {
466
+ rows.acquire(entities[i]);
467
+ }
468
+
469
+ entry.animation = register_instance_animation(context, entry.instance);
470
+ entry.context = context;
471
+ }
472
+
433
473
  /**
434
474
  * @param {SGMesh} model
435
475
  * @param {Transform64} transform
436
476
  * @param {number} entity
437
477
  */
438
478
  link(model, transform, entity) {
439
- const entry = { nodes: [], on_changed: null, instance: null, animation: null, composition: null };
479
+ const entry = new Entry();
440
480
 
441
- this.#entries.set(entity, entry);
481
+ entry.entity = entity;
482
+ entry.model = model;
483
+ entry.transform = transform;
442
484
 
443
- // The entity is placed the moment its transform moves, not on a poll: a transform that has
444
- // not changed costs nothing, which is the same bargain the scene database makes downstream.
445
- // A Transform64 has no signals of its own, so the announcement comes from the dataset: the
446
- // writer sends TRANSFORM64_EVENT_CHANGE and this wakes on it. Coarser than the three
447
- // sub-object signals it replaces - a scale write wakes a placement that only reads the whole
448
- // transform anyway - and #place already skips when nothing moved.
449
- const on_changed = () => this.#place(entity, transform);
485
+ this.#entries.set(entity, entry);
450
486
 
451
- entry.on_changed = on_changed;
487
+ // The placing entity's own row is marked when its transform moves, not on a poll: an
488
+ // entity that has not moved costs nothing, which is the same bargain the scene database
489
+ // makes downstream. A Transform64 has no signals of its own, so the announcement comes from
490
+ // the dataset. The entities under it follow through the attachment system and need no
491
+ // marking of their own for a move of the root — the GPU composes them.
492
+ entry.on_moved = () => {
493
+ if (entry.context !== null) {
494
+ entry.context.rows.mark_world(entity);
495
+ }
496
+ };
452
497
 
453
- this.entityManager.dataset.addEntityEventListener(entity, TRANSFORM64_EVENT_CHANGE, on_changed);
498
+ this.entityManager.dataset.addEntityEventListener(entity, TRANSFORM64_EVENT_CHANGE, entry.on_moved);
454
499
 
455
500
  if (model.url === null) {
456
501
  // nothing to show yet; {@link update} watches for the url arriving
457
- this.#awaiting_url.push({ entity, model, transform });
502
+ this.#awaiting_url.push(entry);
458
503
 
459
504
  return;
460
505
  }
461
506
 
462
- this.#attach(entity, model.url, transform);
507
+ this.#attach(entry, model.url);
463
508
  }
464
509
 
465
510
  /**
@@ -472,144 +517,75 @@ export class MeshSystem extends System {
472
517
  }
473
518
 
474
519
  /**
475
- * Load the model if it has not been seen, then put a copy of it in the scene.
520
+ * The prefab for a url, loading and compiling it on first mention.
476
521
  *
477
- * @param {number} entity
478
522
  * @param {string} url
479
- * @param {Transform64} transform
523
+ * @returns {Promise<Prefab>}
480
524
  */
481
- async #attach(entity, url, transform) {
482
- /*
483
- Which entry this load is for, decided before the wait rather than after it. A load is in
484
- flight for as long as a fetch and a decode take, and the entity can leave and come back
485
- inside that window — so asking `#entries` afterwards answers "the entry this entity has
486
- now", which may be a different one. Attaching to that leaves the scene holding a second
487
- model nothing owns, and its skins registered with the GPU under a record that has already
488
- been overwritten.
489
- */
490
- const started_for = this.#entries.get(entity);
491
-
492
- let bundle = this.#bundles.get(url);
493
-
494
- if (bundle === undefined) {
495
- bundle = this.#load(url);
496
-
497
- this.#bundles.set(url, bundle);
498
- }
499
-
500
- const loaded = await bundle;
525
+ #model(url) {
526
+ let prefab = this.#models.get(url);
501
527
 
502
- const entry = this.#entries.get(entity);
528
+ if (prefab === undefined) {
529
+ prefab = this.#load(url).then(bundle => prefab_compile(bundle));
503
530
 
504
- if (entry !== started_for) {
505
- // the entity left while its model was in flight, or left and came back as another
506
- // entry — both ordinary at level-load rates
507
- return;
531
+ this.#models.set(url, prefab);
508
532
  }
509
533
 
510
- if (loaded.skins.length === 0 && loaded.clips.length === 0) {
511
- this.#expand(entity, loaded, transform);
512
-
513
- return;
514
- }
515
-
516
- const instance = instantiate_scene_bundle(loaded);
517
-
518
- entry.instance = instance;
519
-
520
- for (const node of instance.roots) {
521
- entry.nodes.push(node);
522
-
523
- this.#scene.add(node);
524
- }
525
-
526
- this.#place(entity, transform);
527
-
528
- // The GPU hears about it on the next update rather than here: a model finishes loading
529
- // whenever it finishes, and there may be no device to tell.
530
- this.#unregistered.push(entry);
534
+ return prefab;
531
535
  }
532
536
 
533
537
  /**
534
- * Put a model into the dataset as entities.
538
+ * Load and compile the model if it has not been seen, then spawn it under the entity.
535
539
  *
536
- * **This is what placing a model means in an ECS** (D47): meep has no scene graph to hand a file
537
- * to, so the file's nodes become entities — parented, named, placed, and carrying a
538
- * `ShadedGeometry` where they draw — and `ShadedGeometrySystem` gives each of those a row.
539
- * Nothing here touches the scene, and no copy of the model is made: the entities name the
540
- * bundle's own geometry and material, so a model placed two hundred times is one of each.
541
- *
542
- * **Only a model that neither deforms nor animates comes this way.** A skinned one deforms
543
- * against a skeleton the renderer owns and the GPU poses; an animated one has clips that drive
544
- * the nodes of an instance, and `GPUAnimationManager` addresses those nodes rather than
545
- * entities. Making joints entities, or moving playback onto entity transforms, are both designs
546
- * outside this program (D47) — so anything with a skin or a clip keeps the instance path above,
547
- * exactly as Phase 4 built it.
548
- *
549
- * @param {number} entity
550
- * @param {SceneBundle} bundle
551
- * @param {Transform64} transform
540
+ * @param {Entry} entry
541
+ * @param {string} url
552
542
  */
553
- #expand(entity, bundle, transform) {
554
- const entry = this.#entries.get(entity);
555
-
556
- const composition = shade_bundle_to_entity_composition(bundle);
543
+ async #attach(entry, url) {
544
+ const entity = entry.entity;
557
545
 
558
- composition.entity.add(ParentEntity.from(entity));
546
+ const prefab = await this.#model(url);
559
547
 
560
- // Copying is only half of it: the composed entity is a writer like any other, so the
561
- // systems placing ITS nodes wake on its own announcement, not on the source entity is.
562
- // EntityNode.transform is the hierarchy pose, not the entity's component - the component is
563
- // the world transform the node syncs down into. Under signals the copy alone triggered that
564
- // sync; a Transform64 has none, so the sync is asked for explicitly.
565
- const follow = () => {
566
- composition.transform.copy(transform);
567
-
568
- composition.transform_changed();
569
- };
570
-
571
- follow();
548
+ /*
549
+ Which entry this load is for was decided before the wait rather than after it. A load is in
550
+ flight for as long as a fetch and a decode take, and the entity can leave and come back
551
+ inside that window — so asking `#entries` afterwards answers "the entry this entity has
552
+ now", which may be a different one. Spawning for that one would leave a model in the scene
553
+ nothing owns.
554
+ */
555
+ if (this.#entries.get(entity) !== entry) {
556
+ // the entity left while its model was in flight, or left and came back as another
557
+ // entry — both ordinary at level-load rates
558
+ return;
559
+ }
572
560
 
573
- composition.build(this.entityManager.dataset);
561
+ const dataset = this.entityManager.dataset;
574
562
 
575
- // the build linked the composed entity's own systems; sync once more so they see the pose
576
- follow();
563
+ const instance = prefab_instantiate(prefab, dataset, entity);
577
564
 
578
- // the composed entity follows the source transform, and a Transform64 has no signals of
579
- // its own, so the follow rides the dataset announcement like every other consumer
580
- const ecd = this.entityManager.dataset;
565
+ entry.instance = instance;
581
566
 
582
- ecd.addEntityEventListener(entity, TRANSFORM64_EVENT_CHANGE, follow);
567
+ // A joint's offset moving — an IK solver, a ragdoll, a cloth writing it — is that joint's
568
+ // row. The world transforms the attachment system composes below it are not: the GPU
569
+ // composes those itself, from the offsets.
570
+ const entities = instance.entities;
583
571
 
584
- composition.on.destroyed.addOne(
585
- () => ecd.removeEntityEventListener(entity, TRANSFORM64_EVENT_CHANGE, follow)
586
- );
572
+ for (let i = 1; i < entities.length; i++) {
573
+ const member = entities[i];
587
574
 
588
- entry.composition = composition;
589
- }
575
+ const on_offset_moved = () => {
576
+ if (entry.context !== null) {
577
+ entry.context.rows.mark_local(member);
578
+ }
579
+ };
590
580
 
591
- /**
592
- * @param {number} entity
593
- * @param {Transform64} transform
594
- */
595
- #place(entity, transform) {
596
- const entry = this.#entries.get(entity);
581
+ entry.on_offset_moved.set(member, on_offset_moved);
597
582
 
598
- if (entry === undefined) {
599
- return;
583
+ dataset.addEntityEventListener(member, TRANSFORM_ATTACHMENT_EVENT_CHANGE, on_offset_moved);
600
584
  }
601
585
 
602
- const nodes = entry.nodes;
603
-
604
- for (let i = 0; i < nodes.length; i++) {
605
- const node = nodes[i];
606
-
607
- node.transform_local.copy(transform);
608
-
609
- // recomputes transform_global down the subtree, and bumps the version the scene
610
- // database reads to decide what to upload
611
- node.updateMatrices();
612
- }
586
+ // The GPU hears about it on the next update rather than here: a model finishes loading
587
+ // whenever it finishes, and there may be no device to tell.
588
+ this.#unregistered.push(entry);
613
589
  }
614
590
 
615
591
  /**
@@ -622,21 +598,12 @@ export class MeshSystem extends System {
622
598
  return;
623
599
  }
624
600
 
625
- if (entry.on_changed !== null) {
626
- this.entityManager.dataset.removeEntityEventListener(entity, TRANSFORM64_EVENT_CHANGE, entry.on_changed);
627
-
628
- entry.on_changed = null;
629
- }
630
-
631
- for (let i = 0; i < entry.nodes.length; i++) {
632
- this.#scene.remove(entry.nodes[i]);
633
- }
601
+ this.#entries.delete(entity);
634
602
 
635
- if (entry.composition !== null) {
636
- // the entities the model became are the model, so they go with it
637
- entry.composition.destroy();
603
+ const dataset = this.entityManager.dataset;
638
604
 
639
- entry.composition = null;
605
+ if (dataset.entityExists(entity)) {
606
+ dataset.removeEntityEventListener(entity, TRANSFORM64_EVENT_CHANGE, entry.on_moved);
640
607
  }
641
608
 
642
609
  const waiting = this.#unregistered.indexOf(entry);
@@ -646,23 +613,49 @@ export class MeshSystem extends System {
646
613
  this.#unregistered.splice(waiting, 1);
647
614
  }
648
615
 
649
- const awaiting = this.#awaiting_url.findIndex(pending => pending.entity === entity);
616
+ const awaiting = this.#awaiting_url.indexOf(entry);
650
617
 
651
618
  if (awaiting !== -1) {
652
619
  // it left before it ever had a model to load
653
620
  this.#awaiting_url.splice(awaiting, 1);
654
621
  }
655
622
 
656
- const registration = entry.animation;
623
+ const instance = entry.instance;
657
624
 
658
- if (registration !== null) {
659
- if (this.#graphics.scene_context(this.#scene) === registration.context) {
660
- unregister_instance_animation(registration);
625
+ if (instance === null) {
626
+ return;
627
+ }
628
+
629
+ entry.instance = null;
630
+
631
+ for (const [member, listener] of entry.on_offset_moved) {
632
+ if (dataset.entityExists(member)) {
633
+ dataset.removeEntityEventListener(member, TRANSFORM_ATTACHMENT_EVENT_CHANGE, listener);
661
634
  }
635
+ }
662
636
 
663
- entry.animation = null;
637
+ entry.on_offset_moved.clear();
638
+
639
+ // A destroyed context must not be handed its rows or its ids back: a renderer restart
640
+ // takes the GPU scene context with it, and what the old one issued means nothing to the
641
+ // context that replaces it — so the entry forgets them rather than returning them.
642
+ if (entry.context !== null && entry.context === this.#graphics.scene_context(this.#scene)) {
643
+ const rows = entry.context.rows;
644
+ const entities = instance.entities;
645
+
646
+ for (let i = 0; i < entities.length; i++) {
647
+ rows.release(entities[i]);
648
+ }
649
+
650
+ if (entry.animation !== null) {
651
+ unregister_instance_animation(entry.animation);
652
+ }
664
653
  }
665
654
 
666
- this.#entries.delete(entity);
655
+ entry.animation = null;
656
+ entry.context = null;
657
+
658
+ // the entities the model became are the model, so they go with it
659
+ prefab_instance_destroy(dataset, instance);
667
660
  }
668
661
  }