@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
@@ -0,0 +1,245 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+
3
+ /**
4
+ * One tree for {@link frame_fabrik_solve} to pose: its joints, as the animation left them, the goals
5
+ * pulling on them, and, once solved, where they went.
6
+ *
7
+ * Every array is sized once, at construction, for the most joints and goals the problem will ever
8
+ * hold; a solve allocates nothing. Joints are indices into the problem, not entities: the problem
9
+ * knows nothing about where its tree came from.
10
+ *
11
+ * The caller fills the inputs and {@link joint_count} / {@link goal_count}; the fields under "solver
12
+ * state" belong to the solver, which overwrites them on every solve.
13
+ *
14
+ * @author Alex Goldring
15
+ * @copyright Company Named Limited (c) 2026
16
+ */
17
+ export class FrameFabrikProblem {
18
+
19
+ /**
20
+ * @param {number} joint_capacity the most joints a solve will be given
21
+ * @param {number} goal_capacity the most goals a solve will be given
22
+ */
23
+ constructor(joint_capacity, goal_capacity) {
24
+ assert.isPositiveInteger(joint_capacity, 'joint_capacity');
25
+ assert.isPositiveInteger(goal_capacity, 'goal_capacity');
26
+
27
+ /**
28
+ * @readonly
29
+ * @type {number}
30
+ */
31
+ this.joint_capacity = joint_capacity;
32
+
33
+ /**
34
+ * @readonly
35
+ * @type {number}
36
+ */
37
+ this.goal_capacity = goal_capacity;
38
+
39
+ /**
40
+ * How many joints this solve poses.
41
+ * @type {number}
42
+ */
43
+ this.joint_count = 0;
44
+
45
+ /**
46
+ * How many goals pull on them.
47
+ * @type {number}
48
+ */
49
+ this.goal_count = 0;
50
+
51
+ /**
52
+ * Each joint's parent, as an index into this problem, or -1 for a joint whose parent the solve
53
+ * does not pose: its parent's frame is fixed, as animated. Every parent comes before its
54
+ * children, `joint_parent[i] < i`.
55
+ * @type {Int32Array}
56
+ */
57
+ this.joint_parent = new Int32Array(joint_capacity);
58
+
59
+ /**
60
+ * Where each joint is as animated, in world. Packed `[x, y, z]` per joint.
61
+ * @type {Float64Array}
62
+ */
63
+ this.base_position = new Float64Array(joint_capacity * 3);
64
+
65
+ /**
66
+ * How each joint is turned as animated, in world, a unit quaternion. Packed `[x, y, z, w]` per
67
+ * joint.
68
+ * @type {Float64Array}
69
+ */
70
+ this.base_rotation = new Float64Array(joint_capacity * 4);
71
+
72
+ /**
73
+ * How each joint is turned relative to its parent as animated, a unit quaternion: the parent's
74
+ * {@link base_rotation} composed with it is the joint's. For a joint whose parent is not posed,
75
+ * relative to that parent, whose frame it gives the solve. Packed `[x, y, z, w]` per joint.
76
+ * @type {Float64Array}
77
+ */
78
+ this.base_local_rotation = new Float64Array(joint_capacity * 4);
79
+
80
+ /**
81
+ * 1 for a joint whose turn relative to its parent is limited, by {@link limit_basis_a},
82
+ * {@link limit_basis_b}, {@link limit_lower} and {@link limit_upper}; 0 for one that turns
83
+ * freely.
84
+ * @type {Uint8Array}
85
+ */
86
+ this.joint_limited = new Uint8Array(joint_capacity);
87
+
88
+ /**
89
+ * The limit's frame in the parent's, a unit quaternion: a physics `Joint`'s `localBasisA`.
90
+ * Packed `[x, y, z, w]` per joint.
91
+ * @type {Float64Array}
92
+ */
93
+ this.limit_basis_a = new Float64Array(joint_capacity * 4);
94
+
95
+ /**
96
+ * The limit's frame in the joint's own, a unit quaternion: a physics `Joint`'s `localBasisB`.
97
+ * Packed `[x, y, z, w]` per joint.
98
+ * @type {Float64Array}
99
+ */
100
+ this.limit_basis_b = new Float64Array(joint_capacity * 4);
101
+
102
+ /**
103
+ * Lower bounds of the turn of frame B relative to frame A, as `swing_twist_error_array`
104
+ * measures it: `[twist about X, swing Y, swing Z]` per joint, radians. `-Infinity` for an
105
+ * axis that turns freely, 0 for a locked one.
106
+ * @type {Float64Array}
107
+ */
108
+ this.limit_lower = new Float64Array(joint_capacity * 3);
109
+
110
+ /**
111
+ * Upper bounds, as {@link limit_lower}.
112
+ * @type {Float64Array}
113
+ */
114
+ this.limit_upper = new Float64Array(joint_capacity * 3);
115
+
116
+ /**
117
+ * The joint each goal pulls on.
118
+ * @type {Int32Array}
119
+ */
120
+ this.goal_effector = new Int32Array(goal_capacity);
121
+
122
+ /**
123
+ * The highest joint each goal turns: its effector or an ancestor of it. The goal's path runs
124
+ * from the effector up to here. This joint turns and never moves.
125
+ * @type {Int32Array}
126
+ */
127
+ this.goal_root = new Int32Array(goal_capacity);
128
+
129
+ /**
130
+ * How hard each goal pulls, 0..1. 0 gives the pose the solve gives without the goal, and the
131
+ * pose is continuous in it.
132
+ * @type {Float64Array}
133
+ */
134
+ this.goal_weight = new Float64Array(goal_capacity);
135
+
136
+ /**
137
+ * The joint each goal's target hangs below, or -1 for a target the solve does not move. A
138
+ * target hanging below a joint is carried by that joint's frame as the solve turns it, read
139
+ * afresh on every iteration.
140
+ * @type {Int32Array}
141
+ */
142
+ this.goal_target_joint = new Int32Array(goal_capacity);
143
+
144
+ /**
145
+ * Where each goal wants its effector, in world, as animated: the frame of
146
+ * {@link goal_target_joint} carries it from there. Packed `[x, y, z]` per goal.
147
+ * @type {Float64Array}
148
+ */
149
+ this.goal_target = new Float64Array(goal_capacity * 3);
150
+
151
+ /**
152
+ * The solved pose: where each joint went, in world. Packed `[x, y, z]` per joint.
153
+ * @type {Float64Array}
154
+ */
155
+ this.solved_position = new Float64Array(joint_capacity * 3);
156
+
157
+ /**
158
+ * The solved pose: how each joint is turned, in world. Packed `[x, y, z, w]` per joint.
159
+ * @type {Float64Array}
160
+ */
161
+ this.solved_rotation = new Float64Array(joint_capacity * 4);
162
+
163
+ // --- solver state ---
164
+
165
+ /**
166
+ * Each joint's place in its parent's frame, as animated: the rigid offset the solve keeps.
167
+ * @type {Float64Array}
168
+ */
169
+ this._offset = new Float64Array(joint_capacity * 3);
170
+
171
+ /**
172
+ * The weight of the link from each joint's parent to it: the heaviest goal whose path holds
173
+ * both ends. 0 for a link no path holds.
174
+ * @type {Float64Array}
175
+ */
176
+ this._link_weight = new Float64Array(joint_capacity);
177
+
178
+ /**
179
+ * Children of joint `i` are `_child[_child_start[i] .. _child_start[i + 1]]`.
180
+ * @type {Int32Array}
181
+ */
182
+ this._child_start = new Int32Array(joint_capacity + 1);
183
+
184
+ /**
185
+ * @type {Int32Array}
186
+ */
187
+ this._child = new Int32Array(joint_capacity);
188
+
189
+ /**
190
+ * How many goals of non-zero weight have the joint on their path.
191
+ * @type {Int32Array}
192
+ */
193
+ this._path_count = new Int32Array(joint_capacity);
194
+
195
+ /**
196
+ * 1 for a joint some goal's path holds below that goal's root.
197
+ * @type {Uint8Array}
198
+ */
199
+ this._interior = new Uint8Array(joint_capacity);
200
+
201
+ /**
202
+ * 1 for a joint that turns and never moves: a goal's root no path holds below its own root.
203
+ * @type {Uint8Array}
204
+ */
205
+ this._root_only = new Uint8Array(joint_capacity);
206
+
207
+ /**
208
+ * The goal whose effector the joint is, or -1.
209
+ * @type {Int32Array}
210
+ */
211
+ this._effector_goal = new Int32Array(joint_capacity);
212
+
213
+ /**
214
+ * The joint whose frame carries each goal's effector when the goal does not pull: the deepest
215
+ * joint of its path another goal's path holds too, else its root's parent (-1 when that is
216
+ * not posed).
217
+ * @type {Int32Array}
218
+ */
219
+ this._goal_anchor = new Int32Array(goal_capacity);
220
+
221
+ /**
222
+ * The effector in its anchor's frame, as animated. Packed `[x, y, z]` per goal.
223
+ * @type {Float64Array}
224
+ */
225
+ this._goal_anchor_offset = new Float64Array(goal_capacity * 3);
226
+
227
+ /**
228
+ * Each target in its target joint's frame, as animated. Packed `[x, y, z]` per goal.
229
+ * @type {Float64Array}
230
+ */
231
+ this._goal_target_local = new Float64Array(goal_capacity * 3);
232
+
233
+ /**
234
+ * This iteration's target for each effector. Packed `[x, y, z]` per goal.
235
+ * @type {Float64Array}
236
+ */
237
+ this._target = new Float64Array(goal_capacity * 3);
238
+
239
+ /**
240
+ * Where each joint was before this iteration, to measure how far the iteration moved it.
241
+ * @type {Float64Array}
242
+ */
243
+ this._previous = new Float64Array(joint_capacity * 3);
244
+ }
245
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Limit joint `i` of a {@link FrameFabrikProblem} by the physics {@link Joint} on its bone:
3
+ * `entityA` the parent bone, `entityB` the bone itself.
4
+ *
5
+ * The limits are the Joint's angular ones, in its frames (`localBasisA` in the parent's,
6
+ * `localBasisB` in the bone's), as the joint solver measures them with `swingTwist` on: the twist
7
+ * about frame X and the swing over Y and Z, each its own range, a box. A LOCKED axis is held at 0,
8
+ * a LIMITED one kept in `[lower, upper]`, and a FREE one left alone; so is a SPRING or a MOTOR,
9
+ * which drive and do not limit. Anchors and the linear axes are ignored: IK turns bones and moves
10
+ * none.
11
+ *
12
+ * `swingTwist` has to be on. Without it physics measures an angle as `2 sin(θ/2)`, so a limit
13
+ * above 114.6 degrees never engages there, and physics and IK would disagree on what the joint
14
+ * allows.
15
+ *
16
+ * @param {FrameFabrikProblem} problem
17
+ * @param {number} i
18
+ * @param {Joint} joint
19
+ */
20
+ export function frame_fabrik_limit_from_joint(problem: FrameFabrikProblem, i: number, joint: Joint): void;
21
+ //# sourceMappingURL=frame_fabrik_limit_from_joint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame_fabrik_limit_from_joint.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,8EAHW,MAAM,sBA2ChB"}
@@ -0,0 +1,63 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { DofMode } from "../../constraint/DofMode.js";
3
+
4
+ /**
5
+ * Limit joint `i` of a {@link FrameFabrikProblem} by the physics {@link Joint} on its bone:
6
+ * `entityA` the parent bone, `entityB` the bone itself.
7
+ *
8
+ * The limits are the Joint's angular ones, in its frames (`localBasisA` in the parent's,
9
+ * `localBasisB` in the bone's), as the joint solver measures them with `swingTwist` on: the twist
10
+ * about frame X and the swing over Y and Z, each its own range, a box. A LOCKED axis is held at 0,
11
+ * a LIMITED one kept in `[lower, upper]`, and a FREE one left alone; so is a SPRING or a MOTOR,
12
+ * which drive and do not limit. Anchors and the linear axes are ignored: IK turns bones and moves
13
+ * none.
14
+ *
15
+ * `swingTwist` has to be on. Without it physics measures an angle as `2 sin(θ/2)`, so a limit
16
+ * above 114.6 degrees never engages there, and physics and IK would disagree on what the joint
17
+ * allows.
18
+ *
19
+ * @param {FrameFabrikProblem} problem
20
+ * @param {number} i
21
+ * @param {Joint} joint
22
+ */
23
+ export function frame_fabrik_limit_from_joint(problem, i, joint) {
24
+ assert.ok(i >= 0 && i < problem.joint_capacity, 'i is a joint of the problem');
25
+ assert.ok(joint.swingTwist === true, 'the Joint measures its angles by swing and twist (swingTwist), as IK clamps them');
26
+
27
+ const mode = joint.dofMode;
28
+
29
+ for (let k = 0; k < 3; k++) {
30
+ const m = mode[3 + k];
31
+
32
+ let lower, upper;
33
+
34
+ if (m === DofMode.LOCKED) {
35
+ lower = 0;
36
+ upper = 0;
37
+ } else if (m === DofMode.LIMITED) {
38
+ lower = joint.dofLowerLimit[3 + k];
39
+ upper = joint.dofUpperLimit[3 + k];
40
+ } else {
41
+ lower = -Infinity;
42
+ upper = Infinity;
43
+ }
44
+
45
+ problem.limit_lower[i * 3 + k] = lower;
46
+ problem.limit_upper[i * 3 + k] = upper;
47
+ }
48
+
49
+ const a = joint.localBasisA;
50
+ const b = joint.localBasisB;
51
+
52
+ problem.limit_basis_a[i * 4] = a[0];
53
+ problem.limit_basis_a[i * 4 + 1] = a[1];
54
+ problem.limit_basis_a[i * 4 + 2] = a[2];
55
+ problem.limit_basis_a[i * 4 + 3] = a[3];
56
+
57
+ problem.limit_basis_b[i * 4] = b[0];
58
+ problem.limit_basis_b[i * 4 + 1] = b[1];
59
+ problem.limit_basis_b[i * 4 + 2] = b[2];
60
+ problem.limit_basis_b[i * 4 + 3] = b[3];
61
+
62
+ problem.joint_limited[i] = 1;
63
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Pose a tree of joints so its effectors reach their goals: frame FABRIK.
3
+ *
4
+ * Every posed joint is a frame, a position and a rotation, with its children at rigid offsets in it,
5
+ * so a branch keeps every child's offset and the solved pose is one the hierarchy composes exactly.
6
+ * Each iteration runs:
7
+ * - **inward**, leaves to roots: each effector onto its target; every other joint with a pulling child
8
+ * fitted toward its pulling children from its old position, then moved to the weighted mean of
9
+ * the positions its children put it at rigidly;
10
+ * - **outward**, roots to leaves: each joint refitted from where its parent now puts it, and its
11
+ * children placed rigidly.
12
+ *
13
+ * A limited joint's fitted turn is projected into its limits in both passes, so the solved pose keeps
14
+ * them (Aristidou, Chrysanthou and Lasenby 2016); a joint the solve only carries keeps its animated
15
+ * turn, inside its limits or not, as it would with no goal.
16
+ *
17
+ * With one pulling child that is the paper's pull (Aristidou and Lasenby 2011). The fits start from
18
+ * the rotation the joint carries from its parent, never from its own last answer, so nothing drifts
19
+ * with the iteration count. A goal's weight scales the links of its path, and its effector's target
20
+ * is `lerp(carried, goal, weight)`: weight 0 gives the pose the solve gives without the goal, and the
21
+ * pose is continuous in the weight. A goal's root turns and never moves.
22
+ *
23
+ * The solve stops when no joint moved by `tolerance` in an iteration, or after `max_iterations`. Not
24
+ * on the distance to the targets: an unreachable target never comes within any distance, and a
25
+ * reachable one comes close while the joints above it are still settling.
26
+ *
27
+ * @param {FrameFabrikProblem} problem filled; the solved pose lands in its `solved_position` and `solved_rotation`
28
+ * @param {number} max_iterations
29
+ * @param {number} tolerance in world units; the solve stops once an iteration moves no joint this far
30
+ * @returns {number} how many iterations ran
31
+ */
32
+ export function frame_fabrik_solve(problem: FrameFabrikProblem, max_iterations: number, tolerance: number): number;
33
+ //# sourceMappingURL=frame_fabrik_solve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame_fabrik_solve.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js"],"names":[],"mappings":"AAqtBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,gFAJW,MAAM,aACN,MAAM,GACJ,MAAM,CA4DlB"}