@woosh/meep-engine 3.42.0 → 3.44.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 (345) hide show
  1. package/editor/prototypeEditorShell.d.ts.map +1 -1
  2. package/editor/prototypeEditorShell.js +4 -2
  3. package/package.json +91 -96
  4. package/src/engine/Clock.d.ts +15 -0
  5. package/src/engine/Clock.d.ts.map +1 -1
  6. package/src/engine/Clock.js +29 -5
  7. package/src/engine/Engine.d.ts.map +1 -1
  8. package/src/engine/Engine.js +11 -19
  9. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts +57 -0
  10. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.d.ts.map +1 -0
  11. package/src/engine/graphics/ecs/mesh-v2/MeshSkin.js +84 -0
  12. package/src/engine/graphics3/AnimationGraphSystem.d.ts +23 -13
  13. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
  14. package/src/engine/graphics3/AnimationGraphSystem.js +61 -64
  15. package/src/engine/graphics3/AnimationSystem.d.ts +24 -15
  16. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
  17. package/src/engine/graphics3/AnimationSystem.js +67 -61
  18. package/src/engine/graphics3/MeshSkinSystem.d.ts +56 -0
  19. package/src/engine/graphics3/MeshSkinSystem.d.ts.map +1 -0
  20. package/src/engine/graphics3/MeshSkinSystem.js +317 -0
  21. package/src/engine/graphics3/MeshSystem.d.ts +15 -35
  22. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  23. package/src/engine/graphics3/MeshSystem.js +21 -298
  24. package/src/engine/graphics3/RowChains.d.ts +76 -0
  25. package/src/engine/graphics3/RowChains.d.ts.map +1 -0
  26. package/src/engine/graphics3/RowChains.js +347 -0
  27. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +6 -0
  28. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  29. package/src/engine/graphics3/ShadedGeometrySystem.js +329 -309
  30. package/src/engine/graphics3/animation/AnimationClips.d.ts +56 -0
  31. package/src/engine/graphics3/animation/AnimationClips.d.ts.map +1 -0
  32. package/src/engine/graphics3/animation/AnimationClips.js +79 -0
  33. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +13 -14
  34. package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
  35. package/src/engine/graphics3/animation/ClipListPlayer.js +262 -263
  36. package/src/engine/graphics3/animation/write_clip_playback.d.ts +3 -3
  37. package/src/engine/graphics3/animation/write_clip_playback.js +4 -4
  38. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +5 -0
  39. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  40. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +80 -75
  41. package/src/engine/graphics3/prefab/PrefabInstance.d.ts +4 -24
  42. package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -1
  43. package/src/engine/graphics3/prefab/PrefabInstance.js +60 -80
  44. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +16 -3
  45. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -1
  46. package/src/engine/graphics3/prefab/prefab_instantiate.js +49 -12
  47. package/src/engine/graphics3/prefab/prefab_place.d.ts +31 -17
  48. package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -1
  49. package/src/engine/graphics3/prefab/prefab_place.js +175 -130
  50. package/src/engine/graphics3/register_clips.d.ts +64 -0
  51. package/src/engine/graphics3/register_clips.d.ts.map +1 -0
  52. package/src/engine/graphics3/register_clips.js +114 -0
  53. package/src/engine/physics/cloth/MEASUREMENTS.md +795 -0
  54. package/src/engine/physics/cloth/PLAN.md +339 -9
  55. package/src/engine/physics/cloth/build/ClothProxy.d.ts +113 -61
  56. package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -1
  57. package/src/engine/physics/cloth/build/ClothProxy.js +142 -77
  58. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts +22 -0
  59. package/src/engine/physics/cloth/build/cloth_bind_in_frame.d.ts.map +1 -0
  60. package/src/engine/physics/cloth/build/cloth_bind_in_frame.js +75 -0
  61. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +43 -30
  62. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  63. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +357 -284
  64. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts +62 -0
  65. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.d.ts.map +1 -0
  66. package/src/engine/physics/cloth/build/cloth_proxy_from_mesh.js +280 -0
  67. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +1 -1
  68. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +1 -1
  69. package/src/engine/physics/cloth/ecs/Cloth.d.ts +17 -9
  70. package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -1
  71. package/src/engine/physics/cloth/ecs/Cloth.js +220 -212
  72. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +6 -0
  73. package/src/engine/physics/cloth/ecs/ClothHold.d.ts +91 -0
  74. package/src/engine/physics/cloth/ecs/ClothHold.d.ts.map +1 -0
  75. package/src/engine/physics/cloth/ecs/ClothHold.js +103 -0
  76. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +254 -48
  77. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  78. package/src/engine/physics/cloth/ecs/ClothInstance.js +277 -47
  79. package/src/engine/physics/cloth/ecs/ClothPin.d.ts +73 -0
  80. package/src/engine/physics/cloth/ecs/ClothPin.d.ts.map +1 -0
  81. package/src/engine/physics/cloth/ecs/ClothPin.js +92 -0
  82. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts +36 -0
  83. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.d.ts.map +1 -0
  84. package/src/engine/physics/cloth/ecs/ClothPinSerializationAdapter.js +61 -0
  85. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +23 -17
  86. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
  87. package/src/engine/physics/cloth/ecs/ClothRig.js +29 -27
  88. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +12 -14
  89. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  90. package/src/engine/physics/cloth/ecs/ClothSystem.js +20 -15
  91. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +57 -36
  92. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  93. package/src/engine/physics/cloth/ecs/ClothWorld.js +816 -179
  94. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +12 -13
  95. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
  96. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +20 -14
  97. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +63 -11
  98. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  99. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +321 -84
  100. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +9 -7
  101. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  102. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +9 -7
  103. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +3 -3
  104. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +30 -30
  105. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts +37 -0
  106. package/src/engine/physics/cloth/ecs/cloth_geodesic.d.ts.map +1 -0
  107. package/src/engine/physics/cloth/ecs/cloth_geodesic.js +142 -0
  108. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts +97 -0
  109. package/src/engine/physics/cloth/ecs/cloth_holds.d.ts.map +1 -0
  110. package/src/engine/physics/cloth/ecs/cloth_holds.js +608 -0
  111. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +2 -2
  112. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
  113. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +160 -9
  114. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +17 -22
  115. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  116. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +55 -117
  117. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -6
  118. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  119. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +44 -15
  120. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +5 -0
  121. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  122. package/src/engine/physics/cloth/ecs/cloth_write_back.js +60 -16
  123. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
  124. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +65 -58
  125. package/src/engine/physics/cloth/playground/collide_main.js +1 -1
  126. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
  127. package/src/engine/physics/cloth/playground/garment_build.js +17 -5
  128. package/src/engine/physics/cloth/playground/garment_main.js +1 -1
  129. package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -1
  130. package/src/engine/physics/cloth/playground/rig_build.js +302 -296
  131. package/src/engine/physics/cloth/solver/ClothState.d.ts +45 -7
  132. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  133. package/src/engine/physics/cloth/solver/ClothState.js +63 -7
  134. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +6 -1
  135. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  136. package/src/engine/physics/cloth/solver/cloth_contact_find.js +7 -2
  137. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts +114 -0
  138. package/src/engine/physics/cloth/solver/cloth_hold_line.d.ts.map +1 -0
  139. package/src/engine/physics/cloth/solver/cloth_hold_line.js +362 -0
  140. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +6 -2
  141. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -1
  142. package/src/engine/physics/cloth/solver/cloth_self_find.js +13 -13
  143. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +24 -12
  144. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  145. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +24 -12
  146. package/src/engine/physics/cloth/solver/cloth_step.d.ts +16 -0
  147. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  148. package/src/engine/physics/cloth/solver/cloth_step.js +183 -20
  149. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +1 -0
  150. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -1
  151. package/src/engine/physics/cloth/solver/cloth_step_instance.js +10 -3
  152. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +1 -1
  153. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -1
  154. package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +353 -346
  155. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +7 -5
  156. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -1
  157. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +7 -5
  158. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +9 -9
  159. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
  160. package/src/engine/physics/cloth/wind/cloth_sample_air.js +26 -26
  161. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  162. package/src/engine/simulation/Ticker.d.ts +13 -0
  163. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  164. package/src/engine/simulation/Ticker.js +43 -8
  165. package/src/shade/RENDERER_CONTRACT.md +8 -2
  166. package/src/shade/playground/mesh_row_ceiling/main.js +2 -1
  167. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  168. package/src/shade/playground/skinned_blas_refit/main.js +11 -19
  169. package/src/shade/playground/skinned_blas_refit/place_character.d.ts +6 -3
  170. package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
  171. package/src/shade/playground/skinned_blas_refit/place_character.js +90 -90
  172. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  173. package/src/shade/playground/skinned_mesh_soup/main.js +502 -509
  174. package/src/shade/playground/texture_encode/README.md +129 -109
  175. package/src/shade/playground/texture_encode/main.js +1430 -1430
  176. package/src/shade/playground/vgeo_runtime/README.md +5 -4
  177. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  178. package/src/shade/renderer/Renderer.js +6 -5
  179. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +45 -14
  180. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  181. package/src/shade/renderer/animation/GPUAnimationManager.js +316 -64
  182. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +5 -0
  183. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  184. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -1
  185. package/src/shade/renderer/atmosphere/GPUSky.d.ts +12 -0
  186. package/src/shade/renderer/atmosphere/GPUSky.d.ts.map +1 -1
  187. package/src/shade/renderer/atmosphere/GPUSky.js +162 -147
  188. package/src/shade/renderer/geometry/BoxGeometry.d.ts +1 -11
  189. package/src/shade/renderer/geometry/BoxGeometry.d.ts.map +1 -1
  190. package/src/shade/renderer/geometry/BoxGeometry.js +6 -13
  191. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts +19 -0
  192. package/src/shade/renderer/geometry/CapsuleGeometry.d.ts.map +1 -0
  193. package/src/shade/renderer/geometry/CapsuleGeometry.js +24 -0
  194. package/src/shade/renderer/geometry/ConeGeometry.d.ts +20 -0
  195. package/src/shade/renderer/geometry/ConeGeometry.d.ts.map +1 -0
  196. package/src/shade/renderer/geometry/ConeGeometry.js +33 -0
  197. package/src/shade/renderer/geometry/CylinderGeometry.d.ts +21 -0
  198. package/src/shade/renderer/geometry/CylinderGeometry.d.ts.map +1 -0
  199. package/src/shade/renderer/geometry/CylinderGeometry.js +35 -0
  200. package/src/shade/renderer/geometry/PlaneGeometry.d.ts +17 -0
  201. package/src/shade/renderer/geometry/PlaneGeometry.d.ts.map +1 -0
  202. package/src/shade/renderer/geometry/PlaneGeometry.js +22 -0
  203. package/src/shade/renderer/geometry/TorusGeometry.d.ts +18 -0
  204. package/src/shade/renderer/geometry/TorusGeometry.d.ts.map +1 -0
  205. package/src/shade/renderer/geometry/TorusGeometry.js +23 -0
  206. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts +21 -0
  207. package/src/shade/renderer/geometry/UVSphereGeometry.d.ts.map +1 -0
  208. package/src/shade/renderer/geometry/UVSphereGeometry.js +34 -0
  209. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts +19 -0
  210. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.d.ts.map +1 -0
  211. package/src/shade/renderer/geometry/primitives/make_capsule_geometry.js +205 -0
  212. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts +21 -0
  213. package/src/shade/renderer/geometry/primitives/make_cone_geometry.d.ts.map +1 -0
  214. package/src/shade/renderer/geometry/primitives/make_cone_geometry.js +36 -0
  215. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts +1 -1
  216. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.d.ts.map +1 -1
  217. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +44 -9
  218. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts +20 -0
  219. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.d.ts.map +1 -0
  220. package/src/shade/renderer/geometry/primitives/make_uv_sphere_geometry.js +190 -0
  221. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  222. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +7 -2
  223. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +26 -8
  224. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
  225. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +56 -39
  226. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts +7 -0
  227. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.d.ts.map +1 -1
  228. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/shader_prefix_scan_csdldf.js +46 -4
  229. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.d.ts.map +1 -1
  230. package/src/shade/renderer/gpu_primitive/prefix_sum/v1/test_prefix_sum.js +4 -2
  231. package/src/shade/renderer/gpu_primitive/sort/defs.d.ts +2 -2
  232. package/src/shade/renderer/gpu_primitive/sort/defs.js +79 -79
  233. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +1 -1
  234. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  235. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +7 -3
  236. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.d.ts.map +1 -1
  237. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +10 -3
  238. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  239. package/src/shade/renderer/particles/DESIGN.md +13 -9
  240. package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
  241. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -3
  242. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
  243. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +200 -194
  244. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  245. package/src/shade/renderer/particles/graph_particles.js +6 -2
  246. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +1 -1
  247. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +1 -1
  248. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -1
  249. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +334 -329
  250. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  251. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  252. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +7 -2
  253. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
  254. package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +16 -4
  255. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +3 -2
  256. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  257. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +3 -2
  258. package/src/shade/renderer/scene/GPUSceneContext.d.ts +9 -1
  259. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  260. package/src/shade/renderer/scene/GPUSceneContext.js +23 -1
  261. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +2444 -2345
  262. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.d.ts.map +1 -1
  263. package/src/shade/renderer/texture/encode/chunk_astc_encode_block_4x4_rgb.js +312 -310
  264. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts +3 -3
  265. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.d.ts.map +1 -1
  266. package/src/shade/renderer/texture/encode/chunk_bc1_encode_block.js +383 -375
  267. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.d.ts.map +1 -1
  268. package/src/shade/renderer/texture/encode/chunk_bc6h_encode_block_mode11.js +349 -346
  269. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts +58 -0
  270. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.d.ts.map +1 -0
  271. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block.js +536 -0
  272. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts +21 -7
  273. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.d.ts.map +1 -1
  274. package/src/shade/renderer/texture/encode/chunk_bc7_encode_block_mode6.js +291 -327
  275. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts +25 -0
  276. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.d.ts.map +1 -0
  277. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode1.js +99 -0
  278. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts +5 -3
  279. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.d.ts.map +1 -1
  280. package/src/shade/renderer/texture/encode/chunk_bc7_pack_mode6.js +47 -71
  281. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts +10 -0
  282. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.d.ts.map +1 -0
  283. package/src/shade/renderer/texture/encode/chunk_bc7_partition_2.js +50 -0
  284. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts +4 -5
  285. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.d.ts.map +1 -1
  286. package/src/shade/renderer/texture/encode/shader_texture_encode_bc7.js +7 -8
  287. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +4 -1
  288. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  289. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +74 -3
  290. package/src/shade/renderer/volumetrics/NOTES.md +1023 -957
  291. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts +5 -4
  292. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.d.ts.map +1 -1
  293. package/src/shade/renderer/volumetrics/chunk_volumetrics_irradiance_sh.js +5 -4
  294. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.d.ts +1 -1
  295. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +1 -1
  296. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.d.ts +1 -1
  297. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +1 -1
  298. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts +41 -0
  299. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.d.ts.map +1 -0
  300. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +112 -0
  301. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +9 -23
  302. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  303. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +18 -126
  304. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts +22 -0
  305. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.d.ts.map +1 -0
  306. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +228 -0
  307. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  308. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +0 -53
  309. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  310. package/src/shade/renderer/water/chunk_water_transport.js +7 -5
  311. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  312. package/src/shade/renderer/water/medium/GPUWaterBodies.js +8 -2
  313. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +3 -2
  314. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  315. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +3 -2
  316. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  317. package/src/shade/renderer/water/shader_water.js +3 -1
  318. package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -1
  319. package/src/shade/renderer/water/surface/GPUWaterSurface.js +3 -1
  320. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +4 -3
  321. package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -1
  322. package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +17 -7
  323. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
  324. package/src/shade/renderer/water/surface/graph_water_tessellation.js +11 -4
  325. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -1
  326. package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +93 -30
  327. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts.map +1 -1
  328. package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js +13 -5
  329. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts +29 -8
  330. package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -1
  331. package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +155 -30
  332. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts +6 -1
  333. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -1
  334. package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +157 -39
  335. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts +91 -21
  336. package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts.map +1 -1
  337. package/src/shade/renderer/water/surface/particles/shader_water_particles.js +442 -70
  338. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +11 -3
  339. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  340. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +3 -0
  341. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  342. package/src/shade/wgsl/validate_wgsl_source.js +74 -3
  343. package/src/engine/graphics3/register_instance_animation.d.ts +0 -114
  344. package/src/engine/graphics3/register_instance_animation.d.ts.map +0 -1
  345. package/src/engine/graphics3/register_instance_animation.js +0 -201
@@ -4,13 +4,10 @@ import { ResourceAccessSpecification } from "../../core/model/ResourceAccessSpec
4
4
  import { PosePlayback } from "../../shade/renderer/animation/pose/PosePlayback.js";
5
5
  import { Animation } from "../ecs/animation/Animation.js";
6
6
  import { System } from "../ecs/System.js";
7
- import { SGMesh } from "../graphics/ecs/mesh-v2/aggregate/SGMesh.js";
7
+ import { AnimationClips } from "./animation/AnimationClips.js";
8
8
  import { ClipListPlayer } from "./animation/ClipListPlayer.js";
9
9
  import { write_clip_playback } from "./animation/write_clip_playback.js";
10
- import {
11
- register_instance_clips,
12
- unregister_instance_clips
13
- } from "./register_instance_animation.js";
10
+ import { register_clips, unregister_clips } from "./register_clips.js";
14
11
 
15
12
  /**
16
13
  * @type {ClipPlayback[]}
@@ -23,9 +20,13 @@ const NOTHING = Object.freeze([]);
23
20
  *
24
21
  * The list path is what the game uses wherever there is no state machine — buildings, critters and
25
22
  * the strategy map's groups — and {@link ClipListPlayer} is what plays it. This is the ECS half:
26
- * which entity has which model, and when the ids the renderer issued for it stopped meaning
23
+ * which clips each entity has, and when the ids the renderer issued for them stopped meaning
27
24
  * anything.
28
25
  *
26
+ * **The clips are the entity's {@link AnimationClips}.** An entity is driven while it carries both
27
+ * components, whoever put them there — a model `MeshSystem` loaded, or a rig built in code. New
28
+ * clips are a new component, which this system sees as the entity leaving and coming back.
29
+ *
29
30
  * **It is the CPU that plays the animation and the GPU that draws it.** Shade can advance a clip
30
31
  * itself, and this never asks it to — `AnimationClipFlags.Playing` is left clear and every audible
31
32
  * clip's time is written down each frame from the player's own clock. That is I-4: the pose
@@ -43,32 +44,31 @@ export class AnimationSystem extends System {
43
44
  #graphics;
44
45
 
45
46
  /**
46
- * The system that owns the scene, the model instances, and the ids the animation manager issued
47
- * for them.
47
+ * The scene whose GPU context issues the clip ids.
48
48
  *
49
- * @type {MeshSystem}
49
+ * @type {Scene}
50
50
  */
51
- #meshes;
51
+ #scene;
52
52
 
53
53
  /**
54
- * @type {Map<number, {player: ClipListPlayer, instance: PrefabInstance|null, clip_registration: InstanceClipRegistration|null, played_slots: Int32Array, written: Float32Array, poses: PosePlayback[]}>}
54
+ * @type {Map<number, {player: ClipListPlayer, clips: ShadeAnimationClip[], bound: boolean, clip_registration: ClipRegistration|null, played_slots: Int32Array, written: Float32Array, poses: PosePlayback[]}>}
55
55
  */
56
56
  #entries = new Map();
57
57
 
58
58
  /**
59
59
  * @param {GraphicsEngine} graphics
60
- * @param {MeshSystem} meshes
60
+ * @param {Scene} scene
61
61
  */
62
- constructor(graphics, meshes) {
62
+ constructor(graphics, scene) {
63
63
  super();
64
64
 
65
65
  assert.defined(graphics, 'graphics');
66
- assert.defined(meshes, 'meshes');
66
+ assert.equal(scene?.isScene, true, 'scene.isScene !== true');
67
67
 
68
68
  this.#graphics = graphics;
69
- this.#meshes = meshes;
69
+ this.#scene = scene;
70
70
 
71
- this.dependencies = [Animation, SGMesh];
71
+ this.dependencies = [Animation, AnimationClips];
72
72
 
73
73
  // this tick's clip times are this system's to set: whatever evaluates a pose from them
74
74
  // (exact queries, IK's base pose) reads Animation and so runs after it
@@ -81,8 +81,7 @@ export class AnimationSystem extends System {
81
81
  * What an entity is playing, and where each of them is.
82
82
  *
83
83
  * One entry per clip in the component's list, in the list's own order. Empty for an entity this
84
- * system is not driving — one that has left, or one whose model has not arrived, which is the
85
- * same wait the clip durations are on.
84
+ * system is not driving — one that has left, or one whose clips arrived since the last update.
86
85
  *
87
86
  * @param {number} entity
88
87
  * @returns {ClipPlayback[]}
@@ -98,14 +97,15 @@ export class AnimationSystem extends System {
98
97
  }
99
98
 
100
99
  /**
101
- * What the entity's model is playing, in the form the CPU pose evaluator takes: one entry per
102
- * clip the model carries, at the weight and the time the renderer has been given.
100
+ * What the entity is playing, in the form the CPU pose evaluator takes: one entry per clip of its
101
+ * {@link AnimationClips} that the list names, at the weight and the time the renderer has been
102
+ * given.
103
103
  *
104
104
  * **Only the clips the list names are here, because they are the only ones registered** (D37).
105
105
  * The GPU's accumulator marks a joint dirty for every bound clip that writes to it, weight and
106
106
  * all — so a bound clip at weight zero resolves the joints only it drives to zero rather than
107
107
  * leaving them at rest. The answer is not to hand the surplus to the evaluator so it agrees with
108
- * a mistake; it is not to bind them, and then a clip of the model nothing names moves nothing.
108
+ * a mistake; it is not to bind them, and then a clip nothing names moves nothing.
109
109
  *
110
110
  * The entries are this system's own and are rewritten by the next call, which is what keeps a
111
111
  * query on a per-frame path from allocating.
@@ -113,16 +113,17 @@ export class AnimationSystem extends System {
113
113
  * @param {PosePlayback[]} target appended to
114
114
  * @param {number} entity
115
115
  * @returns {boolean} whether this system is driving the entity — `false` for one with no
116
- * {@link Animation}, and for one whose model has not arrived
116
+ * {@link Animation} or no {@link AnimationClips}, and for one whose clips arrived since the last
117
+ * update
117
118
  */
118
119
  write_pose_playbacks(target, entity) {
119
120
  const entry = this.#entries.get(entity);
120
121
 
121
- if (entry === undefined || entry.instance === null) {
122
+ if (entry === undefined || !entry.bound) {
122
123
  return false;
123
124
  }
124
125
 
125
- const clips = entry.instance.clips;
126
+ const clips = entry.clips;
126
127
  const weights = entry.player.weights;
127
128
  const poses = entry.poses;
128
129
  const played = entry.played_slots;
@@ -155,14 +156,19 @@ export class AnimationSystem extends System {
155
156
  }
156
157
 
157
158
  /**
159
+ * Only noted here: the clips are taken up by the next {@link update}. A link can happen anywhere
160
+ * the components are added — inside a model's spawn, for one `MeshSystem` loads — and binding is
161
+ * this system's work, on its own tick.
162
+ *
158
163
  * @param {Animation} component
159
- * @param {SGMesh} model
164
+ * @param {AnimationClips} clips
160
165
  * @param {number} entity
161
166
  */
162
- link(component, model, entity) {
167
+ link(component, clips, entity) {
163
168
  this.#entries.set(entity, {
164
169
  player: ClipListPlayer.from(component),
165
- instance: null,
170
+ clips: clips.clips,
171
+ bound: false,
166
172
  clip_registration: null,
167
173
  played_slots: new Int32Array(0),
168
174
  written: new Float32Array(0),
@@ -172,10 +178,10 @@ export class AnimationSystem extends System {
172
178
 
173
179
  /**
174
180
  * @param {Animation} component
175
- * @param {SGMesh} model
181
+ * @param {AnimationClips} clips
176
182
  * @param {number} entity
177
183
  */
178
- unlink(component, model, entity) {
184
+ unlink(component, clips, entity) {
179
185
  const entry = this.#entries.get(entity);
180
186
 
181
187
  if (entry !== undefined) {
@@ -221,23 +227,23 @@ export class AnimationSystem extends System {
221
227
  return;
222
228
  }
223
229
 
224
- if (registration.context === this.#graphics.scene_context(this.#meshes.scene)) {
225
- unregister_instance_clips(registration);
230
+ if (registration.context === this.#graphics.scene_context(this.#scene)) {
231
+ unregister_clips(registration);
226
232
  }
227
233
 
228
234
  entry.clip_registration = null;
229
235
  }
230
236
 
231
237
  /**
232
- * Which of the model's clips the list currently names, kept up to date.
238
+ * Which of the entity's clips the list currently names, kept up to date.
233
239
  *
234
240
  * **The list is edited while the game runs** — `ClipListPlayer` reconciles its playbacks against
235
241
  * it every tick, and `StopAnimationBehavior` empties it outright — so which clips are playable
236
242
  * is not settled once at bind.
237
243
  *
238
244
  * Maintained here rather than alongside the registration because **the pose evaluator needs it
239
- * whether or not there is a device**: `query_entity_node_world_pose` answers on the CPU, from
240
- * the clips this driver plays, and a game with rendering disabled still asks (I-4).
245
+ * whether or not there is a device**: `collect_entity_playbacks` answers on the CPU, from the
246
+ * clips this driver plays, and a game with rendering disabled still asks (I-4).
241
247
  *
242
248
  * @param {object} entry
243
249
  * @returns {boolean} whether the set changed
@@ -247,10 +253,9 @@ export class AnimationSystem extends System {
247
253
  const played = entry.played_slots;
248
254
 
249
255
  /*
250
- The distinct slots, and distinct is the point: two entries of the list can name one clip of
251
- the model, so the number of playbacks is not the number of clips. Comparing the two would
252
- report a change on every frame for a list that had not moved, and a change here is a
253
- re-registration.
256
+ The distinct slots, and distinct is the point: two entries of the list can name one clip, so
257
+ the number of playbacks is not the number of clips. Comparing the two would report a change
258
+ on every frame for a list that had not moved, and a change here is a re-registration.
254
259
  */
255
260
  const wanted = [];
256
261
 
@@ -289,12 +294,11 @@ export class AnimationSystem extends System {
289
294
  * the joints only it drives down to zero with it.
290
295
  *
291
296
  * @param {object} entry
292
- * @param {PrefabInstance} instance
293
297
  * @param {GPUSceneContext} context
294
298
  * @param {boolean} set_changed whether {@link #refresh_played_slots} just moved
295
299
  * @returns {boolean} whether the registration was replaced
296
300
  */
297
- #refresh_clips(entry, instance, context, set_changed) {
301
+ #refresh_clips(entry, context, set_changed) {
298
302
  const registration = entry.clip_registration;
299
303
 
300
304
  if (!set_changed && registration !== null && registration.context === context) {
@@ -303,42 +307,44 @@ export class AnimationSystem extends System {
303
307
 
304
308
  this.#release_clips_only(entry);
305
309
 
306
- entry.clip_registration = register_instance_clips(context, instance, entry.played_slots);
310
+ entry.clip_registration = register_clips(context, entry.clips, entry.played_slots);
307
311
 
308
312
  return true;
309
313
  }
310
314
 
315
+ /**
316
+ * Take up the entity's clips: the list is played against them from here on.
317
+ *
318
+ * @param {object} entry
319
+ * @param {number} entity
320
+ * @param {EntityComponentDataset} ecd
321
+ */
322
+ #bind(entry, entity, ecd) {
323
+ const clips = entry.clips;
324
+
325
+ entry.player.bind(entity, ecd, clips);
326
+
327
+ entry.written = new Float32Array(clips.length).fill(-1);
328
+ entry.poses = clips.map(() => new PosePlayback());
329
+
330
+ entry.bound = true;
331
+ }
332
+
311
333
  /**
312
334
  * @param {number} time_delta_seconds
313
335
  */
314
336
  update(time_delta_seconds) {
315
337
  const ecd = this.entityManager.dataset;
316
338
 
317
- const context = this.#graphics.scene_context(this.#meshes.scene);
339
+ const context = this.#graphics.scene_context(this.#scene);
318
340
 
319
341
  // No device — before the first start, and again after a stop. The clocks still run: a clip
320
342
  // that ends while the renderer is being replaced still says so.
321
343
  const manager = context === null ? null : context.animation_manager;
322
344
 
323
345
  for (const [entity, entry] of this.#entries) {
324
- const instance = this.#meshes.instance_of(entity);
325
-
326
- if (instance === null) {
327
- // the model has not arrived, and its clips are what say how long they run
328
- continue;
329
- }
330
-
331
- if (instance !== entry.instance) {
332
- entry.instance = instance;
333
-
334
- entry.player.bind(entity, ecd, instance);
335
-
336
- entry.written = new Float32Array(instance.clips.length).fill(-1);
337
- entry.poses = instance.clips.map(() => new PosePlayback());
338
-
339
- // ids the manager issued for the model that was here before name clips this one
340
- // does not have
341
- this.#release_clips(entry);
346
+ if (!entry.bound) {
347
+ this.#bind(entry, entity, ecd);
342
348
  }
343
349
 
344
350
  entry.player.tick(time_delta_seconds);
@@ -349,7 +355,7 @@ export class AnimationSystem extends System {
349
355
  continue;
350
356
  }
351
357
 
352
- if (this.#refresh_clips(entry, instance, context, set_changed)) {
358
+ if (this.#refresh_clips(entry, context, set_changed)) {
353
359
  // whatever the last registration was told is not what this one knows
354
360
  entry.written.fill(-1);
355
361
  }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Deforms every primitive that carries a {@link MeshSkin}: registers its skin with the animation
3
+ * manager, binds the primitive to it, and holds a row for each joint and everything above it.
4
+ *
5
+ * **It does not care where the skin came from.** `MeshSystem` puts one on each skinned primitive of
6
+ * a model it loads; code building a skinned mesh puts one there itself. Both are the same
7
+ * components on the same kinds of entities, and this is the whole of what makes them deform —
8
+ * `ShadedGeometrySystem` draws the clone, this binds it.
9
+ *
10
+ * **One skeleton, one registration.** A body and its hair carry a skin each, with the same joints
11
+ * bound the same way; the manager answers both registrations with one skin, so the skeleton's
12
+ * matrices are made once a frame.
13
+ *
14
+ * **Joint rows are chains** ({@link RowChains}). A joint composes on the GPU under its parent's row;
15
+ * under a clip-driven ancestor that is the only place its world is right, and a clip keying the
16
+ * ancestor binds only once the ancestor holds a row.
17
+ *
18
+ * **Registration waits for {@link update}**, never happening at link. A spawn adds components node
19
+ * by node, so a joint later in the file is not complete when the primitive links; and there may be
20
+ * no device to register with. A restart replaces the context and voids every id it issued: they are
21
+ * forgotten rather than handed back, and every skin registers again in the new one.
22
+ */
23
+ export class MeshSkinSystem extends System<any> {
24
+ /**
25
+ * @param {GraphicsEngine} graphics
26
+ * @param {Scene} scene
27
+ */
28
+ constructor(graphics: GraphicsEngine, scene: Scene);
29
+ dependencies: (typeof ShadedGeometry | typeof MeshSkin)[];
30
+ /**
31
+ * @returns {Scene}
32
+ */
33
+ get scene(): import("../../shade/renderer/scene/Scene.js").Scene;
34
+ startup(entityManager: any): Promise<void>;
35
+ shutdown(entityManager: any): Promise<void>;
36
+ /**
37
+ * @param {MeshSkin} skin
38
+ * @param {ShadedGeometry} geometry
39
+ * @param {number} entity
40
+ */
41
+ link(skin: MeshSkin, geometry: ShadedGeometry, entity: number): void;
42
+ /**
43
+ * @param {MeshSkin} skin
44
+ * @param {ShadedGeometry} geometry
45
+ * @param {number} entity
46
+ */
47
+ unlink(skin: MeshSkin, geometry: ShadedGeometry, entity: number): void;
48
+ #private;
49
+ }
50
+ export type GPUSceneContext = import("../../shade/renderer/scene/GPUSceneContext.js").GPUSceneContext;
51
+ export type GraphicsEngine = import("./GraphicsEngine.js").GraphicsEngine;
52
+ export type Scene = import("../../shade/renderer/scene/Scene.js").Scene;
53
+ import { System } from "../ecs/System.js";
54
+ import { ShadedGeometry } from "../graphics/ecs/mesh-v2/ShadedGeometry.js";
55
+ import { MeshSkin } from "../graphics/ecs/mesh-v2/MeshSkin.js";
56
+ //# sourceMappingURL=MeshSkinSystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MeshSkinSystem.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/MeshSkinSystem.js"],"names":[],"mappings":"AAmDA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH;IAsCI;;;OAGG;IACH,sBAHW,cAAc,SACd,KAAK,EAYf;IADG,0DAA8C;IAGlD;;OAEG;IACH,iEAEC;IAED,2CAeC;IAED,4CAUC;IAED;;;;OAIG;IACH,WAJW,QAAQ,YACR,cAAc,UACd,MAAM,QAehB;IAED;;;;OAIG;IACH,aAJW,QAAQ,YACR,cAAc,UACd,MAAM,QAIhB;;CA8HJ;8BApTY,OAAO,+CAA+C,EAAE,eAAe;6BACvE,OAAO,qBAAqB,EAAE,cAAc;oBAC5C,OAAO,qCAAqC,EAAE,KAAK;uBATzC,kBAAkB;+BAEV,2CAA2C;yBADjD,qCAAqC"}
@@ -0,0 +1,317 @@
1
+ import { assert } from "../../core/assert.js";
2
+ import { System } from "../ecs/System.js";
3
+ import { MeshSkin } from "../graphics/ecs/mesh-v2/MeshSkin.js";
4
+ import { ShadedGeometry } from "../graphics/ecs/mesh-v2/ShadedGeometry.js";
5
+ import { ShadedGeometryFlags } from "../graphics/ecs/mesh-v2/ShadedGeometryFlags.js";
6
+ import { RowChains } from "./RowChains.js";
7
+
8
+ /**
9
+ * @typedef {import("../../shade/renderer/scene/GPUSceneContext.js").GPUSceneContext} GPUSceneContext
10
+ * @typedef {import("./GraphicsEngine.js").GraphicsEngine} GraphicsEngine
11
+ * @typedef {import("../../shade/renderer/scene/Scene.js").Scene} Scene
12
+ */
13
+
14
+ /**
15
+ * What the GPU gave one skinned primitive, and in which context.
16
+ */
17
+ class Entry {
18
+ /**
19
+ * @type {number}
20
+ */
21
+ entity = -1;
22
+
23
+ /**
24
+ * @type {MeshSkin}
25
+ */
26
+ skin = null;
27
+
28
+ /**
29
+ * The id the animation manager issued for the skin, or -1 while nothing is registered: not yet,
30
+ * no device, or a restart not yet drained.
31
+ *
32
+ * @type {number}
33
+ */
34
+ skin_id = -1;
35
+
36
+ /**
37
+ * The context {@link skin_id} belongs to, or null while there is none.
38
+ *
39
+ * @type {GPUSceneContext|null}
40
+ */
41
+ context = null;
42
+
43
+ /**
44
+ * Whether the joints' chains are held. They are held from the first registration until the
45
+ * entity leaves, across restarts: the chains re-acquire in a new context on their own.
46
+ *
47
+ * @type {boolean}
48
+ */
49
+ held = false;
50
+ }
51
+
52
+ /**
53
+ * Deforms every primitive that carries a {@link MeshSkin}: registers its skin with the animation
54
+ * manager, binds the primitive to it, and holds a row for each joint and everything above it.
55
+ *
56
+ * **It does not care where the skin came from.** `MeshSystem` puts one on each skinned primitive of
57
+ * a model it loads; code building a skinned mesh puts one there itself. Both are the same
58
+ * components on the same kinds of entities, and this is the whole of what makes them deform —
59
+ * `ShadedGeometrySystem` draws the clone, this binds it.
60
+ *
61
+ * **One skeleton, one registration.** A body and its hair carry a skin each, with the same joints
62
+ * bound the same way; the manager answers both registrations with one skin, so the skeleton's
63
+ * matrices are made once a frame.
64
+ *
65
+ * **Joint rows are chains** ({@link RowChains}). A joint composes on the GPU under its parent's row;
66
+ * under a clip-driven ancestor that is the only place its world is right, and a clip keying the
67
+ * ancestor binds only once the ancestor holds a row.
68
+ *
69
+ * **Registration waits for {@link update}**, never happening at link. A spawn adds components node
70
+ * by node, so a joint later in the file is not complete when the primitive links; and there may be
71
+ * no device to register with. A restart replaces the context and voids every id it issued: they are
72
+ * forgotten rather than handed back, and every skin registers again in the new one.
73
+ */
74
+ export class MeshSkinSystem extends System {
75
+ /**
76
+ * @type {GraphicsEngine}
77
+ */
78
+ #graphics;
79
+
80
+ /**
81
+ * @type {Scene}
82
+ */
83
+ #scene;
84
+
85
+ /**
86
+ * @type {Map<number, Entry>}
87
+ */
88
+ #entries = new Map();
89
+
90
+ /**
91
+ * The scene's GPU context as of the last {@link update}. A different one is a restart.
92
+ *
93
+ * @type {GPUSceneContext|null}
94
+ */
95
+ #context = null;
96
+
97
+ /**
98
+ * Entries not registered with {@link #context}: linked since the last frame, or voided by a
99
+ * restart. A queue rather than a scan, because the answer is almost always "nothing to do".
100
+ *
101
+ * @type {Entry[]}
102
+ */
103
+ #unregistered = [];
104
+
105
+ /**
106
+ * The joints' chains. Null until the system has a dataset.
107
+ *
108
+ * @type {RowChains|null}
109
+ */
110
+ #chains = null;
111
+
112
+ /**
113
+ * @param {GraphicsEngine} graphics
114
+ * @param {Scene} scene
115
+ */
116
+ constructor(graphics, scene) {
117
+ super();
118
+
119
+ assert.defined(graphics, 'graphics');
120
+ assert.defined(scene, 'scene');
121
+
122
+ this.#graphics = graphics;
123
+ this.#scene = scene;
124
+
125
+ this.dependencies = [MeshSkin, ShadedGeometry];
126
+ }
127
+
128
+ /**
129
+ * @returns {Scene}
130
+ */
131
+ get scene() {
132
+ return this.#scene;
133
+ }
134
+
135
+ async startup(entityManager) {
136
+ this.entityManager = entityManager;
137
+
138
+ // the scene's rows are this dataset's entities; the first system to place one says so
139
+ const dataset = entityManager.dataset;
140
+ const scene = this.#scene;
141
+
142
+ assert.ok(
143
+ scene.dataset === null || scene.dataset === undefined || scene.dataset === dataset,
144
+ 'the scene is bound to another dataset'
145
+ );
146
+
147
+ scene.dataset = dataset;
148
+
149
+ this.#chains = new RowChains(dataset);
150
+ }
151
+
152
+ async shutdown(entityManager) {
153
+ for (const entity of Array.from(this.#entries.keys())) {
154
+ this.#drop(entity);
155
+ }
156
+
157
+ this.#chains.destroy();
158
+ this.#chains = null;
159
+
160
+ this.#context = null;
161
+ this.#unregistered.length = 0;
162
+ }
163
+
164
+ /**
165
+ * @param {MeshSkin} skin
166
+ * @param {ShadedGeometry} geometry
167
+ * @param {number} entity
168
+ */
169
+ link(skin, geometry, entity) {
170
+ assert.equal(
171
+ geometry.getFlag(ShadedGeometryFlags.Skinned), true,
172
+ 'a MeshSkin deforms a geometry that draws a clone: set ShadedGeometryFlags.Skinned'
173
+ );
174
+
175
+ const entry = new Entry();
176
+
177
+ entry.entity = entity;
178
+ entry.skin = skin;
179
+
180
+ this.#entries.set(entity, entry);
181
+ this.#unregistered.push(entry);
182
+ }
183
+
184
+ /**
185
+ * @param {MeshSkin} skin
186
+ * @param {ShadedGeometry} geometry
187
+ * @param {number} entity
188
+ */
189
+ unlink(skin, geometry, entity) {
190
+ this.#drop(entity);
191
+ }
192
+
193
+ /**
194
+ * Register what arrived since the last frame, and everything again after a restart.
195
+ *
196
+ * @param {number} time_delta_seconds
197
+ */
198
+ update(time_delta_seconds) {
199
+ const context = this.#graphics.scene_context(this.#scene);
200
+
201
+ if (context === null) {
202
+ // No device — before the first start, or after a stop. The next context to arrive is a
203
+ // change like any other.
204
+ this.#chains.bind(null);
205
+
206
+ return;
207
+ }
208
+
209
+ if (context !== this.#context) {
210
+ this.#context = context;
211
+
212
+ this.#chains.bind(context.rows);
213
+
214
+ const waiting = this.#unregistered;
215
+
216
+ waiting.length = 0;
217
+
218
+ for (const entry of this.#entries.values()) {
219
+ // the old context's ids are void, and only forgotten
220
+ entry.skin_id = -1;
221
+ entry.context = null;
222
+
223
+ waiting.push(entry);
224
+ }
225
+ }
226
+
227
+ const waiting = this.#unregistered;
228
+
229
+ if (waiting.length === 0) {
230
+ return;
231
+ }
232
+
233
+ /*
234
+ An entry comes off the list before it is registered, so a registration that throws
235
+ cannot leave the ones before it queued for a second time — a mesh registered twice is
236
+ refused as a rebind, once a frame, for as long as the game runs. One that cannot be
237
+ registered is dropped with a message, and every other one goes ahead.
238
+ */
239
+ const entries = waiting.slice();
240
+
241
+ waiting.length = 0;
242
+
243
+ for (let i = 0; i < entries.length; i++) {
244
+ const entry = entries[i];
245
+
246
+ try {
247
+ this.#register(entry, context);
248
+ } catch (e) {
249
+ console.error(`MeshSkinSystem: failed to register the skin of entity ${entry.entity}, dropping it`, e);
250
+ }
251
+ }
252
+ }
253
+
254
+ /**
255
+ * @param {Entry} entry
256
+ * @param {GPUSceneContext} context
257
+ */
258
+ #register(entry, context) {
259
+ const skin = entry.skin;
260
+ const joints = skin.joints;
261
+
262
+ if (!entry.held) {
263
+ for (let i = 0; i < joints.length; i++) {
264
+ this.#chains.hold(joints[i]);
265
+ }
266
+
267
+ entry.held = true;
268
+ }
269
+
270
+ const manager = context.animation_manager;
271
+
272
+ entry.skin_id = manager.register_skin(joints, skin.inverse_bind_matrices);
273
+ entry.context = context;
274
+
275
+ manager.bind_skin_mesh(entry.entity, entry.skin_id);
276
+ }
277
+
278
+ /**
279
+ * @param {number} entity
280
+ */
281
+ #drop(entity) {
282
+ const entry = this.#entries.get(entity);
283
+
284
+ if (entry === undefined) {
285
+ return;
286
+ }
287
+
288
+ this.#entries.delete(entity);
289
+
290
+ const waiting = this.#unregistered.indexOf(entry);
291
+
292
+ if (waiting !== -1) {
293
+ this.#unregistered.splice(waiting, 1);
294
+ }
295
+
296
+ // A context replaced by a restart took its ids with it; only the running one gets any back.
297
+ if (entry.context !== null && entry.context === this.#graphics.scene_context(this.#scene)) {
298
+ const manager = entry.context.animation_manager;
299
+
300
+ manager.unbind_skin_mesh(entity);
301
+ manager.unregister_skin(entry.skin_id);
302
+ }
303
+
304
+ entry.skin_id = -1;
305
+ entry.context = null;
306
+
307
+ if (entry.held) {
308
+ const joints = entry.skin.joints;
309
+
310
+ for (let i = 0; i < joints.length; i++) {
311
+ this.#chains.release(joints[i]);
312
+ }
313
+
314
+ entry.held = false;
315
+ }
316
+ }
317
+ }