@aura3d/animation 3.0.0 → 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 +4 -1
- package/dist/AnimationMixer.d.ts.map +1 -1
- package/dist/AnimationMixer.js +47 -29
- package/dist/AnimationMixer.js.map +1 -1
- package/dist/FootIk.d.ts +50 -0
- package/dist/FootIk.d.ts.map +1 -1
- package/dist/FootIk.js +224 -8
- package/dist/FootIk.js.map +1 -1
- package/dist/HumanoidRetargeting.d.ts +6 -2
- package/dist/HumanoidRetargeting.d.ts.map +1 -1
- package/dist/HumanoidRetargeting.js +18 -8
- package/dist/HumanoidRetargeting.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/LocomotionEvidence.d.ts +34 -0
- package/dist/LocomotionEvidence.d.ts.map +1 -0
- package/dist/LocomotionEvidence.js +48 -0
- package/dist/LocomotionEvidence.js.map +1 -0
- package/dist/RootMotion.d.ts +13 -4
- package/dist/RootMotion.d.ts.map +1 -1
- package/dist/RootMotion.js +21 -1
- package/dist/RootMotion.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 +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -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,253 @@
|
|
|
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
|
+
const IDENTITY_QUAT = [0, 0, 0, 1];
|
|
11
|
+
/* ------------------------------------------------------------------ */
|
|
12
|
+
/* matrix → {rotation, position} */
|
|
13
|
+
/* ------------------------------------------------------------------ */
|
|
14
|
+
/**
|
|
15
|
+
* Decompose a column-major 4x4 world matrix into rotation quaternion +
|
|
16
|
+
* translation. Assumes uniform/orthonormal-ish basis (animation palettes are
|
|
17
|
+
* rigid transforms ± uniform scale; any uniform scale is divided out of the
|
|
18
|
+
* rotation columns).
|
|
19
|
+
*/
|
|
20
|
+
export function motionSampleFromMatrix(m) {
|
|
21
|
+
const position = [m[12], m[13], m[14]];
|
|
22
|
+
// Column lengths = per-axis scale magnitudes.
|
|
23
|
+
const sx = Math.hypot(m[0], m[1], m[2]) || 1;
|
|
24
|
+
const sy = Math.hypot(m[4], m[5], m[6]) || 1;
|
|
25
|
+
const sz = Math.hypot(m[8], m[9], m[10]) || 1;
|
|
26
|
+
const r00 = m[0] / sx, r01 = m[4] / sy, r02 = m[8] / sz;
|
|
27
|
+
const r10 = m[1] / sx, r11 = m[5] / sy, r12 = m[9] / sz;
|
|
28
|
+
const r20 = m[2] / sx, r21 = m[6] / sy, r22 = m[10] / sz;
|
|
29
|
+
// Standard rotation-matrix → quat.
|
|
30
|
+
const trace = r00 + r11 + r22;
|
|
31
|
+
let x = 0, y = 0, z = 0, w = 1;
|
|
32
|
+
if (trace > 0) {
|
|
33
|
+
const s = Math.sqrt(trace + 1) * 2;
|
|
34
|
+
w = s / 4;
|
|
35
|
+
x = (r21 - r12) / s;
|
|
36
|
+
y = (r02 - r20) / s;
|
|
37
|
+
z = (r10 - r01) / s;
|
|
38
|
+
}
|
|
39
|
+
else if (r00 > r11 && r00 > r22) {
|
|
40
|
+
const s = Math.sqrt(1 + r00 - r11 - r22) * 2;
|
|
41
|
+
w = (r21 - r12) / s;
|
|
42
|
+
x = s / 4;
|
|
43
|
+
y = (r01 + r10) / s;
|
|
44
|
+
z = (r02 + r20) / s;
|
|
45
|
+
}
|
|
46
|
+
else if (r11 > r22) {
|
|
47
|
+
const s = Math.sqrt(1 + r11 - r00 - r22) * 2;
|
|
48
|
+
w = (r02 - r20) / s;
|
|
49
|
+
x = (r01 + r10) / s;
|
|
50
|
+
y = s / 4;
|
|
51
|
+
z = (r12 + r21) / s;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const s = Math.sqrt(1 + r22 - r00 - r11) * 2;
|
|
55
|
+
w = (r10 - r01) / s;
|
|
56
|
+
x = (r02 + r20) / s;
|
|
57
|
+
y = (r12 + r21) / s;
|
|
58
|
+
z = s / 4;
|
|
59
|
+
}
|
|
60
|
+
const len = Math.hypot(x, y, z, w) || 1;
|
|
61
|
+
return { rotation: [x / len, y / len, z / len, w / len], position };
|
|
62
|
+
}
|
|
63
|
+
/* ------------------------------------------------------------------ */
|
|
64
|
+
/* bone filters */
|
|
65
|
+
/* ------------------------------------------------------------------ */
|
|
66
|
+
const FINGERISH = /finger|thumb|index|middle|ring|pinky|toe|tip|distal/i;
|
|
67
|
+
const LIMBISH = /arm|leg|forearm|upper|lower|hand|foot|shoulder|clavicle|thigh|shin|calf|knee|elbow|wrist|ankle|spine|chest|hips|pelvis|neck|head/i;
|
|
68
|
+
/**
|
|
69
|
+
* §17.3's bone subset: humanoid limb and spine bones only — fingers and toes
|
|
70
|
+
* excluded (they flap at high angular speed and are not what "continuity"
|
|
71
|
+
* judges). `mixamo`-style names (mixamorigHips) and plain names both match.
|
|
72
|
+
*/
|
|
73
|
+
export function isHumanoidMotionBone(bone) {
|
|
74
|
+
if (FINGERISH.test(bone))
|
|
75
|
+
return false;
|
|
76
|
+
return LIMBISH.test(bone);
|
|
77
|
+
}
|
|
78
|
+
/* ------------------------------------------------------------------ */
|
|
79
|
+
/* angular speed */
|
|
80
|
+
/* ------------------------------------------------------------------ */
|
|
81
|
+
/** Shortest-arc angle between two quats, in degrees. */
|
|
82
|
+
export function quatAngleDegrees(a, b) {
|
|
83
|
+
const d = Math.abs(a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]);
|
|
84
|
+
const clamped = Math.min(1, d);
|
|
85
|
+
return (2 * Math.acos(clamped) * 180) / Math.PI;
|
|
86
|
+
}
|
|
87
|
+
/** Per-bone angular-speed series over the sampled window. */
|
|
88
|
+
export function boneAngularSpeeds(frames, isBone = isHumanoidMotionBone) {
|
|
89
|
+
const byBone = new Map();
|
|
90
|
+
for (const frame of frames) {
|
|
91
|
+
for (const [bone, sample] of Object.entries(frame.bones)) {
|
|
92
|
+
if (!isBone(bone))
|
|
93
|
+
continue;
|
|
94
|
+
let series = byBone.get(bone);
|
|
95
|
+
if (series === undefined) {
|
|
96
|
+
series = { speeds: [], times: [] };
|
|
97
|
+
byBone.set(bone, series);
|
|
98
|
+
}
|
|
99
|
+
if (series.lastQ !== undefined && series.lastT !== undefined) {
|
|
100
|
+
const dt = frame.time - series.lastT;
|
|
101
|
+
if (dt > 0) {
|
|
102
|
+
series.speeds.push(quatAngleDegrees(series.lastQ, sample.rotation) / dt);
|
|
103
|
+
series.times.push(series.lastT + dt / 2);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
series.lastQ = sample.rotation;
|
|
107
|
+
series.lastT = frame.time;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return [...byBone.entries()].map(([bone, s]) => ({ bone, speeds: s.speeds, times: s.times }));
|
|
111
|
+
}
|
|
112
|
+
/** Max deg/s across all bones inside [start, end] (0 when empty). */
|
|
113
|
+
export function maxAngularSpeedInWindow(frames, start, end, isBone = isHumanoidMotionBone) {
|
|
114
|
+
return maxAngularSpeedDetailInWindow(frames, start, end, isBone).speed;
|
|
115
|
+
}
|
|
116
|
+
/** The single fastest bone→speed sample inside [start, end], with attribution. */
|
|
117
|
+
export function maxAngularSpeedDetailInWindow(frames, start, end, isBone = isHumanoidMotionBone) {
|
|
118
|
+
let max = 0;
|
|
119
|
+
let bone;
|
|
120
|
+
let at;
|
|
121
|
+
for (const series of boneAngularSpeeds(frames, isBone)) {
|
|
122
|
+
for (let i = 0; i < series.speeds.length; i += 1) {
|
|
123
|
+
const t = series.times[i];
|
|
124
|
+
if (t >= start && t <= end && series.speeds[i] > max) {
|
|
125
|
+
max = series.speeds[i];
|
|
126
|
+
bone = series.bone;
|
|
127
|
+
at = t;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return { speed: max, ...(bone !== undefined ? { bone } : {}), ...(at !== undefined ? { at } : {}) };
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* C over the transition window [t₀ − windowBefore, t₀ + windowAfter]:
|
|
135
|
+
* the max per-bone angular speed (humanoid limb+spine only) divided by the max
|
|
136
|
+
* per-bone angular speed of either clip played alone over the same phase range
|
|
137
|
+
* — supplied via `baselineWindows` (frame ranges of pure clip playback) or an
|
|
138
|
+
* explicit `baselineDegPerSec`. Denominator floored at 90°/s (§17.3).
|
|
139
|
+
*/
|
|
140
|
+
export function transitionContinuity(frames, options) {
|
|
141
|
+
const isBone = options.isBone ?? isHumanoidMotionBone;
|
|
142
|
+
const start = options.transitionTime - (options.windowBefore ?? 0.1);
|
|
143
|
+
const end = options.transitionTime + (options.windowAfter ?? 0.3);
|
|
144
|
+
const fastest = maxAngularSpeedDetailInWindow(frames, start, end, isBone);
|
|
145
|
+
const maxAngularSpeed = fastest.speed;
|
|
146
|
+
let baseline = options.baselineDegPerSec ?? 0;
|
|
147
|
+
for (const [wStart, wEnd] of options.baselineWindows ?? []) {
|
|
148
|
+
baseline = Math.max(baseline, maxAngularSpeedInWindow(frames, wStart, wEnd, isBone));
|
|
149
|
+
}
|
|
150
|
+
baseline = Math.max(baseline, 90); // §17.3 floor: idle→idle cannot divide by ~0
|
|
151
|
+
return {
|
|
152
|
+
continuity: maxAngularSpeed / baseline,
|
|
153
|
+
maxAngularSpeedDegPerSec: maxAngularSpeed,
|
|
154
|
+
baselineDegPerSec: baseline,
|
|
155
|
+
...(fastest.bone !== undefined ? { maxBone: fastest.bone } : {}),
|
|
156
|
+
...(fastest.at !== undefined ? { maxAt: fastest.at } : {})
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* World displacement of a foot bone while its contact flag is set. Contact is
|
|
161
|
+
* a clip footstep event (`contactWindows`) or inferred: foot height < 3 cm AND
|
|
162
|
+
* horizontal speed < 0.1 m/s. §17.3 pass bars: ≤ 2 cm walk / ≤ 3 cm run.
|
|
163
|
+
*/
|
|
164
|
+
export function footSlide(frames, options) {
|
|
165
|
+
const heightM = options.contactHeightM ?? 0.03;
|
|
166
|
+
const speedMps = options.contactSpeedMps ?? 0.1;
|
|
167
|
+
const phases = [];
|
|
168
|
+
for (const bone of options.footBones) {
|
|
169
|
+
const explicit = options.contactWindows?.[bone];
|
|
170
|
+
let inContact = false;
|
|
171
|
+
let phaseStart = 0;
|
|
172
|
+
let phaseStartPos = [0, 0];
|
|
173
|
+
let slide = 0;
|
|
174
|
+
let last;
|
|
175
|
+
const closePhase = (t) => {
|
|
176
|
+
if (inContact)
|
|
177
|
+
phases.push({ bone, startTime: phaseStart, endTime: t, slideM: slide });
|
|
178
|
+
inContact = false;
|
|
179
|
+
slide = 0;
|
|
180
|
+
};
|
|
181
|
+
for (const frame of frames) {
|
|
182
|
+
const sample = frame.bones[bone];
|
|
183
|
+
if (sample === undefined) {
|
|
184
|
+
closePhase(frame.time);
|
|
185
|
+
last = undefined;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const p = sample.position;
|
|
189
|
+
const horizontalSpeed = last === undefined
|
|
190
|
+
? 0
|
|
191
|
+
: Math.hypot(p[0] - last.p[0], p[2] - last.p[2]) / Math.max(1e-6, frame.time - last.t);
|
|
192
|
+
last = { p, t: frame.time };
|
|
193
|
+
const contact = explicit !== undefined
|
|
194
|
+
? explicit.some(([s, e]) => frame.time >= s && frame.time <= e)
|
|
195
|
+
: p[1] <= heightM && horizontalSpeed <= speedMps;
|
|
196
|
+
if (contact && !inContact) {
|
|
197
|
+
inContact = true;
|
|
198
|
+
phaseStart = frame.time;
|
|
199
|
+
phaseStartPos = [p[0], p[2]];
|
|
200
|
+
slide = 0;
|
|
201
|
+
}
|
|
202
|
+
else if (contact) {
|
|
203
|
+
slide = Math.max(slide, Math.hypot(p[0] - phaseStartPos[0], p[2] - phaseStartPos[1]));
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
closePhase(frame.time);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
closePhase(frames.at(-1)?.time ?? phaseStart);
|
|
210
|
+
}
|
|
211
|
+
return { maxSlideM: phases.reduce((m, p) => Math.max(m, p.slideM), 0), phases };
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Normalised-phase difference between two locomotion actions while both are
|
|
215
|
+
* weighted (default bar weight > 0.05). Phase is clip-local time normalised by
|
|
216
|
+
* duration (caller computes — `animationState().activeActions` exposes `time`
|
|
217
|
+
* and the clip durations resolve through `resolveAnimationClips`). §17.3 pass
|
|
218
|
+
* bar: ≤ 1% of the cycle.
|
|
219
|
+
*/
|
|
220
|
+
export function locomotionPhaseError(samples, options = {}) {
|
|
221
|
+
const minWeight = options.minWeight ?? 0.05;
|
|
222
|
+
let max = 0;
|
|
223
|
+
let sum = 0;
|
|
224
|
+
let n = 0;
|
|
225
|
+
for (const s of samples) {
|
|
226
|
+
if (s.a.weight <= minWeight || s.b.weight <= minWeight)
|
|
227
|
+
continue;
|
|
228
|
+
const raw = Math.abs(((s.a.phase % 1) + 1) % 1 - ((s.b.phase % 1) + 1) % 1);
|
|
229
|
+
const err = Math.min(raw, 1 - raw); // circular phase distance in cycles
|
|
230
|
+
max = Math.max(max, err);
|
|
231
|
+
sum += err;
|
|
232
|
+
n += 1;
|
|
233
|
+
}
|
|
234
|
+
return { maxPhaseError: max, meanPhaseError: n === 0 ? 0 : sum / n, comparedFrames: n };
|
|
235
|
+
}
|
|
236
|
+
/* ------------------------------------------------------------------ */
|
|
237
|
+
/* sampling helper */
|
|
238
|
+
/* ------------------------------------------------------------------ */
|
|
239
|
+
/**
|
|
240
|
+
* Build one MotionFrame from a socket reader — the adapter's per-frame hook:
|
|
241
|
+
* `motionFrame(t, boneNames, (bone) => socket(bone).worldMatrix())`.
|
|
242
|
+
*/
|
|
243
|
+
export function motionFrame(time, boneNames, worldMatrix) {
|
|
244
|
+
const bones = {};
|
|
245
|
+
for (const bone of boneNames) {
|
|
246
|
+
const m = worldMatrix(bone);
|
|
247
|
+
if (m !== undefined)
|
|
248
|
+
bones[bone] = motionSampleFromMatrix(m);
|
|
249
|
+
}
|
|
250
|
+
return { time, bones };
|
|
251
|
+
}
|
|
252
|
+
export { IDENTITY_QUAT as MOTION_IDENTITY_QUAT };
|
|
253
|
+
//# sourceMappingURL=MotionMetrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MotionMetrics.js","sourceRoot":"","sources":["../../../../../packages/animation/src/pose/MotionMetrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD-06 T1.1 — flat per-bone TRS storage for the pose pipeline.
|
|
3
|
+
*
|
|
4
|
+
* One `PoseBuffer` holds a full skeleton pose: `positions`/`scales` are
|
|
5
|
+
* `3 × boneCount` (x, y, z) and `rotations` is `4 × boneCount` (x, y, z, w).
|
|
6
|
+
* Fresh buffers start at the identity pose (zero translation/rotation, unit
|
|
7
|
+
* scale); {@link copyPose} copies in place with no allocation.
|
|
8
|
+
*/
|
|
9
|
+
export interface PoseBuffer {
|
|
10
|
+
readonly boneCount: number;
|
|
11
|
+
/** `3 × boneCount` — x, y, z per bone. */
|
|
12
|
+
readonly positions: Float32Array;
|
|
13
|
+
/** `4 × boneCount` — x, y, z, w per bone. */
|
|
14
|
+
readonly rotations: Float32Array;
|
|
15
|
+
/** `3 × boneCount` — x, y, z per bone. */
|
|
16
|
+
readonly scales: Float32Array;
|
|
17
|
+
}
|
|
18
|
+
export declare function createPoseBuffer(boneCount: number): PoseBuffer;
|
|
19
|
+
/** Copy every channel of `src` into `dst` in place. Buffer sizes must match. */
|
|
20
|
+
export declare function copyPose(dst: PoseBuffer, src: PoseBuffer): PoseBuffer;
|
|
21
|
+
/** Restore `pose` to the identity transform on every bone (no allocation). */
|
|
22
|
+
export declare function resetPoseToIdentity(pose: PoseBuffer): PoseBuffer;
|
|
23
|
+
//# sourceMappingURL=PoseBuffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoseBuffer.d.ts","sourceRoot":"","sources":["../../../../../packages/animation/src/pose/PoseBuffer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAkB9D;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU,CAQrE;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAQhE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD-06 T1.1 — flat per-bone TRS storage for the pose pipeline.
|
|
3
|
+
*
|
|
4
|
+
* One `PoseBuffer` holds a full skeleton pose: `positions`/`scales` are
|
|
5
|
+
* `3 × boneCount` (x, y, z) and `rotations` is `4 × boneCount` (x, y, z, w).
|
|
6
|
+
* Fresh buffers start at the identity pose (zero translation/rotation, unit
|
|
7
|
+
* scale); {@link copyPose} copies in place with no allocation.
|
|
8
|
+
*/
|
|
9
|
+
export function createPoseBuffer(boneCount) {
|
|
10
|
+
if (!Number.isInteger(boneCount) || boneCount < 0) {
|
|
11
|
+
throw new Error("createPoseBuffer requires a non-negative integer bone count.");
|
|
12
|
+
}
|
|
13
|
+
const rotations = new Float32Array(boneCount * 4);
|
|
14
|
+
const scales = new Float32Array(boneCount * 3);
|
|
15
|
+
for (let index = 0; index < boneCount; index += 1) {
|
|
16
|
+
rotations[index * 4 + 3] = 1;
|
|
17
|
+
scales[index * 3] = 1;
|
|
18
|
+
scales[index * 3 + 1] = 1;
|
|
19
|
+
scales[index * 3 + 2] = 1;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
boneCount,
|
|
23
|
+
positions: new Float32Array(boneCount * 3),
|
|
24
|
+
rotations,
|
|
25
|
+
scales
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** Copy every channel of `src` into `dst` in place. Buffer sizes must match. */
|
|
29
|
+
export function copyPose(dst, src) {
|
|
30
|
+
if (dst.boneCount !== src.boneCount) {
|
|
31
|
+
throw new Error("copyPose requires buffers with matching bone counts.");
|
|
32
|
+
}
|
|
33
|
+
dst.positions.set(src.positions);
|
|
34
|
+
dst.rotations.set(src.rotations);
|
|
35
|
+
dst.scales.set(src.scales);
|
|
36
|
+
return dst;
|
|
37
|
+
}
|
|
38
|
+
/** Restore `pose` to the identity transform on every bone (no allocation). */
|
|
39
|
+
export function resetPoseToIdentity(pose) {
|
|
40
|
+
pose.positions.fill(0);
|
|
41
|
+
pose.rotations.fill(0);
|
|
42
|
+
pose.scales.fill(1);
|
|
43
|
+
for (let index = 0; index < pose.boneCount; index += 1) {
|
|
44
|
+
pose.rotations[index * 4 + 3] = 1;
|
|
45
|
+
}
|
|
46
|
+
return pose;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=PoseBuffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoseBuffer.js","sourceRoot":"","sources":["../../../../../packages/animation/src/pose/PoseBuffer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IAC/C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAClD,SAAS,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO;QACL,SAAS;QACT,SAAS,EAAE,IAAI,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC;QAC1C,SAAS;QACT,MAAM;KACP,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,QAAQ,CAAC,GAAe,EAAE,GAAe;IACvD,IAAI,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACjC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACjC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,mBAAmB,CAAC,IAAgB;IAClD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD-06 T1.6 — per-bone inertialized transitions (§6.4).
|
|
3
|
+
*
|
|
4
|
+
* `transition(latest, previous, dt)` captures the outgoing pose plus its
|
|
5
|
+
* per-bone velocity (finite difference of the last two output poses).
|
|
6
|
+
* `apply(out, newPose, elapsed)` writes `newPose` with the captured offset
|
|
7
|
+
* decayed by the existing `inertializedQuat` / `inertializedVec3` math —
|
|
8
|
+
* at `elapsed = 0` the output equals the captured pose (position- and
|
|
9
|
+
* velocity-continuous), then converges to `newPose`.
|
|
10
|
+
*/
|
|
11
|
+
import { type PoseBuffer } from "./PoseBuffer.js";
|
|
12
|
+
export declare const DEFAULT_POSE_TRANSITION_HALF_LIFE = 0.15;
|
|
13
|
+
export declare class PoseInertializer {
|
|
14
|
+
private captured;
|
|
15
|
+
private readonly positionVelocities;
|
|
16
|
+
private readonly scaleVelocities;
|
|
17
|
+
/** Per-bone angular velocity: axis (unit vec3, from latest·prev⁻¹) and speed (rad/s). */
|
|
18
|
+
private readonly angularSpeeds;
|
|
19
|
+
private readonly angularAxes;
|
|
20
|
+
private readonly boneCount;
|
|
21
|
+
private halfLife;
|
|
22
|
+
constructor(boneCount: number);
|
|
23
|
+
/** True once a transition has been captured. */
|
|
24
|
+
get active(): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Capture the transition: `latest` is the last output pose before the
|
|
27
|
+
* switch, `previous` the output `dt` seconds earlier (for velocities).
|
|
28
|
+
*/
|
|
29
|
+
transition(latest: PoseBuffer, previous: PoseBuffer, dt: number, halfLife?: number): void;
|
|
30
|
+
/**
|
|
31
|
+
* Write `newPose` with the captured offset decayed over `elapsed` seconds
|
|
32
|
+
* into `out`. Buffers are reused — `out` may alias `newPose`.
|
|
33
|
+
*/
|
|
34
|
+
apply(out: PoseBuffer, newPose: PoseBuffer, elapsed: number): PoseBuffer;
|
|
35
|
+
/** Drop the captured transition (no allocation). */
|
|
36
|
+
clear(): void;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=PoseInertializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoseInertializer.d.ts","sourceRoot":"","sources":["../../../../../packages/animation/src/pose/PoseInertializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEpE,eAAO,MAAM,iCAAiC,OAAO,CAAC;AAEtD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAe;IAClD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAC/C,yFAAyF;IACzF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAe;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAqC;gBAEzC,SAAS,EAAE,MAAM;IAW7B,gDAAgD;IAChD,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,SAAoC,GAAG,IAAI;IAyCpH;;;OAGG;IACH,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU;IAuFxE,oDAAoD;IACpD,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD-06 T1.6 — per-bone inertialized transitions (§6.4).
|
|
3
|
+
*
|
|
4
|
+
* `transition(latest, previous, dt)` captures the outgoing pose plus its
|
|
5
|
+
* per-bone velocity (finite difference of the last two output poses).
|
|
6
|
+
* `apply(out, newPose, elapsed)` writes `newPose` with the captured offset
|
|
7
|
+
* decayed by the existing `inertializedQuat` / `inertializedVec3` math —
|
|
8
|
+
* at `elapsed = 0` the output equals the captured pose (position- and
|
|
9
|
+
* velocity-continuous), then converges to `newPose`.
|
|
10
|
+
*/
|
|
11
|
+
import { inertializationDecayRate, inertializedQuat, inertializedVec3 } from "../Inertialization.js";
|
|
12
|
+
import { createPoseBuffer } from "./PoseBuffer.js";
|
|
13
|
+
export const DEFAULT_POSE_TRANSITION_HALF_LIFE = 0.15;
|
|
14
|
+
export class PoseInertializer {
|
|
15
|
+
captured;
|
|
16
|
+
positionVelocities;
|
|
17
|
+
scaleVelocities;
|
|
18
|
+
/** Per-bone angular velocity: axis (unit vec3, from latest·prev⁻¹) and speed (rad/s). */
|
|
19
|
+
angularSpeeds;
|
|
20
|
+
angularAxes;
|
|
21
|
+
boneCount;
|
|
22
|
+
halfLife = DEFAULT_POSE_TRANSITION_HALF_LIFE;
|
|
23
|
+
constructor(boneCount) {
|
|
24
|
+
if (!Number.isInteger(boneCount) || boneCount < 0) {
|
|
25
|
+
throw new Error("PoseInertializer requires a non-negative integer bone count.");
|
|
26
|
+
}
|
|
27
|
+
this.boneCount = boneCount;
|
|
28
|
+
this.positionVelocities = new Float32Array(boneCount * 3);
|
|
29
|
+
this.scaleVelocities = new Float32Array(boneCount * 3);
|
|
30
|
+
this.angularSpeeds = new Float32Array(boneCount);
|
|
31
|
+
this.angularAxes = new Float32Array(boneCount * 3);
|
|
32
|
+
}
|
|
33
|
+
/** True once a transition has been captured. */
|
|
34
|
+
get active() {
|
|
35
|
+
return this.captured !== undefined;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Capture the transition: `latest` is the last output pose before the
|
|
39
|
+
* switch, `previous` the output `dt` seconds earlier (for velocities).
|
|
40
|
+
*/
|
|
41
|
+
transition(latest, previous, dt, halfLife = DEFAULT_POSE_TRANSITION_HALF_LIFE) {
|
|
42
|
+
if (latest.boneCount !== this.boneCount || previous.boneCount !== this.boneCount) {
|
|
43
|
+
throw new Error("PoseInertializer.transition requires poses matching the constructor bone count.");
|
|
44
|
+
}
|
|
45
|
+
if (!(dt > 0)) {
|
|
46
|
+
throw new Error("PoseInertializer.transition requires a positive dt.");
|
|
47
|
+
}
|
|
48
|
+
if (!this.captured)
|
|
49
|
+
this.captured = createPoseBuffer(this.boneCount);
|
|
50
|
+
const captured = this.captured;
|
|
51
|
+
this.halfLife = halfLife;
|
|
52
|
+
const invDt = 1 / dt;
|
|
53
|
+
for (let bone = 0; bone < this.boneCount; bone += 1) {
|
|
54
|
+
const p = bone * 3;
|
|
55
|
+
const q = bone * 4;
|
|
56
|
+
for (let axis = 0; axis < 3; axis += 1) {
|
|
57
|
+
captured.positions[p + axis] = latest.positions[p + axis];
|
|
58
|
+
captured.scales[p + axis] = latest.scales[p + axis];
|
|
59
|
+
this.positionVelocities[p + axis] = (latest.positions[p + axis] - previous.positions[p + axis]) * invDt;
|
|
60
|
+
this.scaleVelocities[p + axis] = (latest.scales[p + axis] - previous.scales[p + axis]) * invDt;
|
|
61
|
+
}
|
|
62
|
+
captured.rotations[q] = latest.rotations[q];
|
|
63
|
+
captured.rotations[q + 1] = latest.rotations[q + 1];
|
|
64
|
+
captured.rotations[q + 2] = latest.rotations[q + 2];
|
|
65
|
+
captured.rotations[q + 3] = latest.rotations[q + 3];
|
|
66
|
+
// Angular speed: angle of the per-frame delta rotation (latest·prev⁻¹),
|
|
67
|
+
// signed later against each bone's offset axis at apply time.
|
|
68
|
+
const delta = quatMultiply([latest.rotations[q], latest.rotations[q + 1], latest.rotations[q + 2], latest.rotations[q + 3]], quatConjugate([previous.rotations[q], previous.rotations[q + 1], previous.rotations[q + 2], previous.rotations[q + 3]]));
|
|
69
|
+
const w = Math.min(1, Math.abs(normalizeComponent(delta[3])));
|
|
70
|
+
this.angularSpeeds[bone] = (2 * Math.acos(w)) * invDt;
|
|
71
|
+
const axis = quatAxis(delta);
|
|
72
|
+
this.angularAxes[p] = axis[0];
|
|
73
|
+
this.angularAxes[p + 1] = axis[1];
|
|
74
|
+
this.angularAxes[p + 2] = axis[2];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Write `newPose` with the captured offset decayed over `elapsed` seconds
|
|
79
|
+
* into `out`. Buffers are reused — `out` may alias `newPose`.
|
|
80
|
+
*/
|
|
81
|
+
apply(out, newPose, elapsed) {
|
|
82
|
+
if (!this.captured) {
|
|
83
|
+
throw new Error("PoseInertializer.apply called before transition().");
|
|
84
|
+
}
|
|
85
|
+
if (newPose.boneCount !== this.boneCount || out.boneCount !== this.boneCount) {
|
|
86
|
+
throw new Error("PoseInertializer.apply requires poses matching the constructor bone count.");
|
|
87
|
+
}
|
|
88
|
+
const captured = this.captured;
|
|
89
|
+
const halfLife = this.halfLife;
|
|
90
|
+
for (let bone = 0; bone < this.boneCount; bone += 1) {
|
|
91
|
+
const p = bone * 3;
|
|
92
|
+
const q = bone * 4;
|
|
93
|
+
const posOffset = [
|
|
94
|
+
captured.positions[p] - newPose.positions[p],
|
|
95
|
+
captured.positions[p + 1] - newPose.positions[p + 1],
|
|
96
|
+
captured.positions[p + 2] - newPose.positions[p + 2]
|
|
97
|
+
];
|
|
98
|
+
const posVelocity = [
|
|
99
|
+
this.positionVelocities[p],
|
|
100
|
+
this.positionVelocities[p + 1],
|
|
101
|
+
this.positionVelocities[p + 2]
|
|
102
|
+
];
|
|
103
|
+
const decayedPos = inertializedVec3(posOffset, elapsed, halfLife, posVelocity);
|
|
104
|
+
out.positions[p] = newPose.positions[p] + decayedPos[0];
|
|
105
|
+
out.positions[p + 1] = newPose.positions[p + 1] + decayedPos[1];
|
|
106
|
+
out.positions[p + 2] = newPose.positions[p + 2] + decayedPos[2];
|
|
107
|
+
const scaleOffset = [
|
|
108
|
+
captured.scales[p] - newPose.scales[p],
|
|
109
|
+
captured.scales[p + 1] - newPose.scales[p + 1],
|
|
110
|
+
captured.scales[p + 2] - newPose.scales[p + 2]
|
|
111
|
+
];
|
|
112
|
+
const scaleVelocity = [
|
|
113
|
+
this.scaleVelocities[p],
|
|
114
|
+
this.scaleVelocities[p + 1],
|
|
115
|
+
this.scaleVelocities[p + 2]
|
|
116
|
+
];
|
|
117
|
+
const decayedScale = inertializedVec3(scaleOffset, elapsed, halfLife, scaleVelocity);
|
|
118
|
+
out.scales[p] = newPose.scales[p] + decayedScale[0];
|
|
119
|
+
out.scales[p + 1] = newPose.scales[p + 1] + decayedScale[1];
|
|
120
|
+
out.scales[p + 2] = newPose.scales[p + 2] + decayedScale[2];
|
|
121
|
+
const source = [
|
|
122
|
+
captured.rotations[q],
|
|
123
|
+
captured.rotations[q + 1],
|
|
124
|
+
captured.rotations[q + 2],
|
|
125
|
+
captured.rotations[q + 3]
|
|
126
|
+
];
|
|
127
|
+
const target = [
|
|
128
|
+
newPose.rotations[q],
|
|
129
|
+
newPose.rotations[q + 1],
|
|
130
|
+
newPose.rotations[q + 2],
|
|
131
|
+
newPose.rotations[q + 3]
|
|
132
|
+
];
|
|
133
|
+
// Sign the captured angular speed onto this bone's offset axis so
|
|
134
|
+
// momentum keeps pushing in the pre-transition direction.
|
|
135
|
+
const offset = quatMultiply(quatNormalize(source), quatConjugate(quatNormalize(target)));
|
|
136
|
+
const offsetAxis = quatAxis(offset);
|
|
137
|
+
const velAxis = [this.angularAxes[p], this.angularAxes[p + 1], this.angularAxes[p + 2]];
|
|
138
|
+
const sign = dot3(offsetAxis, velAxis) >= 0 ? 1 : -1;
|
|
139
|
+
const offsetAngle = 2 * Math.acos(Math.min(1, Math.abs(offset[3])));
|
|
140
|
+
let blended;
|
|
141
|
+
if (offsetAngle < 1e-4 && this.angularSpeeds[bone] > 0) {
|
|
142
|
+
// Degenerate case: poses already match, so the offset axis is
|
|
143
|
+
// undefined — decay momentum about the *captured velocity* axis
|
|
144
|
+
// instead of an arbitrary fallback axis.
|
|
145
|
+
const decayed = inertializedScalarInline(0, this.angularSpeeds[bone], elapsed, halfLife);
|
|
146
|
+
const momentum = [
|
|
147
|
+
velAxis[0] * Math.sin(decayed / 2),
|
|
148
|
+
velAxis[1] * Math.sin(decayed / 2),
|
|
149
|
+
velAxis[2] * Math.sin(decayed / 2),
|
|
150
|
+
Math.cos(decayed / 2)
|
|
151
|
+
];
|
|
152
|
+
blended = quatNormalize(quatMultiply(momentum, quatNormalize(target)));
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
blended = inertializedQuat(source, target, elapsed, halfLife, this.angularSpeeds[bone] * sign);
|
|
156
|
+
}
|
|
157
|
+
out.rotations[q] = blended[0];
|
|
158
|
+
out.rotations[q + 1] = blended[1];
|
|
159
|
+
out.rotations[q + 2] = blended[2];
|
|
160
|
+
out.rotations[q + 3] = blended[3];
|
|
161
|
+
}
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
/** Drop the captured transition (no allocation). */
|
|
165
|
+
clear() {
|
|
166
|
+
this.captured = undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function quatMultiply(a, b) {
|
|
170
|
+
return [
|
|
171
|
+
a[3] * b[0] + a[0] * b[3] + a[1] * b[2] - a[2] * b[1],
|
|
172
|
+
a[3] * b[1] - a[0] * b[2] + a[1] * b[3] + a[2] * b[0],
|
|
173
|
+
a[3] * b[2] + a[0] * b[1] - a[1] * b[0] + a[2] * b[3],
|
|
174
|
+
a[3] * b[3] - a[0] * b[0] - a[1] * b[1] - a[2] * b[2]
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
function quatConjugate(q) {
|
|
178
|
+
return [-q[0], -q[1], -q[2], q[3]];
|
|
179
|
+
}
|
|
180
|
+
function quatNormalize(q) {
|
|
181
|
+
const length = Math.hypot(q[0], q[1], q[2], q[3]);
|
|
182
|
+
if (length <= 1e-9)
|
|
183
|
+
return [0, 0, 0, 1];
|
|
184
|
+
return [q[0] / length, q[1] / length, q[2] / length, q[3] / length];
|
|
185
|
+
}
|
|
186
|
+
function normalizeComponent(x) {
|
|
187
|
+
return Number.isFinite(x) ? x : 1;
|
|
188
|
+
}
|
|
189
|
+
/** Rotation axis of a unit quaternion (normalized, or +X for identity). */
|
|
190
|
+
function quatAxis(q) {
|
|
191
|
+
const s = Math.sqrt(Math.max(0, 1 - Math.min(1, q[3] * q[3])));
|
|
192
|
+
if (s < 1e-8)
|
|
193
|
+
return [1, 0, 0];
|
|
194
|
+
return [q[0] / s, q[1] / s, q[2] / s];
|
|
195
|
+
}
|
|
196
|
+
function dot3(a, b) {
|
|
197
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
198
|
+
}
|
|
199
|
+
/** `Inertialization.ts`'s scalar spring, inlined so `elapsed = 0` maps to `offset0`. */
|
|
200
|
+
function inertializedScalarInline(offset0, velocity0, t, halfLife) {
|
|
201
|
+
if (!(t > 0))
|
|
202
|
+
return offset0;
|
|
203
|
+
const k = inertializationDecayRate(halfLife);
|
|
204
|
+
if (!Number.isFinite(k))
|
|
205
|
+
return 0;
|
|
206
|
+
return (offset0 + (velocity0 + k * offset0) * t) * Math.exp(-k * t);
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=PoseInertializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoseInertializer.js","sourceRoot":"","sources":["../../../../../packages/animation/src/pose/PoseInertializer.ts"],"names":[],"mappings":"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"}
|