@zephyr3d/scene 0.9.25 → 0.9.27

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 (299) hide show
  1. package/dist/animation/animationset.js +92 -30
  2. package/dist/animation/animationset.js.map +1 -1
  3. package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
  4. package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
  5. package/dist/animation/joint_dynamics/controller.js +7 -5
  6. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  7. package/dist/animation/joint_dynamics/convex_collider.js +320 -0
  8. package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  9. package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
  10. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  11. package/dist/animation/morphtrack.js +3 -4
  12. package/dist/animation/morphtrack.js.map +1 -1
  13. package/dist/animation/skeleton.js +79 -25
  14. package/dist/animation/skeleton.js.map +1 -1
  15. package/dist/animation/spring/multi_chain_spring_system.js +577 -179
  16. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  17. package/dist/animation/spring/spring_collider.js +4 -3
  18. package/dist/animation/spring/spring_collider.js.map +1 -1
  19. package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
  20. package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
  21. package/dist/animation/spring/spring_particle.js +2 -0
  22. package/dist/animation/spring/spring_particle.js.map +1 -1
  23. package/dist/animation/spring/spring_system.js +11 -3
  24. package/dist/animation/spring/spring_system.js.map +1 -1
  25. package/dist/animation/spring_modifier.js +10 -0
  26. package/dist/animation/spring_modifier.js.map +1 -1
  27. package/dist/app/engine.js +53 -43
  28. package/dist/app/engine.js.map +1 -1
  29. package/dist/app/scriptingsystem.js +119 -6
  30. package/dist/app/scriptingsystem.js.map +1 -1
  31. package/dist/app/scriptregistry.js +3 -2
  32. package/dist/app/scriptregistry.js.map +1 -1
  33. package/dist/asset/assetmanager.js +284 -67
  34. package/dist/asset/assetmanager.js.map +1 -1
  35. package/dist/asset/loaders/zhair/zhair_format.js +288 -0
  36. package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
  37. package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
  38. package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
  39. package/dist/asset/model.js +184 -69
  40. package/dist/asset/model.js.map +1 -1
  41. package/dist/camera/camera.js +268 -44
  42. package/dist/camera/camera.js.map +1 -1
  43. package/dist/camera/perspectivecamera.js +3 -1
  44. package/dist/camera/perspectivecamera.js.map +1 -1
  45. package/dist/index.d.ts +9044 -5139
  46. package/dist/index.js +17 -6
  47. package/dist/index.js.map +1 -1
  48. package/dist/material/eye.js +932 -0
  49. package/dist/material/eye.js.map +1 -0
  50. package/dist/material/hair.js +917 -0
  51. package/dist/material/hair.js.map +1 -0
  52. package/dist/material/hairstrand.js +842 -0
  53. package/dist/material/hairstrand.js.map +1 -0
  54. package/dist/material/hairstrand_data.js +162 -0
  55. package/dist/material/hairstrand_data.js.map +1 -0
  56. package/dist/material/lambert.js +5 -2
  57. package/dist/material/lambert.js.map +1 -1
  58. package/dist/material/material.js +48 -10
  59. package/dist/material/material.js.map +1 -1
  60. package/dist/material/meshmaterial.js +120 -19
  61. package/dist/material/meshmaterial.js.map +1 -1
  62. package/dist/material/mixins/albedocolor.js +1 -1
  63. package/dist/material/mixins/albedocolor.js.map +1 -1
  64. package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
  65. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  66. package/dist/material/mixins/lightmodel/lambert.js +5 -4
  67. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  68. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
  69. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  70. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
  71. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  72. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  73. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  74. package/dist/material/mixins/lit.js +106 -19
  75. package/dist/material/mixins/lit.js.map +1 -1
  76. package/dist/material/mixins/pbr/common.js +4 -4
  77. package/dist/material/mixins/pbr/common.js.map +1 -1
  78. package/dist/material/mixins/texture.js +48 -11
  79. package/dist/material/mixins/texture.js.map +1 -1
  80. package/dist/material/mtoon.js +6 -5
  81. package/dist/material/mtoon.js.map +1 -1
  82. package/dist/material/pbrblueprint.js +146 -28
  83. package/dist/material/pbrblueprint.js.map +1 -1
  84. package/dist/material/pbrblueprint_instance.js +501 -0
  85. package/dist/material/pbrblueprint_instance.js.map +1 -0
  86. package/dist/material/pbrmr.js +15 -16
  87. package/dist/material/pbrmr.js.map +1 -1
  88. package/dist/material/shader/helper.js +734 -23
  89. package/dist/material/shader/helper.js.map +1 -1
  90. package/dist/material/shader/terrain_blend.js +55 -0
  91. package/dist/material/shader/terrain_blend.js.map +1 -0
  92. package/dist/material/skin.js +192 -32
  93. package/dist/material/skin.js.map +1 -1
  94. package/dist/material/spriteblueprint.js +16 -1
  95. package/dist/material/spriteblueprint.js.map +1 -1
  96. package/dist/material/subsurfaceprofile.js +86 -23
  97. package/dist/material/subsurfaceprofile.js.map +1 -1
  98. package/dist/material/water.js +2059 -72
  99. package/dist/material/water.js.map +1 -1
  100. package/dist/posteffect/bloom.js +167 -7
  101. package/dist/posteffect/bloom.js.map +1 -1
  102. package/dist/posteffect/coloradjust.js +2 -1
  103. package/dist/posteffect/coloradjust.js.map +1 -1
  104. package/dist/posteffect/compositor.js.map +1 -1
  105. package/dist/posteffect/fxaa.js +2 -1
  106. package/dist/posteffect/fxaa.js.map +1 -1
  107. package/dist/posteffect/grayscale.js +3 -1
  108. package/dist/posteffect/grayscale.js.map +1 -1
  109. package/dist/posteffect/motionblur.js +664 -56
  110. package/dist/posteffect/motionblur.js.map +1 -1
  111. package/dist/posteffect/posteffect.js +12 -1
  112. package/dist/posteffect/posteffect.js.map +1 -1
  113. package/dist/posteffect/sao.js +46 -44
  114. package/dist/posteffect/sao.js.map +1 -1
  115. package/dist/posteffect/skinsss.js +368 -69
  116. package/dist/posteffect/skinsss.js.map +1 -1
  117. package/dist/posteffect/ssgi.js +16 -9
  118. package/dist/posteffect/ssgi.js.map +1 -1
  119. package/dist/posteffect/ssr.js +3 -0
  120. package/dist/posteffect/ssr.js.map +1 -1
  121. package/dist/posteffect/sss.js +121 -36
  122. package/dist/posteffect/sss.js.map +1 -1
  123. package/dist/posteffect/taa.js.map +1 -1
  124. package/dist/posteffect/tonemap.js +44 -1
  125. package/dist/posteffect/tonemap.js.map +1 -1
  126. package/dist/render/abuffer_oit.js +8 -2
  127. package/dist/render/abuffer_oit.js.map +1 -1
  128. package/dist/render/clipmap.js +156 -5
  129. package/dist/render/clipmap.js.map +1 -1
  130. package/dist/render/cull_visitor.js +20 -0
  131. package/dist/render/cull_visitor.js.map +1 -1
  132. package/dist/render/depthpass.js +36 -2
  133. package/dist/render/depthpass.js.map +1 -1
  134. package/dist/render/drawable_mixin.js +26 -1
  135. package/dist/render/drawable_mixin.js.map +1 -1
  136. package/dist/render/dualdepthpeeling_oit.js +3 -2
  137. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  138. package/dist/render/envlight.js +1 -1
  139. package/dist/render/envlight.js.map +1 -1
  140. package/dist/render/fbm_wavegenerator.js +6 -3
  141. package/dist/render/fbm_wavegenerator.js.map +1 -1
  142. package/dist/render/fft_wavegenerator.js +57 -15
  143. package/dist/render/fft_wavegenerator.js.map +1 -1
  144. package/dist/render/gerstner_wavegenerator.js +130 -20
  145. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  146. package/dist/render/globalbindgroup_allocator.js +3 -0
  147. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  148. package/dist/render/hzb.js +80 -22
  149. package/dist/render/hzb.js.map +1 -1
  150. package/dist/render/lightpass.js +6 -3
  151. package/dist/render/lightpass.js.map +1 -1
  152. package/dist/render/oit.js +29 -0
  153. package/dist/render/oit.js.map +1 -0
  154. package/dist/render/render_queue.js +39 -0
  155. package/dist/render/render_queue.js.map +1 -1
  156. package/dist/render/renderer.js +4 -0
  157. package/dist/render/renderer.js.map +1 -1
  158. package/dist/render/rendergraph/blackboard.js +1 -0
  159. package/dist/render/rendergraph/blackboard.js.map +1 -1
  160. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  161. package/dist/render/rendergraph/executor.js +2 -0
  162. package/dist/render/rendergraph/executor.js.map +1 -1
  163. package/dist/render/rendergraph/forward_plus_builder.js +379 -10
  164. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  165. package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
  166. package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
  167. package/dist/render/rendergraph/history_resources.js +8 -1
  168. package/dist/render/rendergraph/history_resources.js.map +1 -1
  169. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  170. package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
  171. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
  172. package/dist/render/rendergraph/types.js.map +1 -1
  173. package/dist/render/shadow_mask_pass.js +73 -8
  174. package/dist/render/shadow_mask_pass.js.map +1 -1
  175. package/dist/render/sky.js +166 -126
  176. package/dist/render/sky.js.map +1 -1
  177. package/dist/render/underwater.js +624 -0
  178. package/dist/render/underwater.js.map +1 -0
  179. package/dist/render/water_caustics.js +1380 -0
  180. package/dist/render/water_caustics.js.map +1 -0
  181. package/dist/render/weightedblended_oit.js +3 -2
  182. package/dist/render/weightedblended_oit.js.map +1 -1
  183. package/dist/scene/basesprite.js +8 -0
  184. package/dist/scene/basesprite.js.map +1 -1
  185. package/dist/scene/batchgroup.js +3 -0
  186. package/dist/scene/batchgroup.js.map +1 -1
  187. package/dist/scene/environment.js +4 -1
  188. package/dist/scene/environment.js.map +1 -1
  189. package/dist/scene/hair.js +963 -0
  190. package/dist/scene/hair.js.map +1 -0
  191. package/dist/scene/light.js +5 -1
  192. package/dist/scene/light.js.map +1 -1
  193. package/dist/scene/mesh.js +481 -47
  194. package/dist/scene/mesh.js.map +1 -1
  195. package/dist/scene/meshdrawable.js +6 -0
  196. package/dist/scene/meshdrawable.js.map +1 -1
  197. package/dist/scene/msdftext.js +3 -0
  198. package/dist/scene/msdftext.js.map +1 -1
  199. package/dist/scene/msdftextsprite.js +3 -0
  200. package/dist/scene/msdftextsprite.js.map +1 -1
  201. package/dist/scene/particlesys.js +6 -0
  202. package/dist/scene/particlesys.js.map +1 -1
  203. package/dist/scene/scene.js +3 -0
  204. package/dist/scene/scene.js.map +1 -1
  205. package/dist/scene/scene_node.js +6 -1
  206. package/dist/scene/scene_node.js.map +1 -1
  207. package/dist/scene/terrain-cm/grass.js +3 -0
  208. package/dist/scene/terrain-cm/grass.js.map +1 -1
  209. package/dist/scene/terrain-cm/grassmaterial.js +3 -0
  210. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  211. package/dist/scene/terrain-cm/terrain-cm.js +6 -0
  212. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  213. package/dist/scene/terrain-cm/texture_cache.js +309 -0
  214. package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
  215. package/dist/scene/water.js +546 -4
  216. package/dist/scene/water.js.map +1 -1
  217. package/dist/shaders/atmosphere.js.map +1 -1
  218. package/dist/shaders/diffusion.js +54 -0
  219. package/dist/shaders/diffusion.js.map +1 -0
  220. package/dist/shaders/shadow.js +33 -21
  221. package/dist/shaders/shadow.js.map +1 -1
  222. package/dist/shaders/temporal.js +71 -33
  223. package/dist/shaders/temporal.js.map +1 -1
  224. package/dist/shaders/water.js +22 -19
  225. package/dist/shaders/water.js.map +1 -1
  226. package/dist/shaders/water_medium.js +56 -0
  227. package/dist/shaders/water_medium.js.map +1 -0
  228. package/dist/shadow/dom.js +546 -0
  229. package/dist/shadow/dom.js.map +1 -0
  230. package/dist/shadow/pcf_opt.js +3 -5
  231. package/dist/shadow/pcf_opt.js.map +1 -1
  232. package/dist/shadow/pcf_pd.js +1 -1
  233. package/dist/shadow/pcf_pd.js.map +1 -1
  234. package/dist/shadow/receiver_bias.js +41 -0
  235. package/dist/shadow/receiver_bias.js.map +1 -0
  236. package/dist/shadow/shader.js +20 -60
  237. package/dist/shadow/shader.js.map +1 -1
  238. package/dist/shadow/shadow_impl.js +89 -0
  239. package/dist/shadow/shadow_impl.js.map +1 -1
  240. package/dist/shadow/shadow_region.js +1 -1
  241. package/dist/shadow/shadow_region.js.map +1 -1
  242. package/dist/shadow/shadowmapper.js +150 -37
  243. package/dist/shadow/shadowmapper.js.map +1 -1
  244. package/dist/shapes/shape.js +11 -2
  245. package/dist/shapes/shape.js.map +1 -1
  246. package/dist/shapes/sphere.js +50 -9
  247. package/dist/shapes/sphere.js.map +1 -1
  248. package/dist/utility/blueprint/common/constants.js +112 -2
  249. package/dist/utility/blueprint/common/constants.js.map +1 -1
  250. package/dist/utility/blueprint/material/func.js +142 -49
  251. package/dist/utility/blueprint/material/func.js.map +1 -1
  252. package/dist/utility/blueprint/material/ir.js +490 -25
  253. package/dist/utility/blueprint/material/ir.js.map +1 -1
  254. package/dist/utility/blueprint/material/texture.js +898 -4
  255. package/dist/utility/blueprint/material/texture.js.map +1 -1
  256. package/dist/utility/serialization/manager.js +434 -101
  257. package/dist/utility/serialization/manager.js.map +1 -1
  258. package/dist/utility/serialization/scene/animation.js +401 -5
  259. package/dist/utility/serialization/scene/animation.js.map +1 -1
  260. package/dist/utility/serialization/scene/batch.js +4 -0
  261. package/dist/utility/serialization/scene/batch.js.map +1 -1
  262. package/dist/utility/serialization/scene/camera.js +186 -26
  263. package/dist/utility/serialization/scene/camera.js.map +1 -1
  264. package/dist/utility/serialization/scene/common.js +26 -5
  265. package/dist/utility/serialization/scene/common.js.map +1 -1
  266. package/dist/utility/serialization/scene/hair.js +1141 -0
  267. package/dist/utility/serialization/scene/hair.js.map +1 -0
  268. package/dist/utility/serialization/scene/light.js +84 -4
  269. package/dist/utility/serialization/scene/light.js.map +1 -1
  270. package/dist/utility/serialization/scene/material.js +1867 -166
  271. package/dist/utility/serialization/scene/material.js.map +1 -1
  272. package/dist/utility/serialization/scene/mesh.js +231 -14
  273. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  274. package/dist/utility/serialization/scene/node.js +141 -7
  275. package/dist/utility/serialization/scene/node.js.map +1 -1
  276. package/dist/utility/serialization/scene/particle.js +4 -0
  277. package/dist/utility/serialization/scene/particle.js.map +1 -1
  278. package/dist/utility/serialization/scene/primitive.js +18 -0
  279. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  280. package/dist/utility/serialization/scene/sprite.js +4 -0
  281. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  282. package/dist/utility/serialization/scene/terrain.js +4 -0
  283. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  284. package/dist/utility/serialization/scene/text.js +4 -0
  285. package/dist/utility/serialization/scene/text.js.map +1 -1
  286. package/dist/utility/serialization/scene/water.js +1105 -21
  287. package/dist/utility/serialization/scene/water.js.map +1 -1
  288. package/dist/utility/serialization/types.js.map +1 -1
  289. package/dist/utility/shprojector.js +9 -8
  290. package/dist/utility/shprojector.js.map +1 -1
  291. package/dist/values.js +49 -2
  292. package/dist/values.js.map +1 -1
  293. package/package.json +3 -3
  294. package/dist/render/rendergraph/frame_graph_context.js +0 -41
  295. package/dist/render/rendergraph/frame_graph_context.js.map +0 -1
  296. package/dist/shaders/ssgi.js +0 -63
  297. package/dist/shaders/ssgi.js.map +0 -1
  298. package/dist/shaders/ssgi_reprojection.js +0 -118
  299. package/dist/shaders/ssgi_reprojection.js.map +0 -1
@@ -236,6 +236,8 @@ function cloneInterpolator(src) {
236
236
  function createJointRetargetRemap(srcSkeleton, dstSkeleton, srcJoint, dstJoint, translationRotation, translationScale, translationCorrection, translationAxisLocks, rotationCorrection) {
237
237
  const si = srcSkeleton.joints.indexOf(srcJoint);
238
238
  const di = dstSkeleton.joints.indexOf(dstJoint);
239
+ const srcReferencePose = srcSkeleton.retargetPose[si];
240
+ const dstReferencePose = dstSkeleton.retargetPose[di];
239
241
  const srcBindPose = srcSkeleton.bindPose[si];
240
242
  const dstBindPose = dstSkeleton.bindPose[di];
241
243
  const srcLen = srcBindPose.position.magnitude;
@@ -244,10 +246,10 @@ function createJointRetargetRemap(srcSkeleton, dstSkeleton, srcJoint, dstJoint,
244
246
  dstNode: dstJoint,
245
247
  dstJointIndex: di,
246
248
  srcNode: srcJoint,
247
- srcBindRotInv: Quaternion.inverse(srcBindPose.rotation),
248
- dstBindRot: dstBindPose.rotation.clone(),
249
+ srcBindRotInv: Quaternion.inverse(srcReferencePose.rotation),
250
+ dstBindRot: dstReferencePose.rotation.clone(),
249
251
  rotationCorrection,
250
- srcBindPos: srcBindPose.position.clone(),
252
+ srcBindPos: srcReferencePose.position.clone(),
251
253
  dstBindPos: dstBindPose.position.clone(),
252
254
  translationScale: translationScale ?? (srcLen > 1e-6 ? dstLen / srcLen : 1),
253
255
  translationRotation,
@@ -275,15 +277,14 @@ function getBindPosition(skeleton, joint) {
275
277
  const index = skeleton.joints.indexOf(joint);
276
278
  return index >= 0 ? skeleton.bindPose[index].position : null;
277
279
  }
278
- function getSkeletonLocalBindTransform(skeleton, node, jointSet, cache) {
280
+ function getSkeletonLocalReferenceTransform(skeleton, node, jointSet, cache) {
279
281
  let transform = cache.get(node);
280
282
  if (!transform) {
281
- const bindPose = getRigBindPoseForNode(skeleton, node);
282
- const position = bindPose.position.clone();
283
- const rotation = bindPose.rotation.clone();
283
+ const position = getRigBindPoseForNode(skeleton, node).position.clone();
284
+ const rotation = getRigReferencePoseForNode(skeleton, node).rotation.clone();
284
285
  const parent = node.parent;
285
286
  if (parent && jointSet.has(parent)) {
286
- const parentTransform = getSkeletonLocalBindTransform(skeleton, parent, jointSet, cache);
287
+ const parentTransform = getSkeletonLocalReferenceTransform(skeleton, parent, jointSet, cache);
287
288
  parentTransform.rotation.transform(position, position);
288
289
  position.addBy(parentTransform.position);
289
290
  Quaternion.multiply(parentTransform.rotation, rotation, rotation);
@@ -345,7 +346,7 @@ function getHumanoidLateralXSign(skeleton) {
345
346
  if (!left || !right || !jointSet.has(left) || !jointSet.has(right)) {
346
347
  continue;
347
348
  }
348
- const dx = getSkeletonLocalBindTransform(skeleton, left, jointSet, cache).position.x - getSkeletonLocalBindTransform(skeleton, right, jointSet, cache).position.x;
349
+ const dx = getSkeletonLocalReferenceTransform(skeleton, left, jointSet, cache).position.x - getSkeletonLocalReferenceTransform(skeleton, right, jointSet, cache).position.x;
349
350
  if (Math.abs(dx) > 1e-5) {
350
351
  score += dx;
351
352
  weight++;
@@ -381,7 +382,7 @@ function getHumanoidForwardZSign(skeleton) {
381
382
  if (!foot || !toes || !jointSet.has(foot) || !jointSet.has(toes)) {
382
383
  continue;
383
384
  }
384
- const dz = getSkeletonLocalBindTransform(skeleton, toes, jointSet, cache).position.z - getSkeletonLocalBindTransform(skeleton, foot, jointSet, cache).position.z;
385
+ const dz = getSkeletonLocalReferenceTransform(skeleton, toes, jointSet, cache).position.z - getSkeletonLocalReferenceTransform(skeleton, foot, jointSet, cache).position.z;
385
386
  if (Math.abs(dz) > 1e-5) {
386
387
  score += dz;
387
388
  weight++;
@@ -420,6 +421,13 @@ function getHumanoidRotationCorrection(srcSkeleton, dstSkeleton, srcSignSkeleton
420
421
  z: determinant * axisZSign
421
422
  };
422
423
  }
424
+ function getRigReferencePoseForNode(skeleton, node) {
425
+ return skeleton.getRetargetPoseForJoint(node) ?? (node === skeleton.rootJoint ? skeleton.rootBindPose : {
426
+ position: node.position,
427
+ rotation: node.rotation,
428
+ scale: node.scale
429
+ });
430
+ }
423
431
  function getRigBindPoseForNode(skeleton, node) {
424
432
  return skeleton.getBindPoseForJoint(node) ?? (node === skeleton.rootJoint ? skeleton.rootBindPose : {
425
433
  position: node.position,
@@ -463,11 +471,36 @@ function getHumanoidRootMotionScale(srcSkeleton, dstSkeleton) {
463
471
  function findTranslationTrack(tracks) {
464
472
  return tracks?.find((track)=>track instanceof NodeTranslationTrack) ?? null;
465
473
  }
466
- function findAncestorTranslationTrack(clip, node, modelRoot) {
474
+ function isTranslationTrackAnimated(track) {
475
+ const inputs = track.interpolator.inputs;
476
+ const outputs = track.interpolator.outputs;
477
+ const cubic = track.interpolator.mode === 'cubicspline';
478
+ const stride = cubic ? 9 : 3;
479
+ const valueOffset = cubic ? 3 : 0;
480
+ if (inputs.length < 2) {
481
+ return false;
482
+ }
483
+ const first = [
484
+ outputs[valueOffset],
485
+ outputs[valueOffset + 1],
486
+ outputs[valueOffset + 2]
487
+ ];
488
+ let maxValue = Math.max(1, Math.abs(first[0]), Math.abs(first[1]), Math.abs(first[2]));
489
+ let maxDelta = 0;
490
+ for(let i = 1; i < inputs.length; i++){
491
+ const base = i * stride + valueOffset;
492
+ for(let axis = 0; axis < 3; axis++){
493
+ maxValue = Math.max(maxValue, Math.abs(outputs[base + axis]));
494
+ maxDelta = Math.max(maxDelta, Math.abs(outputs[base + axis] - first[axis]));
495
+ }
496
+ }
497
+ return maxDelta > maxValue * 1e-5;
498
+ }
499
+ function findAncestorTranslationTrack(clip, node, modelRoot, animatedOnly = false) {
467
500
  let current = node.parent;
468
501
  while(current){
469
502
  const track = findTranslationTrack(clip.tracks.get(current));
470
- if (track) {
503
+ if (track && (!animatedOnly || isTranslationTrackAnimated(track))) {
471
504
  return {
472
505
  node: current,
473
506
  track
@@ -667,18 +700,20 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
667
700
  const remapsByDstNode = new Map();
668
701
  const srcJointSet = new Set(srcSkeleton.joints);
669
702
  const dstJointSet = new Set(dstSkeleton.joints);
670
- const srcBindRotByNode = new Map();
671
- const dstBindRotByNode = new Map();
703
+ const srcReferenceRotByNode = new Map();
704
+ const srcBaseRotByNode = new Map();
705
+ const dstReferenceRotByNode = new Map();
672
706
  const srcRotationTrackByNode = new Map();
673
707
  for(let i = 0; i < srcSkeleton.joints.length; i++){
674
708
  const joint = srcSkeleton.joints[i];
675
- srcBindRotByNode.set(joint, srcSkeleton.bindPose[i].rotation);
709
+ srcReferenceRotByNode.set(joint, srcSkeleton.retargetPose[i].rotation);
710
+ srcBaseRotByNode.set(joint, srcSkeleton.bindPose[i].rotation);
676
711
  const track = findRotationTrack(sourceClip.tracks.get(joint));
677
712
  srcRotationTrackByNode.set(joint, track);
678
713
  collectTrackTimes(track, times);
679
714
  }
680
715
  for(let i = 0; i < dstSkeleton.joints.length; i++){
681
- dstBindRotByNode.set(dstSkeleton.joints[i], dstSkeleton.bindPose[i].rotation);
716
+ dstReferenceRotByNode.set(dstSkeleton.joints[i], dstSkeleton.retargetPose[i].rotation);
682
717
  }
683
718
  for (const remap of remaps){
684
719
  const track = findRotationTrack(sourceClip.tracks.get(remap.srcNode));
@@ -705,7 +740,7 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
705
740
  function getSrcBindWorldRot(node) {
706
741
  let rot = srcBindWorldRots.get(node);
707
742
  if (!rot) {
708
- rot = (srcBindRotByNode.get(node) ?? Quaternion.identity()).clone();
743
+ rot = (srcReferenceRotByNode.get(node) ?? Quaternion.identity()).clone();
709
744
  const parent = node.parent;
710
745
  if (parent && srcJointSet.has(parent)) {
711
746
  Quaternion.multiply(getSrcBindWorldRot(parent), rot, rot);
@@ -719,7 +754,7 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
719
754
  function getDstBindWorldRot(node) {
720
755
  let rot = dstBindWorldRots.get(node);
721
756
  if (!rot) {
722
- rot = (dstBindRotByNode.get(node) ?? Quaternion.identity()).clone();
757
+ rot = (dstReferenceRotByNode.get(node) ?? Quaternion.identity()).clone();
723
758
  const parent = node.parent;
724
759
  if (parent && dstJointSet.has(parent)) {
725
760
  Quaternion.multiply(getDstBindWorldRot(parent), rot, rot);
@@ -738,7 +773,7 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
738
773
  }
739
774
  const parent = node.parent;
740
775
  const parentWorldRot = parent && srcJointSet.has(parent) ? getSrcAnimWorldRot(parent, time) : null;
741
- sampleRotationTrack(srcRotationTrackByNode.get(node) ?? null, time, srcBindRotByNode.get(node) ?? Quaternion.identity(), tmpLocalRot);
776
+ sampleRotationTrack(srcRotationTrackByNode.get(node) ?? null, time, srcBaseRotByNode.get(node) ?? Quaternion.identity(), tmpLocalRot);
742
777
  if (parentWorldRot) {
743
778
  Quaternion.multiply(parentWorldRot, tmpLocalRot, rot);
744
779
  } else {
@@ -776,7 +811,7 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
776
811
  }
777
812
  let rot = dstAnimWorldRots.get(parent);
778
813
  if (!rot) {
779
- rot = (dstBindRotByNode.get(parent) ?? Quaternion.identity()).clone();
814
+ rot = (dstReferenceRotByNode.get(parent) ?? Quaternion.identity()).clone();
780
815
  const parentWorldRot = getDstParentAnimWorldRot(parent, time);
781
816
  if (parentWorldRot) {
782
817
  Quaternion.multiply(parentWorldRot, rot, rot);
@@ -802,7 +837,7 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
802
837
  }
803
838
  }
804
839
  for (const remap of remaps){
805
- if (!rotationTracksByRemap.get(remap)) {
840
+ if (!rotationTracksByRemap.get(remap) && !srcSkeleton.hasRetargetPose && !dstSkeleton.hasRetargetPose) {
806
841
  continue;
807
842
  }
808
843
  const outputs = new Float32Array(outputsByRemap.get(remap));
@@ -1632,6 +1667,7 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
1632
1667
  const options = typeof targetNameOrOptions === 'string' ? copyOptions ?? {} : targetNameOrOptions ?? {};
1633
1668
  const destName = typeof targetNameOrOptions === 'string' ? targetNameOrOptions : options.targetName ?? animationName;
1634
1669
  const rootMotion = options.rootMotion ?? 'scaled';
1670
+ const hipsTranslation = options.hipsTranslation ?? 'scaled';
1635
1671
  const jointTranslations = options.jointTranslations ?? 'skip';
1636
1672
  const sourceClip = sourceSet.get(animationName);
1637
1673
  if (!sourceClip) {
@@ -1731,16 +1767,19 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
1731
1767
  const dstHipsNode = dstSkeleton.humanoidJointMapping.body[HumanoidBodyRig.Hips];
1732
1768
  const srcRootNode = srcSkeleton.rootJoint ?? srcHipsNode;
1733
1769
  const dstRootNode = dstSkeleton.rootJoint ?? dstHipsNode;
1770
+ const hasSeparateHips = srcRootNode !== srcHipsNode && dstRootNode !== dstHipsNode;
1734
1771
  const srcRootRot = computeParentChainRotation(srcRootNode, sourceSet.model, srcSkeleton);
1735
1772
  const dstRootRot = computeParentChainRotation(dstRootNode, this._model, dstSkeleton);
1736
- const srcRootTranslationTrack = findTranslationTrack(sourceClip.tracks.get(srcRootNode));
1737
- const srcAncestorTranslationTrackInfo = !srcRootTranslationTrack ? findAncestorTranslationTrack(sourceClip, srcRootNode, sourceSet.model) : null;
1738
- const srcFallbackHipsTranslationTrack = !srcRootTranslationTrack && !srcAncestorTranslationTrackInfo && srcRootNode !== srcHipsNode ? findTranslationTrack(sourceClip.tracks.get(srcHipsNode)) : null;
1739
- const srcMotionTrack = srcRootTranslationTrack ?? srcAncestorTranslationTrackInfo?.track ?? srcFallbackHipsTranslationTrack;
1740
- const srcMotionNode = srcRootTranslationTrack ? srcRootNode : srcAncestorTranslationTrackInfo ? srcAncestorTranslationTrackInfo.node : srcFallbackHipsTranslationTrack ? srcHipsNode : null;
1773
+ const rootTrackCandidate = findTranslationTrack(sourceClip.tracks.get(srcRootNode));
1774
+ const srcRootTranslationTrack = rootTrackCandidate && (!hasSeparateHips || isTranslationTrackAnimated(rootTrackCandidate)) ? rootTrackCandidate : null;
1775
+ const srcAncestorTranslationTrackInfo = !srcRootTranslationTrack ? findAncestorTranslationTrack(sourceClip, srcRootNode, sourceSet.model, hasSeparateHips) : null;
1776
+ const srcMotionTrack = srcRootTranslationTrack ?? srcAncestorTranslationTrackInfo?.track ?? null;
1777
+ const srcMotionNode = srcRootTranslationTrack ? srcRootNode : srcAncestorTranslationTrackInfo ? srcAncestorTranslationTrackInfo.node : null;
1741
1778
  const srcMotionParentRot = srcMotionNode ? computeParentChainRotation(srcMotionNode, sourceSet.model, srcSkeleton) : srcRootRot;
1742
1779
  const rootTranslationRotation = Quaternion.multiply(Quaternion.inverse(dstRootRot), srcMotionParentRot);
1743
- const rootTranslationScale = rootMotion === 'scaled' ? typeof options.rootMotionScale === 'number' ? options.rootMotionScale : options.rootMotionScale === 'none' ? 1 : getHumanoidRootMotionScale(srcSkeleton, dstSkeleton) : 1;
1780
+ const resolveTranslationScale = (mode)=>typeof mode === 'number' ? mode : mode === 'none' ? 1 : getHumanoidRootMotionScale(srcSkeleton, dstSkeleton);
1781
+ const rootTranslationScale = rootMotion === 'scaled' ? resolveTranslationScale(options.rootMotionScale) : 1;
1782
+ const hipsTranslationScale = hipsTranslation === 'scaled' ? resolveTranslationScale(options.hipsTranslationScale) : 1;
1744
1783
  const jointRemaps = [];
1745
1784
  const jointRemapsByDstSkeleton = new Map([
1746
1785
  [
@@ -1842,9 +1881,14 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
1842
1881
  if (rootMotion === 'locked') {
1843
1882
  dstRootTrack = createConstantTranslationTrack(dstRootBindPose.position);
1844
1883
  } else if (srcMotionTrack && srcMotionNode) {
1845
- const srcMotionBindPose = getRigBindPoseForNode(srcSkeleton, srcMotionNode);
1846
- const rootRemap = createTranslationRetargetRemap(srcMotionNode, dstRootNode, srcMotionBindPose.position, dstRootBindPose.position, dstSkeleton.joints.indexOf(dstRootNode), rootTranslationScale, rootTranslationRotation, humanoidRotationCorrection ?? undefined, options.lockRootMotionAxes, humanoidRotationCorrection ?? undefined);
1884
+ const srcMotionBindPose = getRigReferencePoseForNode(srcSkeleton, srcMotionNode);
1885
+ const rootMotionAxisLocks = options.lockRootMotionAxes ?? (hasSeparateHips ? {
1886
+ y: true
1887
+ } : undefined);
1888
+ const rootRemap = createTranslationRetargetRemap(srcMotionNode, dstRootNode, srcMotionBindPose.position, dstRootBindPose.position, dstSkeleton.joints.indexOf(dstRootNode), rootTranslationScale, rootTranslationRotation, humanoidRotationCorrection ?? undefined, rootMotionAxisLocks, humanoidRotationCorrection ?? undefined);
1847
1889
  dstRootTrack = retargetTranslationTrack(srcMotionTrack, rootRemap);
1890
+ } else {
1891
+ dstRootTrack = createConstantTranslationTrack(dstRootBindPose.position);
1848
1892
  }
1849
1893
  if (dstRootTrack) {
1850
1894
  dstRootTrack.name = srcMotionTrack?.name ?? 'translation';
@@ -1853,6 +1897,24 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
1853
1897
  dstClip.addTrack(dstRootNode, dstRootTrack);
1854
1898
  }
1855
1899
  }
1900
+ if (hasSeparateHips && hipsTranslation !== 'none') {
1901
+ const srcHipsTrack = findTranslationTrack(sourceClip.tracks.get(srcHipsNode)) ?? (srcSkeleton.hasRetargetPose ? createConstantTranslationTrack(getRigBindPoseForNode(srcSkeleton, srcHipsNode).position) : null);
1902
+ const dstHipsBindPose = getRigBindPoseForNode(dstSkeleton, dstHipsNode);
1903
+ let dstHipsTrack = null;
1904
+ if (hipsTranslation === 'locked') {
1905
+ dstHipsTrack = createConstantTranslationTrack(dstHipsBindPose.position);
1906
+ } else if (srcHipsTrack) {
1907
+ const srcHipsReferencePose = getRigReferencePoseForNode(srcSkeleton, srcHipsNode);
1908
+ const hipsRemap = createTranslationRetargetRemap(srcHipsNode, dstHipsNode, srcHipsReferencePose.position, dstHipsBindPose.position, dstSkeleton.joints.indexOf(dstHipsNode), hipsTranslationScale, undefined, humanoidRotationCorrection ?? undefined, undefined, humanoidRotationCorrection ?? undefined);
1909
+ dstHipsTrack = retargetTranslationTrack(srcHipsTrack, hipsRemap);
1910
+ }
1911
+ if (dstHipsTrack) {
1912
+ dstHipsTrack.name = srcHipsTrack?.name ?? 'translation';
1913
+ dstHipsTrack.target = dstHipsNode.persistentId;
1914
+ dstHipsTrack.jointIndex = dstSkeleton.joints.indexOf(dstHipsNode);
1915
+ dstClip.addTrack(dstHipsNode, dstHipsTrack);
1916
+ }
1917
+ }
1856
1918
  for (const [srcNode, srcRemaps] of jointRemapsBySrcNode){
1857
1919
  const srcTracks = sourceClip.tracks.get(srcNode);
1858
1920
  if (!srcTracks) {
@@ -1865,7 +1927,7 @@ function bakeHumanoidRotationTracks(sourceClip, srcSkeleton, dstSkeleton, srcRoo
1865
1927
  if (srcTrack instanceof NodeRotationTrack || srcTrack instanceof NodeEulerRotationTrack) {
1866
1928
  continue;
1867
1929
  } else if (srcTrack instanceof NodeTranslationTrack) {
1868
- if (srcNode === srcRootNode || srcTrack === srcMotionTrack || jointTranslations !== 'preserve') {
1930
+ if (srcNode === srcRootNode || hasSeparateHips && srcNode === srcHipsNode || srcTrack === srcMotionTrack || jointTranslations !== 'preserve') {
1869
1931
  continue;
1870
1932
  }
1871
1933
  dstTrack = retargetTranslationTrack(srcTrack, remap);