@convai/embody 1.0.1-beta.0 → 1.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +12 -8
  3. package/dist/character/createCharacter.d.ts +66 -5
  4. package/dist/character/createCharacter.js +93 -22
  5. package/dist/character/pipeline.d.ts +9 -5
  6. package/dist/clips/animations.d.ts +13 -1
  7. package/dist/clips/animations.js +28 -6
  8. package/dist/clips/retarget.d.ts +168 -0
  9. package/dist/clips/retarget.js +856 -0
  10. package/dist/clips/sources.d.ts +70 -0
  11. package/dist/clips/sources.js +119 -0
  12. package/dist/connect/session.d.ts +11 -0
  13. package/dist/connect/session.js +22 -0
  14. package/dist/index.d.ts +22 -1
  15. package/dist/index.js +12 -0
  16. package/dist/inspect/inspectModel.d.ts +14 -0
  17. package/dist/inspect/inspectModel.js +26 -0
  18. package/dist/inspect/morphMap.d.ts +54 -0
  19. package/dist/inspect/morphMap.js +140 -0
  20. package/dist/inspect/report.d.ts +88 -0
  21. package/dist/inspect/report.js +193 -0
  22. package/dist/motion/eyeAim.d.ts +94 -0
  23. package/dist/motion/eyeAim.js +276 -0
  24. package/dist/motion/eyeGaze.d.ts +17 -0
  25. package/dist/motion/eyeGaze.js +42 -0
  26. package/dist/motion/footLock.d.ts +67 -0
  27. package/dist/motion/footLock.js +176 -0
  28. package/dist/motion/gaze.d.ts +135 -180
  29. package/dist/motion/gaze.js +257 -491
  30. package/dist/motion/hair.d.ts +27 -0
  31. package/dist/motion/hair.js +127 -0
  32. package/dist/motion/hairClearance.d.ts +39 -0
  33. package/dist/motion/hairClearance.js +125 -0
  34. package/dist/motion/morphNormals.d.ts +38 -0
  35. package/dist/motion/morphNormals.js +237 -0
  36. package/dist/motion/types.d.ts +15 -0
  37. package/dist/react/CharacterModel.d.ts +3 -1
  38. package/dist/react/CharacterModel.js +9 -1
  39. package/dist/react/ConvaiCharacter.js +4 -1
  40. package/dist/react/PortraitLights.d.ts +3 -0
  41. package/dist/react/PortraitLights.js +44 -0
  42. package/dist/render/faceMaterials.d.ts +60 -3
  43. package/dist/render/faceMaterials.js +320 -96
  44. package/dist/render/portraitRig.d.ts +28 -0
  45. package/dist/render/portraitRig.js +55 -0
  46. package/dist/render/surfaces.d.ts +181 -0
  47. package/dist/render/surfaces.js +1020 -0
  48. package/dist/rig/resolve.d.ts +8 -2
  49. package/dist/rig/resolve.js +7 -3
  50. package/dist/rig/units.d.ts +35 -16
  51. package/dist/rig/units.js +143 -42
  52. package/dist/speech/expression.d.ts +20 -0
  53. package/dist/speech/expression.js +118 -0
  54. package/dist/speech/lipsync.d.ts +68 -2
  55. package/dist/speech/lipsync.js +205 -5
  56. package/dist/speech/mouthFinish.d.ts +46 -0
  57. package/dist/speech/mouthFinish.js +235 -0
  58. package/dist/speech/voiceClock.d.ts +94 -0
  59. package/dist/speech/voiceClock.js +176 -0
  60. package/package.json +1 -1
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Load-time retargeting: a clip authored on another skeleton (Mixamo, the
3
+ * Unreal mannequin, Rigify) → a clip on the body's own skeleton.
4
+ *
5
+ * Ported from the coffee-shop studio's camera-tuned retargeter and
6
+ * generalised: every rig is read through one table of canonical joints
7
+ * (Mixamo's names), so neither side's bone names are hard-coded into the
8
+ * method. The posture constants are the ones tuned on convai-mha-1 bodies.
9
+ *
10
+ * Method, per sampled frame:
11
+ * 1. Both rigs are put in one canonical frame (left +X, up +Y, forward +Z),
12
+ * measured from their own hip line and the file's vertical.
13
+ * 2. Rest-pose fix: Mixamo rests in a T-pose, a MetaHuman binds in an
14
+ * A-pose. Each target bone gets the shortest-arc rotation that lays its
15
+ * rest direction (bone → mapped child) onto the source's. Feet are left
16
+ * flat, the neck and head keep their own build, and a clavicle built
17
+ * pointing back (Rigify) contributes only its elevation.
18
+ * 3. Each mapped bone takes the source bone's WORLD rotation change since
19
+ * rest; unmapped bones (twists, correctives, extra spine) keep their
20
+ * bind-pose local rotation.
21
+ * 4. The hips move by the source hips' offset, scaled by hip height.
22
+ * 5. Elbows and hands are kept outside the body's own torso and thighs,
23
+ * measured from its skinned vertices (a clip made for a slimmer body
24
+ * otherwise rests its hands inside this one).
25
+ *
26
+ * The top bone (`pelvis` on convai-mha-1) has a parent outside the skin
27
+ * (`root002`). It is solved against that parent's bind-frame transform,
28
+ * `bindMatrix · meshWorld⁻¹ · parent.matrixWorld`; solving it from skin bones
29
+ * alone writes a constant pelvis and breaks every clip that bends at the hips.
30
+ */
31
+ import * as THREE from 'three';
32
+ export type RigKind = 'mixamo' | 'unreal' | 'rigify';
33
+ /** A skeleton's bones read as canonical joints. */
34
+ export interface RigNames {
35
+ kind: RigKind;
36
+ /** Bone name → canonical joint. */
37
+ toCanon: Map<string, string>;
38
+ /** Canonical joint → bone name. */
39
+ fromCanon: Map<string, string>;
40
+ }
41
+ /**
42
+ * Reads a skeleton's bone names as canonical joints: Mixamo (any
43
+ * `mixamorig` prefix, or none), Unreal (UE4/UE5 mannequin, MetaHuman,
44
+ * convai-mha-1) and Rigify deform bones. Spines are matched bottom, middle,
45
+ * top: a 3-bone spine maps 1/2/3, a 5-bone one 1/3/5. `null` when the hips,
46
+ * thighs and feet cannot all be found.
47
+ */
48
+ export declare function readRigNames(names: readonly string[]): RigNames | null;
49
+ /** The skeleton under `root` that `readRigNames` reads, or null. */
50
+ export declare function detectRig(root: THREE.Object3D): RigNames | null;
51
+ interface Pose {
52
+ /** World rotation of each bone, in the rig's own frame. */
53
+ rot: Map<string, THREE.Quaternion>;
54
+ pos: Map<string, THREE.Vector3>;
55
+ }
56
+ /**
57
+ * One body segment's surface, read from the bind mesh: around the bone's
58
+ * axis (bone → tip), the radius the skin and clothing reach in each of
59
+ * SECTORS directions, over the stretch of the axis its vertices cover.
60
+ */
61
+ interface Collider {
62
+ bone: string;
63
+ tip: string;
64
+ /** Radius per sector, bind units. */
65
+ radius: Float32Array;
66
+ /** Covered stretch of the axis, as a fraction of its length. */
67
+ t0: number;
68
+ t1: number;
69
+ /** Sector 0's direction, perpendicular to the axis, bind frame. */
70
+ e1: THREE.Vector3;
71
+ }
72
+ /** The body's skeleton, bind pose and surface, read once and shared by every clip retargeted onto it. */
73
+ export interface TargetRig {
74
+ names: RigNames;
75
+ /** Every skeleton bone, by name. */
76
+ bones: Map<string, THREE.Bone>;
77
+ /** Bind pose, in the skinned mesh's bind frame. */
78
+ bind: Pose;
79
+ /** Each bone's full bind-frame matrix (with scale). */
80
+ bindMatrix: Map<string, THREE.Matrix4>;
81
+ /** Bind-pose local rotation of each bone. */
82
+ local: Map<string, THREE.Quaternion>;
83
+ /** Bind frame → canonical. */
84
+ toCanon: THREE.Quaternion;
85
+ /** Every skeleton bone, parents before children. */
86
+ order: THREE.Bone[];
87
+ /** Hips above the lower ankle, bind units. */
88
+ hipHeight: number;
89
+ /** Bind units per metre, from hip height. */
90
+ unitsPerM: number;
91
+ /**
92
+ * Bind-frame rotation of each top bone's parent: a node outside the skin
93
+ * (`root002` above `pelvis` on convai-mha-1), never animated.
94
+ */
95
+ topParent: Map<string, THREE.Quaternion>;
96
+ /** Bind frame → the hips' parent's local frame (with its scale). */
97
+ hipsParentInv: THREE.Matrix4;
98
+ /** Each bone's bind offset from its parent, in the parent's frame. */
99
+ offset: Map<string, THREE.Vector3>;
100
+ /** Torso and thighs as measured from the skinned meshes, for keeping hands out. */
101
+ colliders: Collider[];
102
+ /** Each bone and every bone below it. */
103
+ subtree: Map<string, string[]>;
104
+ }
105
+ /**
106
+ * Reads the body under `root` as a retarget target: the skinned mesh whose
107
+ * skeleton `readRigNames` reads (the largest, when several are), its bind
108
+ * pose from the inverse bind matrices, and its torso and thighs from every
109
+ * skinned mesh. Nothing is read from the current pose, so a body that is
110
+ * already animating (or scaled and grounded) gives the same rig. `null` when
111
+ * no skeleton is recognised.
112
+ */
113
+ export declare function createTargetRig(root: THREE.Object3D): TargetRig | null;
114
+ /** A loaded animation file: its skeleton (in its rest pose) and every clip in it. */
115
+ export interface AnimationSource {
116
+ root: THREE.Object3D;
117
+ clips: THREE.AnimationClip[];
118
+ names: RigNames;
119
+ /** Each node's rest transform, put back before every retarget. */
120
+ rest: [THREE.Object3D, THREE.Vector3, THREE.Quaternion, THREE.Vector3][];
121
+ }
122
+ /**
123
+ * Wraps a loaded file (an FBXLoader group, or a GLTF's `scene`) as a
124
+ * retarget source, recording its rest pose. Call before anything animates
125
+ * it. `null` when its skeleton is not one `readRigNames` reads.
126
+ */
127
+ export declare function createAnimationSource(root: THREE.Object3D, clips: THREE.AnimationClip[]): AnimationSource | null;
128
+ /**
129
+ * Trunk lean (hips → neck, degrees, + = forward) the convai-mha-1 pack idle
130
+ * holds. Mixamo's idles and talks stand 1–4° further back than Mixamo's rest
131
+ * pose, which reads as a backward lean on these bodies.
132
+ */
133
+ export declare const UPRIGHT_DEG = -3;
134
+ export interface RetargetOptions {
135
+ /** Name of the produced clip. Default: the source clip's. */
136
+ name?: string;
137
+ /** Samples per second. Default 30. */
138
+ fps?: number;
139
+ /**
140
+ * Standing clips: pitch the spine forward so the clip's neutral pose
141
+ * (median lean over its standing frames) leans this much, by at most 6°,
142
+ * keeping the motion around it; knees straightened to about 8° of bend and
143
+ * low shoulders lifted the same way. `null` keeps the source's posture.
144
+ * Clips where the hips drop (kneel, sit) are never corrected. Default
145
+ * `UPRIGHT_DEG`.
146
+ */
147
+ upright?: number | null;
148
+ /** Keep elbows and hands outside the torso and thighs. Default `true`. */
149
+ clearHands?: boolean;
150
+ }
151
+ /** What the retarget changed, on `clip.userData.retarget`. */
152
+ export interface RetargetReport {
153
+ source: RigKind;
154
+ neutralLeanDeg: number;
155
+ trunkCorrectionDeg: number;
156
+ kneeBendDeg: number;
157
+ kneeScale: number;
158
+ shoulderLiftDeg: Record<string, number>;
159
+ /** Deepest an elbow or hand went into the body before clearing, cm. */
160
+ handsClearedCm: number;
161
+ }
162
+ /**
163
+ * Retargets one clip of `source` onto `rig`: a clip of local rotations for
164
+ * the target's bones (only those that ever leave their rest) and the hips'
165
+ * position, sampled at `fps`.
166
+ */
167
+ export declare function retargetClip(source: AnimationSource, src: THREE.AnimationClip, rig: TargetRig, opts?: RetargetOptions): THREE.AnimationClip;
168
+ export {};