@zephyr3d/scene 0.9.27 → 0.10.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 (502) hide show
  1. package/README.md +60 -27
  2. package/dist/animation/animation_bank.js +634 -0
  3. package/dist/animation/animation_bank.js.map +1 -0
  4. package/dist/animation/animation_bank_gpu.js +256 -0
  5. package/dist/animation/animation_bank_gpu.js.map +1 -0
  6. package/dist/animation/animationset.js +54 -0
  7. package/dist/animation/animationset.js.map +1 -1
  8. package/dist/animation/cloth/gpu_cloth_component.js +406 -0
  9. package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
  10. package/dist/animation/cloth/gpu_cloth_system.js +332 -202
  11. package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
  12. package/dist/animation/gpu_animation_driver.js +289 -0
  13. package/dist/animation/gpu_animation_driver.js.map +1 -0
  14. package/dist/animation/joint_dynamics/collision.js +112 -1
  15. package/dist/animation/joint_dynamics/collision.js.map +1 -1
  16. package/dist/animation/joint_dynamics/controller.js +6 -0
  17. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  18. package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
  19. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  20. package/dist/animation/joint_dynamics/solver.js +50 -12
  21. package/dist/animation/joint_dynamics/solver.js.map +1 -1
  22. package/dist/animation/joint_dynamics/types.js.map +1 -1
  23. package/dist/animation/skeleton.js +279 -55
  24. package/dist/animation/skeleton.js.map +1 -1
  25. package/dist/animation/skin_palette_atlas.js +252 -0
  26. package/dist/animation/skin_palette_atlas.js.map +1 -0
  27. package/dist/animation/spring/multi_chain_spring_system.js +298 -38
  28. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  29. package/dist/animation/spring/spring_chain.js +2 -0
  30. package/dist/animation/spring/spring_chain.js.map +1 -1
  31. package/dist/animation/spring/spring_collider.js +159 -21
  32. package/dist/animation/spring/spring_collider.js.map +1 -1
  33. package/dist/animation/spring/spring_particle.js +1 -0
  34. package/dist/animation/spring/spring_particle.js.map +1 -1
  35. package/dist/animation/spring/spring_solver.js +173 -0
  36. package/dist/animation/spring/spring_solver.js.map +1 -0
  37. package/dist/animation/spring/spring_system.js +249 -24
  38. package/dist/animation/spring/spring_system.js.map +1 -1
  39. package/dist/animation/spring_modifier.js +32 -1
  40. package/dist/animation/spring_modifier.js.map +1 -1
  41. package/dist/app/app.js +26 -0
  42. package/dist/app/app.js.map +1 -1
  43. package/dist/app/engine.js +86 -15
  44. package/dist/app/engine.js.map +1 -1
  45. package/dist/app/gamepad.js +191 -0
  46. package/dist/app/gamepad.js.map +1 -0
  47. package/dist/app/inputactions.js +271 -0
  48. package/dist/app/inputactions.js.map +1 -0
  49. package/dist/app/inputmgr.js +331 -22
  50. package/dist/app/inputmgr.js.map +1 -1
  51. package/dist/app/loading.js +138 -0
  52. package/dist/app/loading.js.map +1 -0
  53. package/dist/app/pipelinecache.js +209 -0
  54. package/dist/app/pipelinecache.js.map +1 -0
  55. package/dist/app/runtimescript.js +25 -0
  56. package/dist/app/runtimescript.js.map +1 -1
  57. package/dist/app/scriptingsystem.js +54 -0
  58. package/dist/app/scriptingsystem.js.map +1 -1
  59. package/dist/app/scriptregistry.js +7 -2
  60. package/dist/app/scriptregistry.js.map +1 -1
  61. package/dist/asset/asset_manifest.js +59 -0
  62. package/dist/asset/asset_manifest.js.map +1 -0
  63. package/dist/asset/asset_preload.js +258 -0
  64. package/dist/asset/asset_preload.js.map +1 -0
  65. package/dist/asset/assetmanager.js +117 -65
  66. package/dist/asset/assetmanager.js.map +1 -1
  67. package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
  68. package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
  69. package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
  70. package/dist/asset/loaders/ktx2/basis_location.js +17 -0
  71. package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
  72. package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
  73. package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
  74. package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
  75. package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
  76. package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
  77. package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
  78. package/dist/asset/mesh_lod_builder.js +104 -0
  79. package/dist/asset/mesh_lod_builder.js.map +1 -0
  80. package/dist/asset/mesh_settings.js +111 -0
  81. package/dist/asset/mesh_settings.js.map +1 -0
  82. package/dist/asset/meshopt_decoder.js +18 -0
  83. package/dist/asset/meshopt_decoder.js.map +1 -0
  84. package/dist/asset/meshopt_simplifier.js +26 -0
  85. package/dist/asset/meshopt_simplifier.js.map +1 -0
  86. package/dist/asset/model.js +171 -1
  87. package/dist/asset/model.js.map +1 -1
  88. package/dist/asset/texture_settings.js +231 -0
  89. package/dist/asset/texture_settings.js.map +1 -0
  90. package/dist/asset/zmsh_binary.js +131 -0
  91. package/dist/asset/zmsh_binary.js.map +1 -0
  92. package/dist/asset/zsdf_binary.js +111 -0
  93. package/dist/asset/zsdf_binary.js.map +1 -0
  94. package/dist/blitter/bilateralblur.js +1 -2
  95. package/dist/blitter/bilateralblur.js.map +1 -1
  96. package/dist/blitter/gaussianblur.js +1 -6
  97. package/dist/blitter/gaussianblur.js.map +1 -1
  98. package/dist/camera/base.js +31 -10
  99. package/dist/camera/base.js.map +1 -1
  100. package/dist/camera/camera.js +104 -178
  101. package/dist/camera/camera.js.map +1 -1
  102. package/dist/camera/follow.js +342 -0
  103. package/dist/camera/follow.js.map +1 -0
  104. package/dist/camera/fps.js +9 -7
  105. package/dist/camera/fps.js.map +1 -1
  106. package/dist/camera/orbit.js +46 -19
  107. package/dist/camera/orbit.js.map +1 -1
  108. package/dist/index.d.ts +25436 -15990
  109. package/dist/index.js +65 -11
  110. package/dist/index.js.map +1 -1
  111. package/dist/material/blinn.js +3 -0
  112. package/dist/material/blinn.js.map +1 -1
  113. package/dist/material/eye.js +1 -1
  114. package/dist/material/eye.js.map +1 -1
  115. package/dist/material/hair.js +2 -3
  116. package/dist/material/hair.js.map +1 -1
  117. package/dist/material/lambert.js +4 -1
  118. package/dist/material/lambert.js.map +1 -1
  119. package/dist/material/material.js +66 -4
  120. package/dist/material/material.js.map +1 -1
  121. package/dist/material/meshmaterial.js +118 -45
  122. package/dist/material/meshmaterial.js.map +1 -1
  123. package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
  124. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  125. package/dist/material/mixins/lightmodel/lambert.js +1 -1
  126. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  127. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
  128. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  129. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
  130. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  131. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
  132. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  133. package/dist/material/mixins/lit.js +191 -83
  134. package/dist/material/mixins/lit.js.map +1 -1
  135. package/dist/material/mixins/pbr/common.js +31 -206
  136. package/dist/material/mixins/pbr/common.js.map +1 -1
  137. package/dist/material/mtoon.js +1 -1
  138. package/dist/material/mtoon.js.map +1 -1
  139. package/dist/material/pbrmr.js +3 -0
  140. package/dist/material/pbrmr.js.map +1 -1
  141. package/dist/material/pbrsg.js +3 -0
  142. package/dist/material/pbrsg.js.map +1 -1
  143. package/dist/material/sdf_debug.js +78 -0
  144. package/dist/material/sdf_debug.js.map +1 -0
  145. package/dist/material/shader/helper.js +333 -191
  146. package/dist/material/shader/helper.js.map +1 -1
  147. package/dist/material/shader/terrain_blend.js +204 -43
  148. package/dist/material/shader/terrain_blend.js.map +1 -1
  149. package/dist/material/skin.js +331 -297
  150. package/dist/material/skin.js.map +1 -1
  151. package/dist/material/skinprofile.js +1058 -0
  152. package/dist/material/skinprofile.js.map +1 -0
  153. package/dist/material/sss.js +353 -0
  154. package/dist/material/sss.js.map +1 -0
  155. package/dist/material/sss_kernel.js +265 -0
  156. package/dist/material/sss_kernel.js.map +1 -0
  157. package/dist/material/sssprofile.js +879 -0
  158. package/dist/material/sssprofile.js.map +1 -0
  159. package/dist/material/subsurfaceprofile.js +4 -8
  160. package/dist/material/subsurfaceprofile.js.map +1 -1
  161. package/dist/material/terrain-cm.js +464 -188
  162. package/dist/material/terrain-cm.js.map +1 -1
  163. package/dist/material/unlit.js +3 -0
  164. package/dist/material/unlit.js.map +1 -1
  165. package/dist/material/water.js +1261 -1438
  166. package/dist/material/water.js.map +1 -1
  167. package/dist/node_modules/meshoptimizer/LICENSE +21 -0
  168. package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
  169. package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
  170. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
  171. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
  172. package/dist/physics/character.js +226 -0
  173. package/dist/physics/character.js.map +1 -0
  174. package/dist/physics/collider.js +209 -0
  175. package/dist/physics/collider.js.map +1 -0
  176. package/dist/physics/events.js +79 -0
  177. package/dist/physics/events.js.map +1 -0
  178. package/dist/physics/joint.js +272 -0
  179. package/dist/physics/joint.js.map +1 -0
  180. package/dist/physics/node_physics.js +234 -0
  181. package/dist/physics/node_physics.js.map +1 -0
  182. package/dist/physics/part.js +91 -0
  183. package/dist/physics/part.js.map +1 -0
  184. package/dist/physics/rigid_body.js +379 -0
  185. package/dist/physics/rigid_body.js.map +1 -0
  186. package/dist/physics/vehicle.js +335 -0
  187. package/dist/physics/vehicle.js.map +1 -0
  188. package/dist/physics/world.js +25 -0
  189. package/dist/physics/world.js.map +1 -0
  190. package/dist/posteffect/bloom.js +49 -14
  191. package/dist/posteffect/bloom.js.map +1 -1
  192. package/dist/posteffect/motionblur.js +106 -106
  193. package/dist/posteffect/motionblur.js.map +1 -1
  194. package/dist/posteffect/postsss.js +572 -0
  195. package/dist/posteffect/postsss.js.map +1 -0
  196. package/dist/posteffect/sao.js +2 -6
  197. package/dist/posteffect/sao.js.map +1 -1
  198. package/dist/posteffect/skinsss.js +605 -355
  199. package/dist/posteffect/skinsss.js.map +1 -1
  200. package/dist/posteffect/ssgi.js +91 -162
  201. package/dist/posteffect/ssgi.js.map +1 -1
  202. package/dist/posteffect/ssr.js +3 -11
  203. package/dist/posteffect/ssr.js.map +1 -1
  204. package/dist/posteffect/sss.js +4 -13
  205. package/dist/posteffect/sss.js.map +1 -1
  206. package/dist/posteffect/taa.js +1 -0
  207. package/dist/posteffect/taa.js.map +1 -1
  208. package/dist/render/abuffer_oit.js +3 -2
  209. package/dist/render/abuffer_oit.js.map +1 -1
  210. package/dist/render/clipmap.js +179 -64
  211. package/dist/render/clipmap.js.map +1 -1
  212. package/dist/render/cluster_light.js +958 -224
  213. package/dist/render/cluster_light.js.map +1 -1
  214. package/dist/render/cull_visitor.js +25 -5
  215. package/dist/render/cull_visitor.js.map +1 -1
  216. package/dist/render/debug_views.js +37 -0
  217. package/dist/render/debug_views.js.map +1 -0
  218. package/dist/render/depthpass.js +5 -1
  219. package/dist/render/depthpass.js.map +1 -1
  220. package/dist/render/drawable_mixin.js +53 -6
  221. package/dist/render/drawable_mixin.js.map +1 -1
  222. package/dist/render/dualdepthpeeling_oit.js +5 -5
  223. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  224. package/dist/render/envlight.js +196 -113
  225. package/dist/render/envlight.js.map +1 -1
  226. package/dist/render/fbm_wavegenerator.js +5 -10
  227. package/dist/render/fbm_wavegenerator.js.map +1 -1
  228. package/dist/render/fft_wavegenerator.js +247 -157
  229. package/dist/render/fft_wavegenerator.js.map +1 -1
  230. package/dist/render/gerstner_wavegenerator.js +16 -38
  231. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  232. package/dist/render/gi/probe_volume.js +1334 -0
  233. package/dist/render/gi/probe_volume.js.map +1 -0
  234. package/dist/render/gi/scene_gi.js +282 -0
  235. package/dist/render/gi/scene_gi.js.map +1 -0
  236. package/dist/render/gi/voxel_atlas.js +198 -0
  237. package/dist/render/gi/voxel_atlas.js.map +1 -0
  238. package/dist/render/gi/voxel_lighting.js +652 -0
  239. package/dist/render/gi/voxel_lighting.js.map +1 -0
  240. package/dist/render/gi/voxel_scene.js +642 -0
  241. package/dist/render/gi/voxel_scene.js.map +1 -0
  242. package/dist/render/gi/voxelize_pass.js +223 -0
  243. package/dist/render/gi/voxelize_pass.js.map +1 -0
  244. package/dist/render/globalbindgroup_allocator.js +3 -2
  245. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  246. package/dist/render/gpu_picking.js +9 -36
  247. package/dist/render/gpu_picking.js.map +1 -1
  248. package/dist/render/instance_culling.js +499 -0
  249. package/dist/render/instance_culling.js.map +1 -0
  250. package/dist/render/lightpass.js +19 -8
  251. package/dist/render/lightpass.js.map +1 -1
  252. package/dist/render/lod.js +46 -0
  253. package/dist/render/lod.js.map +1 -0
  254. package/dist/render/primitive.js +301 -9
  255. package/dist/render/primitive.js.map +1 -1
  256. package/dist/render/primitive_readback.js +209 -0
  257. package/dist/render/primitive_readback.js.map +1 -0
  258. package/dist/render/render_queue.js +162 -11
  259. package/dist/render/render_queue.js.map +1 -1
  260. package/dist/render/renderer.js +10 -7
  261. package/dist/render/renderer.js.map +1 -1
  262. package/dist/render/rendergraph/blackboard.js +14 -1
  263. package/dist/render/rendergraph/blackboard.js.map +1 -1
  264. package/dist/render/rendergraph/executor.js +136 -0
  265. package/dist/render/rendergraph/executor.js.map +1 -1
  266. package/dist/render/rendergraph/forward_plus_builder.js +272 -55
  267. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  268. package/dist/render/rendergraph/frame_graph_context.js +41 -0
  269. package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
  270. package/dist/render/rendergraph/scene_render_context.js +31 -2
  271. package/dist/render/rendergraph/scene_render_context.js.map +1 -1
  272. package/dist/render/rendergraph/types.js.map +1 -1
  273. package/dist/render/renderpass.js +28 -5
  274. package/dist/render/renderpass.js.map +1 -1
  275. package/dist/render/sdf/box_allocator.js +98 -0
  276. package/dist/render/sdf/box_allocator.js.map +1 -0
  277. package/dist/render/sdf/global_sdf.js +865 -0
  278. package/dist/render/sdf/global_sdf.js.map +1 -0
  279. package/dist/render/sdf/scene_sdf.js +562 -0
  280. package/dist/render/sdf/scene_sdf.js.map +1 -0
  281. package/dist/render/sdf/sdf_atlas.js +227 -0
  282. package/dist/render/sdf/sdf_atlas.js.map +1 -0
  283. package/dist/render/sdf/sdf_programs.js +42 -0
  284. package/dist/render/sdf/sdf_programs.js.map +1 -0
  285. package/dist/render/sdf/sdf_view.js +199 -0
  286. package/dist/render/sdf/sdf_view.js.map +1 -0
  287. package/dist/render/sdf/waterline.js +610 -0
  288. package/dist/render/sdf/waterline.js.map +1 -0
  289. package/dist/render/shadow_mask_pass.js +142 -25
  290. package/dist/render/shadow_mask_pass.js.map +1 -1
  291. package/dist/render/shore_wave_generator.js +1193 -0
  292. package/dist/render/shore_wave_generator.js.map +1 -0
  293. package/dist/render/sky.js +516 -86
  294. package/dist/render/sky.js.map +1 -1
  295. package/dist/render/transmission_thickness_pass.js +477 -0
  296. package/dist/render/transmission_thickness_pass.js.map +1 -0
  297. package/dist/render/underwater.js +58 -158
  298. package/dist/render/underwater.js.map +1 -1
  299. package/dist/render/virtualtexture/virtual_texture.js +1214 -0
  300. package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
  301. package/dist/render/volumetric_cloud/cloud_common.js +472 -0
  302. package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
  303. package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
  304. package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
  305. package/dist/render/volumetric_cloud/debug_view.js +131 -0
  306. package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
  307. package/dist/render/volumetric_cloud/resources.js +380 -0
  308. package/dist/render/volumetric_cloud/resources.js.map +1 -0
  309. package/dist/render/volumetric_cloud/sky_cache.js +380 -0
  310. package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
  311. package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
  312. package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
  313. package/dist/render/water_caustics.js +134 -319
  314. package/dist/render/water_caustics.js.map +1 -1
  315. package/dist/render/water_foam.js +627 -0
  316. package/dist/render/water_foam.js.map +1 -0
  317. package/dist/render/water_interaction.js +1795 -0
  318. package/dist/render/water_interaction.js.map +1 -0
  319. package/dist/render/weightedblended_oit.js +3 -3
  320. package/dist/render/weightedblended_oit.js.map +1 -1
  321. package/dist/scene/basesprite.js +9 -4
  322. package/dist/scene/basesprite.js.map +1 -1
  323. package/dist/scene/batchgroup.js +108 -12
  324. package/dist/scene/batchgroup.js.map +1 -1
  325. package/dist/scene/environment.js +28 -7
  326. package/dist/scene/environment.js.map +1 -1
  327. package/dist/scene/foliage.js +1020 -0
  328. package/dist/scene/foliage.js.map +1 -0
  329. package/dist/scene/foliage_buckets.js +147 -0
  330. package/dist/scene/foliage_buckets.js.map +1 -0
  331. package/dist/scene/foliage_mask.js +358 -0
  332. package/dist/scene/foliage_mask.js.map +1 -0
  333. package/dist/scene/hair.js +15 -4
  334. package/dist/scene/hair.js.map +1 -1
  335. package/dist/scene/light.js +179 -13
  336. package/dist/scene/light.js.map +1 -1
  337. package/dist/scene/mesh.js +327 -45
  338. package/dist/scene/mesh.js.map +1 -1
  339. package/dist/scene/meshdrawable.js +6 -0
  340. package/dist/scene/meshdrawable.js.map +1 -1
  341. package/dist/scene/msdftext.js +9 -3
  342. package/dist/scene/msdftext.js.map +1 -1
  343. package/dist/scene/msdftextsprite.js +9 -3
  344. package/dist/scene/msdftextsprite.js.map +1 -1
  345. package/dist/scene/particlesys.js +8 -2
  346. package/dist/scene/particlesys.js.map +1 -1
  347. package/dist/scene/physics_settings.js +157 -0
  348. package/dist/scene/physics_settings.js.map +1 -0
  349. package/dist/scene/scene.js +190 -44
  350. package/dist/scene/scene.js.map +1 -1
  351. package/dist/scene/scene_node.js +147 -6
  352. package/dist/scene/scene_node.js.map +1 -1
  353. package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
  354. package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
  355. package/dist/scene/terrain-cm/grass.js +881 -42
  356. package/dist/scene/terrain-cm/grass.js.map +1 -1
  357. package/dist/scene/terrain-cm/grass_gpu.js +929 -0
  358. package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
  359. package/dist/scene/terrain-cm/grassmaterial.js +180 -9
  360. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  361. package/dist/scene/terrain-cm/terrain-cm.js +465 -36
  362. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  363. package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
  364. package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
  365. package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
  366. package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
  367. package/dist/scene/update_queue.js +54 -0
  368. package/dist/scene/update_queue.js.map +1 -0
  369. package/dist/scene/water.js +633 -268
  370. package/dist/scene/water.js.map +1 -1
  371. package/dist/scene/water_surface_sampler.js +324 -0
  372. package/dist/scene/water_surface_sampler.js.map +1 -0
  373. package/dist/scene/wind.js +317 -0
  374. package/dist/scene/wind.js.map +1 -0
  375. package/dist/shaders/atmosphere.js +388 -166
  376. package/dist/shaders/atmosphere.js.map +1 -1
  377. package/dist/shaders/fog.js +100 -32
  378. package/dist/shaders/fog.js.map +1 -1
  379. package/dist/shaders/gi.js +365 -0
  380. package/dist/shaders/gi.js.map +1 -0
  381. package/dist/shaders/ltc_rect.js +202 -0
  382. package/dist/shaders/ltc_rect.js.map +1 -0
  383. package/dist/shaders/misc.js +1 -10
  384. package/dist/shaders/misc.js.map +1 -1
  385. package/dist/shaders/noise.js +5 -1
  386. package/dist/shaders/noise.js.map +1 -1
  387. package/dist/shaders/probes.js +309 -0
  388. package/dist/shaders/probes.js.map +1 -0
  389. package/dist/shaders/sdf.js +537 -0
  390. package/dist/shaders/sdf.js.map +1 -0
  391. package/dist/shaders/shadow.js +104 -70
  392. package/dist/shaders/shadow.js.map +1 -1
  393. package/dist/shaders/skin_brdf.js +243 -0
  394. package/dist/shaders/skin_brdf.js.map +1 -0
  395. package/dist/shaders/ssgi.js +63 -0
  396. package/dist/shaders/ssgi.js.map +1 -0
  397. package/dist/shaders/ssgi_reprojection.js +118 -0
  398. package/dist/shaders/ssgi_reprojection.js.map +1 -0
  399. package/dist/shaders/ssr.js +6 -159
  400. package/dist/shaders/ssr.js.map +1 -1
  401. package/dist/shaders/temporal.js +38 -27
  402. package/dist/shaders/temporal.js.map +1 -1
  403. package/dist/shaders/water.js +32 -82
  404. package/dist/shaders/water.js.map +1 -1
  405. package/dist/shaders/water_medium.js +7 -21
  406. package/dist/shaders/water_medium.js.map +1 -1
  407. package/dist/shadow/dom.js +110 -19
  408. package/dist/shadow/dom.js.map +1 -1
  409. package/dist/shadow/esm.js +3 -3
  410. package/dist/shadow/esm.js.map +1 -1
  411. package/dist/shadow/pcf_opt.js +15 -48
  412. package/dist/shadow/pcf_opt.js.map +1 -1
  413. package/dist/shadow/pcf_pd.js +15 -53
  414. package/dist/shadow/pcf_pd.js.map +1 -1
  415. package/dist/shadow/pcss.js +34 -9
  416. package/dist/shadow/pcss.js.map +1 -1
  417. package/dist/shadow/shadow_impl.js +3 -8
  418. package/dist/shadow/shadow_impl.js.map +1 -1
  419. package/dist/shadow/shadow_region.js +40 -2
  420. package/dist/shadow/shadow_region.js.map +1 -1
  421. package/dist/shadow/shadowmapper.js +93 -53
  422. package/dist/shadow/shadowmapper.js.map +1 -1
  423. package/dist/shadow/ssm.js +18 -72
  424. package/dist/shadow/ssm.js.map +1 -1
  425. package/dist/shadow/vsm.js +3 -3
  426. package/dist/shadow/vsm.js.map +1 -1
  427. package/dist/shapes/shape.js +44 -1
  428. package/dist/shapes/shape.js.map +1 -1
  429. package/dist/utility/buoyancy.js +287 -0
  430. package/dist/utility/buoyancy.js.map +1 -0
  431. package/dist/utility/physical.js +10 -1
  432. package/dist/utility/physical.js.map +1 -1
  433. package/dist/utility/pmrem.js +17 -43
  434. package/dist/utility/pmrem.js.map +1 -1
  435. package/dist/utility/sdf/bake.js +435 -0
  436. package/dist/utility/sdf/bake.js.map +1 -0
  437. package/dist/utility/sdf/bvh.js +576 -0
  438. package/dist/utility/sdf/bvh.js.map +1 -0
  439. package/dist/utility/serialization/manager.js +34 -6
  440. package/dist/utility/serialization/manager.js.map +1 -1
  441. package/dist/utility/serialization/scene/animation.js +46 -5
  442. package/dist/utility/serialization/scene/animation.js.map +1 -1
  443. package/dist/utility/serialization/scene/batch.js +11 -4
  444. package/dist/utility/serialization/scene/batch.js.map +1 -1
  445. package/dist/utility/serialization/scene/camera.js +87 -254
  446. package/dist/utility/serialization/scene/camera.js.map +1 -1
  447. package/dist/utility/serialization/scene/cloth.js +25 -0
  448. package/dist/utility/serialization/scene/cloth.js.map +1 -0
  449. package/dist/utility/serialization/scene/common.js +14 -6
  450. package/dist/utility/serialization/scene/common.js.map +1 -1
  451. package/dist/utility/serialization/scene/foliage.js +821 -0
  452. package/dist/utility/serialization/scene/foliage.js.map +1 -0
  453. package/dist/utility/serialization/scene/hair.js +11 -4
  454. package/dist/utility/serialization/scene/hair.js.map +1 -1
  455. package/dist/utility/serialization/scene/light.js +115 -7
  456. package/dist/utility/serialization/scene/light.js.map +1 -1
  457. package/dist/utility/serialization/scene/material.js +388 -220
  458. package/dist/utility/serialization/scene/material.js.map +1 -1
  459. package/dist/utility/serialization/scene/mesh.js +69 -4
  460. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  461. package/dist/utility/serialization/scene/node.js +140 -5
  462. package/dist/utility/serialization/scene/node.js.map +1 -1
  463. package/dist/utility/serialization/scene/node_physics.js +1318 -0
  464. package/dist/utility/serialization/scene/node_physics.js.map +1 -0
  465. package/dist/utility/serialization/scene/particle.js +11 -4
  466. package/dist/utility/serialization/scene/particle.js.map +1 -1
  467. package/dist/utility/serialization/scene/physics.js +120 -0
  468. package/dist/utility/serialization/scene/physics.js.map +1 -0
  469. package/dist/utility/serialization/scene/primitive.js +124 -10
  470. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  471. package/dist/utility/serialization/scene/scene.js +1687 -51
  472. package/dist/utility/serialization/scene/scene.js.map +1 -1
  473. package/dist/utility/serialization/scene/sprite.js +11 -4
  474. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  475. package/dist/utility/serialization/scene/terrain.js +163 -33
  476. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  477. package/dist/utility/serialization/scene/text.js +11 -4
  478. package/dist/utility/serialization/scene/text.js.map +1 -1
  479. package/dist/utility/serialization/scene/water.js +1543 -264
  480. package/dist/utility/serialization/scene/water.js.map +1 -1
  481. package/dist/utility/serialization/types.js.map +1 -1
  482. package/dist/utility/shprojector.js +10 -22
  483. package/dist/utility/shprojector.js.map +1 -1
  484. package/dist/utility/textures/foam.js +170 -0
  485. package/dist/utility/textures/foam.js.map +1 -0
  486. package/dist/utility/textures/ggxlut.js +17 -43
  487. package/dist/utility/textures/ggxlut.js.map +1 -1
  488. package/dist/utility/textures/ltcdata.js +4 -4
  489. package/dist/utility/textures/ltcdata.js.map +1 -1
  490. package/dist/utility/textures/ltclut.js +16 -6
  491. package/dist/utility/textures/ltclut.js.map +1 -1
  492. package/dist/utility/unsupported.js +24 -0
  493. package/dist/utility/unsupported.js.map +1 -0
  494. package/dist/values.js +13 -1
  495. package/dist/values.js.map +1 -1
  496. package/package.json +25 -12
  497. package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
  498. package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
  499. package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
  500. package/src/asset/meshoptimizer/LICENSE +21 -0
  501. package/dist/animation/joint_dynamics/convex_collider.js +0 -320
  502. package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
@@ -1,6 +1,6 @@
1
- import { Vector3, Disposable, randomUUID, Quaternion, DWeakRef, DRef, Matrix4x4, nextPowerOf2 } from '@zephyr3d/base';
1
+ import { Vector3, Matrix4x4, Disposable, randomUUID, Quaternion, DWeakRef } from '@zephyr3d/base';
2
2
  import { BoundingBox } from '../utility/bounding_volume.js';
3
- import { getDevice } from '../app/api.js';
3
+ import { SkinPaletteAtlas } from './skin_palette_atlas.js';
4
4
 
5
5
  /**
6
6
  * Standardized humanoid joint names for consistent skeleton mapping across models and animations.
@@ -58,7 +58,9 @@ import { getDevice } from '../app/api.js';
58
58
  return HumanoidHandRig;
59
59
  }({});
60
60
  const tmpV0 = new Vector3();
61
- const tmpV1 = new Vector3();
61
+ const tmpMatrix = new Matrix4x4();
62
+ const tmpMatrix2 = new Matrix4x4();
63
+ /** Palette header slot: absolute slot indices of the current and previous sets */ const tmpHeader = new Float32Array(16);
62
64
  const humanoidHelperJointTokens = new Set([
63
65
  'end',
64
66
  'nub',
@@ -294,11 +296,14 @@ function sideJointPatterns(side, patterns) {
294
296
  * - Applies skinning state to associated meshes each frame.
295
297
  * - Computes animated axis-aligned bounding boxes using representative skinned vertices.
296
298
  *
297
- * Joint matrix texture layout:
298
- * - Texture format: `rgba32f`.
299
- * - Stored as a 2-layered ring buffer: current and previous joint transforms to support
300
- * temporal addressing if needed. Offsets are tracked in `_jointOffsets[0]` (current)
301
- * and `_jointOffsets[1]` (previous).
299
+ * Joint matrix palette layout:
300
+ * - A block of slots in the shared {@link SkinPaletteAtlas}, one slot per 4x4 matrix.
301
+ * - Slot 0 is a header holding the absolute slot indices of the current and previous sets.
302
+ * - The rest is a 2-layered ring buffer: current and previous joint transforms to support
303
+ * temporal addressing. Offsets relative to the block are tracked in `_jointOffsets[0]`
304
+ * (current) and `_jointOffsets[1]` (previous).
305
+ * - Palette matrices are relative to {@link SkinBinding.referenceNode}, so they do not change
306
+ * when the whole character moves and can be shared by instances of the same model.
302
307
  *
303
308
  * Usage:
304
309
  * - Construct with a rig, bind data, meshes and submesh bounding info.
@@ -314,8 +319,17 @@ function sideJointPatterns(side, patterns) {
314
319
  /** @internal */ _inverseBindMatrices;
315
320
  /** @internal */ _jointMatrices;
316
321
  /** @internal */ _jointOffsets;
317
- /** @internal */ _jointMatrixArray;
318
- /** @internal */ _jointTexture;
322
+ /** @internal */ _paletteBlock;
323
+ /** @internal Number of meshes skinned by other palettes in place of this binding's */ _paletteSuspendCount;
324
+ /** @internal Increased each time the pose relative to the reference node changes */ _paletteVersion;
325
+ /** @internal Whether both palette sets hold the current pose, so a still pose needs no write */ _paletteSettled;
326
+ /**
327
+ * @internal Joints and the nodes between them and the reference node, whose local transforms
328
+ * make up the pose
329
+ */ _poseNodes;
330
+ /** @internal Sum of the local transform tags of the pose nodes when the pose last changed */ _poseTag;
331
+ /** @internal Meshes waiting for the pose to change before updating again */ _sleepingMeshes;
332
+ /** @internal */ _paletteData;
319
333
  /** @internal */ _playing;
320
334
  /** @internal */ _lastUpdateTime;
321
335
  /**
@@ -331,7 +345,13 @@ function sideJointPatterns(side, patterns) {
331
345
  this._rig = rig;
332
346
  this._joints = joints ?? rig.joints;
333
347
  this._inverseBindMatrices = inverseBindMatrices;
334
- this._jointTexture = new DRef();
348
+ this._paletteBlock = null;
349
+ this._paletteSuspendCount = 0;
350
+ this._paletteVersion = 0;
351
+ this._paletteSettled = false;
352
+ this._poseNodes = null;
353
+ this._poseTag = -1;
354
+ this._sleepingMeshes = new Set();
335
355
  this._playing = false;
336
356
  this._lastUpdateTime = 0;
337
357
  if (bindPose && bindPose !== rig.bindPose) {
@@ -405,9 +425,43 @@ function sideJointPatterns(side, patterns) {
405
425
  /**
406
426
  * Texture containing joint matrices for GPU skinning.
407
427
  *
408
- * Each matrix is stored in 4 texels (one row per texel, RGBA = 4 floats).
428
+ * This is the shared {@link SkinPaletteAtlas} texture; the palette of this binding starts at
429
+ * slot {@link SkinBinding.paletteBase}. Each matrix is stored in 4 texels (one row per texel,
430
+ * RGBA = 4 floats).
409
431
  */ get jointTexture() {
410
- return this._jointTexture.get();
432
+ return SkinPaletteAtlas.instance.texture;
433
+ }
434
+ /**
435
+ * Index of the header slot of this binding's palette in the joint texture.
436
+ *
437
+ * @internal
438
+ */ get paletteBase() {
439
+ return this._paletteBlock?.base ?? 0;
440
+ }
441
+ /**
442
+ * Increased each time the pose relative to the reference node changes, so skinned meshes
443
+ * recompute their bounds only then. A model moving as a whole keeps its pose.
444
+ *
445
+ * @internal
446
+ */ get paletteVersion() {
447
+ return this._paletteVersion;
448
+ }
449
+ /**
450
+ * Have a skinned mesh queued for update the next time the pose changes, instead of every frame.
451
+ *
452
+ * @internal
453
+ */ sleepUntilPoseChanges(mesh) {
454
+ this._sleepingMeshes.add(mesh);
455
+ }
456
+ /**
457
+ * Node the palette matrices are relative to: the parent of the rig's root joint, or null
458
+ * for world space.
459
+ *
460
+ * @remarks
461
+ * A mesh skinned by this binding transforms palette output to its local space by
462
+ * `inverse(mesh.worldMatrix) * referenceNode.worldMatrix`.
463
+ */ get referenceNode() {
464
+ return this._rig.rootJoint?.parent ?? null;
411
465
  }
412
466
  /**
413
467
  * Get joint index by joint node
@@ -439,10 +493,13 @@ function sideJointPatterns(side, patterns) {
439
493
  * @param worldMatrix - Optional world-to-model transform applied before inverse bind.
440
494
  * @internal
441
495
  */ updateJointMatrices() {
442
- if (!this._jointTexture.get()) {
443
- this._createJointTexture();
496
+ if (!this._jointOffsets) {
497
+ this._createPalette();
498
+ } else if (!this._paletteBlock) {
499
+ this._paletteBlock = SkinPaletteAtlas.instance.allocate(this.joints.length * 2 + 1);
444
500
  }
445
- if (this._jointOffsets[0] === 0) {
501
+ const first = this._jointOffsets[0] === 0;
502
+ if (first) {
446
503
  this._jointOffsets[0] = 1;
447
504
  this._jointOffsets[1] = 1;
448
505
  } else {
@@ -452,6 +509,24 @@ function sideJointPatterns(side, patterns) {
452
509
  for(let i = 0; i < this.joints.length; i++){
453
510
  Matrix4x4.multiply(this.joints[i].worldMatrix, this._inverseBindMatrices[i], this._jointMatrices[i + this._jointOffsets[0] - 1]);
454
511
  }
512
+ // CPU-side matrices are world space and always current; the palette and anything derived
513
+ // from the pose only change when the pose relative to the reference node does
514
+ const changed = this._poseChanged() || first;
515
+ if (changed) {
516
+ this._computePalette();
517
+ this._paletteSettled = false;
518
+ this._paletteVersion++;
519
+ for (const mesh of this._sleepingMeshes){
520
+ mesh.scene?.queueUpdateNode(mesh);
521
+ }
522
+ this._sleepingMeshes.clear();
523
+ }
524
+ // The first still frame writes the pose once more so the previous set equals the current
525
+ // one; after that both sets hold it and the atlas is left alone
526
+ if (!this._paletteSettled) {
527
+ this._writePalette();
528
+ this._paletteSettled = !changed;
529
+ }
455
530
  }
456
531
  /**
457
532
  * Reset skeleton to bind pose
@@ -461,14 +536,44 @@ function sideJointPatterns(side, patterns) {
461
536
  this._rig.computeBindPose();
462
537
  }
463
538
  /**
464
- * Compute current joint matrices from the nodes and upload them to the joint texture.
539
+ * Compute current joint matrices from the nodes and write them to the joint texture.
540
+ *
541
+ * @remarks
542
+ * The joint texture is uploaded once per frame when the scene update completes.
465
543
  *
466
544
  * @internal
467
545
  */ apply() {
468
- this.updateJointMatrices();
469
- const tex = this.jointTexture;
470
- this._syncJointMatrixArray();
471
- tex.update(this._jointMatrixArray, 0, 0, tex.width, tex.height);
546
+ if (this._paletteSuspendCount === 0) {
547
+ this.updateJointMatrices();
548
+ }
549
+ }
550
+ /**
551
+ * Stop or resume updating the palette, while meshes are skinned by other palettes in place of
552
+ * this binding's.
553
+ *
554
+ * @remarks
555
+ * Calls are counted; the palette updates again once every suspension is resumed. CPU-side joint
556
+ * matrices are not updated while suspended either.
557
+ *
558
+ * The atlas block of the palette is released while suspended, since no mesh reads it, and
559
+ * allocated again on resume, at a new base: meshes pick it up as their palette overrides are
560
+ * cleared.
561
+ *
562
+ * @param suspend - true to suspend, false to resume
563
+ * @internal
564
+ */ suspendPalette(suspend) {
565
+ const wasSuspended = this._paletteSuspendCount > 0;
566
+ this._paletteSuspendCount = Math.max(0, this._paletteSuspendCount + (suspend ? 1 : -1));
567
+ if (!wasSuspended && this._paletteSuspendCount > 0 && this._paletteBlock) {
568
+ SkinPaletteAtlas.instance.free(this._paletteBlock);
569
+ this._paletteBlock = null;
570
+ } else if (wasSuspended && this._paletteSuspendCount === 0 && this._jointOffsets) {
571
+ this._paletteBlock = SkinPaletteAtlas.instance.allocate(this.joints.length * 2 + 1);
572
+ // The previous set is as old as the suspension, so restart the history: the next update
573
+ // writes both sets, giving no motion for one frame rather than the motion since then
574
+ this._jointOffsets[0] = 0;
575
+ this._paletteSettled = false;
576
+ }
472
577
  }
473
578
  /**
474
579
  * Apply all enabled modifiers.
@@ -500,32 +605,50 @@ function sideJointPatterns(side, patterns) {
500
605
  * Compute the animated bounding box for a single mesh using its representative vertices.
501
606
  *
502
607
  * For each representative vertex:
503
- * - Blends the vertex by up to 4 joint matrices using provided weights.
504
- * - Transforms to the mesh's local space using `invWorldMatrix`.
608
+ * - Blends the vertex by up to 4 palette matrices using provided weights.
609
+ * - Transforms to the mesh's local space using `skinSpaceMatrix`.
505
610
  * - Expands the bounding box.
506
611
  *
612
+ * @remarks
613
+ * Reads the palette, which is relative to {@link SkinBinding.referenceNode} and changes together
614
+ * with {@link SkinBinding.paletteVersion}, rather than the world-space joint matrices: those are
615
+ * a snapshot of when the joints were last updated, and the model may have moved since without
616
+ * changing the pose, so combining them with the current mesh transform offsets the bounds.
617
+ *
507
618
  * @param info - Precomputed bounding data (representative vertices, indices, weights).
508
- * @param invWorldMatrix - Mesh inverse world matrix to convert to model/local space.
619
+ * @param skinSpaceMatrix - Matrix transforming palette output to the mesh's local space,
620
+ * see {@link Mesh.getSkinSpaceMatrix}.
509
621
  * @internal
510
- */ computeBoundingBox(info, invWorldMatrix) {
622
+ */ computeBoundingBox(info, skinSpaceMatrix) {
511
623
  info.boundingBox.beginExtend();
624
+ const palette = this._paletteData;
625
+ if (!palette) {
626
+ return;
627
+ }
628
+ const numJoints = this.joints.length;
512
629
  const influenceCount = Math.max(1, info.influenceCount ?? 4);
513
630
  for(let i = 0; i < info.boundingVertices.length; i++){
514
- tmpV0.setXYZ(0, 0, 0);
631
+ const v = info.boundingVertices[i];
632
+ let x = 0;
633
+ let y = 0;
634
+ let z = 0;
515
635
  const base = i * influenceCount;
516
636
  for(let j = 0; j < influenceCount; j++){
517
637
  const weight = Number(info.boundingVertexJointWeights[base + j]) || 0;
518
638
  if (weight <= 0) {
519
639
  continue;
520
640
  }
521
- const matrix = this._jointMatrices[(Number(info.boundingVertexBlendIndices[base + j]) || 0) + this._jointOffsets[0] - 1];
522
- if (!matrix) {
641
+ const joint = Number(info.boundingVertexBlendIndices[base + j]) || 0;
642
+ if (joint < 0 || joint >= numJoints) {
523
643
  continue;
524
644
  }
525
- matrix.transformPointAffine(info.boundingVertices[i], tmpV1).scaleBy(weight);
526
- tmpV0.addBy(tmpV1);
645
+ const m = joint * 16;
646
+ x += weight * (palette[m] * v.x + palette[m + 4] * v.y + palette[m + 8] * v.z + palette[m + 12]);
647
+ y += weight * (palette[m + 1] * v.x + palette[m + 5] * v.y + palette[m + 9] * v.z + palette[m + 13]);
648
+ z += weight * (palette[m + 2] * v.x + palette[m + 6] * v.y + palette[m + 10] * v.z + palette[m + 14]);
527
649
  }
528
- invWorldMatrix.transformPointAffine(tmpV0, tmpV0);
650
+ tmpV0.setXYZ(x, y, z);
651
+ skinSpaceMatrix.transformPointAffine(tmpV0, tmpV0);
529
652
  info.boundingBox.extend(tmpV0);
530
653
  }
531
654
  }
@@ -536,7 +659,11 @@ function sideJointPatterns(side, patterns) {
536
659
  * - Clears matrix arrays and joint references.
537
660
  */ onDispose() {
538
661
  super.onDispose();
539
- this._jointTexture.dispose();
662
+ if (this._paletteBlock) {
663
+ SkinPaletteAtlas.instance.free(this._paletteBlock);
664
+ this._paletteBlock = null;
665
+ }
666
+ this._sleepingMeshes.clear();
540
667
  const m = SkinBinding._registry.get(this._id);
541
668
  if (m?.get() === this) {
542
669
  SkinBinding._registry.delete(this._id);
@@ -544,38 +671,78 @@ function sideJointPatterns(side, patterns) {
544
671
  }
545
672
  }
546
673
  /**
547
- * Initialize joint texture and CPU-side matrix storage.
674
+ * Allocate the palette block and CPU-side matrix storage.
548
675
  *
549
676
  * Layout details:
550
- * - Texture size is the next power-of-two able to contain all matrices plus two offset texels.
551
- * - `_jointMatrixArray` holds:
552
- * - First 2 vec4s: ring buffer offsets `[current, previous, 0, 0]`.
553
- * - Followed by 2×N matrices (current and previous), each as 16 floats.
554
- * - `_jointMatrices` is a view into `_jointMatrixArray` providing Matrix4x4 objects per slot.
677
+ * - The block holds a header slot followed by 2×N matrix slots (current and previous).
678
+ * - `_jointOffsets` holds the ring buffer offsets `[current, previous]` relative to the block.
679
+ * - `_jointMatrices` holds the world-space skinning matrices of both sets, which CPU-side
680
+ * consumers (bounds, cloth) read.
555
681
  *
556
682
  * @internal
557
- */ _createJointTexture() {
558
- const textureWidth = nextPowerOf2(Math.max(4, Math.ceil(Math.sqrt((this.joints.length * 2 + 1) * 4))));
559
- const device = getDevice();
560
- this._jointTexture.set(device.createTexture2D('rgba32f', textureWidth, textureWidth, {
561
- mipmapping: false,
562
- samplerOptions: {
563
- magFilter: 'nearest',
564
- minFilter: 'nearest'
565
- }
566
- }));
567
- this._jointMatrixArray = new Float32Array(textureWidth * textureWidth * 4);
568
- this._jointOffsets = this._jointMatrixArray.subarray(0, 2);
569
- this._jointOffsets[0] = 0;
570
- this._jointOffsets[1] = 0;
683
+ */ _createPalette() {
684
+ this._paletteBlock = SkinPaletteAtlas.instance.allocate(this.joints.length * 2 + 1);
685
+ this._paletteData = new Float32Array(this.joints.length * 16);
686
+ this._paletteSettled = false;
687
+ this._jointOffsets = new Float32Array(2);
571
688
  this._jointMatrices = Array.from({
572
689
  length: this.joints.length * 2
573
690
  }).map(()=>new Matrix4x4());
574
691
  }
575
- _syncJointMatrixArray() {
576
- for(let i = 0; i < this._jointMatrices.length; i++){
577
- this._jointMatrixArray.set(this._jointMatrices[i], (i + 1) * 16);
692
+ /**
693
+ * Whether the pose may have changed since it last did: the local transform of a joint, or of a
694
+ * node between the joints and the reference node, has changed.
695
+ *
696
+ * @remarks
697
+ * Moving the whole model changes the world matrices of the joints but not the pose, so world
698
+ * matrices cannot tell; and comparing matrices taken back to the reference node trips over
699
+ * rounding far from the origin.
700
+ */ _poseChanged() {
701
+ const reference = this.referenceNode;
702
+ if (!this._poseNodes || this._poseNodes.reference !== reference) {
703
+ const nodes = new Set();
704
+ for (const joint of this.joints){
705
+ for(let node = joint; node && node !== reference; node = node.parent){
706
+ if (nodes.has(node)) {
707
+ break;
708
+ }
709
+ nodes.add(node);
710
+ }
711
+ }
712
+ this._poseNodes = {
713
+ reference,
714
+ nodes: [
715
+ ...nodes
716
+ ]
717
+ };
718
+ this._poseTag = -1;
719
+ }
720
+ let tag = 0;
721
+ for (const node of this._poseNodes.nodes){
722
+ tag += node.localTransformTag;
578
723
  }
724
+ if (tag !== this._poseTag) {
725
+ this._poseTag = tag;
726
+ return true;
727
+ }
728
+ return false;
729
+ }
730
+ /** Compute the current set of matrices relative to the reference node */ _computePalette() {
731
+ const reference = this.referenceNode;
732
+ const invReference = reference ? Matrix4x4.invertAffine(reference.worldMatrix, tmpMatrix) : null;
733
+ const offset = this._jointOffsets[0] - 1;
734
+ for(let i = 0; i < this.joints.length; i++){
735
+ const world = this._jointMatrices[i + offset];
736
+ this._paletteData.set(invReference ? Matrix4x4.multiplyAffine(invReference, world, tmpMatrix2) : world, i * 16);
737
+ }
738
+ }
739
+ /** Write the header and the current set of matrices to the palette */ _writePalette() {
740
+ const atlas = SkinPaletteAtlas.instance;
741
+ const base = this._paletteBlock.base;
742
+ atlas.writeSlots(base + this._jointOffsets[0], this._paletteData);
743
+ tmpHeader[0] = base + this._jointOffsets[0];
744
+ tmpHeader[1] = base + this._jointOffsets[1];
745
+ atlas.writeSlots(base, tmpHeader);
579
746
  }
580
747
  /**
581
748
  * Build representative skinned bounding data for a submesh.
@@ -720,6 +887,63 @@ function sideJointPatterns(side, patterns) {
720
887
  }
721
888
  return result;
722
889
  }
890
+ /**
891
+ * Skin packed direction vectors into mesh-local space for the current skeleton pose.
892
+ *
893
+ * Unlike positions, directions ignore matrix translation and are normalized after
894
+ * conversion through the mesh inverse world matrix.
895
+ *
896
+ * @internal
897
+ */ skinDirectionsToLocal(directions, blendIndices, weights, invWorldMatrix, out, influenceCount) {
898
+ const result = out && out.length === directions.length ? out : new Float32Array(directions.length);
899
+ const matrixOffset = this._jointOffsets[0] - 1;
900
+ const effectiveInfluenceCount = Math.max(1, influenceCount ?? Math.max(1, Math.floor(weights.length / Math.max(1, Math.floor(directions.length / 3)))));
901
+ for(let i = 0; i + 2 < directions.length; i += 3){
902
+ const vertexIndex = i / 3 >> 0;
903
+ const x = directions[i];
904
+ const y = directions[i + 1];
905
+ const z = directions[i + 2];
906
+ let skinnedX = 0;
907
+ let skinnedY = 0;
908
+ let skinnedZ = 0;
909
+ let weightSum = 0;
910
+ const base = vertexIndex * effectiveInfluenceCount;
911
+ for(let j = 0; j < effectiveInfluenceCount; j++){
912
+ const weight = Number(weights[base + j]) || 0;
913
+ if (weight <= 0) {
914
+ continue;
915
+ }
916
+ const jointIndex = (Number(blendIndices[base + j]) || 0) + matrixOffset;
917
+ const matrix = this._jointMatrices[jointIndex];
918
+ if (!matrix) {
919
+ continue;
920
+ }
921
+ skinnedX += (matrix[0] * x + matrix[4] * y + matrix[8] * z) * weight;
922
+ skinnedY += (matrix[1] * x + matrix[5] * y + matrix[9] * z) * weight;
923
+ skinnedZ += (matrix[2] * x + matrix[6] * y + matrix[10] * z) * weight;
924
+ weightSum += weight;
925
+ }
926
+ if (weightSum <= 1e-6) {
927
+ skinnedX = x;
928
+ skinnedY = y;
929
+ skinnedZ = z;
930
+ }
931
+ const localX = invWorldMatrix[0] * skinnedX + invWorldMatrix[4] * skinnedY + invWorldMatrix[8] * skinnedZ;
932
+ const localY = invWorldMatrix[1] * skinnedX + invWorldMatrix[5] * skinnedY + invWorldMatrix[9] * skinnedZ;
933
+ const localZ = invWorldMatrix[2] * skinnedX + invWorldMatrix[6] * skinnedY + invWorldMatrix[10] * skinnedZ;
934
+ const length = Math.hypot(localX, localY, localZ);
935
+ if (length > 1e-8) {
936
+ result[i] = localX / length;
937
+ result[i + 1] = localY / length;
938
+ result[i + 2] = localZ / length;
939
+ } else {
940
+ result[i] = 0;
941
+ result[i + 1] = 1;
942
+ result[i + 2] = 0;
943
+ }
944
+ }
945
+ return result;
946
+ }
723
947
  static normalizeHumanoidJointName(name) {
724
948
  return name.slice(name.lastIndexOf(':') + 1).replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2').replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/([a-zA-Z])(\d+)/g, '$1 $2').replace(/(\d+)([a-zA-Z])/g, '$1 $2').replace(/[_:\/\\.-]+/g, ' ').replace(/[^a-zA-Z0-9]+/g, ' ').toLowerCase().replace(/\bforearm\b/g, 'fore arm').replace(/\bupperarm\b/g, 'upper arm').replace(/\blowerarm\b/g, 'lower arm').replace(/\bupleg\b/g, 'up leg').replace(/\bupperleg\b/g, 'upper leg').replace(/\blowerleg\b/g, 'lower leg').replace(/\btoebase\b/g, 'toe base').replace(/\bupperchest\b/g, 'upper chest').replace(/\btoes\b/g, 'toe').replace(/\blittle\b/g, 'pinky').replace(/\bcollar\b/g, 'clavicle').replace(/\s+/g, ' ').trim();
725
949
  }