@woosh/meep-engine 3.23.0 → 3.25.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 (812) hide show
  1. package/editor/entity_world_bounds.d.ts +9 -3
  2. package/editor/entity_world_bounds.d.ts.map +1 -1
  3. package/editor/entity_world_bounds.js +61 -4
  4. package/package.json +1 -1
  5. package/src/core/binary/allocator/OffsetAllocator.d.ts +40 -2
  6. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  7. package/src/core/binary/allocator/OffsetAllocator.js +124 -29
  8. package/src/core/collection/map/u32_index.d.ts +83 -0
  9. package/src/core/collection/map/u32_index.d.ts.map +1 -0
  10. package/src/core/collection/map/u32_index.js +247 -0
  11. package/src/engine/asset/loaders/GLTFSceneBundleAssetLoader.d.ts +2 -2
  12. package/src/engine/asset/loaders/GLTFSceneBundleAssetLoader.js +2 -2
  13. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts +1 -2
  14. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts.map +1 -1
  15. package/src/engine/asset/loaders/USDSceneBundleAssetLoader.js +4 -12
  16. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts +55 -0
  17. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts.map +1 -0
  18. package/src/engine/ecs/gpu/GPUStateAuthority.js +72 -0
  19. package/src/engine/ecs/gpu/GPUStateAuthorityFlags.d.ts +40 -0
  20. package/src/engine/ecs/gpu/GPUStateAuthorityFlags.d.ts.map +1 -0
  21. package/src/engine/ecs/gpu/GPUStateAuthorityFlags.js +79 -0
  22. package/src/engine/ecs/gpu/gpu_authority_assert_cpu.d.ts +18 -0
  23. package/src/engine/ecs/gpu/gpu_authority_assert_cpu.d.ts.map +1 -0
  24. package/src/engine/ecs/gpu/gpu_authority_assert_cpu.js +27 -0
  25. package/src/engine/ecs/gpu/gpu_authority_declare.d.ts +23 -0
  26. package/src/engine/ecs/gpu/gpu_authority_declare.d.ts.map +1 -0
  27. package/src/engine/ecs/gpu/gpu_authority_declare.js +39 -0
  28. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts +15 -0
  29. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts.map +1 -0
  30. package/src/engine/ecs/gpu/gpu_authority_grant.js +38 -0
  31. package/src/engine/ecs/gpu/gpu_authority_has.d.ts +18 -0
  32. package/src/engine/ecs/gpu/gpu_authority_has.d.ts.map +1 -0
  33. package/src/engine/ecs/gpu/gpu_authority_has.js +28 -0
  34. package/src/engine/ecs/gpu/gpu_authority_revoke.d.ts +24 -0
  35. package/src/engine/ecs/gpu/gpu_authority_revoke.d.ts.map +1 -0
  36. package/src/engine/ecs/gpu/gpu_authority_revoke.js +49 -0
  37. package/src/engine/ecs/ik/IKProblem.d.ts +14 -0
  38. package/src/engine/ecs/ik/IKProblem.d.ts.map +1 -1
  39. package/src/engine/ecs/ik/IKProblem.js +16 -0
  40. package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +1 -1
  41. package/src/engine/ecs/ik/InverseKinematicsSystem.js +19 -0
  42. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +2 -2
  43. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +2 -2
  44. package/src/engine/ecs/ik/ik_bone_chain.d.ts +11 -2
  45. package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +1 -1
  46. package/src/engine/ecs/ik/ik_bone_chain.js +47 -2
  47. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  48. package/src/engine/ecs/ik/ik_write_local_rotation.js +6 -0
  49. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  50. package/src/engine/ecs/speaker/VoiceSystem.js +6 -0
  51. package/src/engine/ecs/transform/T64WorldCache.d.ts +50 -0
  52. package/src/engine/ecs/transform/T64WorldCache.d.ts.map +1 -0
  53. package/src/engine/ecs/transform/T64WorldCache.js +139 -0
  54. package/src/engine/ecs/transform/t64_evaluate_world.d.ts +31 -0
  55. package/src/engine/ecs/transform/t64_evaluate_world.d.ts.map +1 -0
  56. package/src/engine/ecs/transform/t64_evaluate_world.js +126 -0
  57. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts +8 -0
  58. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  59. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +59 -30
  60. package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts.map +1 -1
  61. package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +4 -11
  62. package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.d.ts +14 -0
  63. package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.d.ts.map +1 -0
  64. package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.js +13 -0
  65. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +2 -14
  66. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts.map +1 -1
  67. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +11 -21
  68. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.d.ts +1 -0
  69. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +7 -0
  70. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts +5 -6
  71. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts.map +1 -1
  72. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.js +13 -11
  73. package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.d.ts +14 -0
  74. package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.d.ts.map +1 -0
  75. package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.js +21 -0
  76. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +1 -1
  77. package/src/engine/graphics/ecs/particles/ParticleEffect.js +1 -1
  78. package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.d.ts +1 -1
  79. package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.js +1 -1
  80. package/src/engine/graphics3/AnimationGraphSystem.js +3 -3
  81. package/src/engine/graphics3/AnimationSystem.js +2 -2
  82. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  83. package/src/engine/graphics3/DebugDrawSystem.js +2 -4
  84. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +34 -27
  85. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  86. package/src/engine/graphics3/GPUParticleEmitterSystem.js +185 -85
  87. package/src/engine/graphics3/HighlightOutlineSystem.d.ts +4 -3
  88. package/src/engine/graphics3/HighlightOutlineSystem.d.ts.map +1 -1
  89. package/src/engine/graphics3/HighlightOutlineSystem.js +7 -9
  90. package/src/engine/graphics3/LightSystem.d.ts +7 -5
  91. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  92. package/src/engine/graphics3/LightSystem.js +36 -22
  93. package/src/engine/graphics3/MeshSystem.d.ts +43 -39
  94. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  95. package/src/engine/graphics3/MeshSystem.js +324 -331
  96. package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -1
  97. package/src/engine/graphics3/PathDisplaySystem.js +2 -4
  98. package/src/engine/graphics3/PickingQuery.d.ts +15 -21
  99. package/src/engine/graphics3/PickingQuery.d.ts.map +1 -1
  100. package/src/engine/graphics3/PickingQuery.js +21 -25
  101. package/src/engine/graphics3/PickingSystem.d.ts +60 -31
  102. package/src/engine/graphics3/PickingSystem.d.ts.map +1 -1
  103. package/src/engine/graphics3/PickingSystem.js +413 -273
  104. package/src/engine/graphics3/ShadedGeometrySystem.d.ts +22 -12
  105. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  106. package/src/engine/graphics3/ShadedGeometrySystem.js +309 -174
  107. package/src/engine/graphics3/TerrainSystem.d.ts +19 -11
  108. package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -1
  109. package/src/engine/graphics3/TerrainSystem.js +102 -53
  110. package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -1
  111. package/src/engine/graphics3/TooltipComponentSystem.js +2 -14
  112. package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -1
  113. package/src/engine/graphics3/Trail3DSystem.js +2 -4
  114. package/src/engine/graphics3/animation/ClipListPlayer.d.ts +4 -4
  115. package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
  116. package/src/engine/graphics3/animation/ClipListPlayer.js +2 -2
  117. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts +9 -11
  118. package/src/engine/graphics3/highlight/pack_highlight_table.d.ts.map +1 -1
  119. package/src/engine/graphics3/highlight/pack_highlight_table.js +11 -18
  120. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +4 -3
  121. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  122. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +75 -74
  123. package/src/engine/graphics3/prefab/Prefab.d.ts +130 -0
  124. package/src/engine/graphics3/prefab/Prefab.d.ts.map +1 -0
  125. package/src/engine/graphics3/prefab/Prefab.js +162 -0
  126. package/src/engine/graphics3/prefab/PrefabInstance.d.ts +72 -0
  127. package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -0
  128. package/src/engine/graphics3/prefab/PrefabInstance.js +80 -0
  129. package/src/engine/graphics3/prefab/prefab_compile.d.ts +23 -0
  130. package/src/engine/graphics3/prefab/prefab_compile.d.ts.map +1 -0
  131. package/src/engine/graphics3/prefab/prefab_compile.js +334 -0
  132. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +46 -0
  133. package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -0
  134. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -0
  135. package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.d.ts +70 -0
  136. package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.d.ts.map +1 -0
  137. package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.js +210 -0
  138. package/src/engine/graphics3/prefab/prefab_place.d.ts +60 -0
  139. package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -0
  140. package/src/engine/graphics3/prefab/prefab_place.js +130 -0
  141. package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.d.ts +60 -0
  142. package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.d.ts.map +1 -0
  143. package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.js +128 -0
  144. package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts +40 -0
  145. package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts.map +1 -0
  146. package/src/engine/graphics3/prefab/prefab_skin_frame.js +116 -0
  147. package/src/engine/graphics3/preview/make_model_preview_scene.d.ts +16 -14
  148. package/src/engine/graphics3/preview/make_model_preview_scene.d.ts.map +1 -1
  149. package/src/engine/graphics3/preview/make_model_preview_scene.js +126 -154
  150. package/src/engine/graphics3/preview/make_model_thumbnail.js +1 -1
  151. package/src/engine/graphics3/register_instance_animation.d.ts +6 -6
  152. package/src/engine/graphics3/register_instance_animation.d.ts.map +1 -1
  153. package/src/engine/graphics3/register_instance_animation.js +4 -4
  154. package/src/engine/graphics3/shade_bundle_bounds.d.ts +2 -6
  155. package/src/engine/graphics3/shade_bundle_bounds.d.ts.map +1 -1
  156. package/src/engine/graphics3/shade_bundle_bounds.js +47 -55
  157. package/src/engine/graphics3/shader_picking_gather.d.ts +40 -0
  158. package/src/engine/graphics3/shader_picking_gather.d.ts.map +1 -0
  159. package/src/engine/graphics3/shader_picking_gather.js +120 -0
  160. package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts +11 -18
  161. package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts.map +1 -1
  162. package/src/engine/graphics3/terrain/pack_terrain_row_table.js +48 -53
  163. package/src/engine/physics/cloth/MEASUREMENTS.md +1050 -0
  164. package/src/engine/physics/cloth/PLAN.md +411 -49
  165. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +17 -2
  166. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  167. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +284 -256
  168. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts +52 -0
  169. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.d.ts.map +1 -0
  170. package/src/engine/physics/cloth/ecs/ClothColliderSerializationAdapter.js +70 -0
  171. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts +12 -3
  172. package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts.map +1 -1
  173. package/src/engine/physics/cloth/ecs/ClothDynamics.js +340 -331
  174. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +49 -37
  175. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  176. package/src/engine/physics/cloth/ecs/ClothInstance.js +50 -37
  177. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +7 -8
  178. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
  179. package/src/engine/physics/cloth/ecs/ClothRig.js +7 -8
  180. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts +84 -0
  181. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.d.ts.map +1 -0
  182. package/src/engine/physics/cloth/ecs/ClothSerializationAdapter.js +141 -0
  183. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +51 -81
  184. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  185. package/src/engine/physics/cloth/ecs/ClothSystem.js +81 -870
  186. package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts +48 -0
  187. package/src/engine/physics/cloth/ecs/ClothWorkerCore.d.ts.map +1 -0
  188. package/src/engine/physics/cloth/ecs/ClothWorkerCore.js +107 -0
  189. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +286 -0
  190. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -0
  191. package/src/engine/physics/cloth/ecs/ClothWorld.js +1104 -0
  192. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +182 -0
  193. package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -0
  194. package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +562 -0
  195. package/src/engine/physics/cloth/ecs/cloth.worker.d.ts +2 -0
  196. package/src/engine/physics/cloth/ecs/cloth.worker.d.ts.map +1 -0
  197. package/src/engine/physics/cloth/ecs/cloth.worker.js +12 -0
  198. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  199. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +2 -1
  200. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +58 -0
  201. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
  202. package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +341 -271
  203. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +20 -2
  204. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
  205. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +39 -15
  206. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +19 -23
  207. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  208. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +201 -199
  209. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  210. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +8 -0
  211. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts +29 -0
  212. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.d.ts.map +1 -0
  213. package/src/engine/physics/cloth/ecs/cloth_worker_protocol.js +78 -0
  214. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +18 -34
  215. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
  216. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +58 -115
  217. package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts +17 -0
  218. package/src/engine/physics/cloth/ecs/makeClothWorker.d.ts.map +1 -0
  219. package/src/engine/physics/cloth/ecs/makeClothWorker.js +18 -0
  220. package/src/engine/physics/cloth/playground/README.md +84 -13
  221. package/src/engine/physics/cloth/playground/garment_build.d.ts +0 -1
  222. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
  223. package/src/engine/physics/cloth/playground/garment_build.js +64 -58
  224. package/src/engine/physics/cloth/playground/garment_main.js +59 -33
  225. package/src/engine/physics/cloth/playground/wind.html +166 -0
  226. package/src/engine/physics/cloth/playground/wind_build.d.ts +81 -0
  227. package/src/engine/physics/cloth/playground/wind_build.d.ts.map +1 -0
  228. package/src/engine/physics/cloth/playground/wind_build.js +141 -0
  229. package/src/engine/physics/cloth/playground/wind_main.d.ts +2 -0
  230. package/src/engine/physics/cloth/playground/wind_main.d.ts.map +1 -0
  231. package/src/engine/physics/cloth/playground/wind_main.js +681 -0
  232. package/src/engine/physics/cloth/solver/ClothState.d.ts +134 -79
  233. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  234. package/src/engine/physics/cloth/solver/ClothState.js +273 -12
  235. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +33 -0
  236. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  237. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +34 -0
  238. package/src/engine/physics/cloth/solver/cloth_step.d.ts +21 -2
  239. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  240. package/src/engine/physics/cloth/solver/cloth_step.js +173 -4
  241. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts +40 -0
  242. package/src/engine/physics/cloth/solver/cloth_step_instance.d.ts.map +1 -0
  243. package/src/engine/physics/cloth/solver/cloth_step_instance.js +284 -0
  244. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts +107 -0
  245. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.d.ts.map +1 -0
  246. package/src/engine/physics/cloth/solver/cloth_wind_accelerate.js +263 -0
  247. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +88 -0
  248. package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts.map +1 -0
  249. package/src/engine/physics/cloth/wind/AbstractClothWind.js +100 -0
  250. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts +85 -0
  251. package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts.map +1 -0
  252. package/src/engine/physics/cloth/wind/ClothAmbientWind.js +182 -0
  253. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts +79 -0
  254. package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -0
  255. package/src/engine/physics/cloth/wind/ClothFluidWind.js +210 -0
  256. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +101 -0
  257. package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -0
  258. package/src/engine/physics/cloth/wind/cloth_sample_air.js +290 -0
  259. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  260. package/src/shade/RENDERER_CONTRACT.md +85 -53
  261. package/src/shade/device/ShadeGPUCommandContext.d.ts +23 -0
  262. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  263. package/src/shade/device/ShadeGPUCommandContext.js +36 -0
  264. package/src/shade/device/mock/texture_copy.d.ts.map +1 -1
  265. package/src/shade/device/mock/texture_copy.js +28 -0
  266. package/src/shade/playground/add_random_meshes.d.ts +4 -4
  267. package/src/shade/playground/add_random_meshes.d.ts.map +1 -1
  268. package/src/shade/playground/add_random_meshes.js +20 -16
  269. package/src/shade/playground/avboit/main.d.ts +1 -0
  270. package/src/shade/playground/avboit/main.d.ts.map +1 -1
  271. package/src/shade/playground/avboit/main.js +916 -875
  272. package/src/shade/playground/basis_textures/main.d.ts.map +1 -1
  273. package/src/shade/playground/basis_textures/main.js +22 -8
  274. package/src/shade/playground/basis_textures/texture_inventory.d.ts +2 -2
  275. package/src/shade/playground/basis_textures/texture_inventory.d.ts.map +1 -1
  276. package/src/shade/playground/basis_textures/texture_inventory.js +6 -7
  277. package/src/shade/playground/ground_seam/main.d.ts.map +1 -1
  278. package/src/shade/playground/ground_seam/main.js +13 -4
  279. package/src/shade/playground/ground_seam/make_ground.d.ts +13 -4
  280. package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -1
  281. package/src/shade/playground/ground_seam/make_ground.js +21 -16
  282. package/src/shade/playground/particle_ecs/bonfire_editor.js +3 -3
  283. package/src/shade/playground/particle_system/main.js +11 -10
  284. package/src/shade/playground/particle_system/particle_prototype.d.ts +15 -10
  285. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  286. package/src/shade/playground/particle_system/particle_prototype.js +56 -15
  287. package/src/shade/playground/particle_system/particle_scene.d.ts +68 -28
  288. package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
  289. package/src/shade/playground/particle_system/particle_scene.js +149 -53
  290. package/src/shade/playground/readback_crossover/index.html +41 -0
  291. package/src/shade/playground/readback_crossover/main.d.ts +2 -0
  292. package/src/shade/playground/readback_crossover/main.d.ts.map +1 -0
  293. package/src/shade/playground/readback_crossover/main.js +372 -0
  294. package/src/shade/playground/skinned_blas_refit/README.md +11 -7
  295. package/src/shade/playground/skinned_blas_refit/add_floor.d.ts +13 -44
  296. package/src/shade/playground/skinned_blas_refit/add_floor.d.ts.map +1 -1
  297. package/src/shade/playground/skinned_blas_refit/add_floor.js +19 -59
  298. package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
  299. package/src/shade/playground/skinned_blas_refit/main.js +67 -58
  300. package/src/shade/playground/skinned_blas_refit/place_character.d.ts +40 -54
  301. package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
  302. package/src/shade/playground/skinned_blas_refit/place_character.js +47 -74
  303. package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts +3 -3
  304. package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts.map +1 -1
  305. package/src/shade/playground/skinned_blas_refit/sweep_views.js +4 -3
  306. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts +3 -3
  307. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts.map +1 -1
  308. package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.js +11 -4
  309. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.d.ts.map +1 -1
  310. package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.js +38 -9
  311. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts +3 -3
  312. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
  313. package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +9 -6
  314. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts +3 -3
  315. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts.map +1 -1
  316. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +3 -3
  317. package/src/shade/playground/skinned_mesh_soup/README.md +6 -6
  318. package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
  319. package/src/shade/playground/skinned_mesh_soup/main.js +44 -102
  320. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts +5 -5
  321. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
  322. package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +42 -33
  323. package/src/shade/playground/sponza_path_trace/main.d.ts +1 -0
  324. package/src/shade/playground/sponza_path_trace/main.d.ts.map +1 -1
  325. package/src/shade/playground/sponza_path_trace/main.js +393 -363
  326. package/src/shade/playground/ssr_reprojection/main.js +11 -9
  327. package/src/shade/playground/ssr_reprojection/scene.d.ts +15 -4
  328. package/src/shade/playground/ssr_reprojection/scene.d.ts.map +1 -1
  329. package/src/shade/playground/ssr_reprojection/scene.js +32 -11
  330. package/src/shade/playground/ssr_variance/main.js +1 -1
  331. package/src/shade/playground/ssr_variance/scene.d.ts +10 -4
  332. package/src/shade/playground/ssr_variance/scene.d.ts.map +1 -1
  333. package/src/shade/playground/ssr_variance/scene.js +39 -15
  334. package/src/shade/playground/vgeo_runtime/README.md +94 -0
  335. package/src/shade/playground/vgeo_runtime/index.html +62 -0
  336. package/src/shade/playground/vgeo_runtime/main.d.ts +2 -0
  337. package/src/shade/playground/vgeo_runtime/main.d.ts.map +1 -0
  338. package/src/shade/playground/vgeo_runtime/main.js +399 -0
  339. package/src/shade/playground/vgeo_viewer/main.js +6 -2
  340. package/src/shade/playground/vgeo_viewer/sample_asset.js +1 -1
  341. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  342. package/src/shade/playground/volumetrics_froxel/main.js +936 -922
  343. package/src/shade/renderer/GraphicsContext.d.ts +7 -0
  344. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  345. package/src/shade/renderer/GraphicsContext.js +11 -0
  346. package/src/shade/renderer/Renderer.d.ts +3 -2
  347. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  348. package/src/shade/renderer/Renderer.js +3 -2
  349. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +39 -47
  350. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  351. package/src/shade/renderer/animation/GPUAnimationManager.js +319 -256
  352. package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts +26 -22
  353. package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts.map +1 -1
  354. package/src/shade/renderer/animation/ShadeAnimationChannel.js +28 -23
  355. package/src/shade/renderer/animation/ShadeAnimationClip.d.ts +14 -6
  356. package/src/shade/renderer/animation/ShadeAnimationClip.d.ts.map +1 -1
  357. package/src/shade/renderer/animation/ShadeAnimationClip.js +20 -8
  358. package/src/shade/renderer/animation/Skin.d.ts +19 -19
  359. package/src/shade/renderer/animation/Skin.d.ts.map +1 -1
  360. package/src/shade/renderer/animation/Skin.js +15 -13
  361. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts +6 -5
  362. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts.map +1 -1
  363. package/src/shade/renderer/animation/pose/pose_evaluate_local.js +9 -9
  364. package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts +5 -59
  365. package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts.map +1 -1
  366. package/src/shade/renderer/animation/skin_clip_scale_conflicts.js +8 -132
  367. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +65 -62
  368. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  369. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +148 -194
  370. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.d.ts.map +1 -1
  371. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +4 -7
  372. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.d.ts +2 -2
  373. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +2 -2
  374. package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts +74 -0
  375. package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts.map +1 -0
  376. package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.js +240 -0
  377. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +14 -0
  378. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  379. package/src/shade/renderer/buffer/table/GPUDatabase.js +64 -6
  380. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts +190 -0
  381. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts.map +1 -0
  382. package/src/shade/renderer/buffer/table/GPUDatabaseReadback.js +1323 -0
  383. package/src/shade/renderer/buffer/table/GPUPageMetadata.d.ts +10 -0
  384. package/src/shade/renderer/buffer/table/GPUPageMetadata.d.ts.map +1 -1
  385. package/src/shade/renderer/buffer/table/GPUPageMetadata.js +12 -0
  386. package/src/shade/renderer/buffer/table/GPUReadbackStatus.d.ts +15 -0
  387. package/src/shade/renderer/buffer/table/GPUReadbackStatus.d.ts.map +1 -0
  388. package/src/shade/renderer/buffer/table/GPUReadbackStatus.js +34 -0
  389. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +75 -7
  390. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  391. package/src/shade/renderer/buffer/table/GPUTypedTable.js +518 -135
  392. package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.d.ts +19 -0
  393. package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.d.ts.map +1 -0
  394. package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.js +18 -0
  395. package/src/shade/renderer/buffer/table/WordViews.d.ts +39 -0
  396. package/src/shade/renderer/buffer/table/WordViews.d.ts.map +1 -0
  397. package/src/shade/renderer/buffer/table/WordViews.js +62 -0
  398. package/src/shade/renderer/buffer/table/gpu_table_gather_shader.d.ts +27 -0
  399. package/src/shade/renderer/buffer/table/gpu_table_gather_shader.d.ts.map +1 -0
  400. package/src/shade/renderer/buffer/table/gpu_table_gather_shader.js +117 -0
  401. package/src/shade/renderer/buffer/table/serde/generate_record_writer.d.ts +121 -0
  402. package/src/shade/renderer/buffer/table/serde/generate_record_writer.d.ts.map +1 -0
  403. package/src/shade/renderer/buffer/table/serde/generate_record_writer.js +395 -0
  404. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  405. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +70 -20
  406. package/src/shade/renderer/camera/Camera.d.ts +14 -0
  407. package/src/shade/renderer/camera/Camera.d.ts.map +1 -1
  408. package/src/shade/renderer/camera/Camera.js +7 -1
  409. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +1 -1
  410. package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.d.ts.map +1 -1
  411. package/src/shade/renderer/geometry/GEOMETRY_METADATA_STRUCT.js +16 -1
  412. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  413. package/src/shade/renderer/geometry/GPUGeometryManager.js +29 -9
  414. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts +10 -0
  415. package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts.map +1 -1
  416. package/src/shade/renderer/geometry/GPUGeometryMetadata.js +13 -0
  417. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  418. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +6 -5
  419. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +3 -3
  420. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  421. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +15 -11
  422. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +46 -18
  423. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +70 -22
  424. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +97 -19
  425. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +12 -2
  426. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  427. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +14 -3
  428. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts +2 -2
  429. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
  430. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +124 -6
  431. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts +22 -0
  432. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +1 -0
  433. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.js +53 -0
  434. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +8 -1
  435. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  436. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +8 -1
  437. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts +16 -0
  438. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.d.ts.map +1 -0
  439. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FEATURE_IGNORABLE_BOUNDED_PAGES.js +15 -0
  440. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts +54 -0
  441. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.d.ts.map +1 -0
  442. package/src/shade/renderer/geometry/virtual/format/page/VGEO_DEFAULT_PAGE_SIZE.js +53 -0
  443. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +13 -2
  444. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
  445. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +14 -2
  446. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +100 -0
  447. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  448. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +113 -0
  449. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  450. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +5 -0
  451. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  452. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +108 -0
  453. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  454. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +23 -0
  455. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  456. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +40 -0
  457. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +228 -0
  458. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -0
  459. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +932 -0
  460. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +176 -0
  461. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -0
  462. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +425 -0
  463. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +241 -0
  464. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +574 -0
  465. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +120 -0
  466. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -0
  467. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +674 -0
  468. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +287 -0
  469. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -0
  470. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +976 -0
  471. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts +42 -0
  472. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.d.ts.map +1 -0
  473. package/src/shade/renderer/geometry/virtual/runtime/VirtualGeometry.js +96 -0
  474. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts +16 -0
  475. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.d.ts.map +1 -0
  476. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_CULL.js +15 -0
  477. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts +19 -0
  478. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -0
  479. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +83 -0
  480. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts +9 -0
  481. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.d.ts.map +1 -0
  482. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_WORKGROUP_SIZE.js +8 -0
  483. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +19 -0
  484. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -0
  485. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +160 -0
  486. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts +3 -0
  487. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -0
  488. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +255 -0
  489. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts +3 -0
  490. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -0
  491. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +80 -0
  492. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts +3 -0
  493. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -0
  494. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +144 -0
  495. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts +3 -0
  496. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -0
  497. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +530 -0
  498. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +39 -0
  499. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -0
  500. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +54 -0
  501. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts +41 -0
  502. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.d.ts.map +1 -0
  503. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_if_enabled.js +56 -0
  504. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts +49 -0
  505. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -0
  506. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +328 -0
  507. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +10 -0
  508. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts.map +1 -0
  509. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +51 -0
  510. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +13 -0
  511. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -0
  512. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +12 -0
  513. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +17 -0
  514. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts.map +1 -0
  515. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +99 -0
  516. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts +9 -0
  517. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.d.ts.map +1 -0
  518. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +8 -0
  519. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +7 -0
  520. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts.map +1 -0
  521. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +27 -0
  522. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts +14 -0
  523. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.d.ts.map +1 -0
  524. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_NONE.js +13 -0
  525. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts +7 -0
  526. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.d.ts.map +1 -0
  527. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_OFFSET.js +35 -0
  528. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts +9 -0
  529. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.d.ts.map +1 -0
  530. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GEOMETRY_ROW_WORDS.js +8 -0
  531. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts +15 -0
  532. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.d.ts.map +1 -0
  533. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_FLAG_SELECTABLE.js +14 -0
  534. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +7 -0
  535. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts.map +1 -0
  536. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +36 -0
  537. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +10 -0
  538. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -0
  539. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +9 -0
  540. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts +11 -0
  541. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.d.ts.map +1 -0
  542. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_OFFSET.js +54 -0
  543. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts +9 -0
  544. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.d.ts.map +1 -0
  545. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_INSTANCE_WORDS.js +8 -0
  546. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts +11 -0
  547. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.d.ts.map +1 -0
  548. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_LEAF_BIT.js +10 -0
  549. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts +7 -0
  550. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.d.ts.map +1 -0
  551. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_OFFSET.js +30 -0
  552. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts +9 -0
  553. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.d.ts.map +1 -0
  554. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NODE_ROW_WORDS.js +8 -0
  555. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts +13 -0
  556. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.d.ts.map +1 -0
  557. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_NO_CHILD_PAGE.js +12 -0
  558. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts +14 -0
  559. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.d.ts.map +1 -0
  560. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_NONE.js +13 -0
  561. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +11 -0
  562. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts.map +1 -0
  563. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +61 -0
  564. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts +9 -0
  565. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -0
  566. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +8 -0
  567. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts +13 -0
  568. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.d.ts.map +1 -0
  569. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_ITEM_WORDS.js +12 -0
  570. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts +9 -0
  571. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.d.ts.map +1 -0
  572. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_GROUP_BIT.js +8 -0
  573. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts +20 -0
  574. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.d.ts.map +1 -0
  575. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_WANT_WORDS.js +19 -0
  576. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts +23 -0
  577. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -0
  578. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +70 -0
  579. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +18 -0
  580. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -0
  581. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +25 -0
  582. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +35 -0
  583. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -0
  584. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +41 -0
  585. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +32 -0
  586. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -0
  587. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +138 -0
  588. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.d.ts +1 -1
  589. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.js +4 -4
  590. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts +1 -3
  591. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts.map +1 -1
  592. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.js +5 -4
  593. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +1 -1
  594. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  595. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +1 -4
  596. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts +8 -3
  597. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts.map +1 -1
  598. package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.js +19 -14
  599. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts.map +1 -1
  600. package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +9 -1
  601. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts +3 -3
  602. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts.map +1 -1
  603. package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.js +12 -5
  604. package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +1 -1
  605. package/src/shade/renderer/light/GPULightCollection.d.ts +29 -0
  606. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  607. package/src/shade/renderer/light/GPULightCollection.js +444 -329
  608. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.d.ts.map +1 -1
  609. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.js +7 -1
  610. package/src/shade/renderer/light/LightCollection.d.ts +29 -1
  611. package/src/shade/renderer/light/LightCollection.d.ts.map +1 -1
  612. package/src/shade/renderer/light/LightCollection.js +50 -1
  613. package/src/shade/renderer/light/make_sunlight.js +2 -2
  614. package/src/shade/renderer/light/model/Light.d.ts +29 -2
  615. package/src/shade/renderer/light/model/Light.d.ts.map +1 -1
  616. package/src/shade/renderer/light/model/Light.js +30 -2
  617. package/src/shade/renderer/light/model/io/light_record_directional.d.ts +3 -1
  618. package/src/shade/renderer/light/model/io/light_record_directional.d.ts.map +1 -1
  619. package/src/shade/renderer/light/model/io/light_record_directional.js +8 -5
  620. package/src/shade/renderer/light/model/io/light_record_point.d.ts +3 -1
  621. package/src/shade/renderer/light/model/io/light_record_point.d.ts.map +1 -1
  622. package/src/shade/renderer/light/model/io/light_record_point.js +5 -2
  623. package/src/shade/renderer/light/model/io/light_record_spot.d.ts +4 -1
  624. package/src/shade/renderer/light/model/io/light_record_spot.d.ts.map +1 -1
  625. package/src/shade/renderer/light/model/io/light_record_spot.js +10 -6
  626. package/src/shade/renderer/light/place_light.d.ts +16 -0
  627. package/src/shade/renderer/light/place_light.d.ts.map +1 -0
  628. package/src/shade/renderer/light/place_light.js +36 -0
  629. package/src/shade/renderer/light/shader_refresh_light_poses.d.ts +44 -0
  630. package/src/shade/renderer/light/shader_refresh_light_poses.d.ts.map +1 -0
  631. package/src/shade/renderer/light/shader_refresh_light_poses.js +154 -0
  632. package/src/shade/renderer/lightmap/GPULightMap.js +1 -1
  633. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
  634. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +12 -14
  635. package/src/shade/renderer/loader/SceneBundle.d.ts +53 -28
  636. package/src/shade/renderer/loader/SceneBundle.d.ts.map +1 -1
  637. package/src/shade/renderer/loader/SceneBundle.js +111 -56
  638. package/src/shade/renderer/loader/SceneNode.d.ts +81 -0
  639. package/src/shade/renderer/loader/SceneNode.d.ts.map +1 -0
  640. package/src/shade/renderer/loader/SceneNode.js +114 -0
  641. package/src/shade/renderer/loader/gltf/load_gltf.d.ts +3 -2
  642. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  643. package/src/shade/renderer/loader/gltf/load_gltf.js +110 -142
  644. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  645. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.d.ts +4 -4
  646. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.d.ts.map +1 -1
  647. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.js +2 -2
  648. package/src/shade/renderer/loader/usd/load_usd.d.ts +3 -2
  649. package/src/shade/renderer/loader/usd/load_usd.d.ts.map +1 -1
  650. package/src/shade/renderer/loader/usd/load_usd.js +4 -5
  651. package/src/shade/renderer/loader/usd/usd_build_scene.d.ts +3 -3
  652. package/src/shade/renderer/loader/usd/usd_build_scene.d.ts.map +1 -1
  653. package/src/shade/renderer/loader/usd/usd_build_scene.js +47 -55
  654. package/src/shade/renderer/material/GPUMaterialManager.js +1 -1
  655. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +5 -4
  656. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  657. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +8 -15
  658. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts +15 -13
  659. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts.map +1 -1
  660. package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.js +40 -21
  661. package/src/shade/renderer/particles/DESIGN.md +53 -50
  662. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +31 -17
  663. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  664. package/src/shade/renderer/particles/GPUParticleSystem.js +54 -91
  665. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +12 -11
  666. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  667. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +12 -11
  668. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +13 -19
  669. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -1
  670. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +19 -25
  671. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +34 -24
  672. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  673. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +53 -40
  674. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +1 -1
  675. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +1 -1
  676. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  677. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  678. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +9 -0
  679. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts.map +1 -1
  680. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.js +2 -1
  681. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.d.ts.map +1 -1
  682. package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.js +5 -2
  683. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  684. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +13 -2
  685. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +1 -1
  686. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +1 -1
  687. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +1 -1
  688. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  689. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +12 -1
  690. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  691. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +10 -0
  692. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +1 -1
  693. package/src/shade/renderer/scene/DynamicMesh.d.ts +13 -4
  694. package/src/shade/renderer/scene/DynamicMesh.d.ts.map +1 -1
  695. package/src/shade/renderer/scene/DynamicMesh.js +14 -4
  696. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +38 -18
  697. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  698. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +112 -60
  699. package/src/shade/renderer/scene/GPUSceneContext.d.ts +69 -44
  700. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  701. package/src/shade/renderer/scene/GPUSceneContext.js +244 -525
  702. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +5 -5
  703. package/src/shade/renderer/scene/NODE3D_STRUCT.js +5 -5
  704. package/src/shade/renderer/scene/Scene.d.ts +18 -60
  705. package/src/shade/renderer/scene/Scene.d.ts.map +1 -1
  706. package/src/shade/renderer/scene/Scene.js +53 -146
  707. package/src/shade/renderer/scene/bvh/StaticSceneBVH.d.ts +24 -3
  708. package/src/shade/renderer/scene/bvh/StaticSceneBVH.d.ts.map +1 -1
  709. package/src/shade/renderer/scene/bvh/StaticSceneBVH.js +53 -13
  710. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts +5 -6
  711. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts.map +1 -1
  712. package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.js +5 -6
  713. package/src/shade/renderer/scene/optimization/scene_optimize.d.ts +10 -2
  714. package/src/shade/renderer/scene/optimization/scene_optimize.d.ts.map +1 -1
  715. package/src/shade/renderer/scene/optimization/scene_optimize.js +266 -230
  716. package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.d.ts +53 -0
  717. package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.d.ts.map +1 -0
  718. package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.js +144 -0
  719. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +227 -0
  720. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -0
  721. package/src/shade/renderer/scene/rows/GPUSceneRows.js +1158 -0
  722. package/src/shade/renderer/scene/rows/place_primitive.d.ts +48 -0
  723. package/src/shade/renderer/scene/rows/place_primitive.d.ts.map +1 -0
  724. package/src/shade/renderer/scene/rows/place_primitive.js +98 -0
  725. package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts +10 -8
  726. package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts.map +1 -1
  727. package/src/shade/renderer/scene/serialization/deserialize_scene.js +24 -27
  728. package/src/shade/renderer/scene/serialization/serialize_scene.d.ts +9 -2
  729. package/src/shade/renderer/scene/serialization/serialize_scene.d.ts.map +1 -1
  730. package/src/shade/renderer/scene/serialization/serialize_scene.js +25 -4
  731. package/src/shade/renderer/scene/verify_gpu_tlas_build.js +2 -2
  732. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts +35 -0
  733. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.d.ts.map +1 -0
  734. package/src/shade/renderer/shader/chunk/geometry/mat3/chunk_mat3_singular_values.js +91 -0
  735. package/src/shade/renderer/shader/chunk/light/DIRECTIONAL_LIGHT_STRUCT.d.ts.map +1 -1
  736. package/src/shade/renderer/shader/chunk/light/DIRECTIONAL_LIGHT_STRUCT.js +5 -0
  737. package/src/shade/renderer/shader/chunk/light/POINT_LIGHT_STRUCT.d.ts.map +1 -1
  738. package/src/shade/renderer/shader/chunk/light/POINT_LIGHT_STRUCT.js +5 -0
  739. package/src/shade/renderer/shader/chunk/light/SPOT_LIGHT_STRUCT.d.ts.map +1 -1
  740. package/src/shade/renderer/shader/chunk/light/SPOT_LIGHT_STRUCT.js +5 -0
  741. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts +39 -0
  742. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
  743. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +112 -64
  744. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +7 -0
  745. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  746. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +1541 -1352
  747. package/src/shade/renderer/shadow/map/PointLightShadowmap.js +1 -1
  748. package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +1 -1
  749. package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +1 -1
  750. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts +29 -0
  751. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts.map +1 -0
  752. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.js +43 -0
  753. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.d.ts +13 -0
  754. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.d.ts.map +1 -0
  755. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.js +12 -0
  756. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts +49 -0
  757. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts.map +1 -0
  758. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.js +194 -0
  759. package/src/shade/renderer/shadow/map/csm_debug_draw_preview.js +1 -1
  760. package/src/shade/renderer/shadow/map/shadowmap_update_score.js +1 -1
  761. package/src/shade/renderer/shadow/ray/RTXShadows.js +1 -1
  762. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +1 -1
  763. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
  764. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +3 -1
  765. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +8 -8
  766. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  767. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +4 -3
  768. package/src/engine/graphics3/instantiate_scene_bundle.d.ts +0 -54
  769. package/src/engine/graphics3/instantiate_scene_bundle.d.ts.map +0 -1
  770. package/src/engine/graphics3/instantiate_scene_bundle.js +0 -164
  771. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts +0 -39
  772. package/src/engine/graphics3/shade_node_to_entity_composition.d.ts.map +0 -1
  773. package/src/engine/graphics3/shade_node_to_entity_composition.js +0 -88
  774. package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts +0 -35
  775. package/src/shade/renderer/animation/compute_skin_world_bounds.d.ts.map +0 -1
  776. package/src/shade/renderer/animation/compute_skin_world_bounds.js +0 -146
  777. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts +0 -96
  778. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.d.ts.map +0 -1
  779. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.js +0 -531
  780. package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts +0 -20
  781. package/src/shade/renderer/animation/pose/pose_evaluate_world.d.ts.map +0 -1
  782. package/src/shade/renderer/animation/pose/pose_evaluate_world.js +0 -76
  783. package/src/shade/renderer/animation/skin_bind_transform.d.ts +0 -25
  784. package/src/shade/renderer/animation/skin_bind_transform.d.ts.map +0 -1
  785. package/src/shade/renderer/animation/skin_bind_transform.js +0 -33
  786. package/src/shade/renderer/animation/skin_frame_defect.d.ts +0 -34
  787. package/src/shade/renderer/animation/skin_frame_defect.d.ts.map +0 -1
  788. package/src/shade/renderer/animation/skin_frame_defect.js +0 -132
  789. package/src/shade/renderer/animation/skin_joint_matrix.d.ts +0 -24
  790. package/src/shade/renderer/animation/skin_joint_matrix.d.ts.map +0 -1
  791. package/src/shade/renderer/animation/skin_joint_matrix.js +0 -46
  792. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts +0 -70
  793. package/src/shade/renderer/animation/skin_normalize_mesh_frame.d.ts.map +0 -1
  794. package/src/shade/renderer/animation/skin_normalize_mesh_frame.js +0 -216
  795. package/src/shade/renderer/scene/InstanceBatch.d.ts +0 -92
  796. package/src/shade/renderer/scene/InstanceBatch.d.ts.map +0 -1
  797. package/src/shade/renderer/scene/InstanceBatch.js +0 -235
  798. package/src/shade/renderer/scene/Mesh.d.ts +0 -55
  799. package/src/shade/renderer/scene/Mesh.d.ts.map +0 -1
  800. package/src/shade/renderer/scene/Mesh.js +0 -168
  801. package/src/shade/renderer/scene/Node3D.d.ts +0 -140
  802. package/src/shade/renderer/scene/Node3D.d.ts.map +0 -1
  803. package/src/shade/renderer/scene/Node3D.js +0 -263
  804. package/src/shade/renderer/scene/SceneNodeBinding.d.ts +0 -52
  805. package/src/shade/renderer/scene/SceneNodeBinding.d.ts.map +0 -1
  806. package/src/shade/renderer/scene/SceneNodeBinding.js +0 -56
  807. package/src/shade/renderer/scene/SkinnedMesh.d.ts +0 -110
  808. package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +0 -1
  809. package/src/shade/renderer/scene/SkinnedMesh.js +0 -170
  810. package/src/shade/renderer/scene/TransformAuthority.d.ts +0 -19
  811. package/src/shade/renderer/scene/TransformAuthority.d.ts.map +0 -1
  812. package/src/shade/renderer/scene/TransformAuthority.js +0 -33
@@ -0,0 +1,1104 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { quat3_multiply } from "../../../../core/geom/3d/quaternion/quat3_multiply.js";
3
+ import { quat3_nlerp } from "../../../../core/geom/3d/quaternion/quat3_nlerp.js";
4
+ import { v3_quaternion_apply } from "../../../../core/geom/vec3/v3_quaternion_apply.js";
5
+ import { v3_quaternion_apply_inverse } from "../../../../core/geom/vec3/v3_quaternion_apply_inverse.js";
6
+ import {
7
+ TransformAttachment
8
+ } from "../../../ecs/transform-attachment/TransformAttachment.js";
9
+ import {
10
+ TransformAttachmentSystem
11
+ } from "../../../ecs/transform-attachment/TransformAttachmentSystem.js";
12
+ import {
13
+ TRANSFORM64_ROTATION_OFFSET,
14
+ TRANSFORM64_TRANSLATION_OFFSET
15
+ } from "../../../ecs/transform/Transform64.js";
16
+ import { t64_evaluate_world } from "../../../ecs/transform/t64_evaluate_world.js";
17
+ import {
18
+ collect_entity_playbacks
19
+ } from "../../../graphics3/pose/collect_entity_playbacks.js";
20
+ import { MeshSystem } from "../../../graphics3/MeshSystem.js";
21
+ import { CLOTH_SELF_RADIUS_MAX_RATIO, CLOTH_SELF_RADIUS_MIN_RATIO } from "../solver/cloth_solver_constants.js";
22
+ import { cloth_air_changed, cloth_sample_air } from "../wind/cloth_sample_air.js";
23
+ import { ClothStepParam } from "../solver/cloth_step_instance.js";
24
+ import { ClothStepResult } from "../solver/ClothState.js";
25
+ import { ClothColliderSystem } from "./ClothColliderSystem.js";
26
+ import { ClothDynamicsFlags } from "./ClothDynamicsFlags.js";
27
+ import { ClothFlags } from "./ClothFlags.js";
28
+ import { ClothInstance } from "./ClothInstance.js";
29
+ import { ClothRig } from "./ClothRig.js";
30
+ import {
31
+ CLOTH_ANCHOR_ROTATION_LIMIT,
32
+ CLOTH_ANCHOR_TRAVEL_REACH,
33
+ CLOTH_SLEEP_SPEED_RATIO,
34
+ CLOTH_SLEEP_STEPS,
35
+ CLOTH_STABILISE_STEPS,
36
+ CLOTH_TELEPORT_FLOOR,
37
+ CLOTH_TELEPORT_REACH,
38
+ cloth_drag_response,
39
+ cloth_velocity_limit,
40
+ cloth_velocity_retention
41
+ } from "./cloth_dynamics_map.js";
42
+ import {
43
+ cloth_colliders_moved,
44
+ cloth_gather_colliders
45
+ } from "./cloth_gather_colliders.js";
46
+ import {
47
+ cloth_dynamics_change_needs_reseed,
48
+ cloth_reparameterise
49
+ } from "./cloth_build_rows.js";
50
+ import { cloth_seed_subtree } from "./cloth_seed_subtree.js";
51
+ import { cloth_seed_rig } from "./cloth_seed_rig.js";
52
+ import { cloth_write_back } from "./cloth_write_back.js";
53
+ import { cloth_write_back_rig } from "./cloth_write_back_rig.js";
54
+
55
+ /**
56
+ * # Every cloth in a scene, and everything a step needs that is not arithmetic
57
+ *
58
+ * One {@link ClothInstance} per {@link Cloth} component, stepped at the fixed
59
+ * rate. Per step, per cloth: move the local frame with the anchor, point the
60
+ * leash rows at where they measure from, gather the colliders that could touch
61
+ * it, step, and put the result back on the subtree. The animated pose the
62
+ * leashes are measured against is not recomposed per step — in the entity path
63
+ * it is constant in the anchor's own frame, and `cloth_seed_subtree.js` bakes
64
+ * it.
65
+ *
66
+ * ## Why this is not a `System`
67
+ *
68
+ * Because two of them drive it. {@link ClothSystem} steps every cloth inline;
69
+ * {@link WorkerClothSystem} hands the arithmetic to a worker and joins it on the
70
+ * next tick. §12 asks those two to produce **bit-identical** results, and the
71
+ * cheapest way to be sure of that is for there to be one copy of everything
72
+ * except the dispatch — so the registry, the seeding, the frame handling, the
73
+ * broadphase and the write-back live here, and the two systems differ only in
74
+ * where {@link ClothWorld#prepare} and {@link ClothWorld#finish} are separated
75
+ * by a thread.
76
+ *
77
+ * That split is also exactly §12's: "arbitrary user-facing work — component
78
+ * reads, `Transform64` sync, index queries — stays on the main thread; the pure
79
+ * numeric step crosses". {@link ensure_seeded} and {@link advance} are the first
80
+ * half, `cloth_step_instance` is the second, {@link finish} is what the result
81
+ * is worth.
82
+ *
83
+ * Seeding is its own call rather than the top of {@link advance} because the
84
+ * worker needs to get between them: a cloth's `ClothState` is what it registers
85
+ * with the worker, so it has to exist — and be acknowledged — before the cloth
86
+ * can be nominated for a step, and a re-seed replaces it and starts that again.
87
+ *
88
+ * ## The parameter block
89
+ *
90
+ * {@link prepare} does not call the step and does not return its arguments; it
91
+ * **writes them into a `Float64` block** the caller supplies. For
92
+ * {@link ClothSystem} that block is a private scratch array and the step follows
93
+ * immediately; for {@link WorkerClothSystem} it is a slice of the shared command
94
+ * region and the step happens on another thread. Neither system ever computes a
95
+ * step parameter of its own, so neither can compute one differently.
96
+ *
97
+ * ## The local frame and the inertia model — §7 P7
98
+ *
99
+ * Particles live in the anchor's own frame. When the anchor moves, the cloth is
100
+ * asked how much of that motion it would like to feel:
101
+ * `ClothDynamics#inertia = 1` keeps every particle's **world** position and
102
+ * velocity, so a cape trails a sprinting character; `0` keeps their **local**
103
+ * ones, so the cloth rides the anchor as though it were standing still. The
104
+ * blend between the two is a lerp in the local frame, which is all the frame
105
+ * change is.
106
+ *
107
+ * The felt motion is limited before the blend, which is what makes "character
108
+ * sprints, cape behaves" a default rather than a tuning exercise, and the limits
109
+ * are derived from the cloth's own reach rather than authored.
110
+ *
111
+ * ## The wind — §10
112
+ *
113
+ * {@link wind} is a source of air and {@link advance} samples it into the
114
+ * cloth's own buffer, once per particle per step. That is the one piece of M6
115
+ * that stays on this thread: a fluid field is an ECS component holding a
116
+ * hundred thousand floats that its own solver rewrites every step, and the
117
+ * *answer* is three floats a particle. `cloth_sample_air.js` carries the
118
+ * decision; the aerodynamic arithmetic built on top of it lives in
119
+ * `cloth_step_instance` with everything else the budget is spent on.
120
+ *
121
+ * A source is optional and additive, like the collider index. With none, the
122
+ * step's drag response is zero, `cloth_step` takes the uniform-gravity path,
123
+ * and a scene produces the bytes M5 measured.
124
+ *
125
+ * ## Teleport — §7 P6
126
+ *
127
+ * Anchor motion past a threshold is not locomotion and is not treated as any
128
+ * amount of it. `ClothFlags.TeleportKeep` carries the shape across, which in a
129
+ * local frame is literally doing nothing; the default re-seeds at the animated
130
+ * pose with zero velocity and opens a stabilisation window in which the
131
+ * velocity limit ramps back from nothing, so the first steps after a reset
132
+ * cannot produce a whip.
133
+ *
134
+ * @author Alex Goldring
135
+ * @copyright Company Named Limited (c) 2026
136
+ */
137
+ export class ClothWorld {
138
+
139
+ /**
140
+ * World gravity, m/s². Rotated into each cloth's local frame per step.
141
+ * @type {Float64Array}
142
+ */
143
+ gravity = new Float64Array([0, -9.81, 0]);
144
+
145
+ /**
146
+ * Live cloths, ordered so that an instance whose anchor sits inside another
147
+ * instance's subtree steps after it.
148
+ * @type {ClothInstance[]}
149
+ */
150
+ instances = [];
151
+
152
+ /**
153
+ * Where a skinned model instance comes from. Anything that answers
154
+ * `instance_of(entity)` with a `PrefabInstance` — skins whose joints
155
+ * are entities — will do, and {@link MeshSystem} is what does in a
156
+ * running engine.
157
+ *
158
+ * Public and assignable because a garment's joints are a *rendering*
159
+ * structure and `MeshSystem` needs a graphics engine, a scene and a loader
160
+ * to exist — so a spec that wants joints without a renderer sets this
161
+ * instead, and gets exactly the interface the system uses.
162
+ *
163
+ * `null` means no rig can seed, which is the same additive shape the
164
+ * collider index has: a scene without one gets M1's cloth rather than an
165
+ * error.
166
+ * @type {{instance_of: function(number): (PrefabInstance|null)}|null}
167
+ */
168
+ models = null;
169
+
170
+ /**
171
+ * @type {EntityManager|null}
172
+ */
173
+ entityManager = null;
174
+
175
+ /**
176
+ * @type {TransformAttachmentSystem|null}
177
+ */
178
+ attachments = null;
179
+
180
+ /**
181
+ * The collider index's owner, or `null` when the manager has none — in
182
+ * which case cloth simply does not collide, which is exactly M1's
183
+ * behaviour and is what makes the collision layer additive rather than a
184
+ * new requirement on every scene.
185
+ * @type {ClothColliderSystem|null}
186
+ */
187
+ colliders = null;
188
+
189
+ /**
190
+ * Where the air comes from — §10. `null` means no air, which is the
191
+ * default and is **additive** in exactly the way the collider index is: a
192
+ * scene without one gets M5's cloth rather than an error, and adding one is
193
+ * the whole of turning wind on.
194
+ *
195
+ * Null rather than a still-air ambient, and the distinction is real. A
196
+ * source that answers zero everywhere is not "no wind": the drag row is a
197
+ * relaxation toward the air, so still air still resists a *moving* cloth,
198
+ * with the normal-facing factor making that resistance anisotropic. That is
199
+ * better physics than `ClothDynamics#damping`'s isotropic decay and it is
200
+ * not free — so it is a thing a scene asks for. What a cloth does in air
201
+ * that is not moving is `damping`'s job (§7 P5, where it is load-bearing);
202
+ * what it does in air that *is* is this.
203
+ *
204
+ * Assign {@link ClothAmbientWind} for weather, {@link ClothFluidWind} to
205
+ * read the fluid simulation and fall back to weather outside it.
206
+ * @type {AbstractClothWind|null}
207
+ */
208
+ wind = null;
209
+
210
+ /**
211
+ * Seconds of fixed step this world has **stepped**, which is the clock a
212
+ * wind source's gust is a function of.
213
+ *
214
+ * Accumulated from `dt` rather than read from a wall clock, because
215
+ * {@link ClothSystem} and {@link WorkerClothSystem} share this object and
216
+ * §12's parity gate is over every byte of every step: two runs of the same
217
+ * scene have the same `dt` sequence and therefore the same weather.
218
+ *
219
+ * **Stepped rather than ticked**, and that distinction is load-bearing
220
+ * rather than pedantic. A cloth under the worker is not advanced until its
221
+ * registration is acknowledged (§39), so the two systems reach a cloth's
222
+ * *first* step at different tick counts — and a clock that counted ticks
223
+ * would hand that cloth a different gust on the same step under the two
224
+ * systems, which is a divergence the parity gate would report and the design
225
+ * would deserve. So the clock moves when {@link advance} first runs in a
226
+ * tick: the world's weather is a function of how much cloth time has
227
+ * passed, not of how long something has been asking.
228
+ * @type {number}
229
+ */
230
+ time = 0;
231
+
232
+ /**
233
+ * Fixed-step seconds this tick owes the clock, consumed by the first
234
+ * {@link advance} — see {@link time}. Zero once spent.
235
+ * @type {number}
236
+ * @private
237
+ */
238
+ __wind_pending = 0;
239
+
240
+ /**
241
+ * Whether a cloth's {@link ClothState} must be backed by a
242
+ * `SharedArrayBuffer`. Stamped onto every instance as it is linked;
243
+ * {@link WorkerClothSystem} sets it, {@link ClothSystem} leaves it alone.
244
+ * @type {boolean}
245
+ */
246
+ shared_state = false;
247
+
248
+ /**
249
+ * @type {Map<number, ClothInstance>}
250
+ * @private
251
+ */
252
+ __by_entity = new Map();
253
+
254
+ /**
255
+ * @type {boolean}
256
+ * @private
257
+ */
258
+ __order_dirty = false;
259
+
260
+ /**
261
+ * Resolve the systems a cloth world reads. Called from the owning system's
262
+ * `startup`.
263
+ *
264
+ * @param {EntityManager} entityManager
265
+ */
266
+ attach(entityManager) {
267
+ this.entityManager = entityManager;
268
+
269
+ this.attachments = entityManager.getSystem(TransformAttachmentSystem);
270
+
271
+ assert.notNull(
272
+ this.attachments,
273
+ 'ClothSystem needs a TransformAttachmentSystem: the subtree walk is its parent-to-children index'
274
+ );
275
+
276
+ // Optional by design. A scene with no ClothColliderSystem gets cloth
277
+ // that does not collide, rather than cloth that throws.
278
+ this.colliders = entityManager.getSystem(ClothColliderSystem) ?? null;
279
+
280
+ if (this.models === null) {
281
+ this.models = entityManager.getSystem(MeshSystem) ?? null;
282
+ }
283
+ }
284
+
285
+ /**
286
+ * @param {Cloth} cloth
287
+ * @param {Transform64} transform
288
+ * @param {number} entity
289
+ * @returns {ClothInstance}
290
+ */
291
+ link(cloth, transform, entity) {
292
+ const instance = new ClothInstance();
293
+
294
+ instance.entity = entity;
295
+ instance.cloth = cloth;
296
+ instance.transform = transform;
297
+ instance.shared_state = this.shared_state;
298
+
299
+ this.instances.push(instance);
300
+ this.__by_entity.set(entity, instance);
301
+
302
+ this.__order_dirty = true;
303
+
304
+ return instance;
305
+ }
306
+
307
+ /**
308
+ * @param {number} entity
309
+ * @returns {ClothInstance|undefined} the instance that was removed
310
+ */
311
+ unlink(entity) {
312
+ const instance = this.__by_entity.get(entity);
313
+
314
+ if (instance === undefined) {
315
+ return undefined;
316
+ }
317
+
318
+ this.__by_entity.delete(entity);
319
+
320
+ const index = this.instances.indexOf(instance);
321
+
322
+ if (index >= 0) {
323
+ this.instances.splice(index, 1);
324
+ }
325
+
326
+ return instance;
327
+ }
328
+
329
+ /**
330
+ * Throw away a cloth's binding so the next step walks its subtree again.
331
+ *
332
+ * The walk is done once, because a rope's links do not come and go. When
333
+ * they do — a chain gains a link, a rig is rebuilt — this is how you say so,
334
+ * and it is the same contract `TransformAttachment#parent` already carries:
335
+ * the structure is immutable while it is attached, and changing it is an
336
+ * explicit act rather than something the engine polls for.
337
+ *
338
+ * @param {number} entity
339
+ * @returns {ClothInstance|undefined} the instance that will re-seed
340
+ */
341
+ reseed(entity) {
342
+ const instance = this.__by_entity.get(entity);
343
+
344
+ if (instance === undefined) {
345
+ return undefined;
346
+ }
347
+
348
+ instance.seeded = false;
349
+ instance.anchor_valid = false;
350
+
351
+ this.__order_dirty = true;
352
+
353
+ return instance;
354
+ }
355
+
356
+ /**
357
+ * Wake a sleeping cloth. Anchor motion and a `ClothDynamics` change do this
358
+ * on their own; a caller that has changed the world in some way the cloth
359
+ * cannot see — M6's wind, for one — says so here.
360
+ *
361
+ * @param {number} entity
362
+ * @returns {void}
363
+ */
364
+ wake(entity) {
365
+ const instance = this.__by_entity.get(entity);
366
+
367
+ if (instance !== undefined) {
368
+ instance.asleep = false;
369
+ instance.still_steps = 0;
370
+ }
371
+ }
372
+
373
+ /**
374
+ * @param {number} entity
375
+ * @returns {ClothInstance|undefined}
376
+ */
377
+ instanceOf(entity) {
378
+ return this.__by_entity.get(entity);
379
+ }
380
+
381
+ /**
382
+ * Everything that happens once per tick rather than once per cloth.
383
+ *
384
+ * @param {EntityComponentDataset} ecd
385
+ * @param {number} dt seconds
386
+ */
387
+ begin(ecd, dt) {
388
+ if (this.__order_dirty) {
389
+ this.#reorder(ecd);
390
+ }
391
+
392
+ // Owed to the clock, and spent by the first `advance` — see {@link time}
393
+ // for why the two are not the same moment. Assigned rather than set, so a
394
+ // world whose source is taken away does not carry a debt.
395
+ this.__wind_pending = this.wind === null ? 0 : dt;
396
+
397
+ // The index is refreshed here rather than in its own system's fixed
398
+ // update, because the engine's ordering cannot put a reader after a
399
+ // writer of the same component and `ClothColliderSystem` reads strictly
400
+ // less than this system does. §4.1's conclusion, applied a second time:
401
+ // the answer is not a third mechanism, it is one call site.
402
+ if (this.colliders !== null) {
403
+ this.colliders.refresh();
404
+ }
405
+ }
406
+
407
+ /**
408
+ * Make sure this cloth has a `ClothState` that matches its current
409
+ * `ClothDynamics`, seeding or re-seeding it if not.
410
+ *
411
+ * @param {ClothInstance} instance
412
+ * @param {EntityComponentDataset} ecd
413
+ * @param {number} dt seconds
414
+ * @returns {boolean} whether the cloth is ready to be stepped — `false` for
415
+ * one that has been refused, or a rig whose model has not loaded yet
416
+ */
417
+ ensure_seeded(instance, ecd, dt) {
418
+ if (instance.refused) {
419
+ return false;
420
+ }
421
+
422
+ if (!instance.seeded) {
423
+ this.#seed(instance, ecd, dt);
424
+
425
+ if (!instance.seeded) {
426
+ // A rig whose model has not finished loading. Nothing is
427
+ // wrong and nothing is retried-with-backoff: the next step
428
+ // asks again, and a model that never loads costs one map
429
+ // lookup a step.
430
+ return false;
431
+ }
432
+ } else if (!instance.cloth.dynamics.equals(instance.dynamics_seen)) {
433
+ if (cloth_dynamics_change_needs_reseed(instance.dynamics_seen, instance.cloth.dynamics)) {
434
+ this.#seed(instance, ecd, dt);
435
+ } else {
436
+ cloth_reparameterise(instance, dt);
437
+ }
438
+
439
+ instance.asleep = false;
440
+ instance.still_steps = 0;
441
+ }
442
+
443
+ return true;
444
+ }
445
+
446
+ /**
447
+ * Take what the step produced: the sleep test, and the pose onto whichever
448
+ * hierarchy this cloth was built on.
449
+ *
450
+ * @param {ClothInstance} instance
451
+ * @param {EntityComponentDataset} ecd
452
+ * @returns {void}
453
+ */
454
+ finish(instance, ecd) {
455
+ const result = instance.state.result;
456
+
457
+ instance.contact_count = result[ClothStepResult.CONTACT_COUNT];
458
+ instance.self_pairs = result[ClothStepResult.SELF_PAIRS];
459
+
460
+ const speed = result[ClothStepResult.SPEED];
461
+
462
+ if ((instance.cloth.flags & ClothFlags.NeverSleep) === 0) {
463
+ if (speed < CLOTH_SLEEP_SPEED_RATIO * instance.reach) {
464
+ instance.still_steps++;
465
+
466
+ if (instance.still_steps >= CLOTH_SLEEP_STEPS) {
467
+ instance.asleep = true;
468
+ }
469
+ } else {
470
+ instance.still_steps = 0;
471
+ }
472
+ }
473
+
474
+ instance.blend_seen = instance.cloth.blend;
475
+
476
+ if (instance.rig === null) {
477
+ cloth_write_back(instance, ecd);
478
+ } else {
479
+ cloth_write_back_rig(instance, ecd);
480
+ }
481
+ }
482
+
483
+ /**
484
+ * Walk whichever hierarchy this cloth is built on.
485
+ *
486
+ * **The discriminator is a component's presence** (§3.1): `Cloth` alone
487
+ * simulates the entity's own transform subtree, `Cloth` + {@link ClothRig}
488
+ * simulates the joints of the skinned model the entity is showing. There is
489
+ * no mode field anywhere, and the solver does not know which ran.
490
+ *
491
+ * A rig can fail to seed for reasons that are not errors — the model has
492
+ * not loaded, or nothing in the manager hands out model instances — and one
493
+ * that does is left unseeded for the next step to try again. A rig that
494
+ * fails for a reason that *is* an error says so once and then stops, because
495
+ * a proxy that does not fit its skin will not start fitting it.
496
+ *
497
+ * @param {ClothInstance} instance
498
+ * @param {EntityComponentDataset} ecd
499
+ * @param {number} dt
500
+ * @private
501
+ */
502
+ #seed(instance, ecd, dt) {
503
+ const rig = ecd.getComponent(instance.entity, ClothRig);
504
+
505
+ if (rig === undefined || rig === null || rig.proxy === null) {
506
+ instance.rig = null;
507
+
508
+ cloth_seed_subtree(instance, ecd, this.attachments, dt);
509
+
510
+ return;
511
+ }
512
+
513
+ if (this.models === null) {
514
+ this.#refuse(instance, `entity ${instance.entity} has a ClothRig and nothing hands out model instances`);
515
+
516
+ return;
517
+ }
518
+
519
+ const model = this.models.instance_of(instance.entity);
520
+
521
+ if (model === null || model === undefined) {
522
+ // Still loading. Not an error, and not worth a message.
523
+ return;
524
+ }
525
+
526
+ const skin = model.skins[rig.skin];
527
+
528
+ const error = rig.proxy.checkAgainst(skin);
529
+
530
+ if (error !== "") {
531
+ this.#refuse(instance, `entity ${instance.entity}: ${error}`);
532
+
533
+ return;
534
+ }
535
+
536
+ instance.rig = rig;
537
+
538
+ cloth_seed_rig(instance, rig.proxy, skin.joints, ecd, dt);
539
+ }
540
+
541
+ /**
542
+ * Say once why a rig will not seed, and stop asking.
543
+ *
544
+ * @param {ClothInstance} instance
545
+ * @param {string} message
546
+ * @private
547
+ */
548
+ #refuse(instance, message) {
549
+ if (instance.refused) {
550
+ return;
551
+ }
552
+
553
+ instance.refused = true;
554
+
555
+ console.warn(`ClothSystem: ${message}`);
556
+ }
557
+
558
+ /**
559
+ * Depth-first order by hierarchy depth, so a nested cloth reads an anchor
560
+ * the cloth above it has already written.
561
+ *
562
+ * @param {EntityComponentDataset} ecd
563
+ * @private
564
+ */
565
+ #reorder(ecd) {
566
+ const instances = this.instances;
567
+
568
+ for (let i = 0; i < instances.length; i++) {
569
+ const instance = instances[i];
570
+
571
+ let depth = 0;
572
+ let entity = instance.entity;
573
+
574
+ // Bounded by the number of entities; a cycle in the attachment
575
+ // graph is not this system's to diagnose, but it is this loop's to
576
+ // survive.
577
+ for (let guard = 0; guard < 4096; guard++) {
578
+ const attachment = ecd.getComponent(entity, TransformAttachment);
579
+
580
+ if (attachment === undefined) {
581
+ break;
582
+ }
583
+
584
+ entity = attachment.parent;
585
+ depth++;
586
+ }
587
+
588
+ instance.depth = depth;
589
+ }
590
+
591
+ instances.sort((a, b) => a.depth - b.depth);
592
+
593
+ this.__order_dirty = false;
594
+ }
595
+
596
+ /**
597
+ * Carry one seeded cloth to the edge of its step and write the parameters
598
+ * the step will run on: whatever the anchor did to the local frame, where
599
+ * the leash rows measure from, and the colliders within reach.
600
+ *
601
+ * @param {ClothInstance} instance
602
+ * @param {number} dt seconds
603
+ * @param {Float64Array} params
604
+ * @param {number} offset first word of this cloth's block in `params`
605
+ * @returns {boolean} whether the cloth should be stepped — `false` for one
606
+ * that is asleep, and then nothing has been written to `params`
607
+ */
608
+ advance(instance, dt, params, offset) {
609
+ if (this.__wind_pending !== 0) {
610
+ this.time += this.__wind_pending;
611
+
612
+ this.__wind_pending = 0;
613
+
614
+ // Once a tick rather than once a cloth: a source that reads the
615
+ // dataset — every live fluid field and its world box — walks it here
616
+ // and every cloth then reads the cache. `FluidSystem` makes the same
617
+ // trade for its own effector broadphase.
618
+ //
619
+ // Here rather than in `begin` because of the clock, and {@link time}
620
+ // is where that is argued. Above the sleep tests deliberately: a
621
+ // world whose every cloth is asleep still has weather, and §10's
622
+ // "sleep wakes on a wind change" is the whole reason it needs to.
623
+ if (this.wind !== null) {
624
+ this.wind.begin(
625
+ this.time,
626
+ this.entityManager === null ? null : this.entityManager.dataset
627
+ );
628
+ }
629
+ }
630
+
631
+ const transform = instance.rig === null
632
+ ? instance.transform
633
+ : this.#anchor_pose(instance);
634
+
635
+ const tx = transform[TRANSFORM64_TRANSLATION_OFFSET];
636
+ const ty = transform[TRANSFORM64_TRANSLATION_OFFSET + 1];
637
+ const tz = transform[TRANSFORM64_TRANSLATION_OFFSET + 2];
638
+
639
+ const qx = transform[TRANSFORM64_ROTATION_OFFSET];
640
+ const qy = transform[TRANSFORM64_ROTATION_OFFSET + 1];
641
+ const qz = transform[TRANSFORM64_ROTATION_OFFSET + 2];
642
+ const qw = transform[TRANSFORM64_ROTATION_OFFSET + 3];
643
+
644
+ const previous_translation = instance.anchor_translation;
645
+ const previous_rotation = instance.anchor_rotation;
646
+
647
+ if (instance.cloth.blend !== instance.blend_seen) {
648
+ instance.asleep = false;
649
+ instance.still_steps = 0;
650
+ }
651
+
652
+ const moved = instance.anchor_valid && (
653
+ previous_translation[0] !== tx
654
+ || previous_translation[1] !== ty
655
+ || previous_translation[2] !== tz
656
+ || previous_rotation[0] !== qx
657
+ || previous_rotation[1] !== qy
658
+ || previous_rotation[2] !== qz
659
+ || previous_rotation[3] !== qw
660
+ );
661
+
662
+ if (moved) {
663
+ instance.asleep = false;
664
+ instance.still_steps = 0;
665
+ }
666
+
667
+ if (instance.asleep && this.colliders !== null && instance.state !== null) {
668
+ // §7 P5's "wake on collider motion". A sleeping cloth is neither
669
+ // stepped nor written back, so something has to notice the world it
670
+ // was resting against moving out from under it, and a broadphase
671
+ // query plus a pose comparison is three orders of magnitude cheaper
672
+ // than the step it decides whether to skip.
673
+ if (cloth_colliders_moved(instance, this.colliders.index)) {
674
+ instance.asleep = false;
675
+ instance.still_steps = 0;
676
+ }
677
+ }
678
+
679
+ if (instance.asleep && this.wind !== null && instance.state !== null
680
+ && instance.cloth.dynamics.drag > 0) {
681
+ // §10's "sleep wakes on a wind change, so a settled banner does not
682
+ // sleep through a gust". One sample at the cloth's centre against
683
+ // the air the last applied step saw — the same shape as the collider
684
+ // test above, and the same argument: asking is orders of magnitude
685
+ // cheaper than the step it decides whether to skip.
686
+ if (cloth_air_changed(
687
+ instance.state, this.wind,
688
+ instance.anchor_translation, instance.anchor_rotation,
689
+ instance.air_seen, CLOTH_SLEEP_SPEED_RATIO * instance.reach
690
+ )) {
691
+ instance.asleep = false;
692
+ instance.still_steps = 0;
693
+ }
694
+ }
695
+
696
+ if (instance.asleep) {
697
+ // Nothing is stepped and nothing is written: the pose on the
698
+ // subtree is already the pose, and rewriting it is what would make
699
+ // §7 P5's "bit-identical across the following 300 steps" an
700
+ // aspiration rather than a fact.
701
+ return false;
702
+ }
703
+
704
+ if (instance.anchor_valid) {
705
+ const displacement = Math.hypot(tx - previous_translation[0], ty - previous_translation[1], tz - previous_translation[2]);
706
+
707
+ const teleport = displacement > Math.max(
708
+ CLOTH_TELEPORT_REACH * instance.reach,
709
+ CLOTH_TELEPORT_FLOOR
710
+ );
711
+
712
+ if (teleport) {
713
+ this.#teleport(instance);
714
+ } else {
715
+ move_local_frame(
716
+ instance,
717
+ tx, ty, tz, qx, qy, qz, qw,
718
+ previous_translation, previous_rotation
719
+ );
720
+ }
721
+ }
722
+
723
+ previous_translation[0] = tx;
724
+ previous_translation[1] = ty;
725
+ previous_translation[2] = tz;
726
+
727
+ previous_rotation[0] = qx;
728
+ previous_rotation[1] = qy;
729
+ previous_rotation[2] = qz;
730
+ previous_rotation[3] = qw;
731
+
732
+ instance.anchor_valid = true;
733
+
734
+ refresh_leash_targets(instance);
735
+
736
+ const dynamics = instance.cloth.dynamics;
737
+
738
+ // Gravity is a world vector and the solve is in the anchor's frame.
739
+ const gravity = this.gravity;
740
+
741
+ v3_quaternion_apply_inverse(LOCAL_GRAVITY, 0, gravity[0], gravity[1], gravity[2], qx, qy, qz, qw);
742
+
743
+ const state = instance.state;
744
+
745
+ const limit = cloth_velocity_limit(
746
+ instance.shortest_row, dynamics.substeps, dynamics.iterations, dt
747
+ );
748
+
749
+ state.contact_radius = dynamics.thickness;
750
+
751
+ if (this.colliders !== null) {
752
+ // The gather's margin is how far a particle may travel this step,
753
+ // which is the velocity clamp read as a distance — the quantity it
754
+ // was built out of (`cloth_dynamics_map.js`).
755
+ cloth_gather_colliders(instance, this.colliders.index, limit * dt);
756
+ } else {
757
+ state.collider_count = 0;
758
+ }
759
+
760
+ // §10. The one piece of a cloth's step that has to read the world and
761
+ // cannot cross to a worker, so it runs here in both systems and what
762
+ // crosses is the answer — three floats a particle, written into a region
763
+ // of the cloth's own shared buffer. `cloth_sample_air.js` is the
764
+ // argument.
765
+ let drag_response = 0;
766
+
767
+ if (this.wind !== null && dynamics.drag > 0) {
768
+ drag_response = cloth_drag_response(dynamics.drag, dt);
769
+
770
+ instance.air_varies = cloth_sample_air(
771
+ state, this.wind,
772
+ instance.anchor_translation, instance.anchor_rotation,
773
+ instance.air_seen
774
+ );
775
+ } else {
776
+ instance.air_varies = false;
777
+ }
778
+
779
+ params[offset + ClothStepParam.DRAG_RESPONSE] = drag_response;
780
+
781
+ const self_collision = (dynamics.flags & ClothDynamicsFlags.SelfCollision) !== 0;
782
+
783
+ params[offset + ClothStepParam.DT] = dt;
784
+ params[offset + ClothStepParam.GRAVITY_X] = LOCAL_GRAVITY[0];
785
+ params[offset + ClothStepParam.GRAVITY_Y] = LOCAL_GRAVITY[1];
786
+ params[offset + ClothStepParam.GRAVITY_Z] = LOCAL_GRAVITY[2];
787
+ params[offset + ClothStepParam.SUBSTEPS] = dynamics.substeps;
788
+ params[offset + ClothStepParam.ITERATIONS] = dynamics.iterations;
789
+ params[offset + ClothStepParam.RETENTION] = cloth_velocity_retention(dynamics.damping, dt);
790
+ params[offset + ClothStepParam.CONTACT_RADIUS] = dynamics.thickness;
791
+ params[offset + ClothStepParam.COLLIDER_COUNT] = state.collider_count;
792
+ params[offset + ClothStepParam.SELF_COLLISION] = self_collision ? 1 : 0;
793
+
794
+ // Half the shortest row, so the row's diameter is one particle
795
+ // spacing. `ClothState#self_radius` carries why the fabric's own
796
+ // thickness is the wrong length here and `MEASUREMENTS.md` §31 is the
797
+ // sweep that settled it. A fabric thicker than its proxy is coarse
798
+ // keeps its thickness — and is then clamped under the closest pair
799
+ // the proxy has with no row between them, because a diameter that
800
+ // reaches that pair puts a cloth which is not folded at all in
801
+ // permanent contact with itself (§36, §37).
802
+ params[offset + ClothStepParam.SELF_RADIUS] = self_collision
803
+ ? Math.min(
804
+ Math.max(dynamics.thickness, instance.shortest_row * CLOTH_SELF_RADIUS_MIN_RATIO),
805
+ instance.closest_free_pair * CLOTH_SELF_RADIUS_MAX_RATIO
806
+ )
807
+ : 0;
808
+
809
+ // Ramp back from nothing over the window. The first step after a
810
+ // reset is allowed no velocity at all, which is what stops a
811
+ // re-seeded cloth from snapping taut and whipping.
812
+ //
813
+ // After the gather, which wants the cloth's *unramped* reach: the
814
+ // broadphase margin is how far a particle could travel, and a cloth
815
+ // that is being held still for three steps is still a cloth whose
816
+ // colliders have to be found before it is let go.
817
+ let clamp_limit = limit;
818
+
819
+ if (instance.stabilise_remaining > 0) {
820
+ clamp_limit *= (CLOTH_STABILISE_STEPS - instance.stabilise_remaining) / CLOTH_STABILISE_STEPS;
821
+
822
+ instance.stabilise_remaining--;
823
+ }
824
+
825
+ params[offset + ClothStepParam.VELOCITY_LIMIT] = clamp_limit;
826
+
827
+ return true;
828
+ }
829
+
830
+ /**
831
+ * The anchor joint's world pose, computed on the CPU from the clips the
832
+ * entity is playing.
833
+ *
834
+ * **Computed, never read back**, for two reasons that are both the engine's
835
+ * own. A joint of an animated skeleton is the GPU's (`GPUStateAuthority`),
836
+ * so nothing maintains its CPU-side world and reading it gives its rest
837
+ * pose under whatever the CPU last composed. And GPU readback is a frame
838
+ * late and asynchronous, so anything depending on it would depend on frame
839
+ * pacing — which is why `query_entity_node_world_pose` exists and is
840
+ * documented as the only sanctioned way to ask this question. A cape and a
841
+ * scabbard on the same shoulder get their answer from the same evaluator,
842
+ * off the same clock, which is what keeps them on the same shoulder.
843
+ *
844
+ * @param {ClothInstance} instance
845
+ * @returns {Transform64}
846
+ * @private
847
+ */
848
+ #anchor_pose(instance) {
849
+ const playbacks = PLAYBACKS;
850
+
851
+ playbacks.length = 0;
852
+
853
+ collect_entity_playbacks(playbacks, this.entityManager, instance.entity);
854
+
855
+ t64_evaluate_world(instance.anchor_pose, this.entityManager.dataset, instance.node_joint[0], playbacks);
856
+
857
+ playbacks.length = 0;
858
+
859
+ return instance.anchor_pose;
860
+ }
861
+
862
+ /**
863
+ * @param {ClothInstance} instance
864
+ * @private
865
+ */
866
+ #teleport(instance) {
867
+ instance.teleport_count++;
868
+
869
+ if ((instance.cloth.flags & ClothFlags.TeleportKeep) !== 0) {
870
+ // `Keep` carries the cloth's shape across the jump. Particles are
871
+ // stored relative to the anchor, so that is exactly what happens if
872
+ // this function does nothing to them — the frame moved and they did
873
+ // not, which is MagicaCloth2's rigid delta expressed in the frame
874
+ // that makes it free.
875
+ return;
876
+ }
877
+
878
+ const state = instance.state;
879
+
880
+ const node_count = instance.node_count;
881
+ const animated = instance.animated_position;
882
+ const particle_of_node = instance.particle_of_node;
883
+
884
+ for (let node = 0; node < node_count; node++) {
885
+ const p = particle_of_node[node] * 3;
886
+ const n = node * 3;
887
+
888
+ state.position[p] = animated[n];
889
+ state.position[p + 1] = animated[n + 1];
890
+ state.position[p + 2] = animated[n + 2];
891
+ }
892
+
893
+ state.position_previous.set(state.position);
894
+ state.velocity.fill(0);
895
+ state.inertia_blend.fill(0);
896
+
897
+ // The multipliers describe forces in a configuration that no longer
898
+ // exists. Carrying them across would apply the old pose's tension to
899
+ // the new one on the first iteration, which is a whip with extra steps.
900
+ state.stretch_lambda.fill(0);
901
+ state.bend_lambda.fill(0);
902
+ state.leash_lambda.fill(0);
903
+
904
+ instance.stabilise_remaining = CLOTH_STABILISE_STEPS;
905
+ }
906
+ }
907
+
908
+ /**
909
+ * The clip set handed to the pose evaluator, rebuilt per call from the
910
+ * animation systems' own entries. Nothing in here outlives the call.
911
+ * @type {PosePlayback[]}
912
+ * @private
913
+ */
914
+ const PLAYBACKS = [];
915
+
916
+ /**
917
+ * @type {Float64Array}
918
+ * @private
919
+ */
920
+ const LOCAL_GRAVITY = new Float64Array(3);
921
+
922
+ /**
923
+ * @type {Float64Array}
924
+ * @private
925
+ */
926
+ const FRAME = new Float64Array(8);
927
+
928
+ /**
929
+ * Carry the particles across a change of anchor pose, by however much of it the
930
+ * fabric is willing to feel. §7 P7.
931
+ *
932
+ * A particle at local `p` was at world `t_prev + q_prev·p`. Holding that world
933
+ * position fixed, its local coordinates become `D + Q·p` with
934
+ * `D = q_now⁻¹·(t_prev − t_now)` and `Q = q_now⁻¹ ⊗ q_prev`. Feeling *all* of
935
+ * the anchor's motion is taking that; feeling *none* is leaving `p` alone; and
936
+ * `inertia` is the lerp between them. Velocity is carried the same way, minus
937
+ * the translation, since a translation of the frame does not rotate a vector.
938
+ *
939
+ * `D` and `Q` are limited before the lerp. The limits are the cloth's own reach
940
+ * per step and a fixed angle per step, which is what makes an anchor that
941
+ * teleports a metre — or spins — something a cape *lags behind* rather than
942
+ * something it is fired out of.
943
+ *
944
+ * @param {ClothInstance} instance
945
+ * @param {number} tx
946
+ * @param {number} ty
947
+ * @param {number} tz
948
+ * @param {number} qx
949
+ * @param {number} qy
950
+ * @param {number} qz
951
+ * @param {number} qw
952
+ * @param {Float64Array} previous_translation
953
+ * @param {Float64Array} previous_rotation
954
+ * @private
955
+ */
956
+ function move_local_frame(
957
+ instance,
958
+ tx, ty, tz, qx, qy, qz, qw,
959
+ previous_translation, previous_rotation
960
+ ) {
961
+ let inertia = instance.cloth.dynamics.inertia;
962
+
963
+ if (inertia <= 0) {
964
+ return;
965
+ }
966
+
967
+ if (inertia > 1) {
968
+ inertia = 1;
969
+ }
970
+
971
+ v3_quaternion_apply_inverse(
972
+ FRAME, 0,
973
+ previous_translation[0] - tx,
974
+ previous_translation[1] - ty,
975
+ previous_translation[2] - tz,
976
+ qx, qy, qz, qw
977
+ );
978
+
979
+ const travel_limit = CLOTH_ANCHOR_TRAVEL_REACH * instance.reach;
980
+
981
+ const travel = Math.hypot(FRAME[0], FRAME[1], FRAME[2]);
982
+
983
+ if (travel > travel_limit && travel > 0) {
984
+ const scale = travel_limit / travel;
985
+
986
+ FRAME[0] *= scale;
987
+ FRAME[1] *= scale;
988
+ FRAME[2] *= scale;
989
+ }
990
+
991
+ quat3_multiply(
992
+ FRAME, 4,
993
+ -qx, -qy, -qz, qw,
994
+ previous_rotation[0], previous_rotation[1], previous_rotation[2], previous_rotation[3]
995
+ );
996
+
997
+ // `|w|` is `cos(θ/2)`, so this is the angle test without an `acos`.
998
+ const half_angle_cos = FRAME[7] < 0 ? -FRAME[7] : FRAME[7];
999
+
1000
+ if (half_angle_cos < Math.cos(CLOTH_ANCHOR_ROTATION_LIMIT * 0.5)) {
1001
+ const angle = 2 * Math.acos(half_angle_cos > 1 ? 1 : half_angle_cos);
1002
+
1003
+ quat3_nlerp(
1004
+ FRAME, 4,
1005
+ 0, 0, 0, 1,
1006
+ FRAME[4], FRAME[5], FRAME[6], FRAME[7],
1007
+ CLOTH_ANCHOR_ROTATION_LIMIT / angle
1008
+ );
1009
+ }
1010
+
1011
+ const state = instance.state;
1012
+
1013
+ const particle_count = state.particle_count;
1014
+
1015
+ const position = state.position;
1016
+ const velocity = state.velocity;
1017
+
1018
+ const dx = FRAME[0];
1019
+ const dy = FRAME[1];
1020
+ const dz = FRAME[2];
1021
+
1022
+ const rx = FRAME[4];
1023
+ const ry = FRAME[5];
1024
+ const rz = FRAME[6];
1025
+ const rw = FRAME[7];
1026
+
1027
+ for (let i = 0; i < particle_count; i++) {
1028
+ const p = i * 3;
1029
+
1030
+ v3_quaternion_apply(CARRIED, 0, position[p], position[p + 1], position[p + 2], rx, ry, rz, rw);
1031
+
1032
+ position[p] += inertia * (CARRIED[0] + dx - position[p]);
1033
+ position[p + 1] += inertia * (CARRIED[1] + dy - position[p + 1]);
1034
+ position[p + 2] += inertia * (CARRIED[2] + dz - position[p + 2]);
1035
+
1036
+ v3_quaternion_apply(CARRIED, 0, velocity[p], velocity[p + 1], velocity[p + 2], rx, ry, rz, rw);
1037
+
1038
+ velocity[p] += inertia * (CARRIED[0] - velocity[p]);
1039
+ velocity[p + 1] += inertia * (CARRIED[1] - velocity[p + 1]);
1040
+ velocity[p + 2] += inertia * (CARRIED[2] - velocity[p + 2]);
1041
+ }
1042
+
1043
+ // The anchor is pinned and is the origin of the frame it anchors, so it is
1044
+ // the one particle that must not be carried anywhere.
1045
+ const anchor = instance.particle_of_node[0] * 3;
1046
+
1047
+ position[anchor] = 0;
1048
+ position[anchor + 1] = 0;
1049
+ position[anchor + 2] = 0;
1050
+
1051
+ velocity[anchor] = 0;
1052
+ velocity[anchor + 1] = 0;
1053
+ velocity[anchor + 2] = 0;
1054
+ }
1055
+
1056
+ /**
1057
+ * @type {Float64Array}
1058
+ * @private
1059
+ */
1060
+ const CARRIED = new Float64Array(3);
1061
+
1062
+ /**
1063
+ * Point every leash row at where it measures from: a slack row at the
1064
+ * particle's animated position, a tether at the anchor.
1065
+ *
1066
+ * @param {ClothInstance} instance
1067
+ * @private
1068
+ */
1069
+ function refresh_leash_targets(instance) {
1070
+ const state = instance.state;
1071
+
1072
+ const target = state.leash_target;
1073
+
1074
+ const animated = instance.animated_position;
1075
+
1076
+ const anchor = instance.particle_of_node[0] * 3;
1077
+
1078
+ const anchor_x = state.position[anchor];
1079
+ const anchor_y = state.position[anchor + 1];
1080
+ const anchor_z = state.position[anchor + 2];
1081
+
1082
+ const node_count = instance.node_count;
1083
+
1084
+ const slack_row = instance.slack_row;
1085
+ const tether_row = instance.tether_row;
1086
+
1087
+ for (let node = 1; node < node_count; node++) {
1088
+ const tether = tether_row[node];
1089
+
1090
+ if (tether >= 0) {
1091
+ target[tether * 3] = anchor_x;
1092
+ target[tether * 3 + 1] = anchor_y;
1093
+ target[tether * 3 + 2] = anchor_z;
1094
+ }
1095
+
1096
+ const slack = slack_row[node];
1097
+
1098
+ if (slack >= 0) {
1099
+ target[slack * 3] = animated[node * 3];
1100
+ target[slack * 3 + 1] = animated[node * 3 + 1];
1101
+ target[slack * 3 + 2] = animated[node * 3 + 2];
1102
+ }
1103
+ }
1104
+ }