@aura3d/animation 3.0.1 → 4.0.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.
- package/dist/AnimationController.d.ts +8 -0
- package/dist/AnimationController.d.ts.map +1 -1
- package/dist/AnimationController.js +93 -0
- package/dist/AnimationController.js.map +1 -1
- package/dist/AnimationMixer.d.ts.map +1 -1
- package/dist/AnimationMixer.js +11 -0
- package/dist/AnimationMixer.js.map +1 -1
- package/dist/FootIk.d.ts +41 -0
- package/dist/FootIk.d.ts.map +1 -1
- package/dist/FootIk.js +202 -0
- package/dist/FootIk.js.map +1 -1
- package/dist/IK.d.ts +26 -0
- package/dist/IK.d.ts.map +1 -1
- package/dist/IK.js +515 -0
- package/dist/IK.js.map +1 -1
- package/dist/Keyframe.d.ts.map +1 -1
- package/dist/Keyframe.js +13 -12
- package/dist/Keyframe.js.map +1 -1
- package/dist/SpringBones.d.ts +80 -0
- package/dist/SpringBones.d.ts.map +1 -1
- package/dist/SpringBones.js +593 -49
- package/dist/SpringBones.js.map +1 -1
- package/dist/browser-index.d.ts +1 -1
- package/dist/browser-index.d.ts.map +1 -1
- package/dist/browser-index.js +1 -1
- package/dist/browser-index.js.map +1 -1
- package/dist/contracts/index.d.ts +2 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +7 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/pose.d.ts +25 -0
- package/dist/contracts/pose.d.ts.map +1 -0
- package/dist/contracts/pose.js +41 -0
- package/dist/contracts/pose.js.map +1 -0
- package/dist/experimental/CrowdAnimation.d.ts +13 -0
- package/dist/experimental/CrowdAnimation.d.ts.map +1 -0
- package/dist/experimental/CrowdAnimation.js +14 -0
- package/dist/experimental/CrowdAnimation.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lanes/index.d.ts +17 -0
- package/dist/lanes/index.d.ts.map +1 -0
- package/dist/lanes/index.js +17 -0
- package/dist/lanes/index.js.map +1 -0
- package/dist/lanes/prd01.d.ts +6 -0
- package/dist/lanes/prd01.d.ts.map +1 -0
- package/dist/lanes/prd01.js +6 -0
- package/dist/lanes/prd01.js.map +1 -0
- package/dist/lanes/prd02.d.ts +6 -0
- package/dist/lanes/prd02.d.ts.map +1 -0
- package/dist/lanes/prd02.js +6 -0
- package/dist/lanes/prd02.js.map +1 -0
- package/dist/lanes/prd03.d.ts +6 -0
- package/dist/lanes/prd03.d.ts.map +1 -0
- package/dist/lanes/prd03.js +6 -0
- package/dist/lanes/prd03.js.map +1 -0
- package/dist/lanes/prd04.d.ts +6 -0
- package/dist/lanes/prd04.d.ts.map +1 -0
- package/dist/lanes/prd04.js +6 -0
- package/dist/lanes/prd04.js.map +1 -0
- package/dist/lanes/prd05.d.ts +6 -0
- package/dist/lanes/prd05.d.ts.map +1 -0
- package/dist/lanes/prd05.js +6 -0
- package/dist/lanes/prd05.js.map +1 -0
- package/dist/lanes/prd06.d.ts +37 -0
- package/dist/lanes/prd06.d.ts.map +1 -0
- package/dist/lanes/prd06.js +26 -0
- package/dist/lanes/prd06.js.map +1 -0
- package/dist/lanes/prd07.d.ts +6 -0
- package/dist/lanes/prd07.d.ts.map +1 -0
- package/dist/lanes/prd07.js +6 -0
- package/dist/lanes/prd07.js.map +1 -0
- package/dist/lanes/prd08.d.ts +6 -0
- package/dist/lanes/prd08.d.ts.map +1 -0
- package/dist/lanes/prd08.js +6 -0
- package/dist/lanes/prd08.js.map +1 -0
- package/dist/lanes/prd09.d.ts +6 -0
- package/dist/lanes/prd09.d.ts.map +1 -0
- package/dist/lanes/prd09.js +6 -0
- package/dist/lanes/prd09.js.map +1 -0
- package/dist/lanes/prd10.d.ts +6 -0
- package/dist/lanes/prd10.d.ts.map +1 -0
- package/dist/lanes/prd10.js +6 -0
- package/dist/lanes/prd10.js.map +1 -0
- package/dist/lanes/prd11.d.ts +6 -0
- package/dist/lanes/prd11.d.ts.map +1 -0
- package/dist/lanes/prd11.js +6 -0
- package/dist/lanes/prd11.js.map +1 -0
- package/dist/lanes/prd12.d.ts +6 -0
- package/dist/lanes/prd12.d.ts.map +1 -0
- package/dist/lanes/prd12.js +6 -0
- package/dist/lanes/prd12.js.map +1 -0
- package/dist/lanes/prd13.d.ts +6 -0
- package/dist/lanes/prd13.d.ts.map +1 -0
- package/dist/lanes/prd13.js +6 -0
- package/dist/lanes/prd13.js.map +1 -0
- package/dist/lanes/prd14.d.ts +6 -0
- package/dist/lanes/prd14.d.ts.map +1 -0
- package/dist/lanes/prd14.js +6 -0
- package/dist/lanes/prd14.js.map +1 -0
- package/dist/lanes/prd15.d.ts +6 -0
- package/dist/lanes/prd15.d.ts.map +1 -0
- package/dist/lanes/prd15.js +6 -0
- package/dist/lanes/prd15.js.map +1 -0
- package/dist/pose/BoneMask.d.ts +39 -0
- package/dist/pose/BoneMask.d.ts.map +1 -0
- package/dist/pose/BoneMask.js +160 -0
- package/dist/pose/BoneMask.js.map +1 -0
- package/dist/pose/CcdIkConstraint.d.ts +38 -0
- package/dist/pose/CcdIkConstraint.d.ts.map +1 -0
- package/dist/pose/CcdIkConstraint.js +198 -0
- package/dist/pose/CcdIkConstraint.js.map +1 -0
- package/dist/pose/CompiledClip.d.ts +48 -0
- package/dist/pose/CompiledClip.d.ts.map +1 -0
- package/dist/pose/CompiledClip.js +209 -0
- package/dist/pose/CompiledClip.js.map +1 -0
- package/dist/pose/LookAtConstraint.d.ts +48 -0
- package/dist/pose/LookAtConstraint.d.ts.map +1 -0
- package/dist/pose/LookAtConstraint.js +251 -0
- package/dist/pose/LookAtConstraint.js.map +1 -0
- package/dist/pose/MotionMetrics.d.ts +136 -0
- package/dist/pose/MotionMetrics.d.ts.map +1 -0
- package/dist/pose/MotionMetrics.js +253 -0
- package/dist/pose/MotionMetrics.js.map +1 -0
- package/dist/pose/PoseBuffer.d.ts +23 -0
- package/dist/pose/PoseBuffer.d.ts.map +1 -0
- package/dist/pose/PoseBuffer.js +48 -0
- package/dist/pose/PoseBuffer.js.map +1 -0
- package/dist/pose/PoseInertializer.d.ts +38 -0
- package/dist/pose/PoseInertializer.d.ts.map +1 -0
- package/dist/pose/PoseInertializer.js +208 -0
- package/dist/pose/PoseInertializer.js.map +1 -0
- package/dist/pose/PoseMixer.d.ts +256 -0
- package/dist/pose/PoseMixer.d.ts.map +1 -0
- package/dist/pose/PoseMixer.js +848 -0
- package/dist/pose/PoseMixer.js.map +1 -0
- package/dist/pose/Retarget.d.ts +77 -0
- package/dist/pose/Retarget.d.ts.map +1 -0
- package/dist/pose/Retarget.js +378 -0
- package/dist/pose/Retarget.js.map +1 -0
- package/dist/pose/RetargetCache.d.ts +21 -0
- package/dist/pose/RetargetCache.d.ts.map +1 -0
- package/dist/pose/RetargetCache.js +102 -0
- package/dist/pose/RetargetCache.js.map +1 -0
- package/dist/pose/RetargetWorker.d.ts +21 -0
- package/dist/pose/RetargetWorker.d.ts.map +1 -0
- package/dist/pose/RetargetWorker.js +56 -0
- package/dist/pose/RetargetWorker.js.map +1 -0
- package/dist/pose/SkeletonBinding.d.ts +55 -0
- package/dist/pose/SkeletonBinding.d.ts.map +1 -0
- package/dist/pose/SkeletonBinding.js +62 -0
- package/dist/pose/SkeletonBinding.js.map +1 -0
- package/dist/pose/blendKernels.d.ts +32 -0
- package/dist/pose/blendKernels.d.ts.map +1 -0
- package/dist/pose/blendKernels.js +101 -0
- package/dist/pose/blendKernels.js.map +1 -0
- package/dist/pose/makeClipAdditive.d.ts +22 -0
- package/dist/pose/makeClipAdditive.d.ts.map +1 -0
- package/dist/pose/makeClipAdditive.js +101 -0
- package/dist/pose/makeClipAdditive.js.map +1 -0
- package/dist/pose/poseMixerFlags.d.ts +18 -0
- package/dist/pose/poseMixerFlags.d.ts.map +1 -0
- package/dist/pose/poseMixerFlags.js +30 -0
- package/dist/pose/poseMixerFlags.js.map +1 -0
- package/dist/pose/quatFlat.d.ts +16 -0
- package/dist/pose/quatFlat.d.ts.map +1 -0
- package/dist/pose/quatFlat.js +88 -0
- package/dist/pose/quatFlat.js.map +1 -0
- package/dist/pose/retarget.worker.d.ts +25 -0
- package/dist/pose/retarget.worker.d.ts.map +1 -0
- package/dist/pose/retarget.worker.js +22 -0
- package/dist/pose/retarget.worker.js.map +1 -0
- package/package.json +14 -2
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T3.3 (PRD-06 §7.1/7.2) — `LookAtConstraint`: pose-space look-at that
|
|
3
|
+
* distributes the required yaw/pitch across the named bones by weight,
|
|
4
|
+
* enforces `yawLimitDeg`/`pitchLimitDeg` on the aggregate rotation, and
|
|
5
|
+
* smooths applied angles with a critically-damped spring (`halfLife`,
|
|
6
|
+
* default 0.12 s — same convention as PoseInertializer).
|
|
7
|
+
*
|
|
8
|
+
* Stateful: the spring keeps per-constraint applied yaw/pitch; ±180° targets
|
|
9
|
+
* unwrap against the previous applied yaw so sweeping behind the character
|
|
10
|
+
* never snaps sign.
|
|
11
|
+
*
|
|
12
|
+
* `eyes` (optional bone names) aim directly at the target after the weighted
|
|
13
|
+
* pass — eye saccades are instant, not spring-smoothed.
|
|
14
|
+
*/
|
|
15
|
+
const UP = [0, 1, 0];
|
|
16
|
+
function jointIndex(skeleton, name) {
|
|
17
|
+
const indices = skeleton.jointIndicesByName.get(name);
|
|
18
|
+
if (!indices || indices.length === 0)
|
|
19
|
+
throw new Error(`LookAtConstraint: unknown bone "${name}".`);
|
|
20
|
+
return indices[0];
|
|
21
|
+
}
|
|
22
|
+
function jointFrame(pose, skeleton, joint, cache) {
|
|
23
|
+
const cached = cache.get(joint);
|
|
24
|
+
if (cached)
|
|
25
|
+
return cached;
|
|
26
|
+
const pos = [pose.positions[joint * 3], pose.positions[joint * 3 + 1], pose.positions[joint * 3 + 2]];
|
|
27
|
+
const rot = [pose.rotations[joint * 4], pose.rotations[joint * 4 + 1], pose.rotations[joint * 4 + 2], pose.rotations[joint * 4 + 3]];
|
|
28
|
+
const scl = [pose.scales[joint * 3], pose.scales[joint * 3 + 1], pose.scales[joint * 3 + 2]];
|
|
29
|
+
const parent = skeleton.parentIndices[joint] ?? -1;
|
|
30
|
+
if (parent < 0 || parent >= skeleton.boneCount || parent === joint) {
|
|
31
|
+
const frame = { position: pos, rotation: rot, scale: scl };
|
|
32
|
+
cache.set(joint, frame);
|
|
33
|
+
return frame;
|
|
34
|
+
}
|
|
35
|
+
const pf = jointFrame(pose, skeleton, parent, cache);
|
|
36
|
+
const scaled = [pos[0] * pf.scale[0], pos[1] * pf.scale[1], pos[2] * pf.scale[2]];
|
|
37
|
+
const rotated = rotateVec3(pf.rotation, scaled);
|
|
38
|
+
const frame = {
|
|
39
|
+
position: [pf.position[0] + rotated[0], pf.position[1] + rotated[1], pf.position[2] + rotated[2]],
|
|
40
|
+
rotation: multiplyQuat(pf.rotation, rot),
|
|
41
|
+
scale: [pf.scale[0] * scl[0], pf.scale[1] * scl[1], pf.scale[2] * scl[2]]
|
|
42
|
+
};
|
|
43
|
+
cache.set(joint, frame);
|
|
44
|
+
return frame;
|
|
45
|
+
}
|
|
46
|
+
function rotateVec3(q, v) {
|
|
47
|
+
const [x, y, z, w] = q;
|
|
48
|
+
const tx = 2 * (y * v[2] - z * v[1]);
|
|
49
|
+
const ty = 2 * (z * v[0] - x * v[2]);
|
|
50
|
+
const tz = 2 * (x * v[1] - y * v[0]);
|
|
51
|
+
return [v[0] + w * tx + (y * tz - z * ty), v[1] + w * ty + (z * tx - x * tz), v[2] + w * tz + (x * ty - y * tx)];
|
|
52
|
+
}
|
|
53
|
+
function multiplyQuat(a, b) {
|
|
54
|
+
const [ax, ay, az, aw] = a;
|
|
55
|
+
const [bx, by, bz, bw] = b;
|
|
56
|
+
return [
|
|
57
|
+
ax * bw + aw * bx + ay * bz - az * by,
|
|
58
|
+
ay * bw + aw * by + az * bx - ax * bz,
|
|
59
|
+
az * bw + aw * bz + ax * by - ay * bx,
|
|
60
|
+
aw * bw - ax * bx - ay * by - az * bz
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
function axisAngle(axis, radians) {
|
|
64
|
+
const half = radians / 2;
|
|
65
|
+
const s = Math.sin(half);
|
|
66
|
+
return [axis[0] * s, axis[1] * s, axis[2] * s, Math.cos(half)];
|
|
67
|
+
}
|
|
68
|
+
function normalize(v) {
|
|
69
|
+
const l = Math.hypot(v[0], v[1], v[2]);
|
|
70
|
+
return l <= 1e-9 ? [0, 0, 0] : [v[0] / l, v[1] / l, v[2] / l];
|
|
71
|
+
}
|
|
72
|
+
/** Invert a TRS-only mat4 for target world→model conversion. */
|
|
73
|
+
function invertModelTRS(matrix) {
|
|
74
|
+
const sx = Math.hypot(matrix[0], matrix[1], matrix[2]);
|
|
75
|
+
const sy = Math.hypot(matrix[4], matrix[5], matrix[6]);
|
|
76
|
+
const sz = Math.hypot(matrix[8], matrix[9], matrix[10]);
|
|
77
|
+
const m00 = matrix[0] / (sx || 1), m10 = matrix[1] / (sx || 1), m20 = matrix[2] / (sx || 1);
|
|
78
|
+
const m01 = matrix[4] / (sy || 1), m11 = matrix[5] / (sy || 1), m21 = matrix[6] / (sy || 1);
|
|
79
|
+
const m02 = matrix[8] / (sz || 1), m12 = matrix[9] / (sz || 1), m22 = matrix[10] / (sz || 1);
|
|
80
|
+
const trace = m00 + m11 + m22;
|
|
81
|
+
let q;
|
|
82
|
+
if (trace > 0) {
|
|
83
|
+
const s = 0.5 / Math.sqrt(trace + 1);
|
|
84
|
+
q = [(m21 - m12) * s, (m02 - m20) * s, (m10 - m01) * s, 0.25 / s];
|
|
85
|
+
}
|
|
86
|
+
else if (m00 > m11 && m00 > m22) {
|
|
87
|
+
const s = 2 * Math.sqrt(1 + m00 - m11 - m22);
|
|
88
|
+
q = [0.25 * s, (m01 + m10) / s, (m02 + m20) / s, (m21 - m12) / s];
|
|
89
|
+
}
|
|
90
|
+
else if (m11 > m22) {
|
|
91
|
+
const s = 2 * Math.sqrt(1 + m11 - m00 - m22);
|
|
92
|
+
q = [(m01 + m10) / s, 0.25 * s, (m12 + m21) / s, (m02 - m20) / s];
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const s = 2 * Math.sqrt(1 + m22 - m00 - m11);
|
|
96
|
+
q = [(m02 + m20) / s, (m12 + m21) / s, 0.25 * s, (m10 - m01) / s];
|
|
97
|
+
}
|
|
98
|
+
const l = Math.hypot(q[0], q[1], q[2], q[3]) || 1;
|
|
99
|
+
return {
|
|
100
|
+
rotation: [q[0] / l, q[1] / l, q[2] / l, q[3] / l],
|
|
101
|
+
scale: [sx, sy, sz],
|
|
102
|
+
position: [matrix[12], matrix[13], matrix[14]]
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function forwardVector(axis) {
|
|
106
|
+
if (axis === "-z")
|
|
107
|
+
return [0, 0, -1];
|
|
108
|
+
if (axis === "+y")
|
|
109
|
+
return [0, 1, 0];
|
|
110
|
+
return [0, 0, 1];
|
|
111
|
+
}
|
|
112
|
+
export function createLookAtConstraint(spec) {
|
|
113
|
+
const halfLife = spec.halfLife ?? 0.12;
|
|
114
|
+
const yawLimit = ((spec.yawLimitDeg ?? 90) * Math.PI) / 180;
|
|
115
|
+
const pitchLimit = ((spec.pitchLimitDeg ?? 60) * Math.PI) / 180;
|
|
116
|
+
const axis = forwardVector(spec.forwardAxis ?? "+z");
|
|
117
|
+
const state = { yaw: 0, pitch: 0 };
|
|
118
|
+
return {
|
|
119
|
+
get smoothed() {
|
|
120
|
+
return { yaw: state.yaw, pitch: state.pitch };
|
|
121
|
+
},
|
|
122
|
+
reset() {
|
|
123
|
+
state.yaw = 0;
|
|
124
|
+
state.pitch = 0;
|
|
125
|
+
},
|
|
126
|
+
apply(pose, skeleton, modelMatrix, target, dt) {
|
|
127
|
+
const frames = new Map();
|
|
128
|
+
const invModel = invertModelTRS(modelMatrix);
|
|
129
|
+
// Target in model space.
|
|
130
|
+
const shifted = [target[0] - invModel.position[0], target[1] - invModel.position[1], target[2] - invModel.position[2]];
|
|
131
|
+
const invRot = [-invModel.rotation[0], -invModel.rotation[1], -invModel.rotation[2], invModel.rotation[3]];
|
|
132
|
+
const rotatedTarget = rotateVec3(invRot, shifted);
|
|
133
|
+
const targetLocal = [
|
|
134
|
+
rotatedTarget[0] / (invModel.scale[0] || 1),
|
|
135
|
+
rotatedTarget[1] / (invModel.scale[1] || 1),
|
|
136
|
+
rotatedTarget[2] / (invModel.scale[2] || 1)
|
|
137
|
+
];
|
|
138
|
+
// Desired yaw/pitch off the LAST weighted bone's current forward.
|
|
139
|
+
const last = spec.bones[spec.bones.length - 1];
|
|
140
|
+
if (!last)
|
|
141
|
+
return;
|
|
142
|
+
const lastFrame = jointFrame(pose, skeleton, jointIndex(skeleton, last.bone), frames);
|
|
143
|
+
const forward = rotateVec3(lastFrame.rotation, axis);
|
|
144
|
+
const toTarget = normalize([
|
|
145
|
+
targetLocal[0] - lastFrame.position[0],
|
|
146
|
+
targetLocal[1] - lastFrame.position[1],
|
|
147
|
+
targetLocal[2] - lastFrame.position[2]
|
|
148
|
+
]);
|
|
149
|
+
if (Math.hypot(toTarget[0], toTarget[1], toTarget[2]) <= 1e-9)
|
|
150
|
+
return;
|
|
151
|
+
// Yaw about model up: signed angle between the XZ projections.
|
|
152
|
+
const forwardFlat = normalize([forward[0], 0, forward[2]]);
|
|
153
|
+
const targetFlat = normalize([toTarget[0], 0, toTarget[2]]);
|
|
154
|
+
// atan2(cross·up, dot) — cross(f,t)·up = fz·tx − fx·tz
|
|
155
|
+
const crossY = forwardFlat[2] * targetFlat[0] - forwardFlat[0] * targetFlat[2];
|
|
156
|
+
const yaw = Math.atan2(crossY, forwardFlat[0] * targetFlat[0] + forwardFlat[2] * targetFlat[2]);
|
|
157
|
+
// Pitch = the rotation about the yawed RIGHT axis needed to lift the
|
|
158
|
+
// CURRENT forward to the target's elevation — a delta, not the target's
|
|
159
|
+
// absolute elevation (an animated forward already pitched by the clip
|
|
160
|
+
// would otherwise keep its pitch residual forever). R_x(+θ) pitches +Z
|
|
161
|
+
// DOWN, so the correction is forwardElev − targetElev.
|
|
162
|
+
const pitch = Math.atan2(forward[1], Math.max(1e-9, Math.hypot(forward[0], forward[2]))) -
|
|
163
|
+
Math.atan2(toTarget[1], Math.max(1e-9, Math.hypot(toTarget[0], toTarget[2])));
|
|
164
|
+
let targetYaw = Math.max(-yawLimit, Math.min(yawLimit, yaw));
|
|
165
|
+
const targetPitch = Math.max(-pitchLimit, Math.min(pitchLimit, pitch));
|
|
166
|
+
// The constraint composes each frame's distributed share ON TOP of the
|
|
167
|
+
// animated pose (the pose the mixer just wrote — never last frame's
|
|
168
|
+
// constraint output), so the smoothed angles are absolute and
|
|
169
|
+
// convergent. `state` starts at 0 for a smooth ramp-in.
|
|
170
|
+
// ±180° unwrap: pull the TARGET onto the smoothed value's branch — the
|
|
171
|
+
// smoothed yaw itself keeps growing continuously past ±π (equivalent mod
|
|
172
|
+
// 2π in the applied share), so sweeping behind never snaps sign.
|
|
173
|
+
while (targetYaw - state.yaw > Math.PI)
|
|
174
|
+
targetYaw -= Math.PI * 2;
|
|
175
|
+
while (targetYaw - state.yaw < -Math.PI)
|
|
176
|
+
targetYaw += Math.PI * 2;
|
|
177
|
+
const blend = 1 - Math.pow(2, -dt / halfLife);
|
|
178
|
+
state.yaw += (targetYaw - state.yaw) * blend;
|
|
179
|
+
state.pitch += (targetPitch - state.pitch) * blend;
|
|
180
|
+
// Distribute smoothed angles across the bones by weight; write back.
|
|
181
|
+
for (const entry of spec.bones) {
|
|
182
|
+
const index = jointIndex(skeleton, entry.bone);
|
|
183
|
+
const frame = jointFrame(pose, skeleton, index, frames);
|
|
184
|
+
const yawShare = state.yaw * entry.weight;
|
|
185
|
+
const pitchShare = state.pitch * entry.weight;
|
|
186
|
+
const yawQ = axisAngle(UP, yawShare);
|
|
187
|
+
const afterYaw = multiplyQuat(yawQ, frame.rotation);
|
|
188
|
+
// Pitch about the bone's post-yaw RIGHT axis — the horizontal axis
|
|
189
|
+
// perpendicular to its current forward (`cross(UP, fwd)` = +X yawed by
|
|
190
|
+
// the forward's own azimuth). Using the yawed model +X instead pitches
|
|
191
|
+
// about an axis off by the whole azimuth, leaking the share into
|
|
192
|
+
// roll/yaw and leaving a residual that grows with off-axis targets.
|
|
193
|
+
const postYawForward = rotateVec3(afterYaw, axis);
|
|
194
|
+
const right = normalize([
|
|
195
|
+
postYawForward[2],
|
|
196
|
+
0,
|
|
197
|
+
-postYawForward[0]
|
|
198
|
+
]);
|
|
199
|
+
const pitchQ = axisAngle(right, pitchShare);
|
|
200
|
+
const world = multiplyQuat(pitchQ, afterYaw);
|
|
201
|
+
const l = Math.hypot(world[0], world[1], world[2], world[3]) || 1;
|
|
202
|
+
const normalized = [world[0] / l, world[1] / l, world[2] / l, world[3] / l];
|
|
203
|
+
const parent = skeleton.parentIndices[index] ?? -1;
|
|
204
|
+
const parentRot = parent >= 0 ? jointFrame(pose, skeleton, parent, frames).rotation : [0, 0, 0, 1];
|
|
205
|
+
const inv = [-parentRot[0], -parentRot[1], -parentRot[2], parentRot[3]];
|
|
206
|
+
const local = multiplyQuat(inv, normalized);
|
|
207
|
+
const ll = Math.hypot(local[0], local[1], local[2], local[3]) || 1;
|
|
208
|
+
pose.rotations[index * 4] = local[0] / ll;
|
|
209
|
+
pose.rotations[index * 4 + 1] = local[1] / ll;
|
|
210
|
+
pose.rotations[index * 4 + 2] = local[2] / ll;
|
|
211
|
+
pose.rotations[index * 4 + 3] = local[3] / ll;
|
|
212
|
+
// Downstream bones see this bone's new world rotation — drop the whole
|
|
213
|
+
// cache so later entries recompute against the updated pose.
|
|
214
|
+
frames.clear();
|
|
215
|
+
}
|
|
216
|
+
// Eyes aim directly at the target (instant saccade, no spring).
|
|
217
|
+
for (const eyeName of spec.eyes ?? []) {
|
|
218
|
+
const index = jointIndex(skeleton, eyeName);
|
|
219
|
+
const frame = jointFrame(pose, skeleton, index, frames);
|
|
220
|
+
const eyeForward = rotateVec3(frame.rotation, axis);
|
|
221
|
+
const eyeToTarget = normalize([
|
|
222
|
+
targetLocal[0] - frame.position[0],
|
|
223
|
+
targetLocal[1] - frame.position[1],
|
|
224
|
+
targetLocal[2] - frame.position[2]
|
|
225
|
+
]);
|
|
226
|
+
const d = eyeForward[0] * eyeToTarget[0] + eyeForward[1] * eyeToTarget[1] + eyeForward[2] * eyeToTarget[2];
|
|
227
|
+
if (d > 1 - 1e-6)
|
|
228
|
+
continue;
|
|
229
|
+
const cross = [
|
|
230
|
+
eyeForward[1] * eyeToTarget[2] - eyeForward[2] * eyeToTarget[1],
|
|
231
|
+
eyeForward[2] * eyeToTarget[0] - eyeForward[0] * eyeToTarget[2],
|
|
232
|
+
eyeForward[0] * eyeToTarget[1] - eyeForward[1] * eyeToTarget[0]
|
|
233
|
+
];
|
|
234
|
+
const w = Math.sqrt((1 + Math.max(-1, d)) / 2);
|
|
235
|
+
const s = 1 / (2 * w);
|
|
236
|
+
const aim = [cross[0] * s, cross[1] * s, cross[2] * s, w];
|
|
237
|
+
const world = multiplyQuat(aim, frame.rotation);
|
|
238
|
+
const parent = skeleton.parentIndices[index] ?? -1;
|
|
239
|
+
const parentRot = parent >= 0 ? jointFrame(pose, skeleton, parent, frames).rotation : [0, 0, 0, 1];
|
|
240
|
+
const inv = [-parentRot[0], -parentRot[1], -parentRot[2], parentRot[3]];
|
|
241
|
+
const local = multiplyQuat(inv, world);
|
|
242
|
+
const ll = Math.hypot(local[0], local[1], local[2], local[3]) || 1;
|
|
243
|
+
pose.rotations[index * 4] = local[0] / ll;
|
|
244
|
+
pose.rotations[index * 4 + 1] = local[1] / ll;
|
|
245
|
+
pose.rotations[index * 4 + 2] = local[2] / ll;
|
|
246
|
+
pose.rotations[index * 4 + 3] = local[3] / ll;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=LookAtConstraint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LookAtConstraint.js","sourceRoot":"","sources":["../../../../../packages/animation/src/pose/LookAtConstraint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* §17.3 motion-quality metrics (T1.14). Pure functions over per-frame bone
|
|
3
|
+
* samples — world-space rotation (quat) and position per bone at a fixed
|
|
4
|
+
* cadence (the lane samples at 60 Hz from engine bone sockets; spec: "from
|
|
5
|
+
* engine bone data, not from screenshots").
|
|
6
|
+
*
|
|
7
|
+
* NOT built on `MotionQuality.ts` (E42): that tracker measures motion
|
|
8
|
+
* *existence* (tracksApplied, poseDiversityScore) — these measure quality.
|
|
9
|
+
*/
|
|
10
|
+
/** Quaternion [x,y,z,w]. */
|
|
11
|
+
export type MotionQuat = readonly [number, number, number, number];
|
|
12
|
+
/** World position [x,y,z]. */
|
|
13
|
+
export type MotionVec3 = readonly [number, number, number];
|
|
14
|
+
export interface MotionBoneSample {
|
|
15
|
+
readonly rotation: MotionQuat;
|
|
16
|
+
readonly position: MotionVec3;
|
|
17
|
+
}
|
|
18
|
+
/** One sampled frame: sim time in seconds → per-bone rotation+position. */
|
|
19
|
+
export interface MotionFrame {
|
|
20
|
+
readonly time: number;
|
|
21
|
+
readonly bones: Readonly<Record<string, MotionBoneSample>>;
|
|
22
|
+
}
|
|
23
|
+
declare const IDENTITY_QUAT: MotionQuat;
|
|
24
|
+
/**
|
|
25
|
+
* Decompose a column-major 4x4 world matrix into rotation quaternion +
|
|
26
|
+
* translation. Assumes uniform/orthonormal-ish basis (animation palettes are
|
|
27
|
+
* rigid transforms ± uniform scale; any uniform scale is divided out of the
|
|
28
|
+
* rotation columns).
|
|
29
|
+
*/
|
|
30
|
+
export declare function motionSampleFromMatrix(m: ArrayLike<number>): MotionBoneSample;
|
|
31
|
+
/**
|
|
32
|
+
* §17.3's bone subset: humanoid limb and spine bones only — fingers and toes
|
|
33
|
+
* excluded (they flap at high angular speed and are not what "continuity"
|
|
34
|
+
* judges). `mixamo`-style names (mixamorigHips) and plain names both match.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isHumanoidMotionBone(bone: string): boolean;
|
|
37
|
+
/** Shortest-arc angle between two quats, in degrees. */
|
|
38
|
+
export declare function quatAngleDegrees(a: MotionQuat, b: MotionQuat): number;
|
|
39
|
+
export interface BoneAngularSpeed {
|
|
40
|
+
readonly bone: string;
|
|
41
|
+
/** deg/s, frame-to-frame. */
|
|
42
|
+
readonly speeds: readonly number[];
|
|
43
|
+
readonly times: readonly number[];
|
|
44
|
+
}
|
|
45
|
+
/** Per-bone angular-speed series over the sampled window. */
|
|
46
|
+
export declare function boneAngularSpeeds(frames: readonly MotionFrame[], isBone?: (bone: string) => boolean): BoneAngularSpeed[];
|
|
47
|
+
/** Max deg/s across all bones inside [start, end] (0 when empty). */
|
|
48
|
+
export declare function maxAngularSpeedInWindow(frames: readonly MotionFrame[], start: number, end: number, isBone?: typeof isHumanoidMotionBone): number;
|
|
49
|
+
/** The single fastest bone→speed sample inside [start, end], with attribution. */
|
|
50
|
+
export declare function maxAngularSpeedDetailInWindow(frames: readonly MotionFrame[], start: number, end: number, isBone?: typeof isHumanoidMotionBone): {
|
|
51
|
+
readonly speed: number;
|
|
52
|
+
readonly bone?: string;
|
|
53
|
+
readonly at?: number;
|
|
54
|
+
};
|
|
55
|
+
export interface ContinuityResult {
|
|
56
|
+
/** C = maxAngularSpeed / max(baseline, 90°/s). */
|
|
57
|
+
readonly continuity: number;
|
|
58
|
+
readonly maxAngularSpeedDegPerSec: number;
|
|
59
|
+
readonly baselineDegPerSec: number;
|
|
60
|
+
/** Attribution for the fastest sample (diagnostics on gate failures). */
|
|
61
|
+
readonly maxBone?: string;
|
|
62
|
+
readonly maxAt?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* C over the transition window [t₀ − windowBefore, t₀ + windowAfter]:
|
|
66
|
+
* the max per-bone angular speed (humanoid limb+spine only) divided by the max
|
|
67
|
+
* per-bone angular speed of either clip played alone over the same phase range
|
|
68
|
+
* — supplied via `baselineWindows` (frame ranges of pure clip playback) or an
|
|
69
|
+
* explicit `baselineDegPerSec`. Denominator floored at 90°/s (§17.3).
|
|
70
|
+
*/
|
|
71
|
+
export declare function transitionContinuity(frames: readonly MotionFrame[], options: {
|
|
72
|
+
readonly transitionTime: number;
|
|
73
|
+
readonly windowBefore?: number;
|
|
74
|
+
readonly windowAfter?: number;
|
|
75
|
+
/** Frame ranges where a single clip plays alone (baseline measurement). */
|
|
76
|
+
readonly baselineWindows?: readonly (readonly [number, number])[];
|
|
77
|
+
readonly baselineDegPerSec?: number;
|
|
78
|
+
readonly isBone?: (bone: string) => boolean;
|
|
79
|
+
}): ContinuityResult;
|
|
80
|
+
export interface FootContactPhase {
|
|
81
|
+
readonly bone: string;
|
|
82
|
+
readonly startTime: number;
|
|
83
|
+
readonly endTime: number;
|
|
84
|
+
/** Max horizontal (XZ) displacement from the phase's first position, metres. */
|
|
85
|
+
readonly slideM: number;
|
|
86
|
+
}
|
|
87
|
+
export interface FootSlideResult {
|
|
88
|
+
readonly maxSlideM: number;
|
|
89
|
+
readonly phases: readonly FootContactPhase[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* World displacement of a foot bone while its contact flag is set. Contact is
|
|
93
|
+
* a clip footstep event (`contactWindows`) or inferred: foot height < 3 cm AND
|
|
94
|
+
* horizontal speed < 0.1 m/s. §17.3 pass bars: ≤ 2 cm walk / ≤ 3 cm run.
|
|
95
|
+
*/
|
|
96
|
+
export declare function footSlide(frames: readonly MotionFrame[], options: {
|
|
97
|
+
readonly footBones: readonly string[];
|
|
98
|
+
readonly contactHeightM?: number;
|
|
99
|
+
readonly contactSpeedMps?: number;
|
|
100
|
+
/** Explicit contact windows per bone — overrides the inferred rule. */
|
|
101
|
+
readonly contactWindows?: Readonly<Record<string, readonly (readonly [number, number])[]>>;
|
|
102
|
+
}): FootSlideResult;
|
|
103
|
+
export interface LocomotionPhaseSample {
|
|
104
|
+
readonly time: number;
|
|
105
|
+
readonly a: {
|
|
106
|
+
readonly phase: number;
|
|
107
|
+
readonly weight: number;
|
|
108
|
+
};
|
|
109
|
+
readonly b: {
|
|
110
|
+
readonly phase: number;
|
|
111
|
+
readonly weight: number;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export interface LocomotionPhaseErrorResult {
|
|
115
|
+
/** Max |phaseA − phaseB| (circular, in [0, 0.5]) over frames where both weights pass the bar. */
|
|
116
|
+
readonly maxPhaseError: number;
|
|
117
|
+
readonly meanPhaseError: number;
|
|
118
|
+
readonly comparedFrames: number;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Normalised-phase difference between two locomotion actions while both are
|
|
122
|
+
* weighted (default bar weight > 0.05). Phase is clip-local time normalised by
|
|
123
|
+
* duration (caller computes — `animationState().activeActions` exposes `time`
|
|
124
|
+
* and the clip durations resolve through `resolveAnimationClips`). §17.3 pass
|
|
125
|
+
* bar: ≤ 1% of the cycle.
|
|
126
|
+
*/
|
|
127
|
+
export declare function locomotionPhaseError(samples: readonly LocomotionPhaseSample[], options?: {
|
|
128
|
+
readonly minWeight?: number;
|
|
129
|
+
}): LocomotionPhaseErrorResult;
|
|
130
|
+
/**
|
|
131
|
+
* Build one MotionFrame from a socket reader — the adapter's per-frame hook:
|
|
132
|
+
* `motionFrame(t, boneNames, (bone) => socket(bone).worldMatrix())`.
|
|
133
|
+
*/
|
|
134
|
+
export declare function motionFrame(time: number, boneNames: readonly string[], worldMatrix: (bone: string) => ArrayLike<number> | undefined): MotionFrame;
|
|
135
|
+
export { IDENTITY_QUAT as MOTION_IDENTITY_QUAT };
|
|
136
|
+
//# sourceMappingURL=MotionMetrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MotionMetrics.d.ts","sourceRoot":"","sources":["../../../../../packages/animation/src/pose/MotionMetrics.ts"],"names":[],"mappings":"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"}
|