@woosh/meep-engine 3.39.0 → 3.41.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 (561) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/geom/3d/quaternion/swing_twist_clamp.d.ts +24 -0
  4. package/src/core/geom/3d/quaternion/swing_twist_clamp.d.ts.map +1 -0
  5. package/src/core/geom/3d/quaternion/swing_twist_clamp.js +62 -0
  6. package/src/core/geom/3d/quaternion/swing_twist_compose.d.ts +15 -0
  7. package/src/core/geom/3d/quaternion/swing_twist_compose.d.ts.map +1 -0
  8. package/src/core/geom/3d/quaternion/swing_twist_compose.js +36 -0
  9. package/src/core/geom/3d/quaternion/swing_twist_error.d.ts +39 -0
  10. package/src/core/geom/3d/quaternion/swing_twist_error.d.ts.map +1 -0
  11. package/src/core/geom/3d/quaternion/swing_twist_error.js +85 -0
  12. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts +11 -6
  13. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts.map +1 -1
  14. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +27 -13
  15. package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts +25 -0
  16. package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts.map +1 -0
  17. package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.js +166 -0
  18. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts +5 -3
  19. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -1
  20. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.js +5 -3
  21. package/src/engine/EngineHarness.d.ts.map +1 -1
  22. package/src/engine/EngineHarness.js +17 -4
  23. package/src/engine/animation/curve/AnimationCurve.d.ts +3 -0
  24. package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
  25. package/src/engine/animation/curve/AnimationCurve.js +6 -1
  26. package/src/engine/asset/loaders/image/avif/threaded_image_encoder.js +1 -1
  27. package/src/engine/ecs/EntityManager.d.ts +9 -1
  28. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  29. package/src/engine/ecs/EntityManager.js +26 -27
  30. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts +20 -0
  31. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts.map +1 -1
  32. package/src/engine/ecs/gpu/GPUStateAuthority.js +21 -0
  33. package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.d.ts +13 -0
  34. package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.d.ts.map +1 -0
  35. package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.js +12 -0
  36. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts +6 -0
  37. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts.map +1 -1
  38. package/src/engine/ecs/gpu/gpu_authority_grant.js +7 -1
  39. package/src/engine/ecs/gpu/gpu_authority_held.d.ts +14 -0
  40. package/src/engine/ecs/gpu/gpu_authority_held.d.ts.map +1 -0
  41. package/src/engine/ecs/gpu/gpu_authority_held.js +23 -0
  42. package/src/engine/ecs/gpu/gpu_authority_hold.d.ts +23 -0
  43. package/src/engine/ecs/gpu/gpu_authority_hold.d.ts.map +1 -0
  44. package/src/engine/ecs/gpu/gpu_authority_hold.js +41 -0
  45. package/src/engine/ecs/gpu/gpu_authority_unhold.d.ts +14 -0
  46. package/src/engine/ecs/gpu/gpu_authority_unhold.d.ts.map +1 -0
  47. package/src/engine/ecs/gpu/gpu_authority_unhold.js +32 -0
  48. package/src/engine/ecs/ik/IKGoal.d.ts +59 -0
  49. package/src/engine/ecs/ik/IKGoal.d.ts.map +1 -0
  50. package/src/engine/ecs/ik/IKGoal.js +83 -0
  51. package/src/engine/ecs/ik/IKGoalSystem.d.ts +75 -0
  52. package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -0
  53. package/src/engine/ecs/ik/IKGoalSystem.js +1456 -0
  54. package/src/engine/ecs/ik/PLAN.md +179 -0
  55. package/src/engine/ecs/speaker/VoiceSystem.d.ts +2 -2
  56. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  57. package/src/engine/ecs/storage/BinaryBufferSerializer.d.ts.map +1 -1
  58. package/src/engine/ecs/storage/BinaryBufferSerializer.js +4 -5
  59. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +7 -3
  60. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  61. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +5 -2
  62. package/src/engine/ecs/system/orderSystemsByDeclaredAccess.d.ts +33 -0
  63. package/src/engine/ecs/system/orderSystemsByDeclaredAccess.d.ts.map +1 -0
  64. package/src/engine/ecs/system/orderSystemsByDeclaredAccess.js +282 -0
  65. package/src/engine/ecs/transform/T64WorldCache.js +139 -139
  66. package/src/engine/ecs/transform/t64_evaluate_local.d.ts +25 -0
  67. package/src/engine/ecs/transform/t64_evaluate_local.d.ts.map +1 -0
  68. package/src/engine/ecs/transform/t64_evaluate_local.js +35 -0
  69. package/src/engine/ecs/transform/t64_evaluate_world.d.ts +5 -3
  70. package/src/engine/ecs/transform/t64_evaluate_world.d.ts.map +1 -1
  71. package/src/engine/ecs/transform/t64_evaluate_world.js +128 -126
  72. package/src/engine/graphics/ecs/water/Water.d.ts +14 -17
  73. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  74. package/src/engine/graphics/ecs/water/Water.js +100 -110
  75. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.d.ts.map +1 -1
  76. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.js +36 -38
  77. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_3_4.d.ts +6 -0
  78. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_3_4.d.ts.map +1 -0
  79. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_3_4.js +10 -0
  80. package/src/engine/graphics/ecs/water/WaterWaves.d.ts +3 -3
  81. package/src/engine/graphics/ecs/water/WaterWaves.js +46 -46
  82. package/src/engine/graphics/texture/sampler/sampler2d_to_avif.d.ts.map +1 -1
  83. package/src/engine/graphics/texture/sampler/sampler2d_to_avif.js +8 -5
  84. package/src/engine/graphics3/AnimationGraphSystem.d.ts +2 -0
  85. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
  86. package/src/engine/graphics3/AnimationGraphSystem.js +337 -329
  87. package/src/engine/graphics3/AnimationSystem.d.ts +2 -0
  88. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
  89. package/src/engine/graphics3/AnimationSystem.js +360 -352
  90. package/src/engine/graphics3/WaterSystem.d.ts +21 -74
  91. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  92. package/src/engine/graphics3/WaterSystem.js +174 -367
  93. package/src/engine/physics/cloth/MEASUREMENTS.md +130 -0
  94. package/src/engine/physics/cloth/PLAN.md +16 -1
  95. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +5 -6
  96. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
  97. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +5 -6
  98. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +4 -7
  99. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  100. package/src/engine/physics/cloth/ecs/ClothInstance.js +4 -7
  101. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +4 -3
  102. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  103. package/src/engine/physics/cloth/ecs/ClothSystem.js +4 -3
  104. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  105. package/src/engine/physics/cloth/ecs/ClothWorld.js +10 -0
  106. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +24 -24
  107. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  108. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +46 -43
  109. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +1 -1
  110. package/src/engine/physics/cloth/ecs/cloth_write_back.js +1 -1
  111. package/src/engine/physics/constraint/solve_constraints.d.ts +0 -35
  112. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  113. package/src/engine/physics/constraint/solve_constraints.js +1 -83
  114. package/src/engine/physics/ecs/ContactProbe.d.ts +73 -0
  115. package/src/engine/physics/ecs/ContactProbe.d.ts.map +1 -0
  116. package/src/engine/physics/ecs/ContactProbe.js +103 -0
  117. package/src/engine/physics/ecs/ContactProbeSystem.d.ts +44 -0
  118. package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -0
  119. package/src/engine/physics/ecs/ContactProbeSystem.js +397 -0
  120. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +1 -1
  121. package/src/engine/physics/fluid/ecs/FluidComponent.js +1 -1
  122. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  123. package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.d.ts +205 -0
  124. package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.d.ts.map +1 -0
  125. package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.js +245 -0
  126. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.d.ts +21 -0
  127. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.d.ts.map +1 -0
  128. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.js +63 -0
  129. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts +33 -0
  130. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -0
  131. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +874 -0
  132. package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.d.ts +27 -0
  133. package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.d.ts.map +1 -0
  134. package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.js +77 -0
  135. package/src/engine/physics/inverse_kinematics/two_bone_path_solve.d.ts +36 -0
  136. package/src/engine/physics/inverse_kinematics/two_bone_path_solve.d.ts.map +1 -0
  137. package/src/engine/physics/inverse_kinematics/two_bone_path_solve.js +97 -0
  138. package/src/engine/physics/inverse_kinematics/two_joint_ik.d.ts +33 -11
  139. package/src/engine/physics/inverse_kinematics/two_joint_ik.d.ts.map +1 -1
  140. package/src/engine/physics/inverse_kinematics/two_joint_ik.js +158 -67
  141. package/src/format/image/avif/api/convert_to_rgba.d.ts +2 -2
  142. package/src/format/image/avif/api/convert_to_rgba.d.ts.map +1 -1
  143. package/src/format/image/avif/api/convert_to_rgba.js +10 -9
  144. package/src/format/image/avif/api/decode_avif.d.ts +2 -2
  145. package/src/format/image/avif/api/decode_avif.d.ts.map +1 -1
  146. package/src/format/image/avif/api/decode_avif.js +1 -1
  147. package/src/shade/playground/ssr_reprojection/README.md +111 -103
  148. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.js +68 -68
  149. package/src/shade/playground/ssr_reprojection/index.html +80 -79
  150. package/src/shade/playground/ssr_reprojection/main.js +256 -247
  151. package/src/shade/playground/ssr_variance/capture.js +96 -96
  152. package/src/shade/playground/ssr_variance/reference.js +78 -78
  153. package/src/shade/playground/vsm/README.md +96 -0
  154. package/src/shade/playground/vsm/VSMDebugOverlay.d.ts +49 -0
  155. package/src/shade/playground/vsm/VSMDebugOverlay.d.ts.map +1 -0
  156. package/src/shade/playground/vsm/VSMDebugOverlay.js +351 -0
  157. package/src/shade/playground/vsm/clipmap_panel.d.ts +8 -0
  158. package/src/shade/playground/vsm/clipmap_panel.d.ts.map +1 -0
  159. package/src/shade/playground/vsm/clipmap_panel.js +138 -0
  160. package/src/shade/playground/vsm/index.html +170 -0
  161. package/src/shade/playground/vsm/main.d.ts +2 -0
  162. package/src/shade/playground/vsm/main.d.ts.map +1 -0
  163. package/src/shade/playground/vsm/main.js +389 -0
  164. package/src/shade/playground/vsm/scenes.d.ts +52 -0
  165. package/src/shade/playground/vsm/scenes.d.ts.map +1 -0
  166. package/src/shade/playground/vsm/scenes.js +320 -0
  167. package/src/shade/playground/vsm/verify_vsm.d.ts +38 -0
  168. package/src/shade/playground/vsm/verify_vsm.d.ts.map +1 -0
  169. package/src/shade/playground/vsm/verify_vsm.js +305 -0
  170. package/src/shade/playground/water_refraction/README.md +57 -9
  171. package/src/shade/playground/water_refraction/main.js +12 -3
  172. package/src/shade/playground/water_refraction/world.d.ts +1 -0
  173. package/src/shade/playground/water_refraction/world.d.ts.map +1 -1
  174. package/src/shade/playground/water_refraction/world.js +15 -5
  175. package/src/shade/renderer/Renderer.d.ts +19 -0
  176. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  177. package/src/shade/renderer/Renderer.js +72 -1
  178. package/src/shade/renderer/animation/ANIMATION_TRACK_BINDING_STRUCT.d.ts.map +1 -1
  179. package/src/shade/renderer/animation/ANIMATION_TRACK_BINDING_STRUCT.js +10 -1
  180. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +18 -4
  181. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  182. package/src/shade/renderer/animation/GPUAnimationManager.js +269 -23
  183. package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.d.ts +12 -4
  184. package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.d.ts.map +1 -1
  185. package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.js +12 -4
  186. package/src/shade/renderer/animation/chunk_pose_accumulator.d.ts.map +1 -1
  187. package/src/shade/renderer/animation/chunk_pose_accumulator.js +14 -1
  188. package/src/shade/renderer/animation/pose/PoseChannelIndex.d.ts +78 -0
  189. package/src/shade/renderer/animation/pose/PoseChannelIndex.d.ts.map +1 -0
  190. package/src/shade/renderer/animation/pose/PoseChannelIndex.js +274 -0
  191. package/src/shade/renderer/animation/pose/PosePlayback.d.ts +40 -3
  192. package/src/shade/renderer/animation/pose/PosePlayback.d.ts.map +1 -1
  193. package/src/shade/renderer/animation/pose/PosePlayback.js +77 -3
  194. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts +21 -3
  195. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts.map +1 -1
  196. package/src/shade/renderer/animation/pose/pose_evaluate_local.js +79 -11
  197. package/src/shade/renderer/animation/shader_animation_apply.js +1 -1
  198. package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts +3 -2
  199. package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts.map +1 -1
  200. package/src/shade/renderer/animation/shader_animation_pose_resolve.js +187 -176
  201. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +7 -0
  202. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  203. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +11 -0
  204. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.d.ts +3 -1
  205. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.d.ts.map +1 -1
  206. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +10 -1
  207. package/src/shade/renderer/buffer/table/serde/table_wgsl_gen_read_code.d.ts.map +1 -1
  208. package/src/shade/renderer/buffer/table/serde/table_wgsl_gen_read_code.js +28 -0
  209. package/src/shade/renderer/buffer/table/serde/table_wgsl_gen_write_code.d.ts.map +1 -1
  210. package/src/shade/renderer/buffer/table/serde/table_wgsl_gen_write_code.js +31 -1
  211. package/src/shade/renderer/geometry/MeshletGeometry.d.ts +3 -0
  212. package/src/shade/renderer/geometry/MeshletGeometry.d.ts.map +1 -1
  213. package/src/shade/renderer/geometry/MeshletGeometry.js +1 -0
  214. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.d.ts.map +1 -1
  215. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.js +62 -4
  216. package/src/shade/renderer/light/environment/rgbe/parse_rgbe.d.ts +1 -1
  217. package/src/shade/renderer/light/environment/rgbe/parse_rgbe.js +2 -2
  218. package/src/shade/renderer/light/environment/rgbe/rgbe_byte_to_rgb_half.d.ts +2 -2
  219. package/src/shade/renderer/light/environment/rgbe/rgbe_byte_to_rgb_half.d.ts.map +1 -1
  220. package/src/shade/renderer/light/environment/rgbe/rgbe_byte_to_rgb_half.js +6 -14
  221. package/src/shade/renderer/light/environment/sh_exponential/chunk_sh_exp_workgroup_sum.d.ts.map +1 -1
  222. package/src/shade/renderer/light/environment/sh_exponential/chunk_sh_exp_workgroup_sum.js +5 -1
  223. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  224. package/src/shade/renderer/medium/ParticipatingMedium.d.ts +3 -0
  225. package/src/shade/renderer/medium/ParticipatingMedium.d.ts.map +1 -1
  226. package/src/shade/renderer/medium/ParticipatingMedium.js +7 -0
  227. package/src/shade/renderer/object_property/chunk_write_object_property.d.ts +3 -1
  228. package/src/shade/renderer/object_property/chunk_write_object_property.d.ts.map +1 -1
  229. package/src/shade/renderer/object_property/chunk_write_object_property.js +5 -2
  230. package/src/shade/renderer/object_property/chunk_write_object_property_node3d.d.ts +4 -0
  231. package/src/shade/renderer/object_property/chunk_write_object_property_node3d.d.ts.map +1 -1
  232. package/src/shade/renderer/object_property/chunk_write_object_property_node3d.js +6 -1
  233. package/src/shade/renderer/postprocess/eye/shader_autoexposure_build_histogram.d.ts.map +1 -1
  234. package/src/shade/renderer/postprocess/eye/shader_autoexposure_build_histogram.js +5 -35
  235. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  236. package/src/shade/renderer/postprocess/ssr/SSR.d.ts +12 -4
  237. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  238. package/src/shade/renderer/postprocess/ssr/SSR.js +36 -8
  239. package/src/shade/renderer/postprocess/ssr/SSR_DENOISE_TILE_SIZE.d.ts +3 -0
  240. package/src/shade/renderer/postprocess/ssr/SSR_DENOISE_TILE_SIZE.d.ts.map +1 -0
  241. package/src/shade/renderer/postprocess/ssr/SSR_DENOISE_TILE_SIZE.js +2 -0
  242. package/src/shade/renderer/postprocess/ssr/chunk_ssr_denoise_tile_active.d.ts +8 -0
  243. package/src/shade/renderer/postprocess/ssr/chunk_ssr_denoise_tile_active.d.ts.map +1 -0
  244. package/src/shade/renderer/postprocess/ssr/chunk_ssr_denoise_tile_active.js +40 -0
  245. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -1
  246. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +150 -137
  247. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_classify.d.ts +3 -0
  248. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_classify.d.ts.map +1 -0
  249. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_classify.js +44 -0
  250. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_dilate.d.ts +5 -0
  251. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_dilate.d.ts.map +1 -0
  252. package/src/shade/renderer/postprocess/ssr/shader_ssr_denoise_tile_dilate.js +35 -0
  253. package/src/shade/renderer/postprocess/ssr/ssr_graph_denoise_tiles.d.ts +26 -0
  254. package/src/shade/renderer/postprocess/ssr/ssr_graph_denoise_tiles.d.ts.map +1 -0
  255. package/src/shade/renderer/postprocess/ssr/ssr_graph_denoise_tiles.js +42 -0
  256. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +1 -0
  257. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
  258. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +113 -105
  259. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts +2 -0
  260. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
  261. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +177 -167
  262. package/src/shade/renderer/rasterize/DEPTH_STENCIL_STATE_SHADOW.d.ts.map +1 -1
  263. package/src/shade/renderer/rasterize/DEPTH_STENCIL_STATE_SHADOW.js +10 -0
  264. package/src/shade/renderer/rasterize/RasterizationJob.d.ts +1 -2
  265. package/src/shade/renderer/rasterize/RasterizationJob.d.ts.map +1 -1
  266. package/src/shade/renderer/rasterize/RasterizationJob.js +1 -2
  267. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +5 -6
  268. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
  269. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +5 -6
  270. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +2 -2
  271. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  272. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +1 -1
  273. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
  274. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +11 -0
  275. package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts +1 -1
  276. package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts.map +1 -1
  277. package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.js +135 -73
  278. package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts +7 -0
  279. package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts.map +1 -1
  280. package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.js +29 -1
  281. package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.d.ts +19 -0
  282. package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.d.ts.map +1 -0
  283. package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.js +167 -0
  284. package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.d.ts +25 -0
  285. package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.d.ts.map +1 -0
  286. package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.js +124 -0
  287. package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.d.ts +19 -0
  288. package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.d.ts.map +1 -0
  289. package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.js +48 -0
  290. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +17 -1
  291. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  292. package/src/shade/renderer/scene/rows/GPUSceneRows.js +29 -3
  293. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/build_lut_fog_parameters_jendersie_deon.d.ts.map +1 -1
  294. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/build_lut_fog_parameters_jendersie_deon.js +4 -5
  295. package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.d.ts.map +1 -1
  296. package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.js +1 -5
  297. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_importance.d.ts +30 -0
  298. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_importance.d.ts.map +1 -0
  299. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_importance.js +54 -0
  300. package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.d.ts.map +1 -1
  301. package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.js +3 -2
  302. package/src/shade/renderer/shadow/map/DIRECTIONAL_SHADOWMAP_STRUCT.d.ts +19 -0
  303. package/src/shade/renderer/shadow/map/DIRECTIONAL_SHADOWMAP_STRUCT.d.ts.map +1 -0
  304. package/src/shade/renderer/shadow/map/DIRECTIONAL_SHADOWMAP_STRUCT.js +27 -0
  305. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts +1 -0
  306. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
  307. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +4 -0
  308. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +54 -0
  309. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  310. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +502 -10
  311. package/src/shade/renderer/shadow/map/Shadowmap.d.ts +3 -2
  312. package/src/shade/renderer/shadow/map/Shadowmap.d.ts.map +1 -1
  313. package/src/shade/renderer/shadow/map/Shadowmap.js +3 -2
  314. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.d.ts +8 -0
  315. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.d.ts.map +1 -1
  316. package/src/shade/renderer/shadow/map/shader/chunk_sample_shadowmap_atlas_for_light.js +34 -3
  317. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts +3 -2
  318. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts.map +1 -1
  319. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.js +17 -2
  320. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.d.ts.map +1 -1
  321. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_point2.js +137 -133
  322. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_FIRST_TEXEL_SIZE.d.ts +15 -0
  323. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_FIRST_TEXEL_SIZE.d.ts.map +1 -0
  324. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_FIRST_TEXEL_SIZE.js +14 -0
  325. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_PAGE_BUDGET.d.ts +16 -0
  326. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_PAGE_BUDGET.d.ts.map +1 -0
  327. package/src/shade/renderer/shadow/vsm/DEFAULT_VSM_PAGE_BUDGET.js +15 -0
  328. package/src/shade/renderer/shadow/vsm/PLAN.md +440 -0
  329. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +43 -0
  330. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.d.ts +42 -0
  331. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.d.ts.map +1 -0
  332. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.js +153 -0
  333. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts +327 -0
  334. package/src/shade/renderer/shadow/vsm/VSMPageManager.d.ts.map +1 -0
  335. package/src/shade/renderer/shadow/vsm/VSMPageManager.js +1408 -0
  336. package/src/shade/renderer/shadow/vsm/VSM_COVER_LEVEL_STEP.d.ts +14 -0
  337. package/src/shade/renderer/shadow/vsm/VSM_COVER_LEVEL_STEP.d.ts.map +1 -0
  338. package/src/shade/renderer/shadow/vsm/VSM_COVER_LEVEL_STEP.js +13 -0
  339. package/src/shade/renderer/shadow/vsm/VSM_FEEDBACK_LAYOUT.d.ts +63 -0
  340. package/src/shade/renderer/shadow/vsm/VSM_FEEDBACK_LAYOUT.d.ts.map +1 -0
  341. package/src/shade/renderer/shadow/vsm/VSM_FEEDBACK_LAYOUT.js +70 -0
  342. package/src/shade/renderer/shadow/vsm/VSM_LEVEL_LIMIT.d.ts +11 -0
  343. package/src/shade/renderer/shadow/vsm/VSM_LEVEL_LIMIT.d.ts.map +1 -0
  344. package/src/shade/renderer/shadow/vsm/VSM_LEVEL_LIMIT.js +10 -0
  345. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.d.ts +54 -0
  346. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.d.ts.map +1 -0
  347. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.js +75 -0
  348. package/src/shade/renderer/shadow/vsm/VSM_RECORD_STRUCT.d.ts +23 -0
  349. package/src/shade/renderer/shadow/vsm/VSM_RECORD_STRUCT.d.ts.map +1 -0
  350. package/src/shade/renderer/shadow/vsm/VSM_RECORD_STRUCT.js +85 -0
  351. package/src/shade/renderer/shadow/vsm/VSM_SLOT_STRUCT.d.ts +16 -0
  352. package/src/shade/renderer/shadow/vsm/VSM_SLOT_STRUCT.d.ts.map +1 -0
  353. package/src/shade/renderer/shadow/vsm/VSM_SLOT_STRUCT.js +29 -0
  354. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.d.ts +136 -25
  355. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.d.ts.map +1 -1
  356. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.js +282 -116
  357. package/src/shade/renderer/shadow/vsm/graph_vsm_feedback.d.ts +39 -0
  358. package/src/shade/renderer/shadow/vsm/graph_vsm_feedback.d.ts.map +1 -0
  359. package/src/shade/renderer/shadow/vsm/graph_vsm_feedback.js +289 -0
  360. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_virtual.d.ts +18 -0
  361. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_virtual.d.ts.map +1 -0
  362. package/src/shade/renderer/shadow/vsm/shader/chunk_shadowmap_sample_virtual.js +65 -0
  363. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_addressing.d.ts +17 -0
  364. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_addressing.d.ts.map +1 -0
  365. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_addressing.js +75 -0
  366. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts +14 -0
  367. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts.map +1 -0
  368. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.js +45 -0
  369. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_find_page.d.ts +17 -0
  370. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_find_page.d.ts.map +1 -0
  371. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_find_page.js +100 -0
  372. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_page_view_projection.d.ts +15 -0
  373. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_page_view_projection.d.ts.map +1 -0
  374. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_page_view_projection.js +47 -0
  375. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_demand.d.ts +26 -0
  376. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_demand.d.ts.map +1 -0
  377. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_demand.js +156 -0
  378. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_gather_counts.d.ts +13 -0
  379. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_gather_counts.d.ts.map +1 -0
  380. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_gather_counts.js +65 -0
  381. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.d.ts +30 -0
  382. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.d.ts.map +1 -0
  383. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.js +184 -0
  384. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.d.ts +23 -0
  385. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.d.ts.map +1 -0
  386. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.js +109 -0
  387. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_stale.d.ts +56 -0
  388. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_stale.d.ts.map +1 -0
  389. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_stale.js +211 -0
  390. package/src/shade/renderer/texture/format/decode_typed_gpu_data.d.ts +1 -1
  391. package/src/shade/renderer/texture/format/decode_typed_gpu_data.d.ts.map +1 -1
  392. package/src/shade/renderer/texture/format/decode_typed_gpu_data.js +3 -13
  393. package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts.map +1 -1
  394. package/src/shade/renderer/texture/format/infer_format_from_parameters.js +2 -3
  395. package/src/shade/renderer/texture/texture_write_to_gpu.d.ts.map +1 -1
  396. package/src/shade/renderer/texture/texture_write_to_gpu.js +16 -16
  397. package/src/shade/renderer/texture/virtual/VTPhysicalCache.d.ts +4 -90
  398. package/src/shade/renderer/texture/virtual/VTPhysicalCache.d.ts.map +1 -1
  399. package/src/shade/renderer/texture/virtual/VTPhysicalCache.js +6 -210
  400. package/src/shade/renderer/texture/virtual/VTPhysicalSlots.d.ts +119 -0
  401. package/src/shade/renderer/texture/virtual/VTPhysicalSlots.d.ts.map +1 -0
  402. package/src/shade/renderer/texture/virtual/VTPhysicalSlots.js +245 -0
  403. package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.d.ts +1 -1
  404. package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.d.ts.map +1 -1
  405. package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.js +3 -19
  406. package/src/shade/renderer/texture/virtual/chunk_vt_page_table_entry.d.ts +13 -0
  407. package/src/shade/renderer/texture/virtual/chunk_vt_page_table_entry.d.ts.map +1 -0
  408. package/src/shade/renderer/texture/virtual/chunk_vt_page_table_entry.js +34 -0
  409. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +7 -2
  410. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  411. package/src/shade/renderer/water/GPUWaterRenderer.js +49 -49
  412. package/src/shade/renderer/water/chunk_water_transport.js +3 -3
  413. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +11 -25
  414. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
  415. package/src/shade/renderer/water/medium/GPUWaterBodies.js +64 -116
  416. package/src/shade/renderer/water/medium/WATER_BODIES_STRUCT.d.ts +1 -20
  417. package/src/shade/renderer/water/medium/WATER_BODIES_STRUCT.d.ts.map +1 -1
  418. package/src/shade/renderer/water/medium/WATER_BODIES_STRUCT.js +10 -42
  419. package/src/shade/renderer/water/medium/chunk_water_bodies.d.ts +3 -0
  420. package/src/shade/renderer/water/medium/chunk_water_bodies.d.ts.map +1 -0
  421. package/src/shade/renderer/water/medium/chunk_water_bodies.js +3 -0
  422. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts +1 -5
  423. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts.map +1 -1
  424. package/src/shade/renderer/water/medium/shader_water_bodies_derive.js +32 -30
  425. package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts +4 -0
  426. package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts.map +1 -0
  427. package/src/shade/renderer/water/medium/shader_water_meshlets.js +69 -0
  428. package/src/shade/renderer/water/optics/chunk_water_inscatter.d.ts.map +1 -1
  429. package/src/shade/renderer/water/optics/chunk_water_inscatter.js +124 -123
  430. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -1
  431. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +75 -74
  432. package/src/shade/renderer/water/shader_water.d.ts +1 -1
  433. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  434. package/src/shade/renderer/water/shader_water.js +490 -406
  435. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts +12 -85
  436. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts.map +1 -1
  437. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.js +128 -408
  438. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts +6 -0
  439. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts.map +1 -0
  440. package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js +23 -0
  441. package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts +9 -0
  442. package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts.map +1 -0
  443. package/src/shade/renderer/water/surface/chunk_water_tessellation.js +144 -0
  444. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts +3 -5
  445. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts.map +1 -1
  446. package/src/shade/renderer/water/surface/chunk_water_wave.js +40 -48
  447. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +14 -0
  448. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -0
  449. package/src/shade/renderer/water/surface/graph_water_tessellation.js +34 -0
  450. package/src/shade/renderer/water/surface/shader_water_tiles.d.ts +4 -0
  451. package/src/shade/renderer/water/surface/shader_water_tiles.d.ts.map +1 -0
  452. package/src/shade/renderer/water/surface/shader_water_tiles.js +123 -0
  453. package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts +6 -0
  454. package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts.map +1 -0
  455. package/src/shade/renderer/water/surface/shader_water_wave_batch.js +85 -0
  456. package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts +6 -0
  457. package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts.map +1 -0
  458. package/src/shade/renderer/water/surface/shader_water_wave_domain.js +83 -0
  459. package/src/shade/renderer/water/water_height_texture_from_sampler.d.ts.map +1 -1
  460. package/src/shade/renderer/water/water_height_texture_from_sampler.js +4 -3
  461. package/src/engine/ecs/ik/IKConstraint.d.ts +0 -52
  462. package/src/engine/ecs/ik/IKConstraint.d.ts.map +0 -1
  463. package/src/engine/ecs/ik/IKConstraint.js +0 -95
  464. package/src/engine/ecs/ik/IKProblem.d.ts +0 -45
  465. package/src/engine/ecs/ik/IKProblem.d.ts.map +0 -1
  466. package/src/engine/ecs/ik/IKProblem.js +0 -58
  467. package/src/engine/ecs/ik/IKSolver.d.ts +0 -8
  468. package/src/engine/ecs/ik/IKSolver.d.ts.map +0 -1
  469. package/src/engine/ecs/ik/IKSolver.js +0 -9
  470. package/src/engine/ecs/ik/InverseKinematics.d.ts +0 -48
  471. package/src/engine/ecs/ik/InverseKinematics.d.ts.map +0 -1
  472. package/src/engine/ecs/ik/InverseKinematics.js +0 -119
  473. package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.d.ts +0 -19
  474. package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.d.ts.map +0 -1
  475. package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.js +0 -72
  476. package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts +0 -54
  477. package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +0 -1
  478. package/src/engine/ecs/ik/InverseKinematicsSystem.js +0 -212
  479. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts +0 -8
  480. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts.map +0 -1
  481. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +0 -153
  482. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts +0 -5
  483. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts.map +0 -1
  484. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +0 -120
  485. package/src/engine/ecs/ik/ik_bone_chain.d.ts +0 -64
  486. package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +0 -1
  487. package/src/engine/ecs/ik/ik_bone_chain.js +0 -142
  488. package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts +0 -42
  489. package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts.map +0 -1
  490. package/src/engine/ecs/ik/ik_probe_terrain_contact.js +0 -123
  491. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +0 -18
  492. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +0 -1
  493. package/src/engine/ecs/ik/ik_write_local_rotation.js +0 -32
  494. package/src/engine/graphics/ecs/water/WATER_SIZE.d.ts +0 -2
  495. package/src/engine/graphics/ecs/water/WATER_SIZE.d.ts.map +0 -1
  496. package/src/engine/graphics/ecs/water/WATER_SIZE.js +0 -1
  497. package/src/shade/renderer/light/GPUViewLightContext.d.ts +0 -22
  498. package/src/shade/renderer/light/GPUViewLightContext.d.ts.map +0 -1
  499. package/src/shade/renderer/light/GPUViewLightContext.js +0 -62
  500. package/src/shade/renderer/shadow/map/csm/CSM_SHADOWMAP_STRUCT.d.ts +0 -14
  501. package/src/shade/renderer/shadow/map/csm/CSM_SHADOWMAP_STRUCT.d.ts.map +0 -1
  502. package/src/shade/renderer/shadow/map/csm/CSM_SHADOWMAP_STRUCT.js +0 -20
  503. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.d.ts +0 -27
  504. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.d.ts.map +0 -1
  505. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.js +0 -147
  506. package/src/shade/renderer/shadow/vsm/GPUVirtualShadowTextureResidence.d.ts +0 -7
  507. package/src/shade/renderer/shadow/vsm/GPUVirtualShadowTextureResidence.d.ts.map +0 -1
  508. package/src/shade/renderer/shadow/vsm/GPUVirtualShadowTextureResidence.js +0 -10
  509. package/src/shade/renderer/shadow/vsm/VSM_RESIDENCE_WORKGROUP_TILE_RESOLUTION.d.ts +0 -2
  510. package/src/shade/renderer/shadow/vsm/VSM_RESIDENCE_WORKGROUP_TILE_RESOLUTION.d.ts.map +0 -1
  511. package/src/shade/renderer/shadow/vsm/VSM_RESIDENCE_WORKGROUP_TILE_RESOLUTION.js +0 -1
  512. package/src/shade/renderer/shadow/vsm/VSM_UNIFORMS_STRUCT.d.ts +0 -3
  513. package/src/shade/renderer/shadow/vsm/VSM_UNIFORMS_STRUCT.d.ts.map +0 -1
  514. package/src/shade/renderer/shadow/vsm/VSM_UNIFORMS_STRUCT.js +0 -8
  515. package/src/shade/renderer/shadow/vsm/VirtualShadowmapRenderer.d.ts +0 -27
  516. package/src/shade/renderer/shadow/vsm/VirtualShadowmapRenderer.d.ts.map +0 -1
  517. package/src/shade/renderer/shadow/vsm/VirtualShadowmapRenderer.js +0 -102
  518. package/src/shade/renderer/shadow/vsm/debug_inspect_coarse_bounds_buffer.d.ts +0 -8
  519. package/src/shade/renderer/shadow/vsm/debug_inspect_coarse_bounds_buffer.d.ts.map +0 -1
  520. package/src/shade/renderer/shadow/vsm/debug_inspect_coarse_bounds_buffer.js +0 -34
  521. package/src/shade/renderer/shadow/vsm/debug_inspect_residence_buffer.d.ts +0 -10
  522. package/src/shade/renderer/shadow/vsm/debug_inspect_residence_buffer.d.ts.map +0 -1
  523. package/src/shade/renderer/shadow/vsm/debug_inspect_residence_buffer.js +0 -64
  524. package/src/shade/renderer/shadow/vsm/decode_tile_address.d.ts +0 -11
  525. package/src/shade/renderer/shadow/vsm/decode_tile_address.d.ts.map +0 -1
  526. package/src/shade/renderer/shadow/vsm/decode_tile_address.js +0 -26
  527. package/src/shade/renderer/shadow/vsm/render/vms_render_tiles.d.ts +0 -2
  528. package/src/shade/renderer/shadow/vsm/render/vms_render_tiles.d.ts.map +0 -1
  529. package/src/shade/renderer/shadow/vsm/render/vms_render_tiles.js +0 -11
  530. package/src/shade/renderer/shadow/vsm/vms_pipeline_compute_coarse_bounds.d.ts +0 -20
  531. package/src/shade/renderer/shadow/vsm/vms_pipeline_compute_coarse_bounds.d.ts.map +0 -1
  532. package/src/shade/renderer/shadow/vsm/vms_pipeline_compute_coarse_bounds.js +0 -184
  533. package/src/shade/renderer/shadow/vsm/vsm_residence_pipeline.d.ts +0 -25
  534. package/src/shade/renderer/shadow/vsm/vsm_residence_pipeline.d.ts.map +0 -1
  535. package/src/shade/renderer/shadow/vsm/vsm_residence_pipeline.js +0 -230
  536. package/src/shade/renderer/shadow/vsm/vsm_tile_allocation_pipeline.d.ts +0 -19
  537. package/src/shade/renderer/shadow/vsm/vsm_tile_allocation_pipeline.d.ts.map +0 -1
  538. package/src/shade/renderer/shadow/vsm/vsm_tile_allocation_pipeline.js +0 -127
  539. package/src/shade/renderer/texture/encode/ENCODE_NOTES_2026_09_02.md +0 -462
  540. package/src/shade/renderer/water/optics/chunk_water_light_transmittance.d.ts +0 -23
  541. package/src/shade/renderer/water/optics/chunk_water_light_transmittance.d.ts.map +0 -1
  542. package/src/shade/renderer/water/optics/chunk_water_light_transmittance_dry.d.ts +0 -18
  543. package/src/shade/renderer/water/optics/chunk_water_light_transmittance_dry.d.ts.map +0 -1
  544. package/src/shade/renderer/water/surface/WATER_SURFACE_VERTEX_STRUCT.d.ts +0 -12
  545. package/src/shade/renderer/water/surface/WATER_SURFACE_VERTEX_STRUCT.d.ts.map +0 -1
  546. package/src/shade/renderer/water/surface/WATER_SURFACE_VERTEX_STRUCT.js +0 -27
  547. package/src/shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.d.ts +0 -14
  548. package/src/shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.d.ts.map +0 -1
  549. package/src/shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.js +0 -49
  550. package/src/shade/renderer/water/surface/chunk_water_wave_grid.d.ts +0 -9
  551. package/src/shade/renderer/water/surface/chunk_water_wave_grid.d.ts.map +0 -1
  552. package/src/shade/renderer/water/surface/chunk_water_wave_grid.js +0 -47
  553. package/src/shade/renderer/water/surface/shader_water_surface_write.d.ts +0 -10
  554. package/src/shade/renderer/water/surface/shader_water_surface_write.d.ts.map +0 -1
  555. package/src/shade/renderer/water/surface/shader_water_surface_write.js +0 -51
  556. package/src/shade/renderer/water/surface/shader_water_wave_step.d.ts +0 -12
  557. package/src/shade/renderer/water/surface/shader_water_wave_step.d.ts.map +0 -1
  558. package/src/shade/renderer/water/surface/shader_water_wave_step.js +0 -54
  559. package/src/shade/renderer/water/surface/water_surface_grid_indices.d.ts +0 -13
  560. package/src/shade/renderer/water/surface/water_surface_grid_indices.d.ts.map +0 -1
  561. package/src/shade/renderer/water/surface/water_surface_grid_indices.js +0 -39
@@ -18,12 +18,15 @@ import { POSE_ACCUMULATOR_SLOT_BYTES } from "./POSE_ACCUMULATOR_LAYOUT.js";
18
18
  import { GPUStateAuthorityFlags } from "../../../engine/ecs/gpu/GPUStateAuthorityFlags.js";
19
19
  import { gpu_authority_grant } from "../../../engine/ecs/gpu/gpu_authority_grant.js";
20
20
  import { gpu_authority_revoke } from "../../../engine/ecs/gpu/gpu_authority_revoke.js";
21
+ import { gpu_authority_held } from "../../../engine/ecs/gpu/gpu_authority_held.js";
22
+ import { GPU_AUTHORITY_EVENT_HOLD_CHANGE } from "../../../engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.js";
21
23
  import { row_of_entity } from "../scene/rows/GPUSceneRows.js";
22
24
  import { gpu_authority_declare } from "../../../engine/ecs/gpu/gpu_authority_declare.js";
23
25
  import { TransformAttachment } from "../../../engine/ecs/transform-attachment/TransformAttachment.js";
24
26
  import { TRANSFORM_ATTACHMENT_EVENT_CHANGE } from "../../../engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js";
25
27
  import { Transform64 } from "../../../engine/ecs/transform/Transform64.js";
26
28
  import { pose_evaluate_local } from "./pose/pose_evaluate_local.js";
29
+ import { PosePlayback } from "./pose/PosePlayback.js";
27
30
  import {
28
31
  shader_animation_apply,
29
32
  WORKGROUP_SIZE as ANIMATION_APPLY_WORKGROUP_SIZE,
@@ -61,12 +64,45 @@ const SEED = new Transform64();
61
64
  * The one playback a released joint is evaluated against: the clip that just left it, at the
62
65
  * time and weight it was last set to.
63
66
  *
64
- * @type {{clip: ShadeAnimationClip|null, time: number, weight: number}}
67
+ * @type {PosePlayback}
65
68
  */
66
- const SEED_PLAYBACK = { clip: null, time: 0, weight: 1 };
69
+ const SEED_PLAYBACK = new PosePlayback();
67
70
 
68
71
  const SEED_PLAYBACKS = [SEED_PLAYBACK];
69
72
 
73
+ /**
74
+ * The pose an entity rests at: the rest the CPU twin is handed for it (`pose_evaluate_local`'s
75
+ * `rest`, chosen as `t64_evaluate_world` and `T64WorldCache` choose it) — its offset from its
76
+ * parent, or its own pose when it is attached to nothing.
77
+ *
78
+ * @param {EntityComponentDataset} dataset
79
+ * @param {number} entity
80
+ * @returns {Transform64}
81
+ */
82
+ function rest_of(dataset, entity) {
83
+ const attachment = dataset.getComponent(entity, TransformAttachment);
84
+
85
+ return attachment !== undefined && attachment !== null && dataset.entityExists(attachment.parent)
86
+ ? attachment.transform
87
+ : dataset.getComponent(entity, Transform64);
88
+ }
89
+
90
+ /**
91
+ * The rotation an entity rests at, `[x, y, z, w]` — see {@link rest_of}. Read when a clip binds
92
+ * the entity, which is when its offset becomes the GPU's: this side writes no local pose into a
93
+ * driven entity's row after that. And read again when a CPU writer's hold on it ends, which is
94
+ * when its offset becomes the GPU's again — see {@link GPUAnimationManager#unmute}.
95
+ *
96
+ * @param {EntityComponentDataset} dataset
97
+ * @param {number} entity
98
+ * @returns {number[]}
99
+ */
100
+ function rest_rotation_of(dataset, entity) {
101
+ const rest = rest_of(dataset, entity);
102
+
103
+ return [rest.rotation_x, rest.rotation_y, rest.rotation_z, rest.rotation_w];
104
+ }
105
+
70
106
  /*
71
107
  Generated writers for the rows a registration adds as a run. Through `add_run` every row is a
72
108
  reflective walk of its type, and a run is one row per keyframe, binding or joint where a chain
@@ -96,10 +132,40 @@ const CLIP_BINDINGS_WRITER = generate_record_writer(ANIMATION_CLIP_STATE_STRUCT,
96
132
  */
97
133
  const CLIP_FLAGS_WORD = ANIMATION_CLIP_STATE_STRUCT.get('flags').offset / 4;
98
134
 
135
+ /**
136
+ * Word of a clip record holding the first row of its bindings — where a target's binding is found.
137
+ */
138
+ const CLIP_BINDINGS_FIRST_WORD = ANIMATION_CLIP_STATE_STRUCT.get('bindings_first').offset / 4;
139
+
140
+ /**
141
+ * A binding's `instance` alone: what muting a held target's binding writes.
142
+ */
143
+ const BINDING_INSTANCE_WRITER = generate_record_writer(ANIMATION_TRACK_BINDING_STRUCT, ['instance']);
144
+
145
+ /**
146
+ * Scratch record for {@link BINDING_INSTANCE_WRITER}.
147
+ *
148
+ * @type {{instance: number}}
149
+ */
150
+ const BINDING_INSTANCE = { instance: 0 };
151
+
152
+ /**
153
+ * A binding's `instance` and `rest_rotation`: what unmuting it when its target's hold ends writes.
154
+ */
155
+ const BINDING_UNMUTE_WRITER = generate_record_writer(ANIMATION_TRACK_BINDING_STRUCT, ['instance', 'rest_rotation']);
156
+
157
+ /**
158
+ * Scratch record for {@link BINDING_UNMUTE_WRITER}.
159
+ *
160
+ * @type {{instance: number, rest_rotation: number[]}}
161
+ */
162
+ const BINDING_UNMUTE = { instance: 0, rest_rotation: [0, 0, 0, 1] };
163
+
99
164
  /**
100
165
  * Word of a skin record holding its first joint row — where its matrices start.
101
166
  */
102
167
  const SKIN_JOINTS_FIRST_WORD = ANIMATION_SKIN_STRUCT.get('joints_first').offset / 4;
168
+ const SKIN_JOINT_COUNT_WORD = ANIMATION_SKIN_STRUCT.get('joint_count').offset / 4;
103
169
 
104
170
  /**
105
171
  * A joint's `node` alone — what naming a pending skin's nodes writes, and all it uploads.
@@ -260,12 +326,14 @@ export class GPUAnimationManager {
260
326
  #skin_matrix_count = 0;
261
327
 
262
328
  /**
263
- * How many bound clips drive each entity, by entity. An entity's local TRS is the GPU's for
264
- * as long as this is above zero: the first clip to bind grants `GPUStateAuthority`'s
265
- * TransformAttachment bit, the last to unbind revokes it and marks the row so the CPU writes
266
- * the rest pose back. Stated on the entity, never inferred from the bindings.
329
+ * The bound clips that drive each entity, by entity — counted by the list's length, and named
330
+ * so that a hold can find the bindings to mute. An entity's local TRS is the GPU's while the
331
+ * list is not empty and no CPU writer holds it: the first clip to bind grants
332
+ * `GPUStateAuthority`'s TransformAttachment bit, the last to unbind revokes it and marks the
333
+ * row so the CPU writes the rest pose back. Stated on the entity, never inferred from the
334
+ * bindings.
267
335
  *
268
- * @type {Map<number, number>}
336
+ * @type {Map<number, number[]>}
269
337
  */
270
338
  #clips_driving = new Map();
271
339
 
@@ -295,7 +363,9 @@ export class GPUAnimationManager {
295
363
  *
296
364
  * Lazily allocated on first {@link ensure_pose_accumulator_capacity};
297
365
  * grows by doubling. Grow destroys the old buffer — since resolve
298
- * always leaves it zero, no copy is needed on grow.
366
+ * drains every sum and dirty mask, and the rest rotations are stored
367
+ * afresh by the contributions of the frame that reads them, no copy
368
+ * is needed on grow.
299
369
  *
300
370
  * @type {GPUBuffer|null}
301
371
  */
@@ -510,9 +580,10 @@ export class GPUAnimationManager {
510
580
  * by the per-frame dispatch driver after `scene.build` has
511
581
  * stabilised the transforms-table size for the frame.
512
582
  *
513
- * Grow destroys the previous GPU buffer; resolve always leaves the
514
- * accumulator zeroed at the end of each frame, so there's nothing
515
- * to copy across the realloc.
583
+ * Grow destroys the previous GPU buffer; resolve drains every sum
584
+ * and dirty mask at the end of each frame, and a slot's rest
585
+ * rotation is stored afresh by every frame that reads it, so there's
586
+ * nothing to copy across the realloc.
516
587
  *
517
588
  * @param {number} row_count
518
589
  */
@@ -580,6 +651,23 @@ export class GPUAnimationManager {
580
651
  return joints_first;
581
652
  }
582
653
 
654
+ /**
655
+ * How many joints the skin has — rows of the `skin_matrices` scratch buffer from
656
+ * {@link get_skin_matrix_offset}. Fixed once the skin is registered.
657
+ *
658
+ * @param {number} skin_id
659
+ * @returns {number}
660
+ */
661
+ get_skin_joint_count(skin_id) {
662
+ assert.isNonNegativeInteger(skin_id, 'skin_id');
663
+
664
+ const joint_count = this.#database.get('animation_skins').get_word(skin_id, SKIN_JOINT_COUNT_WORD);
665
+
666
+ assert.defined(joint_count, `unknown skin_id ${skin_id}`);
667
+
668
+ return joint_count;
669
+ }
670
+
583
671
  /**
584
672
  * Add an animation curve. Its keyframes go into `animation_keyframes` as one run of rows, in
585
673
  * order, and the curve's header names the run.
@@ -667,11 +755,15 @@ export class GPUAnimationManager {
667
755
  * playing, not looping). The clip is inert at creation — call
668
756
  * {@link start} to begin GPU-side time advancement.
669
757
  *
758
+ * Each binding states its target's `rest_rotation`, `[x, y, z, w]`: what a Node3D target's
759
+ * rotation resolves to in a frame where every rotation contributed to it sums to nothing. Only
760
+ * a Node3D rotation binding reads it; {@link register_clip} takes it from the target entity.
761
+ *
670
762
  * @param {{
671
763
  * time?: number,
672
764
  * time_start?: number,
673
765
  * time_end?: number,
674
- * bindings: Array<{ track: number, instance: number, property: number }>,
766
+ * bindings: Array<{ track: number, instance: number, property: number, rest_rotation: ArrayLike<number> }>,
675
767
  * }} clip
676
768
  * @returns {number} clip id (index into the `animation_clips` table)
677
769
  */
@@ -706,8 +798,15 @@ export class GPUAnimationManager {
706
798
  assert.isNonNegativeInteger(b.track, `clip.bindings[${i}].track`);
707
799
  assert.isNonNegativeInteger(b.instance, `clip.bindings[${i}].instance`);
708
800
  assert.isNonNegativeInteger(b.property, `clip.bindings[${i}].property`);
801
+ assert.equal(b.rest_rotation.length, 4, `clip.bindings[${i}].rest_rotation.length`);
709
802
 
710
- rows[i] = { track: b.track, instance: b.instance, property: b.property, clip: clip_id };
803
+ rows[i] = {
804
+ track: b.track,
805
+ instance: b.instance,
806
+ property: b.property,
807
+ clip: clip_id,
808
+ rest_rotation: b.rest_rotation
809
+ };
711
810
  }
712
811
 
713
812
  const bindings_first = this.#database.get('animation_bindings').add_run_records(rows, BINDING_WRITER);
@@ -1176,6 +1275,7 @@ export class GPUAnimationManager {
1176
1275
  */
1177
1276
  #try_complete_clip(pending) {
1178
1277
  const rows = this.#scene_context.rows;
1278
+ const dataset = rows.dataset;
1179
1279
  const channels = pending.channels;
1180
1280
  const clip_id = pending.clip_id;
1181
1281
 
@@ -1190,9 +1290,15 @@ export class GPUAnimationManager {
1190
1290
 
1191
1291
  bindings[i] = {
1192
1292
  track: ch.track,
1193
- instance: row_of_entity(target),
1293
+ // a target a CPU writer holds is bound muted: see #mute
1294
+ instance: gpu_authority_held(dataset, target, GPUStateAuthorityFlags.TransformAttachment)
1295
+ ? GPU_DATABASE_NULL
1296
+ : row_of_entity(target),
1194
1297
  property: ch.property,
1195
1298
  clip: clip_id,
1299
+ // a held target's rest is the holder's pose of the moment, taken again when the
1300
+ // hold ends: see #unmute
1301
+ rest_rotation: rest_rotation_of(rows.dataset, target),
1196
1302
  };
1197
1303
  }
1198
1304
 
@@ -1209,8 +1315,9 @@ export class GPUAnimationManager {
1209
1315
 
1210
1316
  /**
1211
1317
  * Hand the entities a clip drives to the GPU: the first clip to bind an entity grants its
1212
- * TransformAttachment authority. Counted per entity, because two clips can drive one joint
1213
- * and it is the GPU's until the last of them leaves.
1318
+ * TransformAttachment authority — unless a CPU writer holds it, which the grant leaves be.
1319
+ * Listed per entity, because two clips can drive one joint and it is the GPU's until the last
1320
+ * of them leaves.
1214
1321
  *
1215
1322
  * @param {number} clip_id
1216
1323
  * @param {Array<{target: number}>} channels
@@ -1231,9 +1338,13 @@ export class GPUAnimationManager {
1231
1338
 
1232
1339
  targets.push(target);
1233
1340
 
1234
- const count = driving.get(target) ?? 0;
1341
+ let clips = driving.get(target);
1342
+
1343
+ if (clips === undefined) {
1344
+ clips = [];
1345
+
1346
+ driving.set(target, clips);
1235
1347
 
1236
- if (count === 0) {
1237
1348
  /*
1238
1349
  The first clip to drive a joint takes its offset, and with it the joint's world
1239
1350
  and every world below: the hierarchy pass composes the subtree from the rows, and
@@ -1246,15 +1357,22 @@ export class GPUAnimationManager {
1246
1357
  GPUStateAuthorityFlags.TransformAttachment | GPUStateAuthorityFlags.Transform64
1247
1358
  );
1248
1359
 
1360
+ // The offset as it stands is the clip's rest, and the row's on every axis it does
1361
+ // not key: an announcement still waiting for the flush is skipped once the bit is set.
1362
+ rows.mark_handover(target);
1363
+
1249
1364
  rows.for_each_descendant(target, descendant => {
1250
1365
  // a prefab declares its animated subtree; an entity attached under a joint
1251
1366
  // from elsewhere is declared here, at the one moment it is taken
1252
1367
  gpu_authority_declare(dataset, descendant);
1253
1368
  gpu_authority_grant(dataset, descendant, GPUStateAuthorityFlags.Transform64);
1254
1369
  });
1370
+
1371
+ // A CPU writer may hold the offset now or later; it says so on the entity.
1372
+ dataset.addEntityEventListener(target, GPU_AUTHORITY_EVENT_HOLD_CHANGE, this.#hold_changed, this);
1255
1373
  }
1256
1374
 
1257
- driving.set(target, count + 1);
1375
+ clips.push(clip_id);
1258
1376
  }
1259
1377
 
1260
1378
  this.#targets_by_clip.set(clip_id, targets);
@@ -1313,11 +1431,11 @@ export class GPUAnimationManager {
1313
1431
 
1314
1432
  for (let i = 0; i < targets.length; i++) {
1315
1433
  const target = targets[i];
1316
- const count = driving.get(target) - 1;
1434
+ const clips = driving.get(target);
1317
1435
 
1318
- if (count > 0) {
1319
- driving.set(target, count);
1436
+ clips.splice(clips.indexOf(clip_id), 1);
1320
1437
 
1438
+ if (clips.length > 0) {
1321
1439
  continue;
1322
1440
  }
1323
1441
 
@@ -1327,6 +1445,8 @@ export class GPUAnimationManager {
1327
1445
  continue;
1328
1446
  }
1329
1447
 
1448
+ dataset.removeEntityEventListener(target, GPU_AUTHORITY_EVENT_HOLD_CHANGE, this.#hold_changed, this);
1449
+
1330
1450
  /*
1331
1451
  The joint's offset comes back to the CPU seeded with the pose the clip left it in,
1332
1452
  evaluated at the clip's own last time and weight — what the accumulator last
@@ -1334,10 +1454,22 @@ export class GPUAnimationManager {
1334
1454
  snapping to the rest pose. Then the world of the joint and of everything under it
1335
1455
  that no other clip still drives from above, and the announcement that recomposes
1336
1456
  the returned subtree on this side and marks the row.
1457
+
1458
+ Unless a CPU writer holds the offset — a cloth simulating a cape joint the clip also
1459
+ keyed. Then the offset was never the clip's to hand back, and what the holder last
1460
+ wrote stands, after the hold as well: nothing binds the joint to take it back when the
1461
+ hold ends, so it stays the CPU's wherever the holder left it. That is the seed's own
1462
+ rule rather than an exception to it. The seed carries on from what is on screen, and a
1463
+ held joint shows its holder: the clip has been muted since the hold began, or since it
1464
+ bound, so its last pose is one the joint has not shown since, and seeding it would
1465
+ snap the joint there until the holder's next write put its own back. A holder that
1466
+ wants another offset left behind — one it captured — writes it before it lets go.
1337
1467
  */
1338
1468
  const attachment = dataset.getComponent(target, TransformAttachment);
1339
1469
 
1340
- if (attachment !== undefined && attachment !== null && shadow !== undefined) {
1470
+ const held = gpu_authority_held(dataset, target, GPUStateAuthorityFlags.TransformAttachment);
1471
+
1472
+ if (!held && attachment !== undefined && attachment !== null && shadow !== undefined) {
1341
1473
  SEED_PLAYBACK.clip = shadow.clip;
1342
1474
  SEED_PLAYBACK.time = shadow.time;
1343
1475
  SEED_PLAYBACK.weight = shadow.weight;
@@ -1370,6 +1502,120 @@ export class GPUAnimationManager {
1370
1502
  }
1371
1503
  }
1372
1504
 
1505
+ /**
1506
+ * A CPU writer took or gave back the offset of an entity a clip drives — see
1507
+ * `GPUStateAuthority#held`. Listened for on every driven entity, from the first clip that binds
1508
+ * it to the last that leaves.
1509
+ *
1510
+ * Taken: every binding naming the entity is muted, and the hold has already cleared the bit,
1511
+ * so from the next frame the row is the holder's offset and nothing else; the row is marked so
1512
+ * the flush carries it whether or not the holder has announced a write yet. Given back with a
1513
+ * clip still bound: unmuted with the rest the holder left, the row marked so that offset goes
1514
+ * up with it (`GPUSceneRows#mark_handover`), and the joint is the clip's again.
1515
+ *
1516
+ * @param {number} _event the entity, as {@link gpu_authority_hold} sends it
1517
+ * @param {number} entity
1518
+ */
1519
+ #hold_changed(_event, entity) {
1520
+ const rows = this.#scene_context.rows;
1521
+ const dataset = rows.dataset;
1522
+
1523
+ if (gpu_authority_held(dataset, entity, GPUStateAuthorityFlags.TransformAttachment)) {
1524
+ this.#mute(entity);
1525
+
1526
+ rows.mark_local(entity);
1527
+ } else {
1528
+ this.#unmute(entity, dataset);
1529
+
1530
+ rows.mark_handover(entity);
1531
+
1532
+ gpu_authority_grant(dataset, entity, GPUStateAuthorityFlags.TransformAttachment);
1533
+ }
1534
+ }
1535
+
1536
+ /**
1537
+ * Point every binding that names `entity` — in every clip driving it — at
1538
+ * {@link GPU_DATABASE_NULL}.
1539
+ *
1540
+ * **The bit does not stop a clip on the GPU.** No pass reads `GPUStateAuthority`: the apply
1541
+ * pass adds every binding into its target's accumulator slot and the resolve writes the row,
1542
+ * after the CPU's flush, every frame, whatever its weight. So a held joint whose bindings still
1543
+ * named its row would show the clip and not its holder. A muted binding names no object —
1544
+ * `write_object_property` writes nothing for the type bits of {@link GPU_DATABASE_NULL} —
1545
+ * so its target's slot stays empty and the resolve leaves the row as the flush wrote it. The
1546
+ * rest of the clip plays as before.
1547
+ *
1548
+ * Only the `instance` word of each binding is written.
1549
+ *
1550
+ * @param {number} entity
1551
+ */
1552
+ #mute(entity) {
1553
+ BINDING_INSTANCE.instance = GPU_DATABASE_NULL;
1554
+
1555
+ this.#write_bindings(entity, BINDING_INSTANCE, BINDING_INSTANCE_WRITER);
1556
+ }
1557
+
1558
+ /**
1559
+ * The reverse of {@link #mute}, when the hold ends: every binding naming `entity` names its row
1560
+ * again, and carries the rest the entity has now.
1561
+ *
1562
+ * The rest a binding took when it bound is not the rest any more. The holder wrote the offset
1563
+ * all through the hold and leaves it where it leaves it — its last pose, or one it captured and
1564
+ * put back — and that offset is the rest the CPU twin reads from here on. A binding that bound
1565
+ * before the hold took the rest from before it; one that bound during it, muted, took the
1566
+ * holder's pose of that moment. Either would resolve a rotation summing to nothing somewhere the
1567
+ * twin does not, and a socket would sit off the drawn mesh.
1568
+ *
1569
+ * @param {number} entity
1570
+ * @param {EntityComponentDataset} dataset
1571
+ */
1572
+ #unmute(entity, dataset) {
1573
+ const rest = rest_of(dataset, entity);
1574
+ const rest_rotation = BINDING_UNMUTE.rest_rotation;
1575
+
1576
+ BINDING_UNMUTE.instance = row_of_entity(entity);
1577
+
1578
+ rest_rotation[0] = rest.rotation_x;
1579
+ rest_rotation[1] = rest.rotation_y;
1580
+ rest_rotation[2] = rest.rotation_z;
1581
+ rest_rotation[3] = rest.rotation_w;
1582
+
1583
+ this.#write_bindings(entity, BINDING_UNMUTE, BINDING_UNMUTE_WRITER);
1584
+ }
1585
+
1586
+ /**
1587
+ * Write `fields` into every binding that names `entity`, in every clip driving it. A binding's
1588
+ * place in its clip's run is its channel's, so the clip's own channels say which rows of the
1589
+ * run to touch.
1590
+ *
1591
+ * @param {number} entity
1592
+ * @param {object} fields
1593
+ * @param {GPURecordWriter} writer
1594
+ */
1595
+ #write_bindings(entity, fields, writer) {
1596
+ const clips = this.#clips_driving.get(entity);
1597
+
1598
+ if (clips === undefined) {
1599
+ return;
1600
+ }
1601
+
1602
+ const clips_table = this.#database.get('animation_clips');
1603
+ const bindings = this.#database.get('animation_bindings');
1604
+
1605
+ for (let c = 0; c < clips.length; c++) {
1606
+ const clip_id = clips[c];
1607
+
1608
+ const first = clips_table.get_word(clip_id, CLIP_BINDINGS_FIRST_WORD);
1609
+ const channels = this.#playback_by_clip.get(clip_id).clip.channels;
1610
+
1611
+ for (let i = 0; i < channels.length; i++) {
1612
+ if (channels[i].target === entity) {
1613
+ bindings.set_fields(first + i, fields, writer);
1614
+ }
1615
+ }
1616
+ }
1617
+ }
1618
+
1373
1619
  /**
1374
1620
  * Drop a clip from the manager: its row, and with it the run of its bindings — the clip's range
1375
1621
  * owns the run, so the table removes it. Tolerates the clip still being pending (drains it from
@@ -11,15 +11,22 @@
11
11
  * Per-axis dirty bits live in a single dirty u32 (atomicOr to set,
12
12
  * atomicLoad in resolve, atomicStore(0) to clear).
13
13
  *
14
- * Layout in u32 indices (slot stride = 16 u32s = 64 bytes — 5 u32s of
15
- * tail padding give the slot a power-of-two stride so addressing is a
14
+ * Layout in u32 indices (slot stride = 16 u32s = 64 bytes — one u32 of
15
+ * tail padding gives the slot a power-of-two stride so addressing is a
16
16
  * shift, not a multiply):
17
17
  *
18
18
  * [0..3] translation.xyz (3 atomic<u32>, f32 bitcast)
19
19
  * [3..7] rotation.xyzw (4 atomic<u32>, f32 bitcast)
20
20
  * [7..10] scale.xyz (3 atomic<u32>, f32 bitcast)
21
21
  * [10] dirty_mask (atomic<u32>, see flag bits below)
22
- * [11..16] padding
22
+ * [11..15] rest_rotation.xyzw (4 atomic<u32>, f32 bitcast)
23
+ * [15] padding
24
+ *
25
+ * `rest_rotation` is not a sum. Every rotation contribution stores its
26
+ * target's rest rotation there, whatever its weight, and the resolve
27
+ * writes it to the row when the rotation sum has length zero. It is not
28
+ * drained: a row is only rotation-dirty in a frame some contribution
29
+ * stored it afresh.
23
30
  *
24
31
  * `dirty_mask` bit layout:
25
32
  * bits 0–2: translation x/y/z written this frame
@@ -35,7 +42,7 @@
35
42
  */
36
43
  /**
37
44
  * u32-stride per pose-accumulator slot. Picked to be a power of two so
38
- * `row << 4` works as the slot offset. 11 u32s are used, 5 are padding.
45
+ * `row << 4` works as the slot offset. 15 u32s are used, 1 is padding.
39
46
  * @type {number}
40
47
  */
41
48
  export const POSE_ACCUMULATOR_STRIDE: number;
@@ -51,6 +58,7 @@ export const POSE_ACCUMULATOR_OFFSET_TRANSLATION: 0;
51
58
  export const POSE_ACCUMULATOR_OFFSET_ROTATION: 3;
52
59
  export const POSE_ACCUMULATOR_OFFSET_SCALE: 7;
53
60
  export const POSE_ACCUMULATOR_OFFSET_DIRTY: 10;
61
+ export const POSE_ACCUMULATOR_OFFSET_REST_ROTATION: 11;
54
62
  /**
55
63
  * Dirty-mask bit layout. Per-axis for T/S, single bit for R.
56
64
  */
@@ -1 +1 @@
1
- {"version":3,"file":"POSE_ACCUMULATOR_LAYOUT.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;GAIG;AACH,sCAFU,MAAM,CAE0B;AAE1C;;;;;GAKG;AACH,0CAFU,MAAM,CAEuD;AAEvE,gDAAgD;AAChD,oDAAqD;AACrD,iDAAkD;AAClD,8CAA+C;AAC/C,+CAAgD;AAEhD;;GAEG;AACH,mCAAoC;AACpC,mCAAoC;AACpC,mCAAoC;AACpC,kCAAmC;AACnC,mCAAoC;AACpC,mCAAoC;AACpC,mCAAoC"}
1
+ {"version":3,"file":"POSE_ACCUMULATOR_LAYOUT.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH;;;;GAIG;AACH,sCAFU,MAAM,CAE0B;AAE1C;;;;;GAKG;AACH,0CAFU,MAAM,CAEuD;AAEvE,gDAAgD;AAChD,oDAAqD;AACrD,iDAAkD;AAClD,8CAA+C;AAC/C,+CAAgD;AAChD,uDAAwD;AAExD;;GAEG;AACH,mCAAoC;AACpC,mCAAoC;AACpC,mCAAoC;AACpC,kCAAmC;AACnC,mCAAoC;AACpC,mCAAoC;AACpC,mCAAoC"}
@@ -11,15 +11,22 @@
11
11
  * Per-axis dirty bits live in a single dirty u32 (atomicOr to set,
12
12
  * atomicLoad in resolve, atomicStore(0) to clear).
13
13
  *
14
- * Layout in u32 indices (slot stride = 16 u32s = 64 bytes — 5 u32s of
15
- * tail padding give the slot a power-of-two stride so addressing is a
14
+ * Layout in u32 indices (slot stride = 16 u32s = 64 bytes — one u32 of
15
+ * tail padding gives the slot a power-of-two stride so addressing is a
16
16
  * shift, not a multiply):
17
17
  *
18
18
  * [0..3] translation.xyz (3 atomic<u32>, f32 bitcast)
19
19
  * [3..7] rotation.xyzw (4 atomic<u32>, f32 bitcast)
20
20
  * [7..10] scale.xyz (3 atomic<u32>, f32 bitcast)
21
21
  * [10] dirty_mask (atomic<u32>, see flag bits below)
22
- * [11..16] padding
22
+ * [11..15] rest_rotation.xyzw (4 atomic<u32>, f32 bitcast)
23
+ * [15] padding
24
+ *
25
+ * `rest_rotation` is not a sum. Every rotation contribution stores its
26
+ * target's rest rotation there, whatever its weight, and the resolve
27
+ * writes it to the row when the rotation sum has length zero. It is not
28
+ * drained: a row is only rotation-dirty in a frame some contribution
29
+ * stored it afresh.
23
30
  *
24
31
  * `dirty_mask` bit layout:
25
32
  * bits 0–2: translation x/y/z written this frame
@@ -36,7 +43,7 @@
36
43
 
37
44
  /**
38
45
  * u32-stride per pose-accumulator slot. Picked to be a power of two so
39
- * `row << 4` works as the slot offset. 11 u32s are used, 5 are padding.
46
+ * `row << 4` works as the slot offset. 15 u32s are used, 1 is padding.
40
47
  * @type {number}
41
48
  */
42
49
  export const POSE_ACCUMULATOR_STRIDE = 16;
@@ -54,6 +61,7 @@ export const POSE_ACCUMULATOR_OFFSET_TRANSLATION = 0;
54
61
  export const POSE_ACCUMULATOR_OFFSET_ROTATION = 3;
55
62
  export const POSE_ACCUMULATOR_OFFSET_SCALE = 7;
56
63
  export const POSE_ACCUMULATOR_OFFSET_DIRTY = 10;
64
+ export const POSE_ACCUMULATOR_OFFSET_REST_ROTATION = 11;
57
65
 
58
66
  /**
59
67
  * Dirty-mask bit layout. Per-axis for T/S, single bit for R.
@@ -1 +1 @@
1
- {"version":3,"file":"chunk_pose_accumulator.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/animation/chunk_pose_accumulator.js"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;;GAgBG;AACH,qCAFU,SAAS,CA4FgB;0BA5HT,iCAAiC"}
1
+ {"version":3,"file":"chunk_pose_accumulator.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/animation/chunk_pose_accumulator.js"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;;;GAgBG;AACH,qCAFU,SAAS,CAwGgB;0BAzIT,iCAAiC"}
@@ -2,6 +2,7 @@ import { CodeChunk } from "../shader/compiler/CodeChunk.js";
2
2
  import { chunk_atomic_add_f32_storage } from "../shader/chunk/atomic/chunk_atomic_add_f32_storage.js";
3
3
  import {
4
4
  POSE_ACCUMULATOR_OFFSET_DIRTY,
5
+ POSE_ACCUMULATOR_OFFSET_REST_ROTATION,
5
6
  POSE_ACCUMULATOR_OFFSET_ROTATION,
6
7
  POSE_ACCUMULATOR_OFFSET_SCALE,
7
8
  POSE_ACCUMULATOR_OFFSET_TRANSLATION,
@@ -40,6 +41,7 @@ const POSE_OFFSET_TRANSLATION: u32 = ${POSE_ACCUMULATOR_OFFSET_TRANSLATION}u;
40
41
  const POSE_OFFSET_ROTATION: u32 = ${POSE_ACCUMULATOR_OFFSET_ROTATION}u;
41
42
  const POSE_OFFSET_SCALE: u32 = ${POSE_ACCUMULATOR_OFFSET_SCALE}u;
42
43
  const POSE_OFFSET_DIRTY: u32 = ${POSE_ACCUMULATOR_OFFSET_DIRTY}u;
44
+ const POSE_OFFSET_REST_ROTATION: u32 = ${POSE_ACCUMULATOR_OFFSET_REST_ROTATION}u;
43
45
 
44
46
  const POSE_DIRTY_TX: u32 = ${POSE_DIRTY_TX}u;
45
47
  const POSE_DIRTY_TY: u32 = ${POSE_DIRTY_TY}u;
@@ -75,7 +77,7 @@ fn pose_accumulator_add_translation(row: u32, value: vec3<f32>, mask: u32) {
75
77
  }
76
78
  }
77
79
 
78
- fn pose_accumulator_add_rotation(row: u32, value: vec4<f32>, mask: u32, weight: f32) {
80
+ fn pose_accumulator_add_rotation(row: u32, value: vec4<f32>, mask: u32, weight: f32, rest: vec4<f32>) {
79
81
  // Rotation tracks normally cover all four channels (quaternion is one
80
82
  // unit). Channels missing from the mask must default to the identity
81
83
  // quaternion (0, 0, 0, 1): the evaluator leaves them at 0, which is
@@ -100,6 +102,17 @@ fn pose_accumulator_add_rotation(row: u32, value: vec4<f32>, mask: u32, weight:
100
102
  atomic_add_f32_storage(&pose_accumulator[base + 1u], value.y);
101
103
  atomic_add_f32_storage(&pose_accumulator[base + 2u], value.z);
102
104
  atomic_add_f32_storage(&pose_accumulator[base + 3u], w);
105
+
106
+ // The target's rest rotation, stored rather than added, by every contribution whatever its
107
+ // weight: the resolve writes it when the sum has length zero, which is every clip rotating the
108
+ // joint playing at weight zero, and by then the row holds the last clip's pose rather than the
109
+ // rest. Every binding of one target carries the same rest, so concurrent stores agree.
110
+ let rest_base = pose_accumulator_slot_base(row) + POSE_OFFSET_REST_ROTATION;
111
+ atomicStore(&pose_accumulator[rest_base + 0u], bitcast<u32>(rest.x));
112
+ atomicStore(&pose_accumulator[rest_base + 1u], bitcast<u32>(rest.y));
113
+ atomicStore(&pose_accumulator[rest_base + 2u], bitcast<u32>(rest.z));
114
+ atomicStore(&pose_accumulator[rest_base + 3u], bitcast<u32>(rest.w));
115
+
103
116
  atomicOr(&pose_accumulator[pose_accumulator_slot_base(row) + POSE_OFFSET_DIRTY], POSE_DIRTY_R);
104
117
  }
105
118
 
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @typedef {import("../ShadeAnimationChannel.js").ShadeAnimationChannel} ShadeAnimationChannel
3
+ * @typedef {import("../ShadeAnimationClip.js").ShadeAnimationClip} ShadeAnimationClip
4
+ */
5
+ /**
6
+ * What {@link PoseChannelIndex#group_of} answers for an entity the clip has no track for.
7
+ *
8
+ * @type {number}
9
+ */
10
+ export const POSE_CHANNEL_GROUP_NONE: number;
11
+ /**
12
+ * A clip's channels grouped by the entity each names, for the CPU pose twin to look one entity up
13
+ * in, rather than scan the whole clip for it once per level of every query.
14
+ *
15
+ * The groups are laid end to end in one array, each in the clip's own order, with a table of where
16
+ * each starts and a {@link Uint32Map} from entity to group: on a 70-joint clip of 210 channels it
17
+ * holds a few KiB, against the ~25 KiB of the clip itself, and nothing in it is handed out to be
18
+ * written. Read it with {@link group_of}, {@link first}, {@link end} and {@link channel}.
19
+ *
20
+ * Built once per clip ({@link of}) and checked, not rebuilt, each time a playback takes the clip
21
+ * again.
22
+ *
23
+ * @author Alex Goldring
24
+ * @copyright Company Named Limited (c) 2026
25
+ */
26
+ export class PoseChannelIndex {
27
+ /**
28
+ * The clip's index, as the clip holds its channels now: the one built before when it still
29
+ * holds, a new one otherwise.
30
+ *
31
+ * @param {ShadeAnimationClip} clip
32
+ * @returns {PoseChannelIndex}
33
+ */
34
+ static of(clip: ShadeAnimationClip): PoseChannelIndex;
35
+ /**
36
+ * @param {ShadeAnimationChannel[]} channels a clip's channels
37
+ */
38
+ constructor(channels: ShadeAnimationChannel[]);
39
+ /**
40
+ * The group of channels naming `entity`, or {@link POSE_CHANNEL_GROUP_NONE} where the clip has no
41
+ * track for it — which is most entities for most clips.
42
+ *
43
+ * @param {number} entity
44
+ * @returns {number}
45
+ */
46
+ group_of(entity: number): number;
47
+ /**
48
+ * @param {number} group
49
+ * @returns {number} the position of the group's first channel
50
+ */
51
+ first(group: number): number;
52
+ /**
53
+ * @param {number} group
54
+ * @returns {number} one past the position of the group's last channel
55
+ */
56
+ end(group: number): number;
57
+ /**
58
+ * @param {number} position from {@link first} up to {@link end}
59
+ * @returns {ShadeAnimationChannel}
60
+ */
61
+ channel(position: number): ShadeAnimationChannel;
62
+ /**
63
+ * Whether this still describes `channels`: every channel naming an entity is where this put it
64
+ * — the same channel, naming the same entity, in the same order among that entity's — and there
65
+ * are as many as there were. A walk of the clip without allocation.
66
+ *
67
+ * @param {ShadeAnimationChannel[]} channels
68
+ * @returns {boolean}
69
+ */
70
+ holds(channels: ShadeAnimationChannel[]): boolean;
71
+ #private;
72
+ }
73
+ export namespace PoseChannelIndex {
74
+ let EMPTY: PoseChannelIndex;
75
+ }
76
+ export type ShadeAnimationChannel = import("../ShadeAnimationChannel.js").ShadeAnimationChannel;
77
+ export type ShadeAnimationClip = import("../ShadeAnimationClip.js").ShadeAnimationClip;
78
+ //# sourceMappingURL=PoseChannelIndex.d.ts.map