ugly-app 0.1.958 → 0.1.960
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/character/client/CharacterCanvas.js +1 -1
- package/dist/character/client/lib/fbxClips.d.ts +7 -8
- package/dist/character/client/lib/fbxClips.d.ts.map +1 -1
- package/dist/character/client/lib/fbxClips.js +59 -295
- package/dist/character/client/lib/fbxClips.js.map +1 -1
- package/dist/character/shared/lib/retarget.d.ts +57 -0
- package/dist/character/shared/lib/retarget.d.ts.map +1 -0
- package/dist/character/shared/lib/retarget.js +324 -0
- package/dist/character/shared/lib/retarget.js.map +1 -0
- package/dist/cli/publish/orchestrator.d.ts.map +1 -1
- package/dist/cli/publish/orchestrator.js +12 -2
- package/dist/cli/publish/orchestrator.js.map +1 -1
- package/dist/cli/staticAssets.d.ts +8 -0
- package/dist/cli/staticAssets.d.ts.map +1 -1
- package/dist/cli/staticAssets.js +10 -0
- package/dist/cli/staticAssets.js.map +1 -1
- package/dist/cli/version.d.ts +1 -1
- package/dist/cli/version.js +1 -1
- package/package.json +1 -1
- package/src/character/client/CharacterCanvas.tsx +1 -1
- package/src/character/client/lib/fbxClips.ts +68 -324
- package/src/character/shared/lib/retarget.ts +369 -0
- package/src/cli/publish/orchestrator.ts +11 -1
- package/src/cli/staticAssets.test.ts +30 -0
- package/src/cli/staticAssets.ts +11 -0
- package/src/cli/version.ts +1 -1
|
@@ -149,7 +149,7 @@ export const CharacterCanvas = forwardRef(function CharacterCanvas({ source, spe
|
|
|
149
149
|
if (loadingPoseRef.current === want)
|
|
150
150
|
return;
|
|
151
151
|
loadingPoseRef.current = want;
|
|
152
|
-
void loadFbxClip(index, want, skel.names, skel.restQ, skel.
|
|
152
|
+
void loadFbxClip(index, want, skel.names, skel.restQ, skel.heads, skel.parents)
|
|
153
153
|
.then((clips) => {
|
|
154
154
|
if (live.dead)
|
|
155
155
|
return;
|
|
@@ -45,16 +45,15 @@ export declare function loadFbxClip(index: FbxClipIndex, name: string, boneNames
|
|
|
45
45
|
*/
|
|
46
46
|
restQ: Float32Array,
|
|
47
47
|
/**
|
|
48
|
-
* The TARGET rig's
|
|
48
|
+
* The TARGET rig's bind WORLD joint positions, `n * 3` — the calibration's yardstick.
|
|
49
49
|
*
|
|
50
|
-
* ⚠️
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* limb" is on each side; the retarget aligns them.
|
|
50
|
+
* ⚠️ POSITIONS, NOT JUST ROTATIONS, because the retarget now works by AIMING: each bone is
|
|
51
|
+
* swung, at bind, until it points the way the clip's bind points it, and a direction is the
|
|
52
|
+
* vector to the child's head. Rotations alone cannot say where a bone points; measured on the
|
|
53
|
+
* real assets the aim gap is the larger half of the arm disagreement (~55° of the ~60°), the
|
|
54
|
+
* half the earlier rotation-only retargets preserved in every frame as crossed arms.
|
|
56
55
|
*/
|
|
57
|
-
|
|
56
|
+
heads: ArrayLike<number>,
|
|
58
57
|
/**
|
|
59
58
|
* The TARGET rig's parent index per bone, `−1` for a root.
|
|
60
59
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fbxClips.d.ts","sourceRoot":"","sources":["../../../../src/character/client/lib/fbxClips.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fbxClips.d.ts","sourceRoot":"","sources":["../../../../src/character/client/lib/fbxClips.ts"],"names":[],"mappings":"AA6BA;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,YAAY,CAAC;QACpB,MAAM,EAAE,YAAY,CAAC;KACtB,EAAE,CAAC;CACL;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,EAAE,CAE1D;AAID;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,MAAM,EAAE;AAC5B;;;;;;;;;;;;GAYG;AACH,KAAK,EAAE,YAAY;AACnB;;;;;;;;GAQG;AACH,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC;AACxB;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,GACzB,OAAO,CAAC,YAAY,EAAE,CAAC,CA8KzB"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
// a decision worth making deliberately rather than inheriting from a file.
|
|
19
19
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
20
20
|
import { stripPrefix } from '../../shared/lib/mixamoMap.js';
|
|
21
|
-
import {
|
|
21
|
+
import { bakeTrack, calibrate, clipWorldBind, } from '../../shared/lib/retarget.js';
|
|
22
22
|
/** The names an index serves, sorted — a picker lists these. */
|
|
23
23
|
export function fbxClipNames(index) {
|
|
24
24
|
return Object.keys(index).sort();
|
|
@@ -47,16 +47,15 @@ export async function loadFbxClip(index, name, boneNames,
|
|
|
47
47
|
*/
|
|
48
48
|
restQ,
|
|
49
49
|
/**
|
|
50
|
-
* The TARGET rig's
|
|
50
|
+
* The TARGET rig's bind WORLD joint positions, `n * 3` — the calibration's yardstick.
|
|
51
51
|
*
|
|
52
|
-
* ⚠️
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* limb" is on each side; the retarget aligns them.
|
|
52
|
+
* ⚠️ POSITIONS, NOT JUST ROTATIONS, because the retarget now works by AIMING: each bone is
|
|
53
|
+
* swung, at bind, until it points the way the clip's bind points it, and a direction is the
|
|
54
|
+
* vector to the child's head. Rotations alone cannot say where a bone points; measured on the
|
|
55
|
+
* real assets the aim gap is the larger half of the arm disagreement (~55° of the ~60°), the
|
|
56
|
+
* half the earlier rotation-only retargets preserved in every frame as crossed arms.
|
|
58
57
|
*/
|
|
59
|
-
|
|
58
|
+
heads,
|
|
60
59
|
/**
|
|
61
60
|
* The TARGET rig's parent index per bone, `−1` for a root.
|
|
62
61
|
*
|
|
@@ -78,10 +77,10 @@ parents) {
|
|
|
78
77
|
// whichever asked first — every bone offset by the difference between two bind poses, playing
|
|
79
78
|
// perfectly. The bone list alone was already keyed for exactly this reason; this is the same trap
|
|
80
79
|
// one level deeper.
|
|
81
|
-
// ⚠️ AND THE PARENTS ARE PART OF THE KEY TOO, for the same reason the rest is: the
|
|
82
|
-
// in each bone's WORLD rest, which two rigs with identical
|
|
83
|
-
// do not share.
|
|
84
|
-
const key = `${name}|${boneNames.join(',')}|${Array.from(restQ, (v) => v.toFixed(4)).join(',')}|${Array.from(
|
|
80
|
+
// ⚠️ AND THE PARENTS AND HEADS ARE PART OF THE KEY TOO, for the same reason the rest is: the
|
|
81
|
+
// retarget bakes in each bone's WORLD rest and bind POSITIONS, which two rigs with identical
|
|
82
|
+
// local rotations but different nesting or proportions do not share.
|
|
83
|
+
const key = `${name}|${boneNames.join(',')}|${Array.from(restQ, (v) => v.toFixed(4)).join(',')}|${Array.from(heads, (v) => v.toFixed(3)).join(',')}|${Array.from(parents).join(',')}`;
|
|
85
84
|
const hit = cache.get(key);
|
|
86
85
|
if (hit)
|
|
87
86
|
return hit;
|
|
@@ -101,204 +100,58 @@ parents) {
|
|
|
101
100
|
// had touched the tree would read a posed frame and the retarget would cancel against the wrong
|
|
102
101
|
// reference — which still produces smooth, confident, wrong motion.
|
|
103
102
|
//
|
|
104
|
-
// ⚠️ THE PARENT LINKS COME WITH IT. The retarget needs each clip bone's WORLD rest
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
103
|
+
// ⚠️ THE PARENT LINKS AND POSITIONS COME WITH IT. The retarget needs each clip bone's WORLD rest
|
|
104
|
+
// and its bind POSITIONS — the calibration aims bones, and a direction is the vector to the
|
|
105
|
+
// child's head.
|
|
106
|
+
const bind = {
|
|
107
|
+
parent: new Map(),
|
|
108
|
+
restLocal: new Map(),
|
|
109
|
+
restPos: new Map(),
|
|
110
|
+
};
|
|
109
111
|
group.traverse((o) => {
|
|
110
112
|
if (!o.isBone)
|
|
111
113
|
return;
|
|
112
114
|
const n = stripPrefix(o.name);
|
|
113
|
-
|
|
115
|
+
bind.restLocal.set(n, [
|
|
114
116
|
o.quaternion.x,
|
|
115
117
|
o.quaternion.y,
|
|
116
118
|
o.quaternion.z,
|
|
117
119
|
o.quaternion.w,
|
|
118
120
|
]);
|
|
119
|
-
|
|
121
|
+
bind.restPos.set(n, [o.position.x, o.position.y, o.position.z]);
|
|
120
122
|
// ⚠️ STOPS AT THE FIRST NON-BONE. Mixamo hangs its skeleton under an Armature node that may
|
|
121
123
|
// carry a Y-up conversion, and that rotation belongs to the FILE, not to the pose — folding it
|
|
122
124
|
// in would rotate the character's whole motion relative to its own body.
|
|
123
125
|
const p = o.parent;
|
|
124
|
-
|
|
126
|
+
bind.parent.set(n, p && p.isBone
|
|
125
127
|
? stripPrefix(p.name)
|
|
126
128
|
: null);
|
|
127
129
|
});
|
|
130
|
+
// ── THE CALIBRATION ────────────────────────────────────────────────────────────────────────────
|
|
131
|
+
// One constant per bone, `K_j`, so that `ours_world(t) = clipWorld_j(t) ⊗ K_j` transfers aim AND
|
|
132
|
+
// twist exactly. The whole design — the per-bone swing that poses our A-pose bind into the clip's
|
|
133
|
+
// T-pose bind, which bones aim and which ride, and why the T-pose clip is a real self-check now —
|
|
134
|
+
// is documented at the top of `shared/lib/retarget.ts`, next to the math. It replaces two
|
|
135
|
+
// retargets that each carried half the A-vs-T bind difference into every frame: the
|
|
136
|
+
// change-of-basis delta replay (twist faithful, arms crossed the torso — measured 62.9°/86.9° of
|
|
137
|
+
// arm error in `Walking`/`Dying`) and the chain-alignment/branch-delta split (aim exact, roll
|
|
138
|
+
// unconstrained — twisted forearms and clawed hands, the 0.1.957 complaint).
|
|
139
|
+
const rig = { names: boneNames, parents, restQ, heads };
|
|
140
|
+
const clipWorld = clipWorldBind(bind);
|
|
141
|
+
const K = calibrate(rig, bind, clipWorld);
|
|
128
142
|
const slot = new Map(boneNames.map((n, i) => [n, i]));
|
|
129
143
|
const PATHS = {
|
|
130
144
|
position: 0,
|
|
131
145
|
quaternion: 1,
|
|
132
146
|
scale: 2,
|
|
133
147
|
};
|
|
134
|
-
// ── PER-BONE FRAME TRANSFER: CHAIN ALIGNMENT + BRANCH DELTA ────────────────────────────────
|
|
135
|
-
//
|
|
136
|
-
// A bone's world orientation does two jobs at once: it aims its child JOINTS (positions come
|
|
137
|
-
// from translations, directions from this rotation) and it carries the pose. The retarget
|
|
138
|
-
// bakes `ourWorld(t) = clipWorld(t) × K_j`, and the whole question is what the constant K_j
|
|
139
|
-
// must be per bone. The audit (`tests/character/irRetarget.test.ts`) pinned the answer by
|
|
140
|
-
// bone CLASS, and the two twisted-hips regressions are what one-rule-for-all costs.
|
|
141
|
-
//
|
|
142
|
-
// CHAIN BONES — exactly one shared, non-junk child (every limb bone, the spine column, the
|
|
143
|
-
// neck): the bone's only observable effect is the direction it aims that child. K_j is the
|
|
144
|
-
// shortest-arc taking our child-offset direction onto the clip's, read in each bone's LOCAL
|
|
145
|
-
// frame at rest — so our limb points where the clip points, exactly, at every frame. This is
|
|
146
|
-
// the "arms crossed while walking" fix: Mixamo's arm swing must move OUR arms absolutely,
|
|
147
|
-
// not relative to a bind they disagree with.
|
|
148
|
-
//
|
|
149
|
-
// BRANCH BONES — zero or ≥2 shared, non-junk children (Hips, Spine2, the hands, the head,
|
|
150
|
-
// toe bases): the child FAN's shape is anatomy, not pose, and the two rigs' fans are NOT
|
|
151
|
-
// congruent (measured: Hips Spine⊾UpLeg ours 90.5° vs clip 108.5°, thighs 156° vs 142°;
|
|
152
|
-
// Spine2's shoulders 25.9° vs 58.9° — and Dying.fbx's skeleton differs again, so no constant
|
|
153
|
-
// can fit every file). Forcing the clip's absolute frame here twists our pelvis ~18° and our
|
|
154
|
-
// chest ~25° into a compromise that matches NEITHER rig — the "hips twisted, body malformed"
|
|
155
|
-
// report. K_j is instead the WORLD DELTA reference `clipRestWorld⁻¹ × ourRestWorld`: at the
|
|
156
|
-
// clip's rest our anatomy appears exactly, and the clip's rotations transfer as world-space
|
|
157
|
-
// deltas. The children's own directions stay clip-true regardless — each child is a chain
|
|
158
|
-
// bone with its own alignment, and its local absorbs the difference.
|
|
159
|
-
//
|
|
160
|
-
// ⚠️ PAIRED BY NAME, NEVER BY ORDER. Child ORDER is a file-format accident, not anatomy: our
|
|
161
|
-
// Hips lists Spine first, Mixamo's lists RightUpLeg first, and pairing "the first child" on
|
|
162
|
-
// each side aimed our up-spine at Mixamo's down-leg — the first twisted-hips regression
|
|
163
|
-
// (Spine2 paired Neck with RightShoulder, hands paired Thumb1 with Index1).
|
|
164
|
-
//
|
|
165
|
-
// ⚠️ JUNK OFFSETS ARE NOT DIRECTIONS. Our rig's placeholder end bones sit at EXACTLY zero
|
|
166
|
-
// offset (HeadTop_End, finger 4s, Toe_Ends) where the clip has real bones, and our Hips→Spine
|
|
167
|
-
// offset is 0.054 — a 5mm joint whose "direction" is cooker noise, not anatomy (the smallest
|
|
168
|
-
// REAL offset on the rig is 0.142, a pinky segment). Any child below EPS_T is skipped on both
|
|
169
|
-
// the chain count and the aim reference: aiming at noise manufactures a twisted joint.
|
|
170
|
-
const shortestArc = (ax, ay, az, bx, by, bz) => {
|
|
171
|
-
const al = Math.hypot(ax, ay, az) || 1;
|
|
172
|
-
const bl = Math.hypot(bx, by, bz) || 1;
|
|
173
|
-
const a = [ax / al, ay / al, az / al];
|
|
174
|
-
const b = [bx / bl, by / bl, bz / bl];
|
|
175
|
-
const d = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
176
|
-
if (d > 1 - 1e-6)
|
|
177
|
-
return [0, 0, 0, 1];
|
|
178
|
-
if (d < -1 + 1e-6) {
|
|
179
|
-
// Antiparallel: any perpendicular axis does. cross(a, X) = (0, az, −ay), or
|
|
180
|
-
// cross(a, Y) = (−az, 0, ax) when a IS the X axis.
|
|
181
|
-
let cx = 0;
|
|
182
|
-
let cy = a[2];
|
|
183
|
-
let cz = -a[1];
|
|
184
|
-
let cl = Math.hypot(cx, cy, cz);
|
|
185
|
-
if (cl < 1e-6) {
|
|
186
|
-
cx = -a[2];
|
|
187
|
-
cy = 0;
|
|
188
|
-
cz = a[0];
|
|
189
|
-
cl = Math.hypot(cx, cy, cz) || 1;
|
|
190
|
-
}
|
|
191
|
-
return [cx / cl, cy / cl, cz / cl, 0];
|
|
192
|
-
}
|
|
193
|
-
const cx = a[1] * b[2] - a[2] * b[1];
|
|
194
|
-
const cy = a[2] * b[0] - a[0] * b[2];
|
|
195
|
-
const cz = a[0] * b[1] - a[1] * b[0];
|
|
196
|
-
const l = Math.hypot(cx, cy, cz, 1 + d) || 1;
|
|
197
|
-
return [cx / l, cy / l, cz / l, (1 + d) / l];
|
|
198
|
-
};
|
|
199
|
-
// Both rigs' REST WORLD orientations — the branch-delta reference needs them. Ours from restQ
|
|
200
|
-
// down the parent chain (parents precede children, so a plain loop is a valid FK walk), the
|
|
201
|
-
// clip's from its file rest down its own hierarchy.
|
|
202
|
-
const ourRestWorld = new Array(boneNames.length);
|
|
203
|
-
for (let j = 0; j < boneNames.length; j++) {
|
|
204
|
-
const p = parents[j] ?? -1;
|
|
205
|
-
const lq = [
|
|
206
|
-
restQ[j * 4] ?? 0,
|
|
207
|
-
restQ[j * 4 + 1] ?? 0,
|
|
208
|
-
restQ[j * 4 + 2] ?? 0,
|
|
209
|
-
restQ[j * 4 + 3] ?? 1,
|
|
210
|
-
];
|
|
211
|
-
ourRestWorld[j] =
|
|
212
|
-
p >= 0 && p < boneNames.length ? qMul(ourRestWorld[p], lq) : lq;
|
|
213
|
-
}
|
|
214
|
-
const clipRestWorld = new Map();
|
|
215
|
-
const clipRestWorldAt = (n) => {
|
|
216
|
-
const hit = clipRestWorld.get(n);
|
|
217
|
-
if (hit)
|
|
218
|
-
return hit;
|
|
219
|
-
const local = clipRest.get(n) ?? [0, 0, 0, 1];
|
|
220
|
-
const p = clipParent.get(n) ?? null;
|
|
221
|
-
const q = p ? qMul(clipRestWorldAt(p), local) : local;
|
|
222
|
-
clipRestWorld.set(n, q);
|
|
223
|
-
return q;
|
|
224
|
-
};
|
|
225
|
-
const ourChildren = new Map();
|
|
226
|
-
for (let j = 0; j < boneNames.length; j++) {
|
|
227
|
-
const p = parents[j] ?? -1;
|
|
228
|
-
if (p >= 0 && p < boneNames.length) {
|
|
229
|
-
const list = ourChildren.get(p) ?? [];
|
|
230
|
-
list.push(j);
|
|
231
|
-
ourChildren.set(p, list);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
const EPS_T = 0.1; // our units: junk offsets are 0.054 (Hips→Spine) and 0; smallest real bone is 0.142
|
|
235
|
-
const EPS_CLIP = 1e-3; // clip units (cm); every real clip offset is ≥ 1.6
|
|
236
|
-
const alignA = new Map();
|
|
237
|
-
for (const [name, j] of slot) {
|
|
238
|
-
if (!clipRest.has(name))
|
|
239
|
-
continue;
|
|
240
|
-
let chain = null;
|
|
241
|
-
let shared = 0;
|
|
242
|
-
for (const oc of ourChildren.get(j) ?? []) {
|
|
243
|
-
const ct = clipRestT.get(boneNames[oc]);
|
|
244
|
-
if (!ct)
|
|
245
|
-
continue;
|
|
246
|
-
const ax = restT[oc * 3] ?? 0, ay = restT[oc * 3 + 1] ?? 0, az = restT[oc * 3 + 2] ?? 0;
|
|
247
|
-
const al = Math.hypot(ax, ay, az);
|
|
248
|
-
const bl = Math.hypot(ct[0], ct[1], ct[2]);
|
|
249
|
-
if (al < EPS_T || bl < EPS_CLIP)
|
|
250
|
-
continue;
|
|
251
|
-
shared++;
|
|
252
|
-
chain = {
|
|
253
|
-
a: [ax / al, ay / al, az / al],
|
|
254
|
-
b: [ct[0] / bl, ct[1] / bl, ct[2] / bl],
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
// Chain bone → shortest-arc direction alignment. Branch bone → world-delta reference, so
|
|
258
|
-
// the clip's rest shows OUR anatomy and only the motion transfers (see the header above).
|
|
259
|
-
alignA.set(j, shared === 1 && chain
|
|
260
|
-
? shortestArc(chain.a[0], chain.a[1], chain.a[2], chain.b[0], chain.b[1], chain.b[2])
|
|
261
|
-
: qMul(qConj(clipRestWorldAt(name)), ourRestWorld[j]));
|
|
262
|
-
}
|
|
263
|
-
// nlerp between two keys, with the double-cover sign fix — the union timeline lands mostly on
|
|
264
|
-
// exact keys, so this is interpolation insurance, not the primary path.
|
|
265
|
-
const sampleTrack = (times, values, t) => {
|
|
266
|
-
let hi = 0;
|
|
267
|
-
while (hi < times.length && times[hi] < t)
|
|
268
|
-
hi++;
|
|
269
|
-
if (hi === 0)
|
|
270
|
-
return [values[0], values[1], values[2], values[3]];
|
|
271
|
-
if (hi >= times.length) {
|
|
272
|
-
const o = (times.length - 1) * 4;
|
|
273
|
-
return [values[o], values[o + 1], values[o + 2], values[o + 3]];
|
|
274
|
-
}
|
|
275
|
-
const lo = hi - 1;
|
|
276
|
-
const span = times[hi] - times[lo];
|
|
277
|
-
const tt = span > 0 ? (t - times[lo]) / span : 0;
|
|
278
|
-
const a = lo * 4, b = hi * 4;
|
|
279
|
-
const sign = values[a] * values[b] +
|
|
280
|
-
values[a + 1] * values[b + 1] +
|
|
281
|
-
values[a + 2] * values[b + 2] +
|
|
282
|
-
values[a + 3] * values[b + 3] <
|
|
283
|
-
0
|
|
284
|
-
? -1
|
|
285
|
-
: 1;
|
|
286
|
-
const q = [
|
|
287
|
-
values[a] + (values[b] * sign - values[a]) * tt,
|
|
288
|
-
values[a + 1] + (values[b + 1] * sign - values[a + 1]) * tt,
|
|
289
|
-
values[a + 2] + (values[b + 2] * sign - values[a + 2]) * tt,
|
|
290
|
-
values[a + 3] + (values[b + 3] * sign - values[a + 3]) * tt,
|
|
291
|
-
];
|
|
292
|
-
const n = Math.hypot(q[0], q[1], q[2], q[3]) || 1;
|
|
293
|
-
return [q[0] / n, q[1] / n, q[2] / n, q[3] / n];
|
|
294
|
-
};
|
|
295
148
|
const out = [];
|
|
296
149
|
let dropped = 0;
|
|
297
150
|
let retargeted = 0;
|
|
298
151
|
for (const clip of group.animations) {
|
|
299
|
-
|
|
300
|
-
// over a common timeline, not per track.
|
|
152
|
+
const channels = [];
|
|
301
153
|
const tracks = new Map();
|
|
154
|
+
const joints = new Map();
|
|
302
155
|
for (const track of clip.tracks) {
|
|
303
156
|
// `mixamorig:LeftArm.quaternion` — the property is after the LAST dot, because bone names
|
|
304
157
|
// can themselves contain dots.
|
|
@@ -317,122 +170,33 @@ parents) {
|
|
|
317
170
|
dropped++;
|
|
318
171
|
continue;
|
|
319
172
|
}
|
|
173
|
+
// ── RETARGET ONTO THE CALIBRATED REFERENCE ─────────────────────────────────────────────
|
|
174
|
+
//
|
|
175
|
+
// ⚠️ WHICH MAKES THE T-POSE CLIP A REAL SELF-CHECK, inverted from what it used to prove. A
|
|
176
|
+
// static clip no longer reproduces our bind — it reproduces the CALIBRATED pose: arms
|
|
177
|
+
// horizontal, palms down, feet flat. The old check passed for right and wrong retargets
|
|
178
|
+
// alike, because a static delta is the identity under ANY formula; the new one fails
|
|
179
|
+
// visibly and numerically (`tests/character/fbxCalibrate.test.ts` — baked directions must
|
|
180
|
+
// land within a degree of the clip's) the moment the swing, the frame order, or the tip
|
|
181
|
+
// rule regresses.
|
|
182
|
+
//
|
|
183
|
+
// ⚠️ THE BAKE READS EVERY TRACK, not only this bone's: a baked local is `parentWorld(t)⁻¹ ⊗
|
|
184
|
+
// world(t)`, and the parent's world is moving too, sampled at this bone's own key times.
|
|
320
185
|
tracks.set(bone, {
|
|
321
|
-
j,
|
|
322
186
|
times: Float32Array.from(track.times),
|
|
323
187
|
values: Float32Array.from(track.values),
|
|
324
188
|
});
|
|
189
|
+
joints.set(bone, j);
|
|
325
190
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
// bind is an A-pose with the elbows bent forward. A walking clip swings Mixamo's arms
|
|
336
|
-
// ~80° down from its bind; replaying that delta on arms already hanging 45° folded the
|
|
337
|
-
// forearms through the torso — the "arms crossed while walking" report — and a static
|
|
338
|
-
// T-pose clip, whose delta is the identity, showed our A-pose bind and called it T-pose.
|
|
339
|
-
//
|
|
340
|
-
// The transfer copies each bone's WORLD orientation with a per-bone constant K_j:
|
|
341
|
-
// ourLocal(t) = ourParentWorld(t)⁻¹ × clipWorld(t) × K_j
|
|
342
|
-
// computed top-down per frame — a hierarchy walk at LOAD time, baked to plain tracks, so
|
|
343
|
-
// playback stays the per-track sample it always was. K_j is the chain-alignment or
|
|
344
|
-
// branch-delta constant computed above: chain bones aim their one child exactly where the
|
|
345
|
-
// clip aims it; branch bones (Hips, Spine2, hands, head) keep OUR anatomy at the clip's
|
|
346
|
-
// rest and transfer only the rotation delta, because the two rigs' child fans are
|
|
347
|
-
// anatomically different shapes and forcing the clip's frame twists the pelvis and chest.
|
|
348
|
-
// Bones without tracks keep our rest local, so an arm-only clip cannot borrow Mixamo's legs.
|
|
349
|
-
//
|
|
350
|
-
// ⚠️ THE T-POSE CHECK NOW ASSERTS THE OPPOSITE OF BEFORE. A static clip used to be a
|
|
351
|
-
// no-op (delta identity → bind pose), which made "T-Pose shows the T-pose" impossible and
|
|
352
|
-
// hid the frame bug behind a green test. Under the copy, T-Pose puts our arms straight
|
|
353
|
-
// out — measured in `tests/character/irArmPose.test.ts`, which checks limb DIRECTIONS
|
|
354
|
-
// (anatomy), not quaternion equality (frames).
|
|
355
|
-
const timelineSet = new Set();
|
|
356
|
-
for (const { times } of tracks.values())
|
|
357
|
-
for (const t of times)
|
|
358
|
-
timelineSet.add(Math.round(t * 1e4) / 1e4);
|
|
359
|
-
const timeline = [...timelineSet].sort((a, b) => a - b);
|
|
360
|
-
const baked = new Map();
|
|
361
|
-
for (const { j } of tracks.values())
|
|
362
|
-
if (!baked.has(j))
|
|
363
|
-
baked.set(j, new Float32Array(timeline.length * 4));
|
|
364
|
-
const clipWorldFrame = new Map();
|
|
365
|
-
const ourWorldFrame = boneNames.map(() => null);
|
|
366
|
-
for (let f = 0; f < timeline.length; f++) {
|
|
367
|
-
const t = timeline[f];
|
|
368
|
-
// The clip's world this frame: tracked bones sample their track, the rest hold the
|
|
369
|
-
// clip's rest local — FK down the clip's own parent map, memoised per frame.
|
|
370
|
-
clipWorldFrame.clear();
|
|
371
|
-
const clipWorldAt = (n) => {
|
|
372
|
-
const hit = clipWorldFrame.get(n);
|
|
373
|
-
if (hit)
|
|
374
|
-
return hit;
|
|
375
|
-
const tr = tracks.get(n);
|
|
376
|
-
const local = tr
|
|
377
|
-
? sampleTrack(tr.times, tr.values, t)
|
|
378
|
-
: (clipRest.get(n) ?? [0, 0, 0, 1]);
|
|
379
|
-
const p = clipParent.get(n) ?? null;
|
|
380
|
-
const q = p ? qMul(clipWorldAt(p), local) : local;
|
|
381
|
-
clipWorldFrame.set(n, q);
|
|
382
|
-
return q;
|
|
383
|
-
};
|
|
384
|
-
// Our locals this frame: driven bones copy the clip's world; the rest hold our rest.
|
|
385
|
-
ourWorldFrame.fill(null);
|
|
386
|
-
const ourWorldAt = (j) => {
|
|
387
|
-
const hit = ourWorldFrame[j];
|
|
388
|
-
if (hit)
|
|
389
|
-
return hit;
|
|
390
|
-
const p = parents[j] ?? -1;
|
|
391
|
-
const pw = p < 0 || p >= boneNames.length
|
|
392
|
-
? [0, 0, 0, 1]
|
|
393
|
-
: ourWorldAt(p);
|
|
394
|
-
const name = boneNames[j];
|
|
395
|
-
let local;
|
|
396
|
-
if (tracks.has(name) && clipRest.has(name)) {
|
|
397
|
-
local = qMul(qConj(pw), qMul(clipWorldAt(name), alignA.get(j) ?? [0, 0, 0, 1]));
|
|
398
|
-
const arr = baked.get(j);
|
|
399
|
-
arr[f * 4] = local[0];
|
|
400
|
-
arr[f * 4 + 1] = local[1];
|
|
401
|
-
arr[f * 4 + 2] = local[2];
|
|
402
|
-
arr[f * 4 + 3] = local[3];
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
local = [
|
|
406
|
-
restQ[j * 4] ?? 0,
|
|
407
|
-
restQ[j * 4 + 1] ?? 0,
|
|
408
|
-
restQ[j * 4 + 2] ?? 0,
|
|
409
|
-
restQ[j * 4 + 3] ?? 1,
|
|
410
|
-
];
|
|
411
|
-
}
|
|
412
|
-
const w = qMul(pw, local);
|
|
413
|
-
ourWorldFrame[j] = w;
|
|
414
|
-
return w;
|
|
415
|
-
};
|
|
416
|
-
for (let j = 0; j < boneNames.length; j++)
|
|
417
|
-
ourWorldAt(j);
|
|
418
|
-
}
|
|
419
|
-
for (const [j, values] of baked) {
|
|
420
|
-
channels.push({
|
|
421
|
-
jointIndex: j,
|
|
422
|
-
path: 1,
|
|
423
|
-
times: Float32Array.from(timeline),
|
|
424
|
-
values,
|
|
425
|
-
});
|
|
426
|
-
retargeted++;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
430
|
-
// ⚠️ NO CLIP-SIDE REST, NO RETARGET. An FBX with no bone hierarchy to read keeps its
|
|
431
|
-
// local rotations wholesale — the exact bug the retarget exists to fix, but half a
|
|
432
|
-
// correction is worse than none, because it looks deliberate. Said out loud in the log
|
|
433
|
-
// line below (`retargeted 0/…`), which is the only place this is visible.
|
|
434
|
-
for (const { j, times, values } of tracks.values())
|
|
435
|
-
channels.push({ jointIndex: j, path: 1, times, values });
|
|
191
|
+
for (const [bone, tr] of tracks) {
|
|
192
|
+
const j = joints.get(bone);
|
|
193
|
+
channels.push({
|
|
194
|
+
jointIndex: j,
|
|
195
|
+
path: 1,
|
|
196
|
+
times: tr.times,
|
|
197
|
+
values: bakeTrack(rig, K, bind, tracks, j),
|
|
198
|
+
});
|
|
199
|
+
retargeted++;
|
|
436
200
|
}
|
|
437
201
|
if (!channels.length)
|
|
438
202
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fbxClips.js","sourceRoot":"","sources":["../../../../src/character/client/lib/fbxClips.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fbxClips.js","sourceRoot":"","sources":["../../../../src/character/client/lib/fbxClips.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type Quat, type Vec3 } from './humanRig.js';
|
|
2
|
+
/** The target rig's bind pose, as the cooked container carries it. */
|
|
3
|
+
export interface RigRest {
|
|
4
|
+
names: readonly string[];
|
|
5
|
+
/** Parent index per bone, −1 for a root. */
|
|
6
|
+
parents: ArrayLike<number>;
|
|
7
|
+
/** Rest LOCAL rotations, `n * 4` xyzw. */
|
|
8
|
+
restQ: ArrayLike<number>;
|
|
9
|
+
/** Bind WORLD joint positions, `n * 3` — verified to agree with `restT` accumulated (1e-5). */
|
|
10
|
+
heads: ArrayLike<number>;
|
|
11
|
+
}
|
|
12
|
+
/** The clip rig's bind pose, read off the FBX bone hierarchy before anything poses it. */
|
|
13
|
+
export interface ClipBind {
|
|
14
|
+
/** Stripped bone name → stripped parent name, `null` at the first non-bone ancestor. */
|
|
15
|
+
parent: Map<string, string | null>;
|
|
16
|
+
/** Stripped bone name → rest LOCAL rotation (`bone.quaternion`). */
|
|
17
|
+
restLocal: Map<string, Quat>;
|
|
18
|
+
/** Stripped bone name → rest LOCAL position (`bone.position`). */
|
|
19
|
+
restPos: Map<string, Vec3>;
|
|
20
|
+
}
|
|
21
|
+
/** One animation's rotation tracks, by stripped bone name. */
|
|
22
|
+
export interface ClipTracks {
|
|
23
|
+
times: Float32Array;
|
|
24
|
+
values: Float32Array;
|
|
25
|
+
}
|
|
26
|
+
/** The shortest rotation taking direction `u` to direction `v`. */
|
|
27
|
+
export declare function shortestArc(u: Vec3, v: Vec3): Quat;
|
|
28
|
+
/** World rotation AND position of every clip bone at bind, walked down the clip hierarchy. */
|
|
29
|
+
export declare function clipWorldBind(bind: ClipBind): Map<string, {
|
|
30
|
+
q: Quat;
|
|
31
|
+
p: Vec3;
|
|
32
|
+
}>;
|
|
33
|
+
/**
|
|
34
|
+
* The per-bone constant `K_j`, ours_world(t) = clipWorld_j(t) ⊗ K_j — see the header.
|
|
35
|
+
*
|
|
36
|
+
* Returns `null` entries for bones the clip does not have: no track will ever address them, and a
|
|
37
|
+
* caller indexing `K[j]` for an undriven bone should get nothing rather than a quiet identity.
|
|
38
|
+
*/
|
|
39
|
+
export declare function calibrate(rig: RigRest, bind: ClipBind, clipWorld: Map<string, {
|
|
40
|
+
q: Quat;
|
|
41
|
+
p: Vec3;
|
|
42
|
+
}>): (Quat | null)[];
|
|
43
|
+
/** Nearest-bracket nlerp sample of a track at `t`, sign-fixed so the short way round is taken. */
|
|
44
|
+
export declare function sampleKeys(tr: ClipTracks, t: number): Quat;
|
|
45
|
+
/**
|
|
46
|
+
* Bake one bone's rotation track into OUR rig's local frames.
|
|
47
|
+
*
|
|
48
|
+
* `tracks` carries EVERY rotation track of the clip, not only this bone's: the local at `t` is
|
|
49
|
+
* `parentWorld(t)⁻¹ ⊗ world(t)`, and the parent's world is moving too, sampled at this bone's own
|
|
50
|
+
* key times. Bones the clip does not drive hold their rest local, which is what playback does with
|
|
51
|
+
* them — so the bake and the player compose the same hierarchy.
|
|
52
|
+
*
|
|
53
|
+
* Keys are made sign-continuous as they are written: q and −q are one rotation, but the player
|
|
54
|
+
* interpolates raw floats, and a hemisphere jump between adjacent keys spins the long way round.
|
|
55
|
+
*/
|
|
56
|
+
export declare function bakeTrack(rig: RigRest, K: (Quat | null)[], bind: ClipBind, tracks: Map<string, ClipTracks>, bone: number): Float32Array;
|
|
57
|
+
//# sourceMappingURL=retarget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retarget.d.ts","sourceRoot":"","sources":["../../../../src/character/shared/lib/retarget.ts"],"names":[],"mappings":"AA4DA,OAAO,EAAqB,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,eAAe,CAAC;AAExE,sEAAsE;AACtE,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,4CAA4C;IAC5C,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC3B,0CAA0C;IAC1C,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACzB,+FAA+F;IAC/F,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;CAC1B;AAED,0FAA0F;AAC1F,MAAM,WAAW,QAAQ;IACvB,wFAAwF;IACxF,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACnC,oEAAoE;IACpE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC7B,kEAAkE;IAClE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;CAC5B;AAED,8DAA8D;AAC9D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;CACtB;AAgBD,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,CAkBlD;AAOD,8FAA8F;AAC9F,wBAAgB,aAAa,CAC3B,IAAI,EAAE,QAAQ,GACb,GAAG,CAAC,MAAM,EAAE;IAAE,CAAC,EAAE,IAAI,CAAC;IAAC,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,CA0BnC;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,CAAC,EAAE,IAAI,CAAC;IAAC,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,GAC3C,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAwEjB;AAED,kGAAkG;AAClG,wBAAgB,UAAU,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CA8B1D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,OAAO,EACZ,CAAC,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,EAClB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC/B,IAAI,EAAE,MAAM,GACX,YAAY,CA0Ed"}
|