@voqalize/avatar 0.4.4 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +65 -154
  2. package/dist/index.d.ts +37 -26
  3. package/dist/index.js +48 -25
  4. package/dist/pin.d.ts +2 -0
  5. package/dist/pin.js +3 -0
  6. package/dist/react.d.ts +21 -6
  7. package/dist/react.js +24 -6
  8. package/package.json +8 -67
  9. package/LICENSE-APACHE-2.0 +0 -201
  10. package/LICENSE-CC-BY-4.0 +0 -396
  11. package/assets/README.md +0 -60
  12. package/assets/tanvi.glb +0 -0
  13. package/assets/tanya.glb +0 -0
  14. package/assets/tara.glb +0 -0
  15. package/assets/tess.glb +0 -0
  16. package/assets/tushar.glb +0 -0
  17. package/client/Avatar.tsx +0 -57
  18. package/client/AvatarClient.ts +0 -818
  19. package/client/createAvatar.ts +0 -177
  20. package/client/index.ts +0 -44
  21. package/client/internal.ts +0 -132
  22. package/client/playout.ts +0 -95
  23. package/client/react.ts +0 -13
  24. package/client/supports.ts +0 -27
  25. package/client/three/assets.ts +0 -26
  26. package/client/three/budgets.ts +0 -27
  27. package/client/three/character-rig.ts +0 -1746
  28. package/client/three/createCharacter.ts +0 -109
  29. package/client/three/holds.ts +0 -69
  30. package/client/three/internal.ts +0 -55
  31. package/client/three/motion-limits.json +0 -124
  32. package/client/three/sequences.ts +0 -281
  33. package/client/three/tanvi-asset.ts +0 -6
  34. package/client/three/tanvi.ts +0 -30
  35. package/client/three/tanya-asset.ts +0 -6
  36. package/client/three/tanya.ts +0 -29
  37. package/client/three/tara-asset.ts +0 -25
  38. package/client/three/tara.ts +0 -36
  39. package/client/three/tess-asset.ts +0 -6
  40. package/client/three/tess.ts +0 -30
  41. package/client/three/tushar-asset.ts +0 -6
  42. package/client/three/tushar.ts +0 -28
  43. package/client/types.ts +0 -235
  44. package/client/useAvatar.ts +0 -74
  45. package/dist/Avatar.d.ts +0 -44
  46. package/dist/Avatar.d.ts.map +0 -1
  47. package/dist/Avatar.js +0 -7
  48. package/dist/Avatar.js.map +0 -1
  49. package/dist/AvatarClient.d.ts +0 -274
  50. package/dist/AvatarClient.d.ts.map +0 -1
  51. package/dist/AvatarClient.js +0 -712
  52. package/dist/AvatarClient.js.map +0 -1
  53. package/dist/createAvatar.d.ts +0 -135
  54. package/dist/createAvatar.d.ts.map +0 -1
  55. package/dist/createAvatar.js +0 -75
  56. package/dist/createAvatar.js.map +0 -1
  57. package/dist/index.d.ts.map +0 -1
  58. package/dist/index.js.map +0 -1
  59. package/dist/internal.d.ts +0 -34
  60. package/dist/internal.d.ts.map +0 -1
  61. package/dist/internal.js +0 -56
  62. package/dist/internal.js.map +0 -1
  63. package/dist/playout.d.ts +0 -42
  64. package/dist/playout.d.ts.map +0 -1
  65. package/dist/playout.js +0 -85
  66. package/dist/playout.js.map +0 -1
  67. package/dist/react.d.ts.map +0 -1
  68. package/dist/react.js.map +0 -1
  69. package/dist/supports.d.ts +0 -19
  70. package/dist/supports.d.ts.map +0 -1
  71. package/dist/supports.js +0 -25
  72. package/dist/supports.js.map +0 -1
  73. package/dist/three/assets.d.ts +0 -10
  74. package/dist/three/assets.d.ts.map +0 -1
  75. package/dist/three/assets.js +0 -23
  76. package/dist/three/assets.js.map +0 -1
  77. package/dist/three/budgets.d.ts +0 -17
  78. package/dist/three/budgets.d.ts.map +0 -1
  79. package/dist/three/budgets.js +0 -21
  80. package/dist/three/budgets.js.map +0 -1
  81. package/dist/three/character-rig.d.ts +0 -366
  82. package/dist/three/character-rig.d.ts.map +0 -1
  83. package/dist/three/character-rig.js +0 -1644
  84. package/dist/three/character-rig.js.map +0 -1
  85. package/dist/three/createCharacter.d.ts +0 -60
  86. package/dist/three/createCharacter.d.ts.map +0 -1
  87. package/dist/three/createCharacter.js +0 -84
  88. package/dist/three/createCharacter.js.map +0 -1
  89. package/dist/three/holds.d.ts +0 -38
  90. package/dist/three/holds.d.ts.map +0 -1
  91. package/dist/three/holds.js +0 -61
  92. package/dist/three/holds.js.map +0 -1
  93. package/dist/three/internal.d.ts +0 -52
  94. package/dist/three/internal.d.ts.map +0 -1
  95. package/dist/three/internal.js +0 -49
  96. package/dist/three/internal.js.map +0 -1
  97. package/dist/three/motion-limits.json +0 -124
  98. package/dist/three/sequences.d.ts +0 -71
  99. package/dist/three/sequences.d.ts.map +0 -1
  100. package/dist/three/sequences.js +0 -262
  101. package/dist/three/sequences.js.map +0 -1
  102. package/dist/three/tanvi-asset.d.ts +0 -7
  103. package/dist/three/tanvi-asset.d.ts.map +0 -1
  104. package/dist/three/tanvi-asset.js +0 -7
  105. package/dist/three/tanvi-asset.js.map +0 -1
  106. package/dist/three/tanvi.d.ts +0 -24
  107. package/dist/three/tanvi.d.ts.map +0 -1
  108. package/dist/three/tanvi.js +0 -24
  109. package/dist/three/tanvi.js.map +0 -1
  110. package/dist/three/tanya-asset.d.ts +0 -7
  111. package/dist/three/tanya-asset.d.ts.map +0 -1
  112. package/dist/three/tanya-asset.js +0 -7
  113. package/dist/three/tanya-asset.js.map +0 -1
  114. package/dist/three/tanya.d.ts +0 -23
  115. package/dist/three/tanya.d.ts.map +0 -1
  116. package/dist/three/tanya.js +0 -23
  117. package/dist/three/tanya.js.map +0 -1
  118. package/dist/three/tara-asset.d.ts +0 -26
  119. package/dist/three/tara-asset.d.ts.map +0 -1
  120. package/dist/three/tara-asset.js +0 -26
  121. package/dist/three/tara-asset.js.map +0 -1
  122. package/dist/three/tara.d.ts +0 -30
  123. package/dist/three/tara.d.ts.map +0 -1
  124. package/dist/three/tara.js +0 -30
  125. package/dist/three/tara.js.map +0 -1
  126. package/dist/three/tess-asset.d.ts +0 -7
  127. package/dist/three/tess-asset.d.ts.map +0 -1
  128. package/dist/three/tess-asset.js +0 -7
  129. package/dist/three/tess-asset.js.map +0 -1
  130. package/dist/three/tess.d.ts +0 -24
  131. package/dist/three/tess.d.ts.map +0 -1
  132. package/dist/three/tess.js +0 -24
  133. package/dist/three/tess.js.map +0 -1
  134. package/dist/three/tushar-asset.d.ts +0 -7
  135. package/dist/three/tushar-asset.d.ts.map +0 -1
  136. package/dist/three/tushar-asset.js +0 -7
  137. package/dist/three/tushar-asset.js.map +0 -1
  138. package/dist/three/tushar.d.ts +0 -22
  139. package/dist/three/tushar.d.ts.map +0 -1
  140. package/dist/three/tushar.js +0 -22
  141. package/dist/three/tushar.js.map +0 -1
  142. package/dist/types.d.ts +0 -149
  143. package/dist/types.d.ts.map +0 -1
  144. package/dist/types.js +0 -140
  145. package/dist/types.js.map +0 -1
  146. package/dist/useAvatar.d.ts +0 -39
  147. package/dist/useAvatar.d.ts.map +0 -1
  148. package/dist/useAvatar.js +0 -35
  149. package/dist/useAvatar.js.map +0 -1
  150. package/src/avatar.d.ts +0 -436
  151. package/src/avatar.js +0 -1378
  152. package/src/behavior.d.ts +0 -42
  153. package/src/behavior.js +0 -114
  154. package/src/camera.js +0 -29
  155. package/src/clips.js +0 -155
  156. package/src/conformance.js +0 -119
  157. package/src/emotions.js +0 -58
  158. package/src/face-core.js +0 -180
  159. package/src/face-myna.d.ts +0 -7
  160. package/src/face-myna.js +0 -786
  161. package/src/face-peep-control-plane.js +0 -167
  162. package/src/face-peep.d.ts +0 -7
  163. package/src/face-peep.js +0 -925
  164. package/src/face-wren.d.ts +0 -7
  165. package/src/face-wren.js +0 -468
  166. package/src/faces.d.ts +0 -12
  167. package/src/faces.js +0 -53
  168. package/src/gaze.js +0 -504
  169. package/src/hand.js +0 -709
  170. package/src/head.js +0 -134
  171. package/src/idle.js +0 -668
  172. package/src/interjections.js +0 -747
  173. package/src/line-art.js +0 -137
  174. package/src/params.js +0 -180
  175. package/src/perform.js +0 -107
  176. package/src/prosody.js +0 -741
  177. package/src/rig.d.ts +0 -31
  178. package/src/rig.js +0 -32
  179. package/src/speech-timing.js +0 -51
  180. package/src/visemes.js +0 -410
package/src/face-core.js DELETED
@@ -1,180 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // face-core — the part of a face module that is not the face.
3
- //
4
- // Three avatars were built independently before this module existed, and their
5
- // renderers converged on the same shape: an element table, a memoized attribute
6
- // writer, and an apply() that runs torso lean → shoulders → parallax → eyes →
7
- // brows → mouth → teeth → tongue. The geometry differs per character; the
8
- // plumbing and the pose mechanics do not. This module absorbs the proven-
9
- // identical parts, so a face module supplies art and feature geometry and gets
10
- // the body mechanics for free.
11
- //
12
- // What lives here is exactly what those faces shared line-for-line, or differed
13
- // in only by a named scalar. Anything a character has an opinion about — what
14
- // an eye is, how a mouth is drawn — stays in the face module. Two of the three
15
- // have since been retired; what they proved about the seam is why this file
16
- // looks the way it does, and helpers only they used went with them.
17
- // ---------------------------------------------------------------------------
18
-
19
- import { clamp } from './params.js';
20
-
21
- /** Attribute-value number formatter: 2 decimal places, no trailing zeros. */
22
- export const f = (n) => (Math.round(n * 100) / 100).toString();
23
-
24
- // Constants every rig agreed on. Named here so a new avatar inherits the
25
- // agreement instead of re-deriving it.
26
- export const LEAN_SCALE = 0.055; // scale gain at torsoLean = 1
27
- export const ROLL_TORSO = 1.5; // degrees of roll the torso follows…
28
- export const ROLL_HEAD = 5.5; // …versus what the head itself takes.
29
-
30
- /**
31
- * Mount the static markup and return the per-instance tools: the svg root, an
32
- * id-scoped selector for building the element table, and the memoized `set`.
33
- * SVG attribute setting is the hot path; `set` skips redundant DOM writes.
34
- */
35
- export function createFaceShell(mount, id, markupHtml) {
36
- mount.innerHTML = markupHtml;
37
- const svg = mount.querySelector(`#${id}`);
38
- const $ = (n) => svg.querySelector(`#${id}-${n}`);
39
- const prev = new Map();
40
- const set = (node, attr, val) => {
41
- const k = node.id + attr;
42
- if (prev.get(k) === val) return;
43
- prev.set(k, val);
44
- node.setAttribute(attr, val);
45
- };
46
- return { svg, $, set };
47
- }
48
-
49
- /** The one return shape every face honours: { svg, apply, theme, destroy }. */
50
- export function faceApi(mount, svg, apply, theme) {
51
- return { svg, apply, theme, destroy: () => { mount.innerHTML = ''; } };
52
- }
53
-
54
- /**
55
- * Blocks A–C of every apply(): torso lean, shoulders, and the layer parallax
56
- * loop. `spec` is a module-level constant in the face module:
57
- *
58
- * leanTravel px of downward travel at torsoLean = 1
59
- * leanPivot {x, y} the scale pivot — behind the head, not the frame base:
60
- * scaling about the bottom makes the head rise as it grows,
61
- * which reads as standing up instead of leaning in
62
- * shrugLift px of shoulder lift at shrug = 1
63
- * shrugTiltDeg degrees of one-sided-shrug rotation at tilt = 1 — a per-rig
64
- * judgement about how much the collar can cover, not taste
65
- * shrugPivot {x, y} the sternum
66
- * yawPx px of head travel at headYaw = 1
67
- * pitchPx px at headPitch = 1
68
- * pitch optional corrective-pose contract for rigs that can nod:
69
- * `{ headLayers, neckLayer, hinge, headTravel, neckTravel,
70
- * foreshorten, neckCompress, neckBase }`.
71
- * `headLayers` must be separate SVG groups for the skull and
72
- * its attached surface layers; `neckLayer` must be behind it.
73
- * This is intentionally a small group-level contract, not a
74
- * second set of authored paths per expression.
75
- * pivot {x, y} roll pivot — the base of the neck, not the chin:
76
- * rotating about the chin swings the whole cranium sideways
77
- * and reads as a puppet on a stick
78
- * breathSwell fractional scale of the torso layers at breath = 1, about
79
- * `swellPivot`. Required. It replaced a rigid vertical bob of
80
- * the whole shirt, which moved the hem — and the hem is the one
81
- * part of a seated torso that does not move, so the result read
82
- * as the figure being nudged up and down rather than as breath.
83
- * A scale about the hem raises the shoulder line and widens the
84
- * chest, which is what an inbreath does and is the only breath
85
- * cue a head-and-shoulders crop can actually show.
86
- * swellPivot {x, y} the hem — bottom of the frame, on the midline
87
- * turnPx px of lateral trunk travel at torsoTurn = 1 (0 if the rig
88
- * does not declare it)
89
- * layers draw-order list of layer names in the element table
90
- * parallax {layer: multiplier} — follows the art, not a standard
91
- * torsoLayers the subset of `layers` that moves at torso speed
92
- * units the rig's linear scale factor relative to the numbers above
93
- * (1 where travels are already in the rig's own units). Kept as
94
- * a separate factor, applied last, so a rig built by scaling
95
- * another's numbers states that lineage — and so evaluation
96
- * order matches code that wrote `travel * 9 * S` longhand.
97
- * Degrees never take it: degrees are degrees at any scale.
98
- *
99
- * In a webcam frame a lean is read almost entirely as a change of scale, so
100
- * that is how it is drawn.
101
- */
102
- export function poseTransforms(p, set, el, spec) {
103
- const u = spec.units;
104
- const lean = p.torsoLean;
105
- const leanT = lean
106
- ? `translate(0 ${f(lean * spec.leanTravel * u)}) `
107
- + `translate(${f(spec.leanPivot.x)} ${f(spec.leanPivot.y)}) `
108
- + `scale(${f(1 + lean * LEAN_SCALE)}) `
109
- + `translate(${f(-spec.leanPivot.x)} ${f(-spec.leanPivot.y)}) `
110
- : '';
111
-
112
- // One shoulder cannot rise without the other when the shirt is a single
113
- // path. A small rotation about the sternum is what a one-sided shrug looks
114
- // like anyway, and it needs no new geometry.
115
- const shrug = (p.shoulderL + p.shoulderR) * 0.5;
116
- const tilt = (p.shoulderR - p.shoulderL) * 0.5;
117
-
118
- // Breath as chest expansion. The swell scales the torso layers about the
119
- // hem, so the shoulder line rises and the chest widens while the bottom of
120
- // the shirt stays put. The head then has to ride whatever the shoulders did
121
- // or the neck telescopes — and that lift is not a tuned constant, it is
122
- // arithmetic: the swell's vertical displacement at the neck pivot. One
123
- // number to author, and the two layers cannot drift out of agreement.
124
- const swell = spec.breathSwell ? p.breath * spec.breathSwell : 0;
125
- const neckLift = swell ? swell * (spec.swellPivot.y - spec.pivot.y) : 0;
126
- const swellT = swell
127
- ? `translate(${f(spec.swellPivot.x)} ${f(spec.swellPivot.y)}) `
128
- + `scale(${f(1 + swell)}) `
129
- + `translate(${f(-spec.swellPivot.x)} ${f(-spec.swellPivot.y)}) `
130
- : '';
131
-
132
- const torsoT = `translate(${f(p.torsoTurn * (spec.turnPx || 0) * u)} ${f(-shrug * spec.shrugLift * u)}) `
133
- + `rotate(${f(-tilt * spec.shrugTiltDeg)} ${f(spec.shrugPivot.x)} ${f(spec.shrugPivot.y)}) `
134
- + swellT;
135
-
136
- const yx = p.headYaw * spec.yawPx;
137
- const py = p.headPitch * spec.pitchPx;
138
- const pitch = spec.pitch;
139
- for (const key of spec.layers) {
140
- const k = spec.parallax[key];
141
- const torso = spec.torsoLayers.includes(key);
142
- const roll = torso ? p.headRoll * ROLL_TORSO : p.headRoll * ROLL_HEAD;
143
- const isPitchHead = !!pitch && pitch.headLayers.includes(key);
144
- const isPitchNeck = !!pitch && pitch.neckLayer === key;
145
- // A pitch-capable rig makes its skull, features and hair move together:
146
- // their old parallax values still apply to yaw, but not to the vertical
147
- // nod. That coherence is the point of separating them from the neck.
148
- const pitchTravel = isPitchHead ? pitch.headTravel
149
- : isPitchNeck ? pitch.neckTravel : k;
150
- const pitchScale = isPitchHead
151
- ? 1 - Math.max(0, p.headPitch) * pitch.foreshorten : 1;
152
- const neckScale = isPitchNeck
153
- ? 1 - Math.max(0, p.headPitch) * pitch.neckCompress : 1;
154
- const pitchT = pitchScale !== 1
155
- ? `translate(${f(pitch.hinge.x)} ${f(pitch.hinge.y)}) scale(1 ${f(pitchScale)}) translate(${f(-pitch.hinge.x)} ${f(-pitch.hinge.y)}) `
156
- : '';
157
- const neckT = neckScale !== 1
158
- ? `translate(${f(pitch.neckBase.x)} ${f(pitch.neckBase.y)}) scale(1 ${f(neckScale)}) translate(${f(-pitch.neckBase.x)} ${f(-pitch.neckBase.y)}) `
159
- : '';
160
- // Torso layers get their breath from the swell inside torsoT; head layers
161
- // get the matching lift, which is derived from the swell rather than tuned
162
- // separately — the neck rides on the chest it sits on.
163
- const bob = torso ? 0 : -neckLift;
164
- set(el[key], 'transform',
165
- leanT + (torso ? torsoT : '')
166
- + pitchT + neckT
167
- + `translate(${f(yx * k)} ${f(py * pitchTravel + bob)}) rotate(${f(roll)} ${f(spec.pivot.x)} ${f(spec.pivot.y)})`);
168
- }
169
- }
170
-
171
- /**
172
- * Upper-and-lower teeth pair (peep, wren). Lower teeth appear only once
173
- * the mouth is genuinely open: below that the lower lip is over them and
174
- * drawing them turns every mid-open viseme into a grin; above it, their
175
- * absence is what made viseme D read as a cave.
176
- */
177
- export function pairedTeeth(p, set, el, teethPath, m) {
178
- set(el.teeth, 'd', teethPath(m, clamp(p.teethUpper), false));
179
- set(el.teethLo, 'd', teethPath(m, clamp(p.teethUpper) * clamp((m.open - 0.45) / 0.4), true));
180
- }
@@ -1,7 +0,0 @@
1
- import type { AvatarMeta, Face, FaceFactory } from "./avatar.js";
2
-
3
- export const createFace: FaceFactory;
4
- export const META: AvatarMeta;
5
- /** Default palette. Passed as `createAvatar({ theme })`; see authoring-a-face.md. */
6
- export const THEME: Readonly<Record<string, string>>;
7
- export const myna: Face;