@voqalize/avatar 0.2.2 → 0.4.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/LICENSE +21 -661
- package/LICENSE-CC-BY-4.0 +396 -0
- package/README.md +191 -662
- package/assets/README.md +48 -0
- package/assets/tanya.glb +0 -0
- package/assets/tara.glb +0 -0
- package/assets/tushar.glb +0 -0
- package/client/Avatar.tsx +57 -0
- package/client/AvatarClient.ts +818 -0
- package/client/arjun.ts +26 -0
- package/client/createAvatar.ts +177 -0
- package/client/createCanvasAvatar.ts +72 -0
- package/client/index.ts +44 -0
- package/client/internal.ts +108 -0
- package/client/interviewer-female.ts +4 -0
- package/client/interviewer-male.ts +4 -0
- package/client/ishita.ts +26 -0
- package/client/kabir.ts +26 -0
- package/client/meera.ts +26 -0
- package/client/naina.ts +26 -0
- package/client/playout.ts +95 -0
- package/client/professional-female-a.ts +4 -0
- package/client/professional-female-b.ts +4 -0
- package/client/professional-male-a.ts +4 -0
- package/client/professional-male-b.ts +4 -0
- package/client/react.ts +13 -0
- package/client/supports.ts +28 -0
- package/client/three/assets.ts +24 -0
- package/client/three/budgets.ts +27 -0
- package/client/three/holds.ts +64 -0
- package/client/three/internal.ts +54 -0
- package/client/three/motion-limits.json +116 -0
- package/client/three/sequences.ts +281 -0
- package/client/three/tanya.ts +69 -0
- package/client/three/tara-rig.ts +1562 -0
- package/client/three/tara.ts +76 -0
- package/client/three/tushar.ts +65 -0
- package/client/types.ts +235 -0
- package/client/useAvatar.ts +74 -0
- package/client/vikram.ts +26 -0
- package/dist/Avatar.d.ts +44 -0
- package/dist/Avatar.d.ts.map +1 -0
- package/{client/dist → dist}/Avatar.js +2 -2
- package/dist/Avatar.js.map +1 -0
- package/dist/AvatarClient.d.ts +274 -0
- package/dist/AvatarClient.d.ts.map +1 -0
- package/dist/AvatarClient.js +712 -0
- package/dist/AvatarClient.js.map +1 -0
- package/dist/arjun.d.ts +7 -0
- package/dist/arjun.d.ts.map +1 -0
- package/dist/arjun.js +20 -0
- package/dist/arjun.js.map +1 -0
- package/dist/createAvatar.d.ts +135 -0
- package/dist/createAvatar.d.ts.map +1 -0
- package/dist/createAvatar.js +75 -0
- package/dist/createAvatar.js.map +1 -0
- package/dist/createCanvasAvatar.d.ts +22 -0
- package/dist/createCanvasAvatar.d.ts.map +1 -0
- package/dist/createCanvasAvatar.js +47 -0
- package/dist/createCanvasAvatar.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +34 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +41 -0
- package/dist/internal.js.map +1 -0
- package/dist/interviewer-female.d.ts +4 -0
- package/dist/interviewer-female.d.ts.map +1 -0
- package/dist/interviewer-female.js +3 -0
- package/dist/interviewer-female.js.map +1 -0
- package/dist/interviewer-male.d.ts +4 -0
- package/dist/interviewer-male.d.ts.map +1 -0
- package/dist/interviewer-male.js +3 -0
- package/dist/interviewer-male.js.map +1 -0
- package/dist/ishita.d.ts +7 -0
- package/dist/ishita.d.ts.map +1 -0
- package/dist/ishita.js +20 -0
- package/dist/ishita.js.map +1 -0
- package/dist/kabir.d.ts +7 -0
- package/dist/kabir.d.ts.map +1 -0
- package/dist/kabir.js +20 -0
- package/dist/kabir.js.map +1 -0
- package/dist/meera.d.ts +7 -0
- package/dist/meera.d.ts.map +1 -0
- package/dist/meera.js +20 -0
- package/dist/meera.js.map +1 -0
- package/dist/naina.d.ts +7 -0
- package/dist/naina.d.ts.map +1 -0
- package/dist/naina.js +20 -0
- package/dist/naina.js.map +1 -0
- package/dist/playout.d.ts +42 -0
- package/dist/playout.d.ts.map +1 -0
- package/dist/playout.js +85 -0
- package/dist/playout.js.map +1 -0
- package/dist/professional-female-a.d.ts +4 -0
- package/dist/professional-female-a.d.ts.map +1 -0
- package/dist/professional-female-a.js +3 -0
- package/dist/professional-female-a.js.map +1 -0
- package/dist/professional-female-b.d.ts +4 -0
- package/dist/professional-female-b.d.ts.map +1 -0
- package/dist/professional-female-b.js +3 -0
- package/dist/professional-female-b.js.map +1 -0
- package/dist/professional-male-a.d.ts +4 -0
- package/dist/professional-male-a.d.ts.map +1 -0
- package/dist/professional-male-a.js +3 -0
- package/dist/professional-male-a.js.map +1 -0
- package/dist/professional-male-b.d.ts +4 -0
- package/dist/professional-male-b.d.ts.map +1 -0
- package/dist/professional-male-b.js +3 -0
- package/dist/professional-male-b.js.map +1 -0
- package/dist/react.d.ts +13 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +13 -0
- package/dist/react.js.map +1 -0
- package/dist/supports.d.ts +20 -0
- package/dist/supports.d.ts.map +1 -0
- package/dist/supports.js +26 -0
- package/dist/supports.js.map +1 -0
- package/dist/three/assets.d.ts +24 -0
- package/dist/three/assets.d.ts.map +1 -0
- package/dist/three/assets.js +22 -0
- package/dist/three/assets.js.map +1 -0
- package/dist/three/budgets.d.ts +17 -0
- package/dist/three/budgets.d.ts.map +1 -0
- package/dist/three/budgets.js +21 -0
- package/dist/three/budgets.js.map +1 -0
- package/dist/three/holds.d.ts +33 -0
- package/dist/three/holds.d.ts.map +1 -0
- package/dist/three/holds.js +56 -0
- package/dist/three/holds.js.map +1 -0
- package/dist/three/internal.d.ts +52 -0
- package/dist/three/internal.d.ts.map +1 -0
- package/dist/three/internal.js +49 -0
- package/dist/three/internal.js.map +1 -0
- package/dist/three/motion-limits.json +116 -0
- package/dist/three/sequences.d.ts +71 -0
- package/dist/three/sequences.d.ts.map +1 -0
- package/dist/three/sequences.js +262 -0
- package/dist/three/sequences.js.map +1 -0
- package/dist/three/tanya.d.ts +35 -0
- package/dist/three/tanya.d.ts.map +1 -0
- package/dist/three/tanya.js +51 -0
- package/dist/three/tanya.js.map +1 -0
- package/dist/three/tara-rig.d.ts +403 -0
- package/dist/three/tara-rig.d.ts.map +1 -0
- package/dist/three/tara-rig.js +1500 -0
- package/dist/three/tara-rig.js.map +1 -0
- package/dist/three/tara.d.ts +35 -0
- package/dist/three/tara.d.ts.map +1 -0
- package/dist/three/tara.js +58 -0
- package/dist/three/tara.js.map +1 -0
- package/dist/three/tushar.d.ts +31 -0
- package/dist/three/tushar.d.ts.map +1 -0
- package/dist/three/tushar.js +47 -0
- package/dist/three/tushar.js.map +1 -0
- package/dist/types.d.ts +149 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +140 -0
- package/dist/types.js.map +1 -0
- package/dist/useAvatar.d.ts +39 -0
- package/dist/useAvatar.d.ts.map +1 -0
- package/dist/useAvatar.js +35 -0
- package/dist/useAvatar.js.map +1 -0
- package/dist/vikram.d.ts +7 -0
- package/dist/vikram.d.ts.map +1 -0
- package/dist/vikram.js +20 -0
- package/dist/vikram.js.map +1 -0
- package/package.json +110 -25
- package/src/avatar.d.ts +218 -120
- package/src/avatar.js +950 -213
- package/src/behavior.d.ts +42 -0
- package/src/behavior.js +114 -0
- package/src/camera.js +29 -0
- package/src/canvas/author/parts/eye.mjs +722 -0
- package/src/canvas/author/parts/hand.mjs +1156 -0
- package/src/canvas/author/parts/mouth.mjs +741 -0
- package/src/canvas/author/parts/nose.mjs +100 -0
- package/src/canvas/author/parts/skin-detail.mjs +67 -0
- package/src/canvas/author/path.mjs +283 -0
- package/src/canvas/author/rig.mjs +405 -0
- package/src/canvas/avatars/round/face.d.mts +3 -0
- package/src/canvas/avatars/round/face.mjs +1307 -0
- package/src/canvas/create-rig.d.ts +15 -0
- package/src/canvas/create-rig.js +100 -0
- package/src/canvas/data/img/professional-female-a-hair-back.webp +0 -0
- package/src/canvas/data/img/professional-female-a-hair-front.webp +0 -0
- package/src/canvas/data/img/professional-female-a-top-body.webp +0 -0
- package/src/canvas/data/img/professional-female-b-hair-back.webp +0 -0
- package/src/canvas/data/img/professional-female-b-hair-front.webp +0 -0
- package/src/canvas/data/img/professional-female-b-top-body.webp +0 -0
- package/src/canvas/data/img/professional-male-a-hair-back.webp +0 -0
- package/src/canvas/data/img/professional-male-a-hair-front.webp +0 -0
- package/src/canvas/data/img/professional-male-a-top-body.webp +0 -0
- package/src/canvas/data/img/professional-male-b-hair-back.webp +0 -0
- package/src/canvas/data/img/professional-male-b-hair-front.webp +0 -0
- package/src/canvas/data/img/professional-male-b-top-body.webp +0 -0
- package/src/canvas/data/img/round-m3-hair-back.webp +0 -0
- package/src/canvas/data/img/round-m3-hair-front.webp +0 -0
- package/src/canvas/data/img/round-m3-top-body.webp +0 -0
- package/src/canvas/data/img/round-w1-hair-back.webp +0 -0
- package/src/canvas/data/img/round-w1-hair-front.webp +0 -0
- package/src/canvas/data/img/round-w1-top-body.webp +0 -0
- package/src/canvas/data/interviewer-female.rig.json +1 -0
- package/src/canvas/data/interviewer-male.rig.json +1 -0
- package/src/canvas/data/professional-female-a.rig.json +1 -0
- package/src/canvas/data/professional-female-b.rig.json +1 -0
- package/src/canvas/data/professional-male-a.rig.json +1 -0
- package/src/canvas/data/professional-male-b.rig.json +1 -0
- package/src/canvas/src/live.js +508 -0
- package/src/canvas/src/render2d.js +218 -0
- package/src/canvas/src/rig.js +297 -0
- package/src/canvas/src/vocab.js +96 -0
- package/src/clips.js +18 -7
- package/src/conformance.js +119 -0
- package/src/emotions.js +8 -5
- package/src/face-core.js +27 -1
- package/src/face-myna.d.ts +7 -0
- package/src/face-myna.js +192 -131
- package/src/face-peep-control-plane.js +167 -0
- package/src/face-peep.d.ts +7 -0
- package/src/face-peep.js +274 -116
- package/src/face-wren.d.ts +7 -0
- package/src/face-wren.js +17 -19
- package/src/faces.d.ts +12 -0
- package/src/faces.js +53 -0
- package/src/gaze.js +434 -58
- package/src/hand.js +120 -91
- package/src/head.js +134 -0
- package/src/idle.js +227 -119
- package/src/interjections.js +200 -31
- package/src/params.js +8 -4
- package/src/perform.js +7 -9
- package/src/prosody.js +647 -0
- package/src/rig.d.ts +24 -0
- package/src/rig.js +32 -0
- package/src/speech-timing.js +23 -0
- package/src/visemes.js +110 -24
- package/client/dist/Avatar.d.ts +0 -27
- package/client/dist/Avatar.d.ts.map +0 -1
- package/client/dist/Avatar.js.map +0 -1
- package/client/dist/AvatarClient.d.ts +0 -139
- package/client/dist/AvatarClient.d.ts.map +0 -1
- package/client/dist/AvatarClient.js +0 -223
- package/client/dist/AvatarClient.js.map +0 -1
- package/client/dist/index.d.ts +0 -22
- package/client/dist/index.d.ts.map +0 -1
- package/client/dist/index.js +0 -22
- package/client/dist/index.js.map +0 -1
- package/client/dist/types.d.ts +0 -86
- package/client/dist/types.d.ts.map +0 -1
- package/client/dist/types.js +0 -31
- package/client/dist/types.js.map +0 -1
- package/client/dist/useAvatar.d.ts +0 -42
- package/client/dist/useAvatar.d.ts.map +0 -1
- package/client/dist/useAvatar.js +0 -51
- package/client/dist/useAvatar.js.map +0 -1
- package/client/src/Avatar.tsx +0 -33
- package/client/src/AvatarClient.ts +0 -270
- package/client/src/index.ts +0 -22
- package/client/src/types.ts +0 -104
- package/client/src/useAvatar.ts +0 -85
- package/docs/contract-avatar.md +0 -371
- package/docs/contract-protocol.md +0 -461
package/src/face-wren.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Avatar: "wren".
|
|
3
3
|
*
|
|
4
4
|
* The second line-art character, and the proof run for the recipe in
|
|
5
|
-
* docs/
|
|
5
|
+
* docs/authoring-a-face.md: static art + a POSE spec + feature blocks + META,
|
|
6
6
|
* with the stroke engine imported from line-art.js rather than carried along.
|
|
7
7
|
* Character: female, thirties, a big natural-curl mass, round glasses, a
|
|
8
8
|
* crew-neck tee. Same idiom as peep — no strokes anywhere, ink and paper and
|
|
@@ -30,10 +30,9 @@ import {
|
|
|
30
30
|
f, createFaceShell, faceApi, poseTransforms, pairedTeeth,
|
|
31
31
|
} from './face-core.js';
|
|
32
32
|
import { taper, taperRing, region } from './line-art.js';
|
|
33
|
+
import { viewBoxForHead } from './camera.js';
|
|
33
34
|
|
|
34
35
|
export const THEME = {
|
|
35
|
-
bg0: '#f6f3ee',
|
|
36
|
-
bg1: '#e8e2d8',
|
|
37
36
|
ink: '#1b1b1b',
|
|
38
37
|
paper: '#ffffff',
|
|
39
38
|
accent: '#f97415',
|
|
@@ -42,10 +41,9 @@ export const THEME = {
|
|
|
42
41
|
tongue: '#8d7f79',
|
|
43
42
|
};
|
|
44
43
|
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const VB = { x: 92, y: 50, w: 576, h: 800 };
|
|
44
|
+
// Wren's hair cloud is her visible crown; the skull begins well below it.
|
|
45
|
+
const FRAME = { centerX: 380, crownY: 102, chinY: 575 };
|
|
46
|
+
const VB = viewBoxForHead(FRAME);
|
|
49
47
|
|
|
50
48
|
export const META = {
|
|
51
49
|
viewBox: { x: VB.x, y: VB.y, w: VB.w, h: VB.h },
|
|
@@ -53,7 +51,7 @@ export const META = {
|
|
|
53
51
|
};
|
|
54
52
|
|
|
55
53
|
// --- landmarks --------------------------------------------------------------
|
|
56
|
-
const CX =
|
|
54
|
+
const CX = FRAME.centerX;
|
|
57
55
|
const HEAD_TOP = 148;
|
|
58
56
|
const CHIN_Y = 572;
|
|
59
57
|
|
|
@@ -224,7 +222,7 @@ const POSE = {
|
|
|
224
222
|
// peep's breath and trunk numbers; same construction, same art units, and
|
|
225
223
|
// the two characters should breathe alike. See face-peep.js for the
|
|
226
224
|
// derivation.
|
|
227
|
-
breathSwell: 0.
|
|
225
|
+
breathSwell: 0.008, swellPivot: { x: CX, y: 950 },
|
|
228
226
|
turnPx: 16,
|
|
229
227
|
layers: LAYERS, parallax: PARALLAX,
|
|
230
228
|
torsoLayers: ['body'],
|
|
@@ -254,8 +252,8 @@ function mouthGeometry(p) {
|
|
|
254
252
|
const h = open * MOUTH_APERTURE;
|
|
255
253
|
const k = clamp(open / 0.18);
|
|
256
254
|
|
|
257
|
-
const yL = cy -
|
|
258
|
-
const yR = cy -
|
|
255
|
+
const yL = cy - 1.5 - p.mouthCornerL * 22;
|
|
256
|
+
const yR = cy - 1.5 - p.mouthCornerR * 22;
|
|
259
257
|
|
|
260
258
|
const apTop = cy - h * 0.25;
|
|
261
259
|
let apBot = cy + h * 0.75;
|
|
@@ -348,14 +346,7 @@ function markup(id, t) {
|
|
|
348
346
|
return `
|
|
349
347
|
<svg id="${id}" viewBox="${VB.x} ${VB.y} ${VB.w} ${VB.h}" xmlns="http://www.w3.org/2000/svg"
|
|
350
348
|
preserveAspectRatio="xMidYMid meet" style="display:block;width:100%;height:100%">
|
|
351
|
-
<defs>
|
|
352
|
-
<radialGradient id="${id}-gBg" cx="50%" cy="36%" r="76%">
|
|
353
|
-
<stop offset="0%" stop-color="${t.bg0}"/><stop offset="100%" stop-color="${t.bg1}"/>
|
|
354
|
-
</radialGradient>
|
|
355
|
-
<clipPath id="${id}-clipMouth"><path id="${id}-clipMouthP" d=""/></clipPath>
|
|
356
|
-
</defs>
|
|
357
|
-
|
|
358
|
-
<rect x="${VB.x}" y="${VB.y}" width="${VB.w}" height="${VB.h}" fill="url(#${id}-gBg)"/>
|
|
349
|
+
<defs><clipPath id="${id}-clipMouth"><path id="${id}-clipMouthP" d=""/></clipPath></defs>
|
|
359
350
|
|
|
360
351
|
<!-- head and neck. No ears: the hair band covers them (see the hair note).
|
|
361
352
|
Hair underlay at head parallax, same insurance as peep's — the cloud
|
|
@@ -468,3 +459,10 @@ export function createFace(mount, theme = {}) {
|
|
|
468
459
|
|
|
469
460
|
return faceApi(mount, svg, apply, t);
|
|
470
461
|
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* This face as a **Face** record — `{ create, meta }`, the shape
|
|
465
|
+
* `createAvatar({ face })` takes. Importing it costs this drawing and nothing
|
|
466
|
+
* else; `src/faces.js` is the all-three table, for tooling.
|
|
467
|
+
*/
|
|
468
|
+
export const wren = { create: createFace, meta: META };
|
package/src/faces.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Face } from "./avatar.js";
|
|
2
|
+
|
|
3
|
+
export const peep: Face;
|
|
4
|
+
export const wren: Face;
|
|
5
|
+
export const myna: Face;
|
|
6
|
+
|
|
7
|
+
/** The faces we ship. Not an open vocabulary — a third face is a code change. */
|
|
8
|
+
export type FaceName = "peep" | "wren" | "myna";
|
|
9
|
+
|
|
10
|
+
export const FACES: Readonly<Record<FaceName, Face>>;
|
|
11
|
+
export const FACE_NAMES: readonly FaceName[];
|
|
12
|
+
export const DEFAULT_FACE: FaceName;
|
package/src/faces.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The faces we ship, as a table — for tooling that wants every one of them.
|
|
3
|
+
*
|
|
4
|
+
* **Importing this costs all three drawings** (~2k lines of path data). That is
|
|
5
|
+
* the right trade for `rig-check`, the contact sheets, the sweep and Studio,
|
|
6
|
+
* which exist to compare faces against each other. It is the wrong trade for an
|
|
7
|
+
* application, which renders one: those import a single face module and hand
|
|
8
|
+
* the record to `createAvatar` directly.
|
|
9
|
+
*
|
|
10
|
+
* import { peep } from '@voqalize/avatar/faces/peep';
|
|
11
|
+
* createAvatar({ mount, client, face: peep });
|
|
12
|
+
*
|
|
13
|
+
* A **Face** is `{ create, meta }` and nothing else.
|
|
14
|
+
*
|
|
15
|
+
* `create` is `createFace(mount, theme) -> { svg, apply, theme, destroy }`,
|
|
16
|
+
* callable standalone — the rig tooling drives faces with no mixer attached.
|
|
17
|
+
* That behavioural contract is the whole of what the *rig* needs: everything
|
|
18
|
+
* else — visemes, emotions, gaze, idle, clips, the mixer — works in parameter
|
|
19
|
+
* space and never learns which face it is driving.
|
|
20
|
+
*
|
|
21
|
+
* `meta` is the descriptor (viewBox, mouthCrop — see META in any face module):
|
|
22
|
+
* the things a HOST or a TOOL needs to frame a face without opening it. A face
|
|
23
|
+
* was once a bare factory, on the argument that a schema guessed from two of
|
|
24
|
+
* them would be wrong; the third settled it. Every rig needed exactly a framing
|
|
25
|
+
* rect and a mouth rect to stop the tooling hard-coding per-face tables, and
|
|
26
|
+
* nothing else — so that is all meta carries.
|
|
27
|
+
*
|
|
28
|
+
* The key is the face's name, not its rank. It used to be possible to read rank
|
|
29
|
+
* into it — the original rig was keyed `default`, which became a lie the moment
|
|
30
|
+
* it stopped being the one we ship. `DEFAULT_FACE` is the only place the choice
|
|
31
|
+
* is made, and `packages/avatar/client/createAvatar.ts` is the only place it is consulted.
|
|
32
|
+
*
|
|
33
|
+
* Two earlier rigs, `classic` and `blue-shirt`, were removed on 2026-08-06:
|
|
34
|
+
* stakeholders accepted the line-art pair and rejected both of the others, so
|
|
35
|
+
* carrying them was maintenance against art nobody wanted. What they taught the
|
|
36
|
+
* abstraction survives them — `face-core.js` exists because all three of the
|
|
37
|
+
* first rigs wrote the same apply(), and META exists because all three needed
|
|
38
|
+
* the same two rects. Their code is in git history if a lesson ever needs
|
|
39
|
+
* re-reading.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import { peep } from './face-peep.js';
|
|
43
|
+
import { wren } from './face-wren.js';
|
|
44
|
+
import { myna } from './face-myna.js';
|
|
45
|
+
|
|
46
|
+
export { peep, wren, myna };
|
|
47
|
+
|
|
48
|
+
export const FACES = { peep, wren, myna };
|
|
49
|
+
|
|
50
|
+
export const FACE_NAMES = Object.keys(FACES);
|
|
51
|
+
|
|
52
|
+
/** The face a host gets when it does not name one. */
|
|
53
|
+
export const DEFAULT_FACE = 'peep';
|