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.
@@ -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.restT, skel.parents)
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 rest LOCAL translations, `n * 3` xyz.
48
+ * The TARGET rig's bind WORLD joint positions, `n * 3` — the calibration's yardstick.
49
49
  *
50
- * ⚠️ NEEDED FOR THE LIMB-DIRECTION ALIGNMENT. Copying the clip's world orientation outright is
51
- * not enough: a bone's job is to aim its CHILD, and the child offset sits at a different
52
- * direction in our bone's local frame than in Mixamo's (the two rigs' bones are rolled
53
- * differently about their own long axes). Without this the copied pose is off by a constant
54
- * 12–22° per arm bone — a T-pose whose arms sag. The child offsets say which way "along the
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
- restT: Float32Array,
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":"AAsBA;;;;;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;;;;;;;;;GASG;AACH,KAAK,EAAE,YAAY;AACnB;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,GACzB,OAAO,CAAC,YAAY,EAAE,CAAC,CAobzB"}
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 { qConj, qMul } from '../../shared/lib/humanRig.js';
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 rest LOCAL translations, `n * 3` xyz.
50
+ * The TARGET rig's bind WORLD joint positions, `n * 3` — the calibration's yardstick.
51
51
  *
52
- * ⚠️ NEEDED FOR THE LIMB-DIRECTION ALIGNMENT. Copying the clip's world orientation outright is
53
- * not enough: a bone's job is to aim its CHILD, and the child offset sits at a different
54
- * direction in our bone's local frame than in Mixamo's (the two rigs' bones are rolled
55
- * differently about their own long axes). Without this the copied pose is off by a constant
56
- * 12–22° per arm bone — a T-pose whose arms sag. The child offsets say which way "along the
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
- restT,
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 retarget bakes
82
- // in each bone's WORLD rest, which two rigs with identical local rotations but different nesting
83
- // do not share.
84
- const key = `${name}|${boneNames.join(',')}|${Array.from(restQ, (v) => v.toFixed(4)).join(',')}|${Array.from(restT, (v) => v.toFixed(4)).join(',')}|${Array.from(parents).join(',')}`;
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, which is the
105
- // product down its chain — a local rotation alone cannot say which way a bone points.
106
- const clipRest = new Map();
107
- const clipRestT = new Map();
108
- const clipParent = new Map();
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
- clipRest.set(n, [
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
- clipRestT.set(n, [o.position.x, o.position.y, o.position.z]);
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
- clipParent.set(n, p && p.isBone
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
- // Quaternion tracks per bone — gathered first, because the retarget below bakes per FRAME
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
- if (!tracks.size)
327
- continue;
328
- const channels = [];
329
- if (clipRest.size) {
330
- // ── WORLD-SPACE RETARGET ─────────────────────────────────────────────────────────────
331
- //
332
- // ⚠️ POSES ARE COPIED, NOT DELTAS. The previous retarget replayed each bone's rotation
333
- // DELTA from the clip's bind on our bind (`ours = ourRest × A⁻¹ × D × A`). That is only
334
- // right when the two binds agree, and they do not: Mixamo authors a T-pose, our rig's
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"}