@voqalize/avatar 0.4.0 → 0.4.2
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/README.md +46 -28
- package/assets/README.md +4 -3
- 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 +20 -0
- package/client/three/assets.ts +16 -16
- package/client/three/holds.ts +7 -2
- package/client/three/internal.ts +5 -5
- package/client/three/motion-limits.json +5 -1
- package/client/three/sequences.ts +5 -5
- package/client/three/tanya-asset.ts +6 -0
- package/client/three/tanya.ts +2 -2
- package/client/three/tara-asset.ts +25 -0
- package/client/three/tara-rig.ts +37 -14
- package/client/three/tara.ts +2 -1
- package/client/three/tess-asset.ts +6 -0
- package/client/three/tess.ts +72 -0
- package/client/three/tushar-asset.ts +6 -0
- package/client/three/tushar.ts +2 -2
- package/dist/internal.d.ts +2 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +12 -1
- package/dist/internal.js.map +1 -1
- package/dist/three/assets.d.ts +1 -16
- package/dist/three/assets.d.ts.map +1 -1
- package/dist/three/assets.js +15 -16
- package/dist/three/assets.js.map +1 -1
- package/dist/three/holds.d.ts +7 -2
- package/dist/three/holds.d.ts.map +1 -1
- package/dist/three/holds.js +7 -2
- package/dist/three/holds.js.map +1 -1
- package/dist/three/internal.d.ts +5 -5
- package/dist/three/internal.js +5 -5
- package/dist/three/motion-limits.json +5 -1
- package/dist/three/sequences.d.ts +5 -5
- package/dist/three/sequences.js +5 -5
- package/dist/three/tanya-asset.d.ts +7 -0
- package/dist/three/tanya-asset.d.ts.map +1 -0
- package/dist/three/tanya-asset.js +7 -0
- package/dist/three/tanya-asset.js.map +1 -0
- package/dist/three/tanya.js +2 -2
- package/dist/three/tanya.js.map +1 -1
- package/dist/three/tara-asset.d.ts +26 -0
- package/dist/three/tara-asset.d.ts.map +1 -0
- package/dist/three/tara-asset.js +26 -0
- package/dist/three/tara-asset.js.map +1 -0
- package/dist/three/tara-rig.d.ts +29 -9
- package/dist/three/tara-rig.d.ts.map +1 -1
- package/dist/three/tara-rig.js +14 -9
- package/dist/three/tara-rig.js.map +1 -1
- package/dist/three/tara.d.ts.map +1 -1
- package/dist/three/tara.js +2 -1
- 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 +38 -0
- package/dist/three/tess.d.ts.map +1 -0
- package/dist/three/tess.js +54 -0
- package/dist/three/tess.js.map +1 -0
- package/dist/three/tushar-asset.d.ts +7 -0
- package/dist/three/tushar-asset.d.ts.map +1 -0
- package/dist/three/tushar-asset.js +7 -0
- package/dist/three/tushar-asset.js.map +1 -0
- package/dist/three/tushar.js +2 -2
- package/dist/three/tushar.js.map +1 -1
- package/package.json +5 -1
- package/src/avatar.d.ts +65 -2
- package/src/avatar.js +68 -63
- package/src/faces.js +1 -1
- package/src/gaze.js +19 -44
- package/src/idle.js +60 -26
- package/src/prosody.js +104 -14
- package/src/rig.d.ts +7 -0
package/client/three/tushar.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import type { PipecatClient } from "@pipecat-ai/client-js";
|
|
13
13
|
import { AvatarClient, createSvgAvatar } from "../internal.js";
|
|
14
|
-
import {
|
|
14
|
+
import { TUSHAR_GLB } from "./tushar-asset.js";
|
|
15
15
|
import { BLENDER_ACTIONS, BLENDER_SEQUENCES, BLENDER_SUPPORTS } from "./sequences.js";
|
|
16
16
|
import { headHold } from "./holds.js";
|
|
17
17
|
import { createTaraRig, TARA_TUNING } from "./tara-rig.js";
|
|
@@ -41,7 +41,7 @@ export function createAvatar(options: AvatarOptions): AvatarInstance {
|
|
|
41
41
|
if (!mount) throw new TypeError("createAvatar: `mount` is required");
|
|
42
42
|
if (!client) throw new TypeError("createAvatar: `client` is required");
|
|
43
43
|
|
|
44
|
-
const rigOptions: TaraRigOptions = { onReady, url:
|
|
44
|
+
const rigOptions: TaraRigOptions = { onReady, url: TUSHAR_GLB };
|
|
45
45
|
// TARA-SPECIFIC, kept on purpose: `TARA_TUNING` (her mouth and motion gains)
|
|
46
46
|
// is the first thing to question if he reads wrong in a call.
|
|
47
47
|
const widget = createSvgAvatar({
|
package/dist/internal.d.ts
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
* renderer uses internally. It is *not* the seam to implement — see
|
|
22
22
|
* docs/design-avatar-interface.md.
|
|
23
23
|
*/
|
|
24
|
-
export { createAvatar as createSvgAvatar, REST, CHANNELS, RANGE, STATES, STATE_NAMES, ACTIONS, ACTION_IDS, GAZE_NAMES, GAZE_TARGETS, EMOTION_NAMES, VisemeTrack, VISEME_LETTERS, VISEME_SHAPES, SILENT, LEAD_MS, SHOULDER_TILT, shapeFor, normalizeCues, textToCues, ARPABET_TO_VISEME, AZURE_VISEME_TO_LETTER, } from "../src/avatar.js";
|
|
25
|
-
export type { AvatarApi, AvatarStateName, AvatarActionId, AvatarGazeName, AvatarEmotionName, AvatarAction, AvatarMeta, VisemeLetter, Cue, PoseChannel, PoseOverrides, CreateAvatarOptions as CreateSvgAvatarOptions, } from "../src/avatar.js";
|
|
24
|
+
export { createAvatar as createSvgAvatar, REST, CHANNELS, RANGE, STATES, STATE_NAMES, ACTIONS, ACTION_IDS, GAZE_NAMES, GAZE_TARGETS, EMOTION_NAMES, VisemeTrack, VISEME_LETTERS, VISEME_SHAPES, SILENT, LEAD_MS, SHOULDER_TILT, INTERNAL_CLIPS, ClipPlayer, TAU, clamp, approach, makeParams, emotionPose, avatarFrame, createSvgRig, shapeFor, normalizeCues, textToCues, ARPABET_TO_VISEME, AZURE_VISEME_TO_LETTER, } from "../src/avatar.js";
|
|
25
|
+
export type { Clip, ClipSample, AvatarApi, AvatarStateName, AvatarActionId, AvatarGazeName, AvatarEmotionName, AvatarAction, AvatarMeta, VisemeLetter, Cue, PoseChannel, PoseOverrides, CreateAvatarOptions as CreateSvgAvatarOptions, } from "../src/avatar.js";
|
|
26
26
|
export type { AvatarFrame, AvatarRig, AvatarRigFactory, HandFrame, RigPose, } from "../src/rig.js";
|
|
27
27
|
export { BEHAVIOR_STATE_IDS, BEHAVIOR_ACTIONS, BEHAVIOR_ACTION_IDS, WIRE_ACTION_TO_BEHAVIOR, } from "../src/behavior.js";
|
|
28
28
|
export type { BehaviorStateId, BehaviorActionId } from "../src/behavior.js";
|
package/dist/internal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../client/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAIL,YAAY,IAAI,eAAe,EAG/B,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EAEb,WAAW,EACX,cAAc,EACd,aAAa,EACb,MAAM,EACN,OAAO,EAEP,aAAa,
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../client/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAIL,YAAY,IAAI,eAAe,EAG/B,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EAEb,WAAW,EACX,cAAc,EACd,aAAa,EACb,MAAM,EACN,OAAO,EAEP,aAAa,EAMb,cAAc,EACd,UAAU,EACV,GAAG,EACH,KAAK,EACL,QAAQ,EAKR,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EACV,IAAI,EACJ,UAAU,EACV,SAAS,EACT,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,GAAG,EACH,WAAW,EACX,aAAa,EACb,mBAAmB,IAAI,sBAAsB,GAC9C,MAAM,kBAAkB,CAAC;AAK1B,YAAY,EACV,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,OAAO,GACR,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAM9D,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/internal.js
CHANGED
|
@@ -32,7 +32,18 @@ REST, CHANNELS, RANGE, STATES, STATE_NAMES, ACTIONS, ACTION_IDS, GAZE_NAMES, GAZ
|
|
|
32
32
|
// The viseme clock and its tables.
|
|
33
33
|
VisemeTrack, VISEME_LETTERS, VISEME_SHAPES, SILENT, LEAD_MS,
|
|
34
34
|
// The body's share of a held tilt, for a page driving a rig by hand.
|
|
35
|
-
SHOULDER_TILT,
|
|
35
|
+
SHOULDER_TILT,
|
|
36
|
+
// Stepping a gesture by hand: the catalogue, the player, and the smoothing
|
|
37
|
+
// law the mixer puts between a clip's keyframes and the face. A filmstrip
|
|
38
|
+
// instrument needs all three, and the one thing it must not do is fork the
|
|
39
|
+
// smoothing — that is the part a keyframe is authored against
|
|
40
|
+
// (docs/internal-mixer.md § Smoothing).
|
|
41
|
+
INTERNAL_CLIPS, ClipPlayer, TAU, clamp, approach,
|
|
42
|
+
// Posing a face directly, with no mixer, no clock and no client above it —
|
|
43
|
+
// what a pose sheet or a rig-conformance page does. `makeParams` fills the
|
|
44
|
+
// rests around a handful of overrides, `emotionPose` names a familiar set of
|
|
45
|
+
// them, `avatarFrame` wraps the result and `createSvgRig(face)` draws it.
|
|
46
|
+
makeParams, emotionPose, avatarFrame, createSvgRig, shapeFor, normalizeCues, textToCues, ARPABET_TO_VISEME, AZURE_VISEME_TO_LETTER, } from "../src/avatar.js";
|
|
36
47
|
export { BEHAVIOR_STATE_IDS, BEHAVIOR_ACTIONS, BEHAVIOR_ACTION_IDS, WIRE_ACTION_TO_BEHAVIOR, } from "../src/behavior.js";
|
|
37
48
|
export { isAvatarMessage, CORE_ACTION_IDS } from "./types.js";
|
|
38
49
|
// A renderer may reuse the one lifecycle/precedence ladder without gaining a
|
package/dist/internal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../client/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO;AACL,2EAA2E;AAC3E,0DAA0D;AAC1D,8DAA8D;AAC9D,YAAY,IAAI,eAAe;AAC/B,8EAA8E;AAC9E,oBAAoB;AACpB,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa;AACb,mCAAmC;AACnC,WAAW,EACX,cAAc,EACd,aAAa,EACb,MAAM,EACN,OAAO;AACP,qEAAqE;AACrE,aAAa,
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../client/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO;AACL,2EAA2E;AAC3E,0DAA0D;AAC1D,8DAA8D;AAC9D,YAAY,IAAI,eAAe;AAC/B,8EAA8E;AAC9E,oBAAoB;AACpB,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa;AACb,mCAAmC;AACnC,WAAW,EACX,cAAc,EACd,aAAa,EACb,MAAM,EACN,OAAO;AACP,qEAAqE;AACrE,aAAa;AACb,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,8DAA8D;AAC9D,wCAAwC;AACxC,cAAc,EACd,UAAU,EACV,GAAG,EACH,KAAK,EACL,QAAQ;AACR,2EAA2E;AAC3E,2EAA2E;AAC3E,6EAA6E;AAC7E,0EAA0E;AAC1E,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AA8B1B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAO9D,6EAA6E;AAC7E,kCAAkC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/three/assets.d.ts
CHANGED
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Where the three compiled characters are, resolved against this module's own
|
|
3
|
-
* location.
|
|
4
|
-
*
|
|
5
|
-
* `new URL(…, import.meta.url)` and not a bundler's asset import: these files
|
|
6
|
-
* are fetched at runtime by a consumer's app, and the spelling has to survive
|
|
7
|
-
* Vite, webpack, Rollup, esbuild, a plain `tsc` output and a browser loading
|
|
8
|
-
* the module directly. The query-suffix form this used to carry is Vite syntax —
|
|
9
|
-
* every other toolchain, including the compiler that now builds this directory,
|
|
10
|
-
* passes it through verbatim and produces an import of a file that is not there.
|
|
11
|
-
*
|
|
12
|
-
* The depth is the same from the source tree and from the compiled one
|
|
13
|
-
* (`client/three/` and `dist/three/` are siblings), so one literal is correct in
|
|
14
|
-
* both — and literal is load-bearing, because a bundler can only follow this
|
|
15
|
-
* pattern when it can read the path without running anything.
|
|
16
|
-
*/
|
|
17
1
|
export declare const ASSETS: Readonly<{
|
|
18
2
|
tara: string;
|
|
19
3
|
tushar: string;
|
|
20
4
|
tanya: string;
|
|
5
|
+
tess: string;
|
|
21
6
|
}>;
|
|
22
7
|
/** Every compiled character, in build order. */
|
|
23
8
|
export type CharacterName = keyof typeof ASSETS;
|
|
@@ -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":"AAeA,eAAO,MAAM,MAAM;;;;;EAKjB,CAAC;AAEH,gDAAgD;AAChD,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,MAAM,CAAC"}
|
package/dist/three/assets.js
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* location.
|
|
2
|
+
* Every compiled character as one table — for a page that enumerates them.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* The depth is the same from the source tree and from the compiled one
|
|
13
|
-
* (`client/three/` and `dist/three/` are siblings), so one literal is correct in
|
|
14
|
-
* both — and literal is load-bearing, because a bundler can only follow this
|
|
15
|
-
* pattern when it can read the path without running anything.
|
|
4
|
+
* Each URL lives in its own module (`tara-asset.ts` and its siblings) and this
|
|
5
|
+
* file only gathers them, because a bundler emits assets per module: anything
|
|
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
|
+
* So the character modules never import this — they import their own — and the
|
|
9
|
+
* only reader is `/internal/three`, a separate entry point that ships nothing.
|
|
16
10
|
*/
|
|
11
|
+
import { TANYA_GLB } from "./tanya-asset.js";
|
|
12
|
+
import { TESS_GLB } from "./tess-asset.js";
|
|
13
|
+
import { TARA_GLB } from "./tara-asset.js";
|
|
14
|
+
import { TUSHAR_GLB } from "./tushar-asset.js";
|
|
17
15
|
export const ASSETS = Object.freeze({
|
|
18
|
-
tara:
|
|
19
|
-
tushar:
|
|
20
|
-
tanya:
|
|
16
|
+
tara: TARA_GLB,
|
|
17
|
+
tushar: TUSHAR_GLB,
|
|
18
|
+
tanya: TANYA_GLB,
|
|
19
|
+
tess: TESS_GLB,
|
|
21
20
|
});
|
|
22
21
|
//# 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
|
|
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,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;CACf,CAAC,CAAC"}
|
package/dist/three/holds.d.ts
CHANGED
|
@@ -3,12 +3,16 @@
|
|
|
3
3
|
* pose units per axis, ready to hand to `createSvgAvatar` as `headHold`.
|
|
4
4
|
*
|
|
5
5
|
* The angles themselves are in `motion-limits.json` and are only
|
|
6
|
-
* there. They were read off the
|
|
6
|
+
* there. They were read off the faces by the person who owns how they
|
|
7
7
|
* look, one axis at a time, at the surface a call actually shows — which is
|
|
8
8
|
* the only way this kind of number can be got, and the reason nothing here
|
|
9
9
|
* recomputes, adjusts or second-guesses one. This file is the unit change and
|
|
10
10
|
* nothing else.
|
|
11
11
|
*
|
|
12
|
+
* An axis the file never carried is the same case, and a character built but
|
|
13
|
+
* not yet driven by the owner has none of them: the file says so instead of
|
|
14
|
+
* carrying a number nobody read, and the fallback below is what holds her.
|
|
15
|
+
*
|
|
12
16
|
* An axis the file marks for re-measurement is not enforced: it was read off an
|
|
13
17
|
* asset that has since been fixed, and holding the driver to a defect that no
|
|
14
18
|
* longer exists is worse than the defect. It falls back to the tightest angle
|
|
@@ -27,7 +31,8 @@ declare const AXIS: {
|
|
|
27
31
|
readonly headRoll: "roll";
|
|
28
32
|
};
|
|
29
33
|
export type HeadHold = Partial<Record<keyof typeof AXIS, number>>;
|
|
30
|
-
/** `name` as the limits file spells it
|
|
34
|
+
/** `name` as the limits file spells it — a character with no live axis there
|
|
35
|
+
* is held to the tightest budget any other is still vouched for. */
|
|
31
36
|
export declare function headHold(name: keyof typeof LIMITS.characters): HeadHold;
|
|
32
37
|
export {};
|
|
33
38
|
//# sourceMappingURL=holds.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"holds.d.ts","sourceRoot":"","sources":["../../client/three/holds.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"holds.d.ts","sourceRoot":"","sources":["../../client/three/holds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,MAAM,MAAM,sBAAsB,CAAuB;AAUhE,QAAA,MAAM,IAAI;;;;CAAoE,CAAC;AAE/E,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,OAAO,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAmBlE;qEACqE;AACrE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,MAAM,CAAC,UAAU,GAAG,QAAQ,CAQvE"}
|
package/dist/three/holds.js
CHANGED
|
@@ -3,12 +3,16 @@
|
|
|
3
3
|
* pose units per axis, ready to hand to `createSvgAvatar` as `headHold`.
|
|
4
4
|
*
|
|
5
5
|
* The angles themselves are in `motion-limits.json` and are only
|
|
6
|
-
* there. They were read off the
|
|
6
|
+
* there. They were read off the faces by the person who owns how they
|
|
7
7
|
* look, one axis at a time, at the surface a call actually shows — which is
|
|
8
8
|
* the only way this kind of number can be got, and the reason nothing here
|
|
9
9
|
* recomputes, adjusts or second-guesses one. This file is the unit change and
|
|
10
10
|
* nothing else.
|
|
11
11
|
*
|
|
12
|
+
* An axis the file never carried is the same case, and a character built but
|
|
13
|
+
* not yet driven by the owner has none of them: the file says so instead of
|
|
14
|
+
* carrying a number nobody read, and the fallback below is what holds her.
|
|
15
|
+
*
|
|
12
16
|
* An axis the file marks for re-measurement is not enforced: it was read off an
|
|
13
17
|
* asset that has since been fixed, and holding the driver to a defect that no
|
|
14
18
|
* longer exists is worse than the defect. It falls back to the tightest angle
|
|
@@ -42,7 +46,8 @@ function safest(axis) {
|
|
|
42
46
|
.filter((deg) => deg !== undefined);
|
|
43
47
|
return angles.length ? Math.min(...angles) : undefined;
|
|
44
48
|
}
|
|
45
|
-
/** `name` as the limits file spells it
|
|
49
|
+
/** `name` as the limits file spells it — a character with no live axis there
|
|
50
|
+
* is held to the tightest budget any other is still vouched for. */
|
|
46
51
|
export function headHold(name) {
|
|
47
52
|
const out = {};
|
|
48
53
|
for (const channel of Object.keys(AXIS)) {
|
package/dist/three/holds.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"holds.js","sourceRoot":"","sources":["../../client/three/holds.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"holds.js","sourceRoot":"","sources":["../../client/three/holds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,MAAM,MAAM,sBAAsB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAErD,4EAA4E;AAC5E,MAAM,QAAQ,GAAG;IACf,OAAO,EAAE,QAAQ,CAAC,GAAG,GAAG,UAAU;IAClC,SAAS,EAAE,QAAQ,CAAC,KAAK,GAAG,UAAU;IACtC,QAAQ,EAAE,QAAQ,CAAC,IAAI,GAAG,UAAU;CAC5B,CAAC;AAEX,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAW,CAAC;AAM/E,+EAA+E;AAC/E,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,IAAY,EAAwB,EAAE;IAChE,MAAM,QAAQ,GAAI,MAAM,CAAC,UAAsD,CAAC,IAAI,CAAC,CAAC;IACtF,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAyB,CAAC;IACvD,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC,CAAC;AAEF,0EAA0E;AAC1E,SAAS,MAAM,CAAC,IAAY;IAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;SAC1C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;SACrC,MAAM,CAAC,CAAC,GAAG,EAAiB,EAAE,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACzD,CAAC;AAED;qEACqE;AACrE,MAAM,UAAU,QAAQ,CAAC,IAAoC;IAC3D,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAA0B,EAAE,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,GAAG,KAAK,SAAS;YAAE,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/three/internal.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The 2.5-D rig, below the `createAvatar` modules — `/internal`, no semver promise.
|
|
3
3
|
*
|
|
4
|
-
* `tara.ts`, `tushar.ts
|
|
5
|
-
* `createAvatar` each, the mixer behind it, nothing to
|
|
6
|
-
* other door, for a page whose subject is the *rig*
|
|
7
|
-
* renderer with no mixer in front of it,
|
|
8
|
-
* head envelope their channels are scaled by. Its readers are the rig instruments
|
|
4
|
+
* A character's own module — `tara.ts`, `tushar.ts`, `tanya.ts`, `tess.ts` — is
|
|
5
|
+
* what a consumer gets: one `createAvatar` each, the mixer behind it, nothing to
|
|
6
|
+
* configure. This is the other door, for a page whose subject is the *rig*
|
|
7
|
+
* rather than the call — the renderer with no mixer in front of it, every
|
|
8
|
+
* compiled character, and the head envelope their channels are scaled by. Its readers are the rig instruments
|
|
9
9
|
* in the working tree, and nothing that ships.
|
|
10
10
|
*
|
|
11
11
|
* It exists because those instruments were reaching around the package instead,
|
package/dist/three/internal.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The 2.5-D rig, below the `createAvatar` modules — `/internal`, no semver promise.
|
|
3
3
|
*
|
|
4
|
-
* `tara.ts`, `tushar.ts
|
|
5
|
-
* `createAvatar` each, the mixer behind it, nothing to
|
|
6
|
-
* other door, for a page whose subject is the *rig*
|
|
7
|
-
* renderer with no mixer in front of it,
|
|
8
|
-
* head envelope their channels are scaled by. Its readers are the rig instruments
|
|
4
|
+
* A character's own module — `tara.ts`, `tushar.ts`, `tanya.ts`, `tess.ts` — is
|
|
5
|
+
* what a consumer gets: one `createAvatar` each, the mixer behind it, nothing to
|
|
6
|
+
* configure. This is the other door, for a page whose subject is the *rig*
|
|
7
|
+
* rather than the call — the renderer with no mixer in front of it, every
|
|
8
|
+
* compiled character, and the head envelope their channels are scaled by. Its readers are the rig instruments
|
|
9
9
|
* in the working tree, and nothing that ships.
|
|
10
10
|
*
|
|
11
11
|
* It exists because those instruments were reaching around the package instead,
|
|
@@ -110,7 +110,11 @@
|
|
|
110
110
|
"fixed": "2026-09-19"
|
|
111
111
|
}
|
|
112
112
|
]
|
|
113
|
+
},
|
|
114
|
+
"tess": {
|
|
115
|
+
"unmeasured": "Nothing here has been read off her. She was built on 2026-09-20 and the owner has not driven her yet, so this entry carries no angle at all rather than a plausible one: `holds.ts` falls back to the tightest angle still live on each axis, which is the budget the faces nobody doubts are already held to. Drive her with the hold-and-move instrument and this becomes the same shape as the entries above.",
|
|
116
|
+
"defects": []
|
|
113
117
|
}
|
|
114
118
|
},
|
|
115
|
-
"remeasure": "An axis carrying `remeasure` was measured on an asset that has since changed. It stays as written
|
|
119
|
+
"remeasure": "An axis carrying `remeasure` was measured on an asset that has since changed. It stays as written — a measurement is not edited by someone who did not make it — and a gate skips it and says so."
|
|
116
120
|
}
|
|
@@ -56,13 +56,13 @@ export declare const BLENDER_ACTIONS: Readonly<{
|
|
|
56
56
|
* What every character in this package answers to — each one's `supports`, the
|
|
57
57
|
* optional declaration a driving UI reads (`AvatarSupport`).
|
|
58
58
|
*
|
|
59
|
-
* Derived rather than written down, because
|
|
60
|
-
*
|
|
61
|
-
* characters inherit whole, and this file's own names. A hand-kept
|
|
62
|
-
* would only be able to disagree with them. `BLENDER_ACTIONS` adds nothing —
|
|
59
|
+
* Derived rather than written down, because every part of it already exists: the
|
|
60
|
+
* ids every avatar owes a server, the mixer's own clip catalogue these
|
|
61
|
+
* characters inherit whole, and this file's own names. A hand-kept copy beside
|
|
62
|
+
* them would only be able to disagree with them. `BLENDER_ACTIONS` adds nothing —
|
|
63
63
|
* it re-shapes an id the mixer already has.
|
|
64
64
|
*
|
|
65
|
-
* It is one list for
|
|
65
|
+
* It is one list for every 2.5-D character for the same reason the tables are:
|
|
66
66
|
* they are one rig driven through one set of channels. A character that stops
|
|
67
67
|
* being able to do one of these owes its own `supports`, not an edit here.
|
|
68
68
|
*/
|
package/dist/three/sequences.js
CHANGED
|
@@ -242,13 +242,13 @@ void BLENDER_ACTIONS;
|
|
|
242
242
|
* What every character in this package answers to — each one's `supports`, the
|
|
243
243
|
* optional declaration a driving UI reads (`AvatarSupport`).
|
|
244
244
|
*
|
|
245
|
-
* Derived rather than written down, because
|
|
246
|
-
*
|
|
247
|
-
* characters inherit whole, and this file's own names. A hand-kept
|
|
248
|
-
* would only be able to disagree with them. `BLENDER_ACTIONS` adds nothing —
|
|
245
|
+
* Derived rather than written down, because every part of it already exists: the
|
|
246
|
+
* ids every avatar owes a server, the mixer's own clip catalogue these
|
|
247
|
+
* characters inherit whole, and this file's own names. A hand-kept copy beside
|
|
248
|
+
* them would only be able to disagree with them. `BLENDER_ACTIONS` adds nothing —
|
|
249
249
|
* it re-shapes an id the mixer already has.
|
|
250
250
|
*
|
|
251
|
-
* It is one list for
|
|
251
|
+
* It is one list for every 2.5-D character for the same reason the tables are:
|
|
252
252
|
* they are one rig driven through one set of channels. A character that stops
|
|
253
253
|
* being able to do one of these owes its own `supports`, not an edit here.
|
|
254
254
|
*/
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where tanya's compiled GLB is. One character, one module — see
|
|
3
|
+
* [tara-asset.ts](./tara-asset.ts) for why that separation is load-bearing and
|
|
4
|
+
* why the `new URL` literal is spelled exactly this way.
|
|
5
|
+
*/
|
|
6
|
+
export declare const TANYA_GLB: string;
|
|
7
|
+
//# sourceMappingURL=tanya-asset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tanya-asset.d.ts","sourceRoot":"","sources":["../../client/three/tanya-asset.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,SAAS,QAA0D,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where tanya's compiled GLB is. One character, one module — see
|
|
3
|
+
* [tara-asset.ts](./tara-asset.ts) for why that separation is load-bearing and
|
|
4
|
+
* why the `new URL` literal is spelled exactly this way.
|
|
5
|
+
*/
|
|
6
|
+
export const TANYA_GLB = new URL("../../assets/tanya.glb", import.meta.url).href;
|
|
7
|
+
//# sourceMappingURL=tanya-asset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tanya-asset.js","sourceRoot":"","sources":["../../client/three/tanya-asset.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC"}
|
package/dist/three/tanya.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* nothing — the rig reads the window from the GLB.
|
|
14
14
|
*/
|
|
15
15
|
import { AvatarClient, createSvgAvatar } from "../internal.js";
|
|
16
|
-
import {
|
|
16
|
+
import { TANYA_GLB } from "./tanya-asset.js";
|
|
17
17
|
import { BLENDER_ACTIONS, BLENDER_SEQUENCES, BLENDER_SUPPORTS } from "./sequences.js";
|
|
18
18
|
import { headHold } from "./holds.js";
|
|
19
19
|
import { createTaraRig, TARA_TUNING } from "./tara-rig.js";
|
|
@@ -26,7 +26,7 @@ export function createAvatar(options) {
|
|
|
26
26
|
throw new TypeError("createAvatar: `mount` is required");
|
|
27
27
|
if (!client)
|
|
28
28
|
throw new TypeError("createAvatar: `client` is required");
|
|
29
|
-
const rigOptions = { onReady, url:
|
|
29
|
+
const rigOptions = { onReady, url: TANYA_GLB };
|
|
30
30
|
// TARA-SPECIFIC, kept on purpose: `TARA_TUNING` (her mouth and motion gains)
|
|
31
31
|
// is the first thing to question if she reads wrong in a call.
|
|
32
32
|
const widget = createSvgAvatar({
|
package/dist/three/tanya.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tanya.js","sourceRoot":"","sources":["../../client/three/tanya.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"tanya.js","sourceRoot":"","sources":["../../client/three/tanya.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAkB3D;kDACkD;AAClD,MAAM,CAAC,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAEzC,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACrD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;IACrE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,CAAC;IAEvE,MAAM,UAAU,GAAmB,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;IAC/D,6EAA6E;IAC7E,+DAA+D;IAC/D,MAAM,MAAM,GAAG,eAAe,CAAC;QAC7B,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK;QAClD,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,WAAW;QACtE,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK;KACtC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAErC,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,OAAO;QACL,OAAO;YACL,IAAI,SAAS;gBAAE,OAAO;YACtB,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM,EAAE,CAAC;YACT,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where tara's compiled GLB is — one character, one module, on purpose.
|
|
3
|
+
*
|
|
4
|
+
* `new URL(…, import.meta.url)` and not a bundler's asset import: these files
|
|
5
|
+
* are fetched at runtime by a consumer's app, and the spelling has to survive
|
|
6
|
+
* Vite, webpack, Rollup, esbuild, a plain `tsc` output and a browser loading the
|
|
7
|
+
* module directly. The query-suffix form this used to carry is Vite syntax —
|
|
8
|
+
* every other toolchain, including the compiler that now builds this directory,
|
|
9
|
+
* passes it through verbatim and produces an import of a file that is not there.
|
|
10
|
+
*
|
|
11
|
+
* The depth is the same from the source tree and from the compiled one
|
|
12
|
+
* (`client/three/` and `dist/three/` are siblings), so one literal is correct in
|
|
13
|
+
* both — and literal is load-bearing, because a bundler can only follow this
|
|
14
|
+
* pattern when it can read the path without running anything.
|
|
15
|
+
*
|
|
16
|
+
* **One module per character is the whole point, and it is a bundling fact, not
|
|
17
|
+
* tidiness.** A bundler that can follow `new URL` emits the file it names, and
|
|
18
|
+
* it decides what to emit per *module*: three literals in one object meant a
|
|
19
|
+
* consumer who imported one character shipped all three GLBs — ~1.3 MB of a
|
|
20
|
+
* character they never mount, in every build we checked. Splitting them is what
|
|
21
|
+
* makes `@voqalize/avatar/avatars/tara` cost tara. Nothing that a character
|
|
22
|
+
* module loads may reach for another character's URL, which is also why the rig
|
|
23
|
+
* takes its `url` from its caller instead of defaulting to tara's.
|
|
24
|
+
*/
|
|
25
|
+
export declare const TARA_GLB: string;
|
|
26
|
+
//# sourceMappingURL=tara-asset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tara-asset.d.ts","sourceRoot":"","sources":["../../client/three/tara-asset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,QAAQ,QAAyD,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where tara's compiled GLB is — one character, one module, on purpose.
|
|
3
|
+
*
|
|
4
|
+
* `new URL(…, import.meta.url)` and not a bundler's asset import: these files
|
|
5
|
+
* are fetched at runtime by a consumer's app, and the spelling has to survive
|
|
6
|
+
* Vite, webpack, Rollup, esbuild, a plain `tsc` output and a browser loading the
|
|
7
|
+
* module directly. The query-suffix form this used to carry is Vite syntax —
|
|
8
|
+
* every other toolchain, including the compiler that now builds this directory,
|
|
9
|
+
* passes it through verbatim and produces an import of a file that is not there.
|
|
10
|
+
*
|
|
11
|
+
* The depth is the same from the source tree and from the compiled one
|
|
12
|
+
* (`client/three/` and `dist/three/` are siblings), so one literal is correct in
|
|
13
|
+
* both — and literal is load-bearing, because a bundler can only follow this
|
|
14
|
+
* pattern when it can read the path without running anything.
|
|
15
|
+
*
|
|
16
|
+
* **One module per character is the whole point, and it is a bundling fact, not
|
|
17
|
+
* tidiness.** A bundler that can follow `new URL` emits the file it names, and
|
|
18
|
+
* it decides what to emit per *module*: three literals in one object meant a
|
|
19
|
+
* consumer who imported one character shipped all three GLBs — ~1.3 MB of a
|
|
20
|
+
* character they never mount, in every build we checked. Splitting them is what
|
|
21
|
+
* makes `@voqalize/avatar/avatars/tara` cost tara. Nothing that a character
|
|
22
|
+
* module loads may reach for another character's URL, which is also why the rig
|
|
23
|
+
* takes its `url` from its caller instead of defaulting to tara's.
|
|
24
|
+
*/
|
|
25
|
+
export const TARA_GLB = new URL("../../assets/tara.glb", import.meta.url).href;
|
|
26
|
+
//# sourceMappingURL=tara-asset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tara-asset.js","sourceRoot":"","sources":["../../client/three/tara-asset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC"}
|
package/dist/three/tara-rig.d.ts
CHANGED
|
@@ -49,10 +49,11 @@ import type { AvatarRig } from "../internal.js";
|
|
|
49
49
|
* shell, and a large turn is where that reads as a cardboard cutout rather than
|
|
50
50
|
* a head. **It opened from 9° to 15° on 2026-09-18.** The cutout was measured
|
|
51
51
|
* rather than assumed — a ladder rendered at 9/12/15/18/21/25/30 and read at
|
|
52
|
-
* crop on
|
|
53
|
-
* tushar. 9° was therefore set at half of where the artefact
|
|
54
|
-
* and the stiffness the owner reported on tanya's turns was
|
|
55
|
-
* her asset. 15° keeps 3° of headroom
|
|
52
|
+
* crop on the characters that existed then is clean to 21° on tara and to 18°
|
|
53
|
+
* on tanya and tushar. 9° was therefore set at half of where the artefact
|
|
54
|
+
* actually begins, and the stiffness the owner reported on tanya's turns was
|
|
55
|
+
* that margin, not her asset. 15° keeps 3° of headroom under the 18° the
|
|
56
|
+
* tightest of them read.
|
|
56
57
|
*
|
|
57
58
|
* This is not for speech: Busso wants ±1.15° of yaw in neutral conversation and
|
|
58
59
|
* always did. It is for a head that turns to *look* at something, which is what
|
|
@@ -334,14 +335,33 @@ export declare const TARA_TUNING: {
|
|
|
334
335
|
export interface TaraRigOptions {
|
|
335
336
|
/** Called once the GLB is in the scene, for a capture tool that must wait. */
|
|
336
337
|
readonly onReady?: () => void;
|
|
337
|
-
/** The character's GLB
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
|
|
338
|
+
/** The character's GLB. The second-character seam: every build fact the rig
|
|
339
|
+
* reads (jaw-shadow tile, rim depth, morph names) travels in the GLB's own
|
|
340
|
+
* extras, so a character built by the same scripts needs nothing else. Tara's
|
|
341
|
+
* tuning is still applied, which is the experiment.
|
|
342
|
+
*
|
|
343
|
+
* Required, and it used to default to tara's. A default meant this module
|
|
344
|
+
* imported one character's URL, and a bundler emits assets per module — so
|
|
345
|
+
* every consumer of *any* character shipped tara's GLB whether or not they
|
|
346
|
+
* mounted her. The caller knows which character it is building; this file
|
|
347
|
+
* must not ([tara-asset.ts](./tara-asset.ts)). */
|
|
348
|
+
readonly url: string;
|
|
342
349
|
/** `false` leaves an asset's expression maps unread, for a capture tool
|
|
343
350
|
* comparing the face with and without them. */
|
|
344
351
|
readonly expression?: boolean;
|
|
352
|
+
/** Keeps the drawing buffer readable after the browser has composited it, so
|
|
353
|
+
* a caller can copy the canvas out at any moment rather than only from
|
|
354
|
+
* inside the frame that drew it.
|
|
355
|
+
*
|
|
356
|
+
* A pose sheet needs this and a consumer must not have it. WebGL contexts are
|
|
357
|
+
* a handful per page, so a sheet of thirty poses cannot be thirty canvases —
|
|
358
|
+
* it holds one pose still, copies the canvas into a tile, and moves on. Copy
|
|
359
|
+
* outside the drawing frame and the buffer has already been cleared, which is
|
|
360
|
+
* a blank tile and not an error. The cost is that the buffer cannot be
|
|
361
|
+
* discarded, which on some drivers means a second copy of every frame; the
|
|
362
|
+
* consumer renders thirty frames a second forever and pays nothing for a
|
|
363
|
+
* readback it never performs. */
|
|
364
|
+
readonly readback?: boolean;
|
|
345
365
|
}
|
|
346
366
|
/**
|
|
347
367
|
* The hair's roll, which is the one thing in this rig that is not a function of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tara-rig.d.ts","sourceRoot":"","sources":["../../client/three/tara-rig.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAe,SAAS,EAAW,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"tara-rig.d.ts","sourceRoot":"","sources":["../../client/three/tara-rig.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAe,SAAS,EAAW,MAAM,gBAAgB,CAAC;AAkBtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAKH,eAAO,MAAM,UAAU,MAAM,CAAC;AAC9B,eAAO,MAAM,QAAQ;;;;CAAkC,CAAC;AAyIxD;;;;;;qDAMqD;AACrD,eAAO,MAAM,OAAO;;;CAA2G,CAAC;AAGhI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiJd,CAAC;AA8bX,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;;;uDASmD;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;oDACgD;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;;;sCAWkC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAsID;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS;;;;CAAyC,CAAC;AAEhE;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,EAAE,IAAI,MAAM;;;CAInF,CAAC;AAkCF,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAga9E"}
|
package/dist/three/tara-rig.js
CHANGED
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
import { REST } from "../internal.js";
|
|
29
29
|
import * as THREE from "three";
|
|
30
30
|
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
|
|
31
|
-
import { ASSETS } from "./assets.js";
|
|
32
31
|
import { HARD_BUDGET, pixelRatioFor } from "./budgets.js";
|
|
33
32
|
/**
|
|
34
33
|
* The camera, from `scripts/render_frame.py`. It is orthographic and that is
|
|
@@ -65,10 +64,11 @@ const FRAME_CENTRE = (FRAME.top + FRAME.bottom) / 2;
|
|
|
65
64
|
* shell, and a large turn is where that reads as a cardboard cutout rather than
|
|
66
65
|
* a head. **It opened from 9° to 15° on 2026-09-18.** The cutout was measured
|
|
67
66
|
* rather than assumed — a ladder rendered at 9/12/15/18/21/25/30 and read at
|
|
68
|
-
* crop on
|
|
69
|
-
* tushar. 9° was therefore set at half of where the artefact
|
|
70
|
-
* and the stiffness the owner reported on tanya's turns was
|
|
71
|
-
* her asset. 15° keeps 3° of headroom
|
|
67
|
+
* crop on the characters that existed then is clean to 21° on tara and to 18°
|
|
68
|
+
* on tanya and tushar. 9° was therefore set at half of where the artefact
|
|
69
|
+
* actually begins, and the stiffness the owner reported on tanya's turns was
|
|
70
|
+
* that margin, not her asset. 15° keeps 3° of headroom under the 18° the
|
|
71
|
+
* tightest of them read.
|
|
72
72
|
*
|
|
73
73
|
* This is not for speech: Busso wants ±1.15° of yaw in neutral conversation and
|
|
74
74
|
* always did. It is for a head that turns to *look* at something, which is what
|
|
@@ -873,9 +873,9 @@ const radians = (deg) => (deg * Math.PI) / 180;
|
|
|
873
873
|
* Three.js throws out of the constructor rather than returning anything, and it
|
|
874
874
|
* has already written its own line to the console by then; that line is kept
|
|
875
875
|
* because it names the underlying reason, which this one does not. */
|
|
876
|
-
function webglRenderer() {
|
|
876
|
+
function webglRenderer(readback = false) {
|
|
877
877
|
try {
|
|
878
|
-
return new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
|
878
|
+
return new THREE.WebGLRenderer({ antialias: true, alpha: true, preserveDrawingBuffer: readback });
|
|
879
879
|
}
|
|
880
880
|
catch {
|
|
881
881
|
return null;
|
|
@@ -1081,12 +1081,17 @@ const expressionWeights = (pose, side, expression, into) => {
|
|
|
1081
1081
|
// `options` is `unknown` in the contract, and stays `unknown` here: the mixer
|
|
1082
1082
|
// passes `rigOptions` through verbatim and has no way to know any rig's shape.
|
|
1083
1083
|
export function createTaraRig(mount, options) {
|
|
1084
|
-
const { onReady, url
|
|
1084
|
+
const { onReady, url, expression: readExpression = true, readback = false } = (options ?? {});
|
|
1085
|
+
// A missing `url` is a caller's defect, not a browser condition — the WebGL
|
|
1086
|
+
// path below degrades because a driver is nobody's fault, whereas this would
|
|
1087
|
+
// otherwise be a 404 on a path spelled `undefined`.
|
|
1088
|
+
if (!url)
|
|
1089
|
+
throw new TypeError("createTaraRig: `url` is required");
|
|
1085
1090
|
const scene = new THREE.Scene();
|
|
1086
1091
|
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 100);
|
|
1087
1092
|
camera.position.set(0, FRAME_CENTRE, 6);
|
|
1088
1093
|
camera.lookAt(0, FRAME_CENTRE, 0);
|
|
1089
|
-
const renderer = webglRenderer();
|
|
1094
|
+
const renderer = webglRenderer(readback);
|
|
1090
1095
|
// No context, no face — and that has to be the whole of it. `createAvatar` is
|
|
1091
1096
|
// synchronous and returns `{ destroy }`, so a consumer has nothing to catch:
|
|
1092
1097
|
// anything thrown here lands in *their* window and takes the call page with
|