@woosh/meep-engine 3.40.0 → 3.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/quaternion/swing_twist_clamp.d.ts +24 -0
  3. package/src/core/geom/3d/quaternion/swing_twist_clamp.d.ts.map +1 -0
  4. package/src/core/geom/3d/quaternion/swing_twist_clamp.js +62 -0
  5. package/src/core/geom/3d/quaternion/swing_twist_compose.d.ts +15 -0
  6. package/src/core/geom/3d/quaternion/swing_twist_compose.d.ts.map +1 -0
  7. package/src/core/geom/3d/quaternion/swing_twist_compose.js +36 -0
  8. package/src/core/geom/3d/quaternion/swing_twist_error.d.ts +39 -0
  9. package/src/core/geom/3d/quaternion/swing_twist_error.d.ts.map +1 -0
  10. package/src/core/geom/3d/quaternion/swing_twist_error.js +85 -0
  11. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts +11 -6
  12. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts.map +1 -1
  13. package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +27 -13
  14. package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts +25 -0
  15. package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts.map +1 -0
  16. package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.js +166 -0
  17. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts +5 -3
  18. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -1
  19. package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.js +5 -3
  20. package/src/engine/animation/curve/AnimationCurve.d.ts +3 -0
  21. package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
  22. package/src/engine/animation/curve/AnimationCurve.js +6 -1
  23. package/src/engine/ecs/EntityManager.d.ts +9 -1
  24. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  25. package/src/engine/ecs/EntityManager.js +26 -27
  26. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts +20 -0
  27. package/src/engine/ecs/gpu/GPUStateAuthority.d.ts.map +1 -1
  28. package/src/engine/ecs/gpu/GPUStateAuthority.js +21 -0
  29. package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.d.ts +13 -0
  30. package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.d.ts.map +1 -0
  31. package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.js +12 -0
  32. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts +6 -0
  33. package/src/engine/ecs/gpu/gpu_authority_grant.d.ts.map +1 -1
  34. package/src/engine/ecs/gpu/gpu_authority_grant.js +7 -1
  35. package/src/engine/ecs/gpu/gpu_authority_held.d.ts +14 -0
  36. package/src/engine/ecs/gpu/gpu_authority_held.d.ts.map +1 -0
  37. package/src/engine/ecs/gpu/gpu_authority_held.js +23 -0
  38. package/src/engine/ecs/gpu/gpu_authority_hold.d.ts +23 -0
  39. package/src/engine/ecs/gpu/gpu_authority_hold.d.ts.map +1 -0
  40. package/src/engine/ecs/gpu/gpu_authority_hold.js +41 -0
  41. package/src/engine/ecs/gpu/gpu_authority_unhold.d.ts +14 -0
  42. package/src/engine/ecs/gpu/gpu_authority_unhold.d.ts.map +1 -0
  43. package/src/engine/ecs/gpu/gpu_authority_unhold.js +32 -0
  44. package/src/engine/ecs/ik/IKGoal.d.ts +59 -0
  45. package/src/engine/ecs/ik/IKGoal.d.ts.map +1 -0
  46. package/src/engine/ecs/ik/IKGoal.js +83 -0
  47. package/src/engine/ecs/ik/IKGoalSystem.d.ts +75 -0
  48. package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -0
  49. package/src/engine/ecs/ik/IKGoalSystem.js +1456 -0
  50. package/src/engine/ecs/ik/PLAN.md +179 -0
  51. package/src/engine/ecs/speaker/VoiceSystem.d.ts +2 -2
  52. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  53. package/src/engine/ecs/storage/BinaryBufferSerializer.d.ts.map +1 -1
  54. package/src/engine/ecs/storage/BinaryBufferSerializer.js +4 -5
  55. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +7 -3
  56. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  57. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +1 -2
  58. package/src/engine/ecs/system/orderSystemsByDeclaredAccess.d.ts +33 -0
  59. package/src/engine/ecs/system/orderSystemsByDeclaredAccess.d.ts.map +1 -0
  60. package/src/engine/ecs/system/orderSystemsByDeclaredAccess.js +282 -0
  61. package/src/engine/ecs/transform/T64WorldCache.js +139 -139
  62. package/src/engine/ecs/transform/t64_evaluate_local.d.ts +25 -0
  63. package/src/engine/ecs/transform/t64_evaluate_local.d.ts.map +1 -0
  64. package/src/engine/ecs/transform/t64_evaluate_local.js +35 -0
  65. package/src/engine/ecs/transform/t64_evaluate_world.d.ts +5 -3
  66. package/src/engine/ecs/transform/t64_evaluate_world.d.ts.map +1 -1
  67. package/src/engine/ecs/transform/t64_evaluate_world.js +128 -126
  68. package/src/engine/graphics3/AnimationGraphSystem.d.ts +2 -0
  69. package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
  70. package/src/engine/graphics3/AnimationGraphSystem.js +337 -329
  71. package/src/engine/graphics3/AnimationSystem.d.ts +2 -0
  72. package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
  73. package/src/engine/graphics3/AnimationSystem.js +360 -352
  74. package/src/engine/physics/cloth/MEASUREMENTS.md +130 -0
  75. package/src/engine/physics/cloth/PLAN.md +16 -1
  76. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +5 -6
  77. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
  78. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +5 -6
  79. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +4 -7
  80. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  81. package/src/engine/physics/cloth/ecs/ClothInstance.js +4 -7
  82. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +4 -3
  83. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  84. package/src/engine/physics/cloth/ecs/ClothSystem.js +4 -3
  85. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  86. package/src/engine/physics/cloth/ecs/ClothWorld.js +10 -0
  87. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +24 -24
  88. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
  89. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +46 -43
  90. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +1 -1
  91. package/src/engine/physics/cloth/ecs/cloth_write_back.js +1 -1
  92. package/src/engine/physics/constraint/solve_constraints.d.ts +0 -35
  93. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  94. package/src/engine/physics/constraint/solve_constraints.js +1 -83
  95. package/src/engine/physics/ecs/ContactProbe.d.ts +73 -0
  96. package/src/engine/physics/ecs/ContactProbe.d.ts.map +1 -0
  97. package/src/engine/physics/ecs/ContactProbe.js +103 -0
  98. package/src/engine/physics/ecs/ContactProbeSystem.d.ts +44 -0
  99. package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -0
  100. package/src/engine/physics/ecs/ContactProbeSystem.js +397 -0
  101. package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +1 -1
  102. package/src/engine/physics/fluid/ecs/FluidComponent.js +1 -1
  103. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  104. package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.d.ts +205 -0
  105. package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.d.ts.map +1 -0
  106. package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.js +245 -0
  107. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.d.ts +21 -0
  108. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.d.ts.map +1 -0
  109. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.js +63 -0
  110. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts +33 -0
  111. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -0
  112. package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +874 -0
  113. package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.d.ts +27 -0
  114. package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.d.ts.map +1 -0
  115. package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.js +77 -0
  116. package/src/engine/physics/inverse_kinematics/two_bone_path_solve.d.ts +36 -0
  117. package/src/engine/physics/inverse_kinematics/two_bone_path_solve.d.ts.map +1 -0
  118. package/src/engine/physics/inverse_kinematics/two_bone_path_solve.js +97 -0
  119. package/src/engine/physics/inverse_kinematics/two_joint_ik.d.ts +33 -11
  120. package/src/engine/physics/inverse_kinematics/two_joint_ik.d.ts.map +1 -1
  121. package/src/engine/physics/inverse_kinematics/two_joint_ik.js +158 -67
  122. package/src/shade/renderer/animation/ANIMATION_TRACK_BINDING_STRUCT.d.ts.map +1 -1
  123. package/src/shade/renderer/animation/ANIMATION_TRACK_BINDING_STRUCT.js +10 -1
  124. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +10 -4
  125. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  126. package/src/shade/renderer/animation/GPUAnimationManager.js +251 -23
  127. package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.d.ts +12 -4
  128. package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.d.ts.map +1 -1
  129. package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.js +12 -4
  130. package/src/shade/renderer/animation/chunk_pose_accumulator.d.ts.map +1 -1
  131. package/src/shade/renderer/animation/chunk_pose_accumulator.js +14 -1
  132. package/src/shade/renderer/animation/pose/PoseChannelIndex.d.ts +78 -0
  133. package/src/shade/renderer/animation/pose/PoseChannelIndex.d.ts.map +1 -0
  134. package/src/shade/renderer/animation/pose/PoseChannelIndex.js +274 -0
  135. package/src/shade/renderer/animation/pose/PosePlayback.d.ts +40 -3
  136. package/src/shade/renderer/animation/pose/PosePlayback.d.ts.map +1 -1
  137. package/src/shade/renderer/animation/pose/PosePlayback.js +77 -3
  138. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts +21 -3
  139. package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts.map +1 -1
  140. package/src/shade/renderer/animation/pose/pose_evaluate_local.js +79 -11
  141. package/src/shade/renderer/animation/shader_animation_apply.js +1 -1
  142. package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts +3 -2
  143. package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts.map +1 -1
  144. package/src/shade/renderer/animation/shader_animation_pose_resolve.js +187 -176
  145. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  146. package/src/shade/renderer/object_property/chunk_write_object_property.d.ts +3 -1
  147. package/src/shade/renderer/object_property/chunk_write_object_property.d.ts.map +1 -1
  148. package/src/shade/renderer/object_property/chunk_write_object_property.js +5 -2
  149. package/src/shade/renderer/object_property/chunk_write_object_property_node3d.d.ts +4 -0
  150. package/src/shade/renderer/object_property/chunk_write_object_property_node3d.d.ts.map +1 -1
  151. package/src/shade/renderer/object_property/chunk_write_object_property_node3d.js +6 -1
  152. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  153. package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts +1 -1
  154. package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts.map +1 -1
  155. package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.js +135 -73
  156. package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts +7 -0
  157. package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts.map +1 -1
  158. package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.js +29 -1
  159. package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.d.ts +19 -0
  160. package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.d.ts.map +1 -0
  161. package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.js +167 -0
  162. package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.d.ts +25 -0
  163. package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.d.ts.map +1 -0
  164. package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.js +124 -0
  165. package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.d.ts +19 -0
  166. package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.d.ts.map +1 -0
  167. package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.js +48 -0
  168. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +17 -1
  169. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  170. package/src/shade/renderer/scene/rows/GPUSceneRows.js +29 -3
  171. package/src/engine/ecs/ik/IKConstraint.d.ts +0 -52
  172. package/src/engine/ecs/ik/IKConstraint.d.ts.map +0 -1
  173. package/src/engine/ecs/ik/IKConstraint.js +0 -95
  174. package/src/engine/ecs/ik/IKProblem.d.ts +0 -45
  175. package/src/engine/ecs/ik/IKProblem.d.ts.map +0 -1
  176. package/src/engine/ecs/ik/IKProblem.js +0 -58
  177. package/src/engine/ecs/ik/IKSolver.d.ts +0 -8
  178. package/src/engine/ecs/ik/IKSolver.d.ts.map +0 -1
  179. package/src/engine/ecs/ik/IKSolver.js +0 -9
  180. package/src/engine/ecs/ik/InverseKinematics.d.ts +0 -48
  181. package/src/engine/ecs/ik/InverseKinematics.d.ts.map +0 -1
  182. package/src/engine/ecs/ik/InverseKinematics.js +0 -119
  183. package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.d.ts +0 -19
  184. package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.d.ts.map +0 -1
  185. package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.js +0 -72
  186. package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts +0 -54
  187. package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +0 -1
  188. package/src/engine/ecs/ik/InverseKinematicsSystem.js +0 -212
  189. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts +0 -8
  190. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts.map +0 -1
  191. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +0 -153
  192. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts +0 -5
  193. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts.map +0 -1
  194. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +0 -120
  195. package/src/engine/ecs/ik/ik_bone_chain.d.ts +0 -64
  196. package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +0 -1
  197. package/src/engine/ecs/ik/ik_bone_chain.js +0 -142
  198. package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts +0 -42
  199. package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts.map +0 -1
  200. package/src/engine/ecs/ik/ik_probe_terrain_contact.js +0 -123
  201. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +0 -18
  202. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +0 -1
  203. package/src/engine/ecs/ik/ik_write_local_rotation.js +0 -32
@@ -1,120 +0,0 @@
1
- import { SurfacePoint3 } from "../../../core/geom/3d/SurfacePoint3.js";
2
- import Quaternion from "../../../core/geom/Quaternion.js";
3
- import Vector3 from "../../../core/geom/Vector3.js";
4
- import { two_joint_ik } from "../../physics/inverse_kinematics/two_joint_ik.js";
5
- import { IKBone, ik_bone_chain } from "./ik_bone_chain.js";
6
- import { ik_probe_terrain_contact } from "./ik_probe_terrain_contact.js";
7
- import { t64_read_rotation } from "../transform/t64_read_rotation.js";
8
- import { t64_read_translation } from "../transform/t64_read_translation.js";
9
- import { IKSolver } from "./IKSolver.js";
10
- import { ik_write_local_rotation } from "./ik_write_local_rotation.js";
11
-
12
- const contact = new SurfacePoint3();
13
-
14
- const targetPosition = new Vector3();
15
-
16
- const positionA = new Vector3();
17
- const positionB = new Vector3();
18
- const positionC = new Vector3();
19
-
20
- const worldRotationA = new Quaternion();
21
- const worldRotationB = new Quaternion();
22
-
23
- const localRotationA = new Quaternion();
24
- const localRotationB = new Quaternion();
25
-
26
- const targetLocalRotationA = new Quaternion();
27
- const targetLocalRotationB = new Quaternion();
28
-
29
- const r0 = new Quaternion();
30
- const r1 = new Quaternion();
31
-
32
- /**
33
- * effector, its parent, its grandparent
34
- *
35
- * @type {IKBone[]}
36
- */
37
- const CHAIN = [new IKBone(), new IKBone(), new IKBone()];
38
-
39
- export class TwoBoneInverseKinematicsSolver extends IKSolver {
40
-
41
-
42
- solve(problem) {
43
-
44
- const { dataset, effector, terrain, constraint, playbacks, cache } = problem;
45
-
46
- if (!ik_bone_chain(CHAIN, dataset, effector, 3, playbacks, cache)) {
47
- // the hierarchy does not hold three links yet
48
- return;
49
- }
50
-
51
- const boneC = CHAIN[0];
52
- const boneB = CHAIN[1];
53
- const boneA = CHAIN[2];
54
-
55
- /*
56
- The world poses are read straight off the components. There is no matrix to bring up to
57
- date first: `TransformAttachmentSystem` composes a world transform the moment anything it
58
- depends on changes, so what is on the component is what the hierarchy currently says.
59
-
60
- They are read OUT of the transforms rather than used in place, because `two_joint_ik` is
61
- geometry math over vectors and quaternions and a Transform64 is an array with none of their
62
- methods on it.
63
- */
64
- t64_read_translation(positionA, boneA.world);
65
- t64_read_translation(positionB, boneB.world);
66
- t64_read_translation(positionC, boneC.world);
67
-
68
- //compute total length of the limb
69
- const limbLength = positionA.distanceTo(positionB) + positionB.distanceTo(positionC);
70
-
71
- //check if there is a penetration with the terrain between the two bones
72
- const influence = ik_probe_terrain_contact(
73
- targetPosition,
74
- contact,
75
- terrain,
76
- positionA.x, positionA.y, positionA.z,
77
- positionC.x, positionC.y, positionC.z,
78
- constraint,
79
- limbLength
80
- );
81
-
82
- if (influence <= 0) {
83
- //no contact, or no influence
84
- return;
85
- }
86
-
87
- t64_read_rotation(localRotationA, boneA.local);
88
- t64_read_rotation(localRotationB, boneB.local);
89
-
90
- t64_read_rotation(worldRotationA, boneA.world);
91
- t64_read_rotation(worldRotationB, boneB.world);
92
-
93
- targetLocalRotationA.copy(localRotationA);
94
- targetLocalRotationB.copy(localRotationB);
95
-
96
- //compute
97
- two_joint_ik(
98
- positionA,
99
- positionB,
100
- positionC,
101
- targetPosition,
102
- 0.01,
103
- worldRotationA,
104
- worldRotationB,
105
- targetLocalRotationA,
106
- targetLocalRotationB
107
- );
108
-
109
- //lerp bone rotations based on influence
110
- r0.lerpQuaternions(localRotationA, targetLocalRotationA, influence);
111
- r1.lerpQuaternions(localRotationB, targetLocalRotationB, influence);
112
-
113
- /*
114
- Both lerps are taken before either write, because a write recomposes every world transform
115
- below it — reading a bone's pose after moving its parent would read the corrected one.
116
- */
117
- ik_write_local_rotation(dataset, boneA, r0);
118
- ik_write_local_rotation(dataset, boneB, r1);
119
- }
120
- }
@@ -1,64 +0,0 @@
1
- /**
2
- * Fill a chain of bones running from the effector up towards the root.
3
- *
4
- * `result[0]` is the effector itself, `result[1]` its parent, and so on. The walk stops early when
5
- * the hierarchy runs out, which is how a chain that is too short to solve announces itself.
6
- *
7
- * @param {IKBone[]} result must hold at least `count` bones
8
- * @param {EntityComponentDataset} dataset
9
- * @param {number} effector
10
- * @param {number} count how many links the solver needs
11
- * @returns {boolean} `false` when the hierarchy holds fewer than `count` links above and including
12
- * the effector, or when one of them is not a full transform pair. Neither is an error — a model
13
- * that has not finished arriving looks exactly like this
14
- */
15
- export function ik_bone_chain(result: IKBone[], dataset: EntityComponentDataset, effector: number, count: number, playbacks?: any, cache?: any): boolean;
16
- /**
17
- * One link of a chain the solvers work on: the entity, the world pose the hierarchy composed for
18
- * it, and the local pose that composition came from.
19
- *
20
- * A solver reads the world pose and writes the local one — writing the world pose directly would be
21
- * overwritten by {@link TransformAttachmentSystem} the moment anything above moved, and the local
22
- * rotation is what a joint angle *is*.
23
- */
24
- export class IKBone {
25
- /**
26
- *
27
- * @type {number}
28
- */
29
- entity: number;
30
- /**
31
- * The bone's world pose this frame. Read only.
32
- *
33
- * The component itself when the CPU composes the chain; {@link evaluated} when the GPU does,
34
- * in which case the component holds whatever the CPU last composed and is not read.
35
- *
36
- * @type {Transform64|null}
37
- */
38
- world: Transform64 | null;
39
- /**
40
- * Where an evaluated world pose is written — see {@link ik_bone_chain}.
41
- *
42
- * @type {Transform64}
43
- */
44
- evaluated: Transform64;
45
- /**
46
- * Relative to the parent bone. This is what a solver writes.
47
- *
48
- * @type {Transform64|null}
49
- */
50
- local: Transform64 | null;
51
- /**
52
- * The component {@link IKBone#local} belongs to.
53
- *
54
- * A Transform64 announces nothing when it is written, so a solver has to say that it changed,
55
- * and the announcement names the component the hierarchy is listening for - which is this one,
56
- * not the transform inside it.
57
- *
58
- * @type {TransformAttachment|null}
59
- */
60
- attachment: TransformAttachment | null;
61
- }
62
- import { Transform64 } from "../transform/Transform64.js";
63
- import { TransformAttachment } from "../transform-attachment/TransformAttachment.js";
64
- //# sourceMappingURL=ik_bone_chain.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ik_bone_chain.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/ik/ik_bone_chain.js"],"names":[],"mappings":"AA2DA;;;;;;;;;;;;;GAaG;AACH,sCARW,MAAM,EAAE,6CAER,MAAM,SACN,MAAM,iCACJ,OAAO,CAwEnB;AArID;;;;;;;GAOG;AACH;IACI;;;OAGG;IACH,QAFU,MAAM,CAEJ;IAEZ;;;;;;;OAOG;IACH,OAFU,WAAW,GAAC,IAAI,CAEb;IAEb;;;;OAIG;IACH,WAFU,WAAW,CAES;IAE9B;;;;OAIG;IACH,OAFU,WAAW,GAAC,IAAI,CAEb;IAEb;;;;;;;;OAQG;IACH,YAFU,mBAAmB,GAAC,IAAI,CAEhB;CACrB;4BApD2B,6BAA6B;oCADrB,gDAAgD"}
@@ -1,142 +0,0 @@
1
- import { assert } from "../../../core/assert.js";
2
- import { GPUStateAuthorityFlags } from "../gpu/GPUStateAuthorityFlags.js";
3
- import { gpu_authority_has } from "../gpu/gpu_authority_has.js";
4
- import { transform_attachment_parent_of } from "../transform-attachment/transform_attachment_parent_of.js";
5
- import { TransformAttachment } from "../transform-attachment/TransformAttachment.js";
6
- import { Transform64 } from "../transform/Transform64.js";
7
- import { t64_evaluate_world } from "../transform/t64_evaluate_world.js";
8
-
9
- /**
10
- * One link of a chain the solvers work on: the entity, the world pose the hierarchy composed for
11
- * it, and the local pose that composition came from.
12
- *
13
- * A solver reads the world pose and writes the local one — writing the world pose directly would be
14
- * overwritten by {@link TransformAttachmentSystem} the moment anything above moved, and the local
15
- * rotation is what a joint angle *is*.
16
- */
17
- export class IKBone {
18
- /**
19
- *
20
- * @type {number}
21
- */
22
- entity = -1;
23
-
24
- /**
25
- * The bone's world pose this frame. Read only.
26
- *
27
- * The component itself when the CPU composes the chain; {@link evaluated} when the GPU does,
28
- * in which case the component holds whatever the CPU last composed and is not read.
29
- *
30
- * @type {Transform64|null}
31
- */
32
- world = null;
33
-
34
- /**
35
- * Where an evaluated world pose is written — see {@link ik_bone_chain}.
36
- *
37
- * @type {Transform64}
38
- */
39
- evaluated = new Transform64();
40
-
41
- /**
42
- * Relative to the parent bone. This is what a solver writes.
43
- *
44
- * @type {Transform64|null}
45
- */
46
- local = null;
47
-
48
- /**
49
- * The component {@link IKBone#local} belongs to.
50
- *
51
- * A Transform64 announces nothing when it is written, so a solver has to say that it changed,
52
- * and the announcement names the component the hierarchy is listening for - which is this one,
53
- * not the transform inside it.
54
- *
55
- * @type {TransformAttachment|null}
56
- */
57
- attachment = null;
58
- }
59
-
60
- /**
61
- * Fill a chain of bones running from the effector up towards the root.
62
- *
63
- * `result[0]` is the effector itself, `result[1]` its parent, and so on. The walk stops early when
64
- * the hierarchy runs out, which is how a chain that is too short to solve announces itself.
65
- *
66
- * @param {IKBone[]} result must hold at least `count` bones
67
- * @param {EntityComponentDataset} dataset
68
- * @param {number} effector
69
- * @param {number} count how many links the solver needs
70
- * @returns {boolean} `false` when the hierarchy holds fewer than `count` links above and including
71
- * the effector, or when one of them is not a full transform pair. Neither is an error — a model
72
- * that has not finished arriving looks exactly like this
73
- */
74
- export function ik_bone_chain(result, dataset, effector, count, playbacks = null, cache = null) {
75
- assert.isNonNegativeInteger(effector, 'effector');
76
- assert.isNonNegativeInteger(count, 'count');
77
- assert.ok(result.length >= count, 'result is too short for the requested chain');
78
-
79
- let entity = effector;
80
-
81
- for (let i = 0; i < count; i++) {
82
- if (entity === -1) {
83
- return false;
84
- }
85
-
86
- const world = dataset.getComponent(entity, Transform64);
87
-
88
- if (world === undefined) {
89
- return false;
90
- }
91
-
92
- const attachment = dataset.getComponent(entity, TransformAttachment);
93
-
94
- if (attachment === undefined) {
95
- // a root, so it has no joint angle to move and cannot be part of a chain
96
- return false;
97
- }
98
-
99
- const bone = result[i];
100
-
101
- bone.entity = entity;
102
- bone.world = world;
103
- bone.local = attachment.transform;
104
- bone.attachment = attachment;
105
-
106
- entity = transform_attachment_parent_of(dataset, entity);
107
- }
108
-
109
- /*
110
- A bone under a GPU-composed ancestor holds the world the CPU last composed, not this frame's:
111
- the chain is then evaluated exactly from the clips, which is what the GPU is drawing. The
112
- flag sits on the whole subtree below a driven joint, so the effector carries it whenever any
113
- bone above does; every bone is checked all the same, because that is cheap and the invariant
114
- is the animation manager's, not this walk's.
115
- */
116
- let gpu_composed = false;
117
-
118
- for (let i = 0; i < count; i++) {
119
- if (gpu_authority_has(dataset, result[i].entity, GPUStateAuthorityFlags.Transform64)) {
120
- gpu_composed = true;
121
- break;
122
- }
123
- }
124
-
125
- if (gpu_composed) {
126
- assert.defined(playbacks, 'playbacks: the chain is GPU-composed, so its world poses have to be evaluated');
127
-
128
- for (let i = 0; i < count; i++) {
129
- const bone = result[i];
130
-
131
- if (cache !== null) {
132
- cache.evaluate(bone.evaluated, dataset, bone.entity, playbacks);
133
- } else {
134
- t64_evaluate_world(bone.evaluated, dataset, bone.entity, playbacks);
135
- }
136
-
137
- bone.world = bone.evaluated;
138
- }
139
- }
140
-
141
- return true;
142
- }
@@ -1,42 +0,0 @@
1
- /**
2
- * Find where an IK chain meets the terrain and how strongly the solver should pull towards it.
3
- *
4
- * Two casts are made. The first travels from `origin` towards `effector` and establishes which
5
- * surface the limb is over at all. The second starts just outside that surface, directly above the
6
- * effector along the surface normal, and comes back down — that is what actually locates the point
7
- * under the effector rather than the point under the limb's root, and it is what `out_contact` and
8
- * `out_target` describe on return.
9
- *
10
- * The returned influence answers "how much of this correction should apply":
11
- * - the effector is BELOW the surface (penetrating) → `1`, correct it fully;
12
- * - the effector HOVERS above the surface → falls off from `1` to `0` across
13
- * `constraint.distance`, measured as a fraction of `length_scale`, so the same constraint reads
14
- * the same way for a long limb and a short one;
15
- * - no surface was found at all → `0`.
16
- *
17
- * This exists because {@link TwoBoneInverseKinematicsSolver} and
18
- * {@link OneBoneSurfaceAlignmentSolver} carried the identical ~70-line probe, comments and variable
19
- * names included, differing only in which lengths they scaled by. The solvers now hold nothing but
20
- * their rotation math.
21
- *
22
- * @param {Vector3} out_target receives the world position the effector should be moved to; only
23
- * written when a non-zero influence is returned
24
- * @param {SurfacePoint3} out_contact receives the surface contact from the SECOND cast; only
25
- * written when a non-zero influence is returned. Solvers that need the contact normal (surface
26
- * alignment) read it from here
27
- * @param {Terrain} terrain
28
- * @param {number} origin_x start of the limb, the root bone's world position
29
- * @param {number} origin_y
30
- * @param {number} origin_z
31
- * @param {number} effector_x world position of the bone being placed. The probe direction is
32
- * `effector - origin`, so these must not coincide
33
- * @param {number} effector_y
34
- * @param {number} effector_z
35
- * @param {IKConstraint} constraint supplies `offset` (how far off the surface the effector rests)
36
- * and `distance` (the hover band over which influence falls off)
37
- * @param {number} length_scale limb length in world units; `constraint.offset` and the hover
38
- * distance are both expressed relative to it. Must be greater than 0
39
- * @returns {number} influence in `[0,1]`; `0` means "do nothing"
40
- */
41
- export function ik_probe_terrain_contact(out_target: Vector3, out_contact: SurfacePoint3, terrain: Terrain, origin_x: number, origin_y: number, origin_z: number, effector_x: number, effector_y: number, effector_z: number, constraint: IKConstraint, length_scale: number): number;
42
- //# sourceMappingURL=ik_probe_terrain_contact.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ik_probe_terrain_contact.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/ik/ik_probe_terrain_contact.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,sHAbW,MAAM,YACN,MAAM,YACN,MAAM,cACN,MAAM,cAEN,MAAM,cACN,MAAM,0CAGN,MAAM,GAEJ,MAAM,CA8ElB"}
@@ -1,123 +0,0 @@
1
- import { v3_displace_in_direction } from "../../../core/geom/vec3/v3_displace_in_direction.js";
2
- import { v3_dot } from "../../../core/geom/vec3/v3_dot.js";
3
- import { v3_length } from "../../../core/geom/vec3/v3_length.js";
4
- import { clamp01 } from "../../../core/math/clamp01.js";
5
- import { inverseLerp } from "../../../core/math/inverseLerp.js";
6
-
7
- /**
8
- * Find where an IK chain meets the terrain and how strongly the solver should pull towards it.
9
- *
10
- * Two casts are made. The first travels from `origin` towards `effector` and establishes which
11
- * surface the limb is over at all. The second starts just outside that surface, directly above the
12
- * effector along the surface normal, and comes back down — that is what actually locates the point
13
- * under the effector rather than the point under the limb's root, and it is what `out_contact` and
14
- * `out_target` describe on return.
15
- *
16
- * The returned influence answers "how much of this correction should apply":
17
- * - the effector is BELOW the surface (penetrating) → `1`, correct it fully;
18
- * - the effector HOVERS above the surface → falls off from `1` to `0` across
19
- * `constraint.distance`, measured as a fraction of `length_scale`, so the same constraint reads
20
- * the same way for a long limb and a short one;
21
- * - no surface was found at all → `0`.
22
- *
23
- * This exists because {@link TwoBoneInverseKinematicsSolver} and
24
- * {@link OneBoneSurfaceAlignmentSolver} carried the identical ~70-line probe, comments and variable
25
- * names included, differing only in which lengths they scaled by. The solvers now hold nothing but
26
- * their rotation math.
27
- *
28
- * @param {Vector3} out_target receives the world position the effector should be moved to; only
29
- * written when a non-zero influence is returned
30
- * @param {SurfacePoint3} out_contact receives the surface contact from the SECOND cast; only
31
- * written when a non-zero influence is returned. Solvers that need the contact normal (surface
32
- * alignment) read it from here
33
- * @param {Terrain} terrain
34
- * @param {number} origin_x start of the limb, the root bone's world position
35
- * @param {number} origin_y
36
- * @param {number} origin_z
37
- * @param {number} effector_x world position of the bone being placed. The probe direction is
38
- * `effector - origin`, so these must not coincide
39
- * @param {number} effector_y
40
- * @param {number} effector_z
41
- * @param {IKConstraint} constraint supplies `offset` (how far off the surface the effector rests)
42
- * and `distance` (the hover band over which influence falls off)
43
- * @param {number} length_scale limb length in world units; `constraint.offset` and the hover
44
- * distance are both expressed relative to it. Must be greater than 0
45
- * @returns {number} influence in `[0,1]`; `0` means "do nothing"
46
- */
47
- export function ik_probe_terrain_contact(
48
- out_target,
49
- out_contact,
50
- terrain,
51
- origin_x, origin_y, origin_z,
52
- effector_x, effector_y, effector_z,
53
- constraint,
54
- length_scale
55
- ) {
56
-
57
- //check if the there is a penetration with the terrain between the two bones
58
- const directionX = effector_x - origin_x;
59
- const directionY = effector_y - origin_y;
60
- const directionZ = effector_z - origin_z;
61
-
62
- let contactExists = terrain.raycastFirstSync(
63
- out_contact,
64
- origin_x,
65
- origin_y,
66
- origin_z,
67
- directionX,
68
- directionY,
69
- directionZ
70
- );
71
-
72
- if (!contactExists) {
73
- //no contact
74
- return 0;
75
- }
76
-
77
- const contactPosition = out_contact.position;
78
- const contactNormal = out_contact.normal;
79
-
80
- //perform secondary cast from the bone, back along the surface normal
81
- contactExists = terrain.raycastFirstSync(
82
- out_contact,
83
- effector_x + contactNormal.x,
84
- effector_y + contactNormal.y,
85
- effector_z + contactNormal.z,
86
- -contactNormal.x,
87
- -contactNormal.y,
88
- -contactNormal.z
89
- );
90
-
91
- if (!contactExists) {
92
- //no contact
93
- return 0;
94
- }
95
-
96
- const targetOffsetDistance = constraint.offset * length_scale;
97
-
98
- v3_displace_in_direction(
99
- out_target,
100
- targetOffsetDistance,
101
- contactPosition.x, contactPosition.y, contactPosition.z,
102
- contactNormal.x, contactNormal.y, contactNormal.z
103
- );
104
-
105
- const delta_contact_c_x = out_target.x - effector_x;
106
- const delta_contact_c_y = out_target.y - effector_y;
107
- const delta_contact_c_z = out_target.z - effector_z;
108
-
109
- //check if current effector position is above the contact point
110
- const dot_contact_side = v3_dot(directionX, directionY, directionZ, delta_contact_c_x, delta_contact_c_y, delta_contact_c_z);
111
-
112
- if (dot_contact_side < 0) {
113
- //penetration detected
114
- return 1;
115
- }
116
-
117
- //no penetration, hovering case, use hover distance for influence
118
- const delta_contact_c_length = v3_length(delta_contact_c_x, delta_contact_c_y, delta_contact_c_z);
119
-
120
- const normalized_effector_distance = inverseLerp(0, length_scale, delta_contact_c_length);
121
-
122
- return 1 - clamp01(constraint.distance.normalizeValue(normalized_effector_distance));
123
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * Write a solved joint angle back onto a bone.
3
- *
4
- * Three separate things have to happen, where a signalling transform did them as one. The rotation
5
- * is written as four numbers. The local matrix is recomposed, because only a translation write
6
- * lands in the matrix on its own. And the change is announced, because a {@link Transform64}
7
- * carries no signals and {@link TransformAttachmentSystem} is waiting to hear that this bone moved
8
- * before it recomposes every world pose below it.
9
- *
10
- * The announcement goes on the attachment's channel and not the transform's, because a bone's local
11
- * pose is not a component in its own right - it lives inside the attachment.
12
- *
13
- * @param {EntityComponentDataset} dataset
14
- * @param {IKBone} bone
15
- * @param {Quaternion} rotation
16
- */
17
- export function ik_write_local_rotation(dataset: EntityComponentDataset, bone: IKBone, rotation: Quaternion): void;
18
- //# sourceMappingURL=ik_write_local_rotation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ik_write_local_rotation.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/ik/ik_write_local_rotation.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AACH,mHAWC"}
@@ -1,32 +0,0 @@
1
- import { GPUStateAuthorityFlags } from "../gpu/GPUStateAuthorityFlags.js";
2
- import { gpu_authority_assert_cpu } from "../gpu/gpu_authority_assert_cpu.js";
3
- import { TRANSFORM_ATTACHMENT_EVENT_CHANGE } from "../transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js";
4
-
5
- /**
6
- * Write a solved joint angle back onto a bone.
7
- *
8
- * Three separate things have to happen, where a signalling transform did them as one. The rotation
9
- * is written as four numbers. The local matrix is recomposed, because only a translation write
10
- * lands in the matrix on its own. And the change is announced, because a {@link Transform64}
11
- * carries no signals and {@link TransformAttachmentSystem} is waiting to hear that this bone moved
12
- * before it recomposes every world pose below it.
13
- *
14
- * The announcement goes on the attachment's channel and not the transform's, because a bone's local
15
- * pose is not a component in its own right - it lives inside the attachment.
16
- *
17
- * @param {EntityComponentDataset} dataset
18
- * @param {IKBone} bone
19
- * @param {Quaternion} rotation
20
- */
21
- export function ik_write_local_rotation(dataset, bone, rotation) {
22
- // A clip-driven bone's offset is the GPU's: the pose accumulator writes its row every frame
23
- // and the flush would not carry this write over it. IK moves bones no clip drives.
24
- gpu_authority_assert_cpu(dataset, bone.entity, GPUStateAuthorityFlags.TransformAttachment);
25
-
26
- const local = bone.local;
27
-
28
- local.setRotation(rotation.x, rotation.y, rotation.z, rotation.w);
29
- local.updateMatrix();
30
-
31
- dataset.sendEvent(bone.entity, TRANSFORM_ATTACHMENT_EVENT_CHANGE);
32
- }