@voqalize/avatar 0.4.1 → 0.4.3
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-APACHE-2.0 +201 -0
- package/README.md +26 -95
- package/assets/README.md +30 -18
- package/assets/tanvi.glb +0 -0
- package/assets/tanya.glb +0 -0
- package/assets/tara.glb +0 -0
- package/assets/tess.glb +0 -0
- package/assets/tushar.glb +0 -0
- package/client/internal.ts +24 -0
- package/client/supports.ts +6 -7
- package/client/three/assets.ts +7 -3
- package/client/three/budgets.ts +1 -1
- package/client/three/{tara-rig.ts → character-rig.ts} +682 -540
- package/client/three/createCharacter.ts +109 -0
- package/client/three/holds.ts +8 -3
- package/client/three/internal.ts +8 -7
- package/client/three/motion-limits.json +10 -2
- package/client/three/sequences.ts +5 -5
- package/client/three/tanvi-asset.ts +6 -0
- package/client/three/tanvi.ts +30 -0
- package/client/three/tanya.ts +18 -58
- package/client/three/tara.ts +19 -60
- package/client/three/tess-asset.ts +6 -0
- package/client/three/tess.ts +30 -0
- package/client/three/tushar.ts +18 -55
- package/dist/internal.d.ts +2 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +16 -1
- package/dist/internal.js.map +1 -1
- package/dist/supports.d.ts +6 -7
- package/dist/supports.d.ts.map +1 -1
- package/dist/supports.js +6 -7
- package/dist/supports.js.map +1 -1
- package/dist/three/assets.d.ts +2 -0
- package/dist/three/assets.d.ts.map +1 -1
- package/dist/three/assets.js +7 -3
- package/dist/three/assets.js.map +1 -1
- package/dist/three/budgets.d.ts +1 -1
- package/dist/three/budgets.js +1 -1
- package/dist/three/character-rig.d.ts +366 -0
- package/dist/three/character-rig.d.ts.map +1 -0
- package/dist/three/{tara-rig.js → character-rig.js} +633 -526
- package/dist/three/character-rig.js.map +1 -0
- package/dist/three/createCharacter.d.ts +60 -0
- package/dist/three/createCharacter.d.ts.map +1 -0
- package/dist/three/createCharacter.js +84 -0
- package/dist/three/createCharacter.js.map +1 -0
- package/dist/three/holds.d.ts +7 -2
- package/dist/three/holds.d.ts.map +1 -1
- package/dist/three/holds.js +8 -3
- package/dist/three/holds.js.map +1 -1
- package/dist/three/internal.d.ts +7 -7
- package/dist/three/internal.d.ts.map +1 -1
- package/dist/three/internal.js +6 -6
- package/dist/three/internal.js.map +1 -1
- package/dist/three/motion-limits.json +10 -2
- package/dist/three/sequences.d.ts +5 -5
- package/dist/three/sequences.js +5 -5
- package/dist/three/tanvi-asset.d.ts +7 -0
- package/dist/three/tanvi-asset.d.ts.map +1 -0
- package/dist/three/tanvi-asset.js +7 -0
- package/dist/three/tanvi-asset.js.map +1 -0
- package/dist/three/tanvi.d.ts +24 -0
- package/dist/three/tanvi.d.ts.map +1 -0
- package/dist/three/tanvi.js +24 -0
- package/dist/three/tanvi.js.map +1 -0
- package/dist/three/tanya.d.ts +16 -28
- package/dist/three/tanya.d.ts.map +1 -1
- package/dist/three/tanya.js +15 -43
- package/dist/three/tanya.js.map +1 -1
- package/dist/three/tara.d.ts +17 -22
- package/dist/three/tara.d.ts.map +1 -1
- package/dist/three/tara.js +16 -45
- package/dist/three/tara.js.map +1 -1
- package/dist/three/tess-asset.d.ts +7 -0
- package/dist/three/tess-asset.d.ts.map +1 -0
- package/dist/three/tess-asset.js +7 -0
- package/dist/three/tess-asset.js.map +1 -0
- package/dist/three/tess.d.ts +24 -0
- package/dist/three/tess.d.ts.map +1 -0
- package/dist/three/tess.js +24 -0
- package/dist/three/tess.js.map +1 -0
- package/dist/three/tushar.d.ts +16 -25
- package/dist/three/tushar.d.ts.map +1 -1
- package/dist/three/tushar.js +15 -40
- package/dist/three/tushar.js.map +1 -1
- package/package.json +10 -49
- package/src/avatar.d.ts +67 -2
- package/src/avatar.js +131 -255
- package/src/faces.js +1 -1
- package/src/gaze.js +20 -47
- package/src/idle.js +69 -27
- package/src/prosody.js +109 -15
- package/src/rig.d.ts +7 -0
- package/src/speech-timing.js +9 -0
- package/src/visemes.js +107 -13
- package/client/arjun.ts +0 -26
- package/client/createCanvasAvatar.ts +0 -72
- package/client/interviewer-female.ts +0 -4
- package/client/interviewer-male.ts +0 -4
- package/client/ishita.ts +0 -26
- package/client/kabir.ts +0 -26
- package/client/meera.ts +0 -26
- package/client/naina.ts +0 -26
- package/client/professional-female-a.ts +0 -4
- package/client/professional-female-b.ts +0 -4
- package/client/professional-male-a.ts +0 -4
- package/client/professional-male-b.ts +0 -4
- package/client/vikram.ts +0 -26
- package/dist/arjun.d.ts +0 -7
- package/dist/arjun.d.ts.map +0 -1
- package/dist/arjun.js +0 -20
- package/dist/arjun.js.map +0 -1
- package/dist/createCanvasAvatar.d.ts +0 -22
- package/dist/createCanvasAvatar.d.ts.map +0 -1
- package/dist/createCanvasAvatar.js +0 -47
- package/dist/createCanvasAvatar.js.map +0 -1
- package/dist/interviewer-female.d.ts +0 -4
- package/dist/interviewer-female.d.ts.map +0 -1
- package/dist/interviewer-female.js +0 -3
- package/dist/interviewer-female.js.map +0 -1
- package/dist/interviewer-male.d.ts +0 -4
- package/dist/interviewer-male.d.ts.map +0 -1
- package/dist/interviewer-male.js +0 -3
- package/dist/interviewer-male.js.map +0 -1
- package/dist/ishita.d.ts +0 -7
- package/dist/ishita.d.ts.map +0 -1
- package/dist/ishita.js +0 -20
- package/dist/ishita.js.map +0 -1
- package/dist/kabir.d.ts +0 -7
- package/dist/kabir.d.ts.map +0 -1
- package/dist/kabir.js +0 -20
- package/dist/kabir.js.map +0 -1
- package/dist/meera.d.ts +0 -7
- package/dist/meera.d.ts.map +0 -1
- package/dist/meera.js +0 -20
- package/dist/meera.js.map +0 -1
- package/dist/naina.d.ts +0 -7
- package/dist/naina.d.ts.map +0 -1
- package/dist/naina.js +0 -20
- package/dist/naina.js.map +0 -1
- package/dist/professional-female-a.d.ts +0 -4
- package/dist/professional-female-a.d.ts.map +0 -1
- package/dist/professional-female-a.js +0 -3
- package/dist/professional-female-a.js.map +0 -1
- package/dist/professional-female-b.d.ts +0 -4
- package/dist/professional-female-b.d.ts.map +0 -1
- package/dist/professional-female-b.js +0 -3
- package/dist/professional-female-b.js.map +0 -1
- package/dist/professional-male-a.d.ts +0 -4
- package/dist/professional-male-a.d.ts.map +0 -1
- package/dist/professional-male-a.js +0 -3
- package/dist/professional-male-a.js.map +0 -1
- package/dist/professional-male-b.d.ts +0 -4
- package/dist/professional-male-b.d.ts.map +0 -1
- package/dist/professional-male-b.js +0 -3
- package/dist/professional-male-b.js.map +0 -1
- package/dist/three/tara-rig.d.ts +0 -409
- package/dist/three/tara-rig.d.ts.map +0 -1
- package/dist/three/tara-rig.js.map +0 -1
- package/dist/vikram.d.ts +0 -7
- package/dist/vikram.d.ts.map +0 -1
- package/dist/vikram.js +0 -20
- package/dist/vikram.js.map +0 -1
- package/src/canvas/author/parts/eye.mjs +0 -722
- package/src/canvas/author/parts/hand.mjs +0 -1156
- package/src/canvas/author/parts/mouth.mjs +0 -741
- package/src/canvas/author/parts/nose.mjs +0 -100
- package/src/canvas/author/parts/skin-detail.mjs +0 -67
- package/src/canvas/author/path.mjs +0 -283
- package/src/canvas/author/rig.mjs +0 -405
- package/src/canvas/avatars/round/face.d.mts +0 -3
- package/src/canvas/avatars/round/face.mjs +0 -1307
- package/src/canvas/create-rig.d.ts +0 -15
- package/src/canvas/create-rig.js +0 -100
- 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 +0 -1
- package/src/canvas/data/interviewer-male.rig.json +0 -1
- package/src/canvas/data/professional-female-a.rig.json +0 -1
- package/src/canvas/data/professional-female-b.rig.json +0 -1
- package/src/canvas/data/professional-male-a.rig.json +0 -1
- package/src/canvas/data/professional-male-b.rig.json +0 -1
- package/src/canvas/src/live.js +0 -508
- package/src/canvas/src/render2d.js +0 -218
- package/src/canvas/src/rig.js +0 -297
- package/src/canvas/src/vocab.js +0 -96
package/dist/supports.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `supports` for every avatar this package ships
|
|
3
|
-
* canvas identities alike.
|
|
2
|
+
* `supports` for every avatar this package ships.
|
|
4
3
|
*
|
|
5
|
-
* It is one constant and one file because they are one renderer:
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* It is one constant and one file because they are one renderer: every avatar
|
|
5
|
+
* mounts the same mixer with the same clip library, so a second list would be
|
|
6
|
+
* the same list with a second chance to be wrong. It is not in
|
|
8
7
|
* `createAvatar.ts`, where the type is documented, because a value is imported
|
|
9
|
-
* for real — reading it from there would pull `peep`'s drawing into
|
|
10
|
-
*
|
|
8
|
+
* for real — reading it from there would pull `peep`'s drawing into every
|
|
9
|
+
* consumer's bundle.
|
|
11
10
|
*
|
|
12
11
|
* The two required ids first, then this renderer's own catalogue. `ACTION_IDS`
|
|
13
12
|
* already carries `RESPONSE_INTERRUPTED` as this renderer's shape for it, so
|
package/dist/supports.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supports.d.ts","sourceRoot":"","sources":["../client/supports.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"supports.d.ts","sourceRoot":"","sources":["../client/supports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,eAAO,MAAM,QAAQ,EAAE,aAKrB,CAAC"}
|
package/dist/supports.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `supports` for every avatar this package ships
|
|
3
|
-
* canvas identities alike.
|
|
2
|
+
* `supports` for every avatar this package ships.
|
|
4
3
|
*
|
|
5
|
-
* It is one constant and one file because they are one renderer:
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* It is one constant and one file because they are one renderer: every avatar
|
|
5
|
+
* mounts the same mixer with the same clip library, so a second list would be
|
|
6
|
+
* the same list with a second chance to be wrong. It is not in
|
|
8
7
|
* `createAvatar.ts`, where the type is documented, because a value is imported
|
|
9
|
-
* for real — reading it from there would pull `peep`'s drawing into
|
|
10
|
-
*
|
|
8
|
+
* for real — reading it from there would pull `peep`'s drawing into every
|
|
9
|
+
* consumer's bundle.
|
|
11
10
|
*
|
|
12
11
|
* The two required ids first, then this renderer's own catalogue. `ACTION_IDS`
|
|
13
12
|
* already carries `RESPONSE_INTERRUPTED` as this renderer's shape for it, so
|
package/dist/supports.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supports.js","sourceRoot":"","sources":["../client/supports.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"supports.js","sourceRoot":"","sources":["../client/supports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,CAAC,MAAM,QAAQ,GAAkB,MAAM,CAAC,MAAM,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,GAAG,eAAe;QAClB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAE,eAAqC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;KACnF,CAAC;CACH,CAAC,CAAC"}
|
package/dist/three/assets.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../client/three/assets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../client/three/assets.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,MAAM;;;;;;EAMjB,CAAC;AAEH,gDAAgD;AAChD,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,MAAM,CAAC"}
|
package/dist/three/assets.js
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Every compiled character as one table — for a page that enumerates them.
|
|
3
3
|
*
|
|
4
4
|
* Each URL lives in its own module (`tara-asset.ts` and its siblings) and this
|
|
5
5
|
* file only gathers them, because a bundler emits assets per module: anything
|
|
6
|
-
* importing *this* ships
|
|
7
|
-
*
|
|
6
|
+
* importing *this* ships every GLB, which is right for a rig instrument that
|
|
7
|
+
* switches between characters and wrong for a consumer who mounted one.
|
|
8
8
|
* So the character modules never import this — they import their own — and the
|
|
9
9
|
* only reader is `/internal/three`, a separate entry point that ships nothing.
|
|
10
10
|
*/
|
|
11
11
|
import { TANYA_GLB } from "./tanya-asset.js";
|
|
12
|
+
import { TANVI_GLB } from "./tanvi-asset.js";
|
|
13
|
+
import { TESS_GLB } from "./tess-asset.js";
|
|
12
14
|
import { TARA_GLB } from "./tara-asset.js";
|
|
13
15
|
import { TUSHAR_GLB } from "./tushar-asset.js";
|
|
14
16
|
export const ASSETS = Object.freeze({
|
|
15
17
|
tara: TARA_GLB,
|
|
16
18
|
tushar: TUSHAR_GLB,
|
|
17
19
|
tanya: TANYA_GLB,
|
|
20
|
+
tess: TESS_GLB,
|
|
21
|
+
tanvi: TANVI_GLB,
|
|
18
22
|
});
|
|
19
23
|
//# sourceMappingURL=assets.js.map
|
package/dist/three/assets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../client/three/assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,UAAU;IAClB,KAAK,EAAE,SAAS;CACjB,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../client/three/assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,UAAU;IAClB,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,SAAS;CACjB,CAAC,CAAC"}
|
package/dist/three/budgets.d.ts
CHANGED
package/dist/three/budgets.js
CHANGED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Blender characters' renderer: the `AvatarRig` contract (`apply(frame)` /
|
|
3
|
+
* `destroy()`) over a Blender-authored GLB. One of these drives every compiled
|
|
4
|
+
* character, and `createCharacter.ts` is what hands it one.
|
|
5
|
+
*
|
|
6
|
+
* The whole file is one idea — **the pose channel is the interface, and every
|
|
7
|
+
* mapping here is a translation of one channel into the one control that
|
|
8
|
+
* renders it.** `scripts/morphs.py` authored the shape keys under the library's
|
|
9
|
+
* own channel names precisely so this file never has to interpret a viseme, a
|
|
10
|
+
* state or an emotion; it receives a fully mixed pose and moves geometry.
|
|
11
|
+
*/
|
|
12
|
+
import type { AvatarRig } from "../internal.js";
|
|
13
|
+
import * as THREE from "three";
|
|
14
|
+
/**
|
|
15
|
+
* Head motion, in degrees at the channel's own clamp, so the envelope is
|
|
16
|
+
* unreachable by construction rather than by a second clamp nobody runs.
|
|
17
|
+
*
|
|
18
|
+
* Yaw is the tight axis: the albedo is a front-orthographic projection of a
|
|
19
|
+
* shallow shell, and a large turn is where that reads as a cardboard cutout
|
|
20
|
+
* rather than a head. A ladder rendered at 9/12/15/18/21/25/30 and read at crop
|
|
21
|
+
* is clean to 21° on tara and to 18° on the tightest of the others, so 15°
|
|
22
|
+
* keeps headroom; pitch and roll opened once `NECK_QUAD` made the neck's follow
|
|
23
|
+
* exact. How far a pose may be *held* is a stricter question, measured per
|
|
24
|
+
* character (`motion-limits.json`, applied through `holds.ts`).
|
|
25
|
+
*
|
|
26
|
+
* The yaw twist's two fields are an expansion in the angle, so their error
|
|
27
|
+
* grows as θ²/6 — 0.85 % at 15°, on a displacement that is itself a fraction of
|
|
28
|
+
* the neck's radius (`morphs.neck_twist`).
|
|
29
|
+
*
|
|
30
|
+
* TARA-SPECIFIC: reach before an artefact; see 3d-avatar-tara-specific.md.
|
|
31
|
+
*/
|
|
32
|
+
export declare const HEAD_CLAMP = 1.4;
|
|
33
|
+
export declare const HEAD_DEG: {
|
|
34
|
+
yaw: number;
|
|
35
|
+
pitch: number;
|
|
36
|
+
roll: number;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Where the head turns about. v 0.36 is the jaw angle and the earlobe, and it
|
|
40
|
+
* sits a fifth of a face height *behind* the face plane — a pivot on the
|
|
41
|
+
* surface spins the face in place, where a real yaw swings the chin across as
|
|
42
|
+
* well as around, which is most of what makes a small turn read.
|
|
43
|
+
*
|
|
44
|
+
* The asset carries this (`stamp_abi`, as `head_pivot`); this is the fallback
|
|
45
|
+
* for a GLB built before the stamp.
|
|
46
|
+
*/
|
|
47
|
+
export declare const PIVOT: THREE.Vector3;
|
|
48
|
+
/**
|
|
49
|
+
* Where the head *tilts* about, from `morphs.ROLL_PIVOT`: the midline just
|
|
50
|
+
* above the chin. A roll is a bend of the whole neck, so its centre is far
|
|
51
|
+
* below the ear, and a drawn head sells it by holding the chin and swinging
|
|
52
|
+
* the crown — Live2D's sample rigs tilt about this same point. About PIVOT
|
|
53
|
+
* instead, the chin swung 7 px the other way at 8° and the head read as a
|
|
54
|
+
* pendulum hung from the ears.
|
|
55
|
+
*
|
|
56
|
+
* It sits inside the yaw and pitch, so a turned head still tilts about its own
|
|
57
|
+
* chin. The asset carries it (`stamp_abi`, as `roll_pivot`); this is the
|
|
58
|
+
* fallback for a GLB built before the stamp, and `morphs.ROLL_PIVOT` has what
|
|
59
|
+
* sets the height.
|
|
60
|
+
*/
|
|
61
|
+
export declare const ROLL_PIVOT: THREE.Vector3;
|
|
62
|
+
/**
|
|
63
|
+
* What the head takes with it, from `build_character.HEAD_PARTS`. `Body` stays
|
|
64
|
+
* behind, and so does `Neck` — but the neck is not *static*: it follows the
|
|
65
|
+
* skull through morph targets of its own (`NECK_QUAD` below).
|
|
66
|
+
*
|
|
67
|
+
* Without that follow a turn dragged the skull's jaw rim across a throat that
|
|
68
|
+
* had not moved, and the rim landed mid-neck as a second jawline — invisible at
|
|
69
|
+
* the 400 × 300 tile, obvious at a 3× crop.
|
|
70
|
+
*
|
|
71
|
+
* The asset carries its own list (`stamp_abi`, as `head_parts`); this is the
|
|
72
|
+
* fallback for a GLB built before the stamp.
|
|
73
|
+
*/
|
|
74
|
+
export declare const HEAD_PARTS: string[];
|
|
75
|
+
/** Degrees per pose unit: the globe turns `pupil * GAZE_TRAVEL / GLOBE_RADIUS`
|
|
76
|
+
* radians, and the head reaches `HEAD_DEG` at the clamp.
|
|
77
|
+
*
|
|
78
|
+
* Exported through `internal.ts` for the same reason as the head envelope. */
|
|
79
|
+
export declare const EYE_DEG: {
|
|
80
|
+
x: number;
|
|
81
|
+
y: number;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* The mixer's per-rig calibration, passed by the character's entry point and by
|
|
85
|
+
* the motion audit so both measure the same face. A pose unit is an angle here
|
|
86
|
+
* and a pixel count on an SVG face, so the speech layer's amplitudes are tuned
|
|
87
|
+
* per rig rather than in the library.
|
|
88
|
+
*
|
|
89
|
+
* The shared look table is drawn for a line face, whose pupils cross most of an
|
|
90
|
+
* eye, so it put every look in the eyes: a thinking look away was the iris
|
|
91
|
+
* parked in the corner of the socket for two thirds of the state, which is
|
|
92
|
+
* side-eye, not thought. Here the head carries about 60 % of a look and the
|
|
93
|
+
* eyes land a third of the way off centre, where a real eye-head shift leaves
|
|
94
|
+
* them (Freedman & Sparks; Pejsa & Andrist). The comment on each target is its
|
|
95
|
+
* world angle, x right and y down.
|
|
96
|
+
*
|
|
97
|
+
* vor Real gain in the light is close to 1. A little under leaves the
|
|
98
|
+
* head some say, so a nod carries the eyes a touch with it rather
|
|
99
|
+
* than pinning them to the lens. Vertically it is well under:
|
|
100
|
+
* her pitch is a shell tipping on a photograph and
|
|
101
|
+
* reads as a fraction of what it is, so the eyes' full answer to
|
|
102
|
+
* it read as the eyes moving on their own — at 0.8, THINKING's
|
|
103
|
+
* up-look rolled the iris to the lid with white beneath it, and
|
|
104
|
+
* the reply that followed dropped it into a downcast look with the
|
|
105
|
+
* lid riding down, while the head was still coming back. At 0.35
|
|
106
|
+
* the eyes mostly go where the head takes them.
|
|
107
|
+
* range How far the reflex may carry the eye in the socket. Unlimited,
|
|
108
|
+
* an up-look's onset put the whole 8° in the eye before the neck
|
|
109
|
+
* moved — the iris pinned under the lid, white beneath it, which
|
|
110
|
+
* on this photograph reads as an eye-roll. Up 0.45 is 2.8° and
|
|
111
|
+
* down 0.5 is 3.1°; the head covers the rest, as it does once the
|
|
112
|
+
* eye nears its effective range. Both were looser (0.55, 0.85)
|
|
113
|
+
* and a gap between turns hit both ends of them every time.
|
|
114
|
+
* lidFollow Down 0.38 keeps the upper lid on the iris: the lid travels
|
|
115
|
+
* 0.068 face units per lid unit and the iris 0.026 per pupil unit.
|
|
116
|
+
* Up a little less, so an upward look opens the eye a hair instead
|
|
117
|
+
* of dragging the lid along with it.
|
|
118
|
+
* avert A conversational look away keeps under half its size in the
|
|
119
|
+
* eyes and gives the neck 0.6 of it — on this face the eyes alone
|
|
120
|
+
* could only make it a glance sideways.
|
|
121
|
+
* head The follow's launch and cruise, in head units. A real head
|
|
122
|
+
* reaches a 7-8° shift in about 0.4 s, its speed scaling with the
|
|
123
|
+
* size of the shift; the shared amble took a thinking look 1.2 s,
|
|
124
|
+
* and the reflex, doing its job, held the eyes in the corner of
|
|
125
|
+
* the socket the whole way.
|
|
126
|
+
*
|
|
127
|
+
* `trunkFollow` is 0.3, under the line faces' 0.45. Live2D's face-tracking
|
|
128
|
+
* sample gives the body a third of the head's yaw (BodyAngleX 10 against
|
|
129
|
+
* AngleX 30; docs/research-head-rotation.md § 5 item 6), and that is the
|
|
130
|
+
* benchmark to sit at, not above. Here it matters for a reason a line face
|
|
131
|
+
* does not have: the neck's outline holds under a twist by construction
|
|
132
|
+
* (`morphs.neck_twist`), so the trunk's sway is what is left moving it — a
|
|
133
|
+
* quarter to a third of it at the yaw peak in the recorded call, read as the
|
|
134
|
+
* neck sliding.
|
|
135
|
+
*/
|
|
136
|
+
export declare const CHARACTER_TUNING: {
|
|
137
|
+
readonly prosodyHeadGain: 1;
|
|
138
|
+
readonly prosodyFaceGain: 1;
|
|
139
|
+
readonly saccadeGain: 2.4;
|
|
140
|
+
readonly aversionGain: 1.8;
|
|
141
|
+
readonly trunkFollow: 0.3;
|
|
142
|
+
readonly brows: {
|
|
143
|
+
readonly range: readonly [-0.28, 0.24];
|
|
144
|
+
readonly floor: 0.11;
|
|
145
|
+
readonly forms: readonly [{
|
|
146
|
+
readonly p: 0.38;
|
|
147
|
+
readonly inner: 0;
|
|
148
|
+
readonly angle: 0;
|
|
149
|
+
}, {
|
|
150
|
+
readonly p: 0.34;
|
|
151
|
+
readonly inner: 0.26;
|
|
152
|
+
readonly angle: 0;
|
|
153
|
+
}, {
|
|
154
|
+
readonly p: 0.28;
|
|
155
|
+
readonly inner: 0;
|
|
156
|
+
readonly angle: 0.3;
|
|
157
|
+
}];
|
|
158
|
+
};
|
|
159
|
+
readonly states: {
|
|
160
|
+
readonly WORKING: {
|
|
161
|
+
readonly pose: {
|
|
162
|
+
readonly headPitch: 0.04;
|
|
163
|
+
readonly lidL: -0.08;
|
|
164
|
+
readonly lidR: -0.08;
|
|
165
|
+
readonly shoulderL: 0.06;
|
|
166
|
+
readonly shoulderR: 0.06;
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
readonly CANT_HEAR: {
|
|
170
|
+
readonly pose: {
|
|
171
|
+
readonly torsoLean: 0.22;
|
|
172
|
+
readonly headPitch: 0.1;
|
|
173
|
+
readonly browRaiseL: -0.14;
|
|
174
|
+
readonly browRaiseR: -0.14;
|
|
175
|
+
readonly browInnerL: 0.22;
|
|
176
|
+
readonly browInnerR: 0.18;
|
|
177
|
+
readonly mouthPress: 0.4;
|
|
178
|
+
readonly mouthCornerL: -0.1;
|
|
179
|
+
readonly mouthCornerR: -0.1;
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
readonly SEARCHING_SCREEN: {
|
|
183
|
+
readonly pose: {
|
|
184
|
+
readonly mouthPress: 0.4;
|
|
185
|
+
readonly mouthCornerL: -0.08;
|
|
186
|
+
readonly mouthCornerR: -0.08;
|
|
187
|
+
readonly browRaiseL: -0.1;
|
|
188
|
+
readonly browRaiseR: -0.06;
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
readonly oculomotor: {
|
|
193
|
+
readonly angles: {
|
|
194
|
+
readonly eye: {
|
|
195
|
+
x: number;
|
|
196
|
+
y: number;
|
|
197
|
+
};
|
|
198
|
+
readonly head: {
|
|
199
|
+
x: number;
|
|
200
|
+
y: number;
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
readonly vor: {
|
|
204
|
+
readonly x: 0.8;
|
|
205
|
+
readonly y: 0.35;
|
|
206
|
+
};
|
|
207
|
+
readonly range: {
|
|
208
|
+
readonly x: 0.8;
|
|
209
|
+
readonly up: 0.45;
|
|
210
|
+
readonly down: 0.5;
|
|
211
|
+
};
|
|
212
|
+
readonly lidFollow: {
|
|
213
|
+
readonly down: 0.38;
|
|
214
|
+
readonly up: 0.3;
|
|
215
|
+
};
|
|
216
|
+
readonly avert: {
|
|
217
|
+
readonly eye: 0.45;
|
|
218
|
+
readonly head: 0.6;
|
|
219
|
+
};
|
|
220
|
+
readonly head: {
|
|
221
|
+
readonly accel: 16;
|
|
222
|
+
readonly speed: 3.5;
|
|
223
|
+
};
|
|
224
|
+
readonly targets: {
|
|
225
|
+
readonly OWN_SCREEN: {
|
|
226
|
+
readonly px: 0.14;
|
|
227
|
+
readonly py: 0.24;
|
|
228
|
+
readonly hx: 0.1;
|
|
229
|
+
readonly hy: 0.06;
|
|
230
|
+
};
|
|
231
|
+
readonly USER_EAR: {
|
|
232
|
+
readonly px: -0.2;
|
|
233
|
+
readonly py: 0.05;
|
|
234
|
+
readonly hx: 0.4;
|
|
235
|
+
readonly hy: 0.02;
|
|
236
|
+
readonly roll: 0.55;
|
|
237
|
+
};
|
|
238
|
+
readonly SCREEN_CENTER: {
|
|
239
|
+
readonly px: 0;
|
|
240
|
+
readonly py: -0.06;
|
|
241
|
+
readonly hx: 0;
|
|
242
|
+
readonly hy: -0.14;
|
|
243
|
+
};
|
|
244
|
+
readonly SCREEN_LEFT: {
|
|
245
|
+
readonly px: -0.42;
|
|
246
|
+
readonly py: -0.1;
|
|
247
|
+
readonly hx: -0.8;
|
|
248
|
+
readonly hy: -0.05;
|
|
249
|
+
};
|
|
250
|
+
readonly SCREEN_RIGHT: {
|
|
251
|
+
readonly px: 0.42;
|
|
252
|
+
readonly py: -0.1;
|
|
253
|
+
readonly hx: 0.8;
|
|
254
|
+
readonly hy: -0.05;
|
|
255
|
+
};
|
|
256
|
+
readonly SCREEN_TOP: {
|
|
257
|
+
readonly px: 0;
|
|
258
|
+
readonly py: -0.26;
|
|
259
|
+
readonly hx: 0;
|
|
260
|
+
readonly hy: -0.28;
|
|
261
|
+
};
|
|
262
|
+
readonly SCREEN_WORK: {
|
|
263
|
+
readonly px: -0.35;
|
|
264
|
+
readonly py: 0.18;
|
|
265
|
+
readonly hx: -0.55;
|
|
266
|
+
readonly hy: 0.12;
|
|
267
|
+
};
|
|
268
|
+
readonly AWAY_THINKING: {
|
|
269
|
+
readonly px: -0.3;
|
|
270
|
+
readonly py: -0.4;
|
|
271
|
+
readonly hx: -0.75;
|
|
272
|
+
readonly hy: -0.33;
|
|
273
|
+
readonly roll: 0.08;
|
|
274
|
+
};
|
|
275
|
+
readonly AWAY_RIGHT: {
|
|
276
|
+
readonly px: 0.3;
|
|
277
|
+
readonly py: -0.36;
|
|
278
|
+
readonly hx: 0.72;
|
|
279
|
+
readonly hy: -0.3;
|
|
280
|
+
readonly roll: -0.06;
|
|
281
|
+
};
|
|
282
|
+
readonly AWAY_DOWN: {
|
|
283
|
+
readonly px: -0.28;
|
|
284
|
+
readonly py: 0.45;
|
|
285
|
+
readonly hx: -0.62;
|
|
286
|
+
readonly hy: 0.16;
|
|
287
|
+
readonly roll: 0.04;
|
|
288
|
+
};
|
|
289
|
+
readonly AWAY_SIDE: {
|
|
290
|
+
readonly px: 0.32;
|
|
291
|
+
readonly py: 0.08;
|
|
292
|
+
readonly hx: 0.72;
|
|
293
|
+
readonly hy: 0.02;
|
|
294
|
+
readonly roll: -0.03;
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
export interface CharacterRigOptions {
|
|
300
|
+
/** Called once the GLB is in the scene, for a capture tool that must wait. */
|
|
301
|
+
readonly onReady?: () => void;
|
|
302
|
+
/** The character's GLB. Every build fact the rig reads (jaw-shadow tile, rim
|
|
303
|
+
* depth, morph names) travels in the GLB's own extras, so a character built
|
|
304
|
+
* by the same scripts needs nothing else.
|
|
305
|
+
*
|
|
306
|
+
* Required, and deliberately not defaulted: a default would make this module
|
|
307
|
+
* import one character's URL, and a bundler emits assets per module — so
|
|
308
|
+
* every consumer of *any* character would ship that one's GLB whether or not
|
|
309
|
+
* they mounted it. The caller knows which character it is building; this
|
|
310
|
+
* file must not ([tara-asset.ts](./tara-asset.ts)). */
|
|
311
|
+
readonly url: string;
|
|
312
|
+
/** `false` leaves an asset's expression maps unread, for a capture tool
|
|
313
|
+
* comparing the face with and without them. */
|
|
314
|
+
readonly expression?: boolean;
|
|
315
|
+
/** Keeps the drawing buffer readable after the browser has composited it, so
|
|
316
|
+
* a caller can copy the canvas out at any moment rather than only from
|
|
317
|
+
* inside the frame that drew it.
|
|
318
|
+
*
|
|
319
|
+
* A pose sheet reuses one context, holding a pose still and copying the
|
|
320
|
+
* canvas into a tile; copy outside the drawing frame without this and the
|
|
321
|
+
* buffer has already been cleared, which is a blank tile and not an error.
|
|
322
|
+
* A consumer must not have it: the buffer can no longer be discarded, which
|
|
323
|
+
* on some drivers means a second copy of every frame. */
|
|
324
|
+
readonly readback?: boolean;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* The hair's roll, which is the one thing in this rig that is not a function of
|
|
328
|
+
* the pose alone. `hold` is the share of the head's roll the hanging hair
|
|
329
|
+
* declines to take, and `hz`/`damping` are how it gets there.
|
|
330
|
+
*
|
|
331
|
+
* A hank that hangs past the jaw is lying on a shoulder, and a shoulder does
|
|
332
|
+
* not tilt when the head does: rolled rigidly with the skull it lifts off the
|
|
333
|
+
* collar and the page shows through behind it, so the shell gives up `hold` of
|
|
334
|
+
* the roll at its lowest rows and none at the crown (`morphs.hair_hold`).
|
|
335
|
+
*
|
|
336
|
+
* The other half is why roll read as a hinge at all. A rigid rotation about a
|
|
337
|
+
* fixed point *is* a hinge, and what a real tilt has that this lacked is hair
|
|
338
|
+
* that arrives late and settles (`docs/research-head-rotation.md` § 3.1:
|
|
339
|
+
* mobility ~0.95, delay 0.8-0.9, one clear overshoot). At 0.65 that is a single
|
|
340
|
+
* visible overshoot, inside 5% of the hold in 450 ms — faster reads as a flick,
|
|
341
|
+
* slower as wet hair.
|
|
342
|
+
*
|
|
343
|
+
* It is on the hair and not on `headRoll` on purpose: every clip in the library
|
|
344
|
+
* is authored pre-compensated for the mixer's per-channel time constants, so a
|
|
345
|
+
* spring on the channel would silently re-time every nod ever authored.
|
|
346
|
+
*/
|
|
347
|
+
export declare const HAIR_ROLL: {
|
|
348
|
+
hold: number;
|
|
349
|
+
hz: number;
|
|
350
|
+
damping: number;
|
|
351
|
+
};
|
|
352
|
+
/**
|
|
353
|
+
* One step of `HAIR_ROLL`'s spring: semi-implicit, the rate taking the frame's
|
|
354
|
+
* acceleration before the angle takes the rate. Explicit Euler rings at this
|
|
355
|
+
* stiffness and 30 fps; this does not, which is the only reason the order of
|
|
356
|
+
* those two lines is worth a sentence.
|
|
357
|
+
*
|
|
358
|
+
* Exported for `test/nods.test.ts`: settle time and overshoot are numbers, not
|
|
359
|
+
* something a still frame can show.
|
|
360
|
+
*/
|
|
361
|
+
export declare const hairRollStep: (angle: number, rate: number, target: number, dt: number) => {
|
|
362
|
+
angle: number;
|
|
363
|
+
rate: number;
|
|
364
|
+
};
|
|
365
|
+
export declare function createCharacterRig(mount: HTMLElement, options?: unknown): AvatarRig;
|
|
366
|
+
//# sourceMappingURL=character-rig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"character-rig.d.ts","sourceRoot":"","sources":["../../client/three/character-rig.ts"],"names":[],"mappings":"AACA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAe,SAAS,EAAW,MAAM,gBAAgB,CAAC;AACtE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B;;;;;;;;;;;;;;;;;GAiBG;AAKH,eAAO,MAAM,UAAU,MAAM,CAAC;AAC9B,eAAO,MAAM,QAAQ;;;;CAAkC,CAAC;AAExD;;;;;;;;GAQG;AACH,eAAO,MAAM,KAAK,eAAsC,CAAC;AAEzD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU,eAAsC,CAAC;AAE9D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,UAC+B,CAAC;AAqFvD;;;+EAG+E;AAC/E,eAAO,MAAM,OAAO;;;CAA2G,CAAC;AAGhI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+HnB,CAAC;AAymBX,MAAM,WAAW,mBAAmB;IAClC,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;;4DAQwD;IACxD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;oDACgD;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;8DAQ0D;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AA4HD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,SAAS;;;;CAAyC,CAAC;AAEhE;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,EAAE,IAAI,MAAM;;;CAInF,CAAC;AA0CF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAmfnF"}
|