@vizij/runtime-react 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +422 -117
- package/dist/index.cjs +3642 -352
- package/dist/index.d.cts +204 -14
- package/dist/index.d.ts +204 -14
- package/dist/index.js +3628 -365
- package/package.json +26 -22
- package/LICENSE +0 -201
package/dist/index.d.cts
CHANGED
|
@@ -1,27 +1,69 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode, PropsWithChildren } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { ValueJSON } from '@vizij/value-json';
|
|
5
5
|
import { IrGraph } from '@vizij/node-graph-authoring';
|
|
6
|
-
import {
|
|
6
|
+
import { RawValue, AnimatableValue } from '@vizij/utils';
|
|
7
7
|
import { World, VizijBundleExtension, VizijProps } from '@vizij/render';
|
|
8
8
|
|
|
9
|
+
/** Value shape hint. Accepted through the public surface, unused by the device. */
|
|
10
|
+
type ShapeJSON = Record<string, unknown>;
|
|
11
|
+
/** Paths a graph reads/writes — metadata for output tracking and seeding. */
|
|
12
|
+
type GraphSubscriptions = {
|
|
13
|
+
inputs?: string[];
|
|
14
|
+
outputs?: string[];
|
|
15
|
+
};
|
|
16
|
+
/** A Vizij graph spec handled structurally (nodes/edges arrays of records). */
|
|
17
|
+
type GraphSpecLike = {
|
|
18
|
+
nodes?: Array<Record<string, unknown>>;
|
|
19
|
+
edges?: Array<Record<string, unknown>>;
|
|
20
|
+
metadata?: unknown;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
};
|
|
23
|
+
/** One graph source composed into the device's behavior. */
|
|
24
|
+
type GraphRegistrationConfig = {
|
|
25
|
+
id?: string;
|
|
26
|
+
spec: GraphSpecLike;
|
|
27
|
+
subs?: GraphSubscriptions;
|
|
28
|
+
};
|
|
29
|
+
/** Per-source merge options. Composition is last-writer-wins today (VIZ-53). */
|
|
30
|
+
type MergeStrategyOptions = Record<string, unknown>;
|
|
31
|
+
/** Player/instance setup carried by animation assets; consumed by the JS clip pipeline. */
|
|
32
|
+
type AnimationSetup = {
|
|
33
|
+
animation?: unknown;
|
|
34
|
+
player?: Record<string, unknown>;
|
|
35
|
+
instance?: Record<string, unknown>;
|
|
36
|
+
};
|
|
9
37
|
type PoseDefinition = {
|
|
10
38
|
id: string;
|
|
11
39
|
name?: string;
|
|
12
40
|
description?: string;
|
|
13
41
|
group?: string | null;
|
|
42
|
+
groupId?: string | null;
|
|
43
|
+
groupIds?: string[];
|
|
14
44
|
values: Record<string, number | undefined>;
|
|
15
45
|
};
|
|
46
|
+
type PoseBlendMode = "average" | "additive";
|
|
47
|
+
type PoseGroupDefinition = {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
path: string;
|
|
51
|
+
blendMode?: PoseBlendMode;
|
|
52
|
+
};
|
|
16
53
|
type PoseRigConfig = {
|
|
17
54
|
version: number;
|
|
18
55
|
faceId?: string | null;
|
|
19
56
|
title?: string;
|
|
20
57
|
description?: string;
|
|
58
|
+
poseGroups?: PoseGroupDefinition[];
|
|
59
|
+
crossGroupBlendMode?: PoseBlendMode;
|
|
21
60
|
neutralInputs: Record<string, number>;
|
|
22
61
|
poses: PoseDefinition[];
|
|
23
|
-
metadata?: Record<string, unknown
|
|
24
|
-
|
|
62
|
+
metadata?: Record<string, unknown> | {
|
|
63
|
+
createdAt: string;
|
|
64
|
+
updatedAt: string;
|
|
65
|
+
author?: string;
|
|
66
|
+
};
|
|
25
67
|
};
|
|
26
68
|
type RootBounds = {
|
|
27
69
|
center: {
|
|
@@ -45,8 +87,8 @@ type VizijGlbAsset = {
|
|
|
45
87
|
rootBounds?: RootBounds;
|
|
46
88
|
} | {
|
|
47
89
|
kind: "world";
|
|
48
|
-
world: World
|
|
49
|
-
animatables: Record<string, AnimatableValue>;
|
|
90
|
+
world: World | Record<string, unknown>;
|
|
91
|
+
animatables: Record<string, AnimatableValue> | Record<string, unknown>;
|
|
50
92
|
bundle?: VizijBundleExtension | null;
|
|
51
93
|
};
|
|
52
94
|
type VizijGraphAsset = {
|
|
@@ -72,10 +114,15 @@ type VizijInputMetadata = {
|
|
|
72
114
|
type AnimationKeyframeLike = {
|
|
73
115
|
time?: number;
|
|
74
116
|
value?: number;
|
|
117
|
+
inTangent?: number | null;
|
|
118
|
+
outTangent?: number | null;
|
|
119
|
+
[key: string]: unknown;
|
|
75
120
|
};
|
|
76
121
|
type AnimationTrackLike = {
|
|
77
122
|
channel: string;
|
|
78
123
|
keyframes?: AnimationKeyframeLike[];
|
|
124
|
+
interpolation?: "linear" | "step" | "cubic" | string;
|
|
125
|
+
[key: string]: unknown;
|
|
79
126
|
};
|
|
80
127
|
type AnimationClipLike = {
|
|
81
128
|
id?: string;
|
|
@@ -90,6 +137,13 @@ type VizijAnimationAsset = {
|
|
|
90
137
|
setup?: Partial<AnimationSetup>;
|
|
91
138
|
weight?: number;
|
|
92
139
|
};
|
|
140
|
+
type VizijProgramAsset = {
|
|
141
|
+
id: string;
|
|
142
|
+
label?: string;
|
|
143
|
+
graph: VizijGraphAsset;
|
|
144
|
+
resetValues?: Record<string, number>;
|
|
145
|
+
metadata?: Record<string, unknown>;
|
|
146
|
+
};
|
|
93
147
|
type VizijAssetBundle = {
|
|
94
148
|
namespace?: string;
|
|
95
149
|
faceId?: string;
|
|
@@ -101,6 +155,7 @@ type VizijAssetBundle = {
|
|
|
101
155
|
stageNeutralFilter?: (id: string, path: string) => boolean;
|
|
102
156
|
};
|
|
103
157
|
animations?: VizijAnimationAsset[];
|
|
158
|
+
programs?: VizijProgramAsset[];
|
|
104
159
|
initialInputs?: Record<string, ValueJSON>;
|
|
105
160
|
metadata?: Record<string, unknown>;
|
|
106
161
|
bundle?: VizijBundleExtension | null;
|
|
@@ -108,7 +163,7 @@ type VizijAssetBundle = {
|
|
|
108
163
|
type RuntimeError = {
|
|
109
164
|
message: string;
|
|
110
165
|
cause?: unknown;
|
|
111
|
-
phase?: "assets" | "
|
|
166
|
+
phase?: "assets" | "engine" | "registration" | "animation" | "bridge" | "driver" | "unknown";
|
|
112
167
|
timestamp: number;
|
|
113
168
|
};
|
|
114
169
|
type VizijRuntimeStatus = {
|
|
@@ -139,6 +194,22 @@ type PlayAnimationOptions = {
|
|
|
139
194
|
speed?: number;
|
|
140
195
|
reset?: boolean;
|
|
141
196
|
};
|
|
197
|
+
type StopAnimationOptions = {
|
|
198
|
+
clearOutputs?: boolean;
|
|
199
|
+
};
|
|
200
|
+
type AnimationPlaybackState = {
|
|
201
|
+
time: number;
|
|
202
|
+
duration: number;
|
|
203
|
+
playing: boolean;
|
|
204
|
+
loop: boolean;
|
|
205
|
+
speed: number;
|
|
206
|
+
};
|
|
207
|
+
type StopProgramOptions = {
|
|
208
|
+
resetOutputs?: boolean;
|
|
209
|
+
};
|
|
210
|
+
type ProgramPlaybackState = {
|
|
211
|
+
state: "playing" | "paused" | "stopped";
|
|
212
|
+
};
|
|
142
213
|
type InputDriverLifecycle = {
|
|
143
214
|
start: () => void;
|
|
144
215
|
stop: () => void;
|
|
@@ -151,23 +222,64 @@ type InputDriverContext = {
|
|
|
151
222
|
faceId?: string;
|
|
152
223
|
};
|
|
153
224
|
type InputDriverFactory = (ctx: InputDriverContext) => InputDriverLifecycle;
|
|
225
|
+
type RuntimeOutputWrite = {
|
|
226
|
+
id: string;
|
|
227
|
+
namespace: string;
|
|
228
|
+
value: RawValue;
|
|
229
|
+
currentValue?: RawValue;
|
|
230
|
+
};
|
|
154
231
|
type VizijRuntimeFaceProps = Omit<VizijProps, "rootId" | "namespace"> & {
|
|
155
232
|
namespaceOverride?: string;
|
|
156
233
|
};
|
|
157
234
|
type VizijRuntimeContextValue = VizijRuntimeStatus & {
|
|
158
235
|
assetBundle: VizijAssetBundle;
|
|
159
236
|
setInput: (path: string, value: ValueJSON, shape?: ShapeJSON) => void;
|
|
237
|
+
/** Current engine-store value of a path (read-your-own-write included). */
|
|
238
|
+
getValueSnapshot: (path: string) => ValueJSON | undefined;
|
|
239
|
+
/**
|
|
240
|
+
* A snapshot of EVERY key currently in the device store, as path → Value in
|
|
241
|
+
* arora's serde JSON shape (pass-through from the device; not `ValueJSON`).
|
|
242
|
+
* `undefined` until the device exists. For mirrors/bridges that forward the
|
|
243
|
+
* whole store (e.g. the standalone's native-store bridge), not for per-path
|
|
244
|
+
* sampling — use `getValueSnapshot` for that.
|
|
245
|
+
*/
|
|
246
|
+
getStoreSnapshot: () => Record<string, unknown> | undefined;
|
|
247
|
+
/**
|
|
248
|
+
* Notifies with each step's drained store changes (path → Value in arora's
|
|
249
|
+
* serde JSON shape; `null` for a cleared key). The change-driven counterpart
|
|
250
|
+
* to `getStoreSnapshot` for store bridges: seed from the snapshot, then stay
|
|
251
|
+
* current from these. Returns an unsubscribe function.
|
|
252
|
+
*/
|
|
253
|
+
subscribeToStoreChanges: (listener: (changes: Record<string, unknown>) => void) => () => void;
|
|
254
|
+
/**
|
|
255
|
+
* Notifies after each engine step, once the step's store changes have been
|
|
256
|
+
* applied. Pair with `getValueSnapshot` to sample values step-aligned.
|
|
257
|
+
* Returns an unsubscribe function.
|
|
258
|
+
*/
|
|
259
|
+
subscribeToStep: (listener: () => void) => () => void;
|
|
260
|
+
setGraphBundle: (bundle: RuntimeGraphBundle, options?: {
|
|
261
|
+
tier?: "auto" | "assets" | "graphs";
|
|
262
|
+
}) => void;
|
|
160
263
|
setValue: (id: string, namespace: string, value: RawValue | ((prev: RawValue | undefined) => RawValue | undefined)) => void;
|
|
161
264
|
stagePoseNeutral: (force?: boolean) => void;
|
|
162
265
|
animateValue: (path: string, target: ValueJSON, options?: AnimateValueOptions) => Promise<void>;
|
|
163
266
|
cancelAnimation: (path: string) => void;
|
|
164
267
|
registerInputDriver: (id: string, factory: InputDriverFactory) => InputDriverLifecycle;
|
|
165
268
|
playAnimation: (id: string, options?: PlayAnimationOptions) => Promise<void>;
|
|
166
|
-
|
|
269
|
+
pauseAnimation: (id: string) => void;
|
|
270
|
+
seekAnimation: (id: string, timeSeconds: number) => void;
|
|
271
|
+
setAnimationLoop: (id: string, enabled: boolean) => void;
|
|
272
|
+
getAnimationState: (id: string) => AnimationPlaybackState | null;
|
|
273
|
+
stopAnimation: (id: string, options?: StopAnimationOptions) => void;
|
|
274
|
+
playProgram: (id: string) => void;
|
|
275
|
+
pauseProgram: (id: string) => void;
|
|
276
|
+
stopProgram: (id: string, options?: StopProgramOptions) => void;
|
|
277
|
+
getProgramState: (id: string) => ProgramPlaybackState | null;
|
|
278
|
+
setAnimationActive: (active: boolean) => void;
|
|
279
|
+
isAnimationActive: () => boolean;
|
|
167
280
|
step: (dt: number, opts?: {
|
|
168
281
|
forceRuntime?: boolean;
|
|
169
282
|
}) => void;
|
|
170
|
-
advanceAnimations: (dt: number) => void;
|
|
171
283
|
inputConstraints: Record<string, {
|
|
172
284
|
min?: number;
|
|
173
285
|
max?: number;
|
|
@@ -179,29 +291,107 @@ type VizijRuntimeProviderProps = {
|
|
|
179
291
|
children: ReactNode;
|
|
180
292
|
namespace?: string;
|
|
181
293
|
faceId?: string;
|
|
294
|
+
updateTier?: RuntimeUpdateTier;
|
|
182
295
|
autoCreate?: boolean;
|
|
183
|
-
createOptions?: CreateOrchOptions;
|
|
184
296
|
autostart?: boolean;
|
|
185
|
-
|
|
297
|
+
/**
|
|
298
|
+
* Whether this provider's device paces itself: when true the device is
|
|
299
|
+
* handed to its own `run()` loop at boot and the provider only pumps its
|
|
300
|
+
* changes; when false the device advances solely on `step(dt,
|
|
301
|
+
* { forceRuntime: true })` calls from the host. A device handed to `run()`
|
|
302
|
+
* keeps its loop even if this later turns false.
|
|
303
|
+
*/
|
|
304
|
+
driveRuntime?: boolean;
|
|
186
305
|
mergeStrategy?: MergeStrategyOptions;
|
|
187
306
|
onRegisterControllers?: (ids: {
|
|
188
307
|
graphs: string[];
|
|
189
308
|
anims: string[];
|
|
190
309
|
}) => void;
|
|
191
310
|
onStatusChange?: (status: VizijRuntimeStatus) => void;
|
|
192
|
-
|
|
311
|
+
transformOutputWrite?: (write: RuntimeOutputWrite) => RuntimeOutputWrite | null;
|
|
312
|
+
};
|
|
313
|
+
type RuntimeUpdateTier = "auto" | "assets" | "graphs";
|
|
314
|
+
type RuntimeUpdatePlan = {
|
|
315
|
+
reloadAssets: boolean;
|
|
316
|
+
reregisterGraphs: boolean;
|
|
317
|
+
};
|
|
318
|
+
type RuntimeGraphBundle = {
|
|
319
|
+
rig?: VizijGraphAsset;
|
|
320
|
+
pose?: VizijAssetBundle["pose"];
|
|
321
|
+
animations?: VizijAnimationAsset[];
|
|
322
|
+
programs?: VizijProgramAsset[];
|
|
193
323
|
};
|
|
194
324
|
|
|
195
325
|
type ProviderProps = PropsWithChildren<VizijRuntimeProviderProps>;
|
|
196
|
-
declare function VizijRuntimeProvider({ assetBundle, children, namespace: namespaceProp, faceId: faceIdProp,
|
|
326
|
+
declare function VizijRuntimeProvider({ assetBundle, children, namespace: namespaceProp, faceId: faceIdProp, updateTier, autoCreate, autostart, driveRuntime, mergeStrategy, onRegisterControllers, onStatusChange, transformOutputWrite, }: ProviderProps): react_jsx_runtime.JSX.Element;
|
|
197
327
|
|
|
198
328
|
declare function VizijRuntimeFaceInner({ namespaceOverride, ...props }: VizijRuntimeFaceProps): react_jsx_runtime.JSX.Element | null;
|
|
199
329
|
declare const VizijRuntimeFace: react.MemoExoticComponent<typeof VizijRuntimeFaceInner>;
|
|
200
330
|
|
|
201
331
|
declare function useVizijRuntime(): VizijRuntimeContextValue;
|
|
202
332
|
|
|
333
|
+
declare function useOptionalVizijRuntime(): VizijRuntimeContextValue | null;
|
|
334
|
+
|
|
203
335
|
declare function useVizijOutputs(paths: string[]): Record<string, RawValue | undefined>;
|
|
204
336
|
|
|
205
337
|
declare function useRigInput(path: string): [RawValue | undefined, (value: ValueJSON, shape?: ShapeJSON) => void];
|
|
206
338
|
|
|
207
|
-
|
|
339
|
+
declare function resolveRuntimeUpdatePlan(previous: VizijAssetBundle | null, next: VizijAssetBundle, tier: RuntimeUpdateTier): RuntimeUpdatePlan;
|
|
340
|
+
|
|
341
|
+
declare const POSE_WEIGHT_INPUT_PATH_PREFIX = "/poses/";
|
|
342
|
+
declare const VISEME_POSE_KEYS: readonly ["a", "at", "b", "e", "e_2", "f", "i", "k", "m", "o", "o_2", "p", "r", "s", "t", "t_2", "u"];
|
|
343
|
+
declare const EXPRESSIVE_EMOTION_POSE_KEYS: readonly ["concerned", "happy", "sad", "sleepy", "surprise"];
|
|
344
|
+
declare const EMOTION_POSE_KEYS: readonly ["concerned", "happy", "neutral", "sad", "sleepy", "surprise", "angry"];
|
|
345
|
+
type PoseSemanticKind = "emotion" | "viseme" | "other";
|
|
346
|
+
declare function buildRigInputPath(faceId: string, path: string): string;
|
|
347
|
+
declare function buildPoseWeightInputPathSegment(poseId: string | null | undefined): string;
|
|
348
|
+
declare function buildPoseWeightRelativePath(poseId: string | null | undefined): string;
|
|
349
|
+
declare function buildPoseWeightPathMap(poses: PoseDefinition[], faceId: string | null | undefined): Map<string, string>;
|
|
350
|
+
declare function normalizePoseSemanticKey(value: string | null | undefined): string | null;
|
|
351
|
+
declare function getPoseSemanticKey(pose: Pick<PoseDefinition, "id" | "name">): string | null;
|
|
352
|
+
declare function resolvePoseMembership(pose: Pick<PoseDefinition, "group" | "groupId" | "groupIds">, groups: PoseGroupDefinition[] | undefined): {
|
|
353
|
+
groupIds: string[];
|
|
354
|
+
primaryGroupId: string | null;
|
|
355
|
+
primaryGroupPath: string | null;
|
|
356
|
+
groupPathsById: Record<string, string>;
|
|
357
|
+
};
|
|
358
|
+
declare function resolvePoseSemantics(pose: Pick<PoseDefinition, "id" | "name" | "group" | "groupId" | "groupIds">, groups: PoseGroupDefinition[] | undefined): {
|
|
359
|
+
key: string | null;
|
|
360
|
+
kind: PoseSemanticKind;
|
|
361
|
+
membership: ReturnType<typeof resolvePoseMembership>;
|
|
362
|
+
};
|
|
363
|
+
declare function filterPosesBySemanticKind(poses: PoseDefinition[], groups: PoseGroupDefinition[] | undefined, kind: PoseSemanticKind): PoseDefinition[];
|
|
364
|
+
declare function buildSemanticPoseWeightPathMap(poses: PoseDefinition[], groups: PoseGroupDefinition[] | undefined, faceId: string | null | undefined, kind: Exclude<PoseSemanticKind, "other">): Map<string, string>;
|
|
365
|
+
|
|
366
|
+
type InputConstraint = {
|
|
367
|
+
min?: number;
|
|
368
|
+
max?: number;
|
|
369
|
+
defaultValue?: number;
|
|
370
|
+
};
|
|
371
|
+
type FaceScalarControl = {
|
|
372
|
+
path: string;
|
|
373
|
+
min: number;
|
|
374
|
+
max: number;
|
|
375
|
+
defaultValue: number;
|
|
376
|
+
};
|
|
377
|
+
type ResolvedFaceControls = {
|
|
378
|
+
faceId: string;
|
|
379
|
+
gazeSource: "standard-vizij" | "standard" | "propsrig" | "coupled-gaze" | "none";
|
|
380
|
+
blinkSource: "lids" | "blink" | "none";
|
|
381
|
+
eyes: {
|
|
382
|
+
leftX: FaceScalarControl | null;
|
|
383
|
+
leftY: FaceScalarControl | null;
|
|
384
|
+
rightX: FaceScalarControl | null;
|
|
385
|
+
rightY: FaceScalarControl | null;
|
|
386
|
+
};
|
|
387
|
+
eyelids: {
|
|
388
|
+
leftUpper: FaceScalarControl | null;
|
|
389
|
+
rightUpper: FaceScalarControl | null;
|
|
390
|
+
};
|
|
391
|
+
blink: FaceScalarControl | null;
|
|
392
|
+
};
|
|
393
|
+
declare function resolveFaceControls(assetBundle: VizijAssetBundle, runtimeFaceId?: string | null, inputConstraints?: Record<string, InputConstraint>): ResolvedFaceControls;
|
|
394
|
+
declare function mapNormalizedControlValue(control: FaceScalarControl, normalizedValue: number): number;
|
|
395
|
+
declare function mapUnitControlValue(control: FaceScalarControl, unitValue: number): number;
|
|
396
|
+
|
|
397
|
+
export { type AnimateValueOptions, type AnimationClipLike, type AnimationKeyframeLike, type AnimationPlaybackState, type AnimationTrackLike, EMOTION_POSE_KEYS, EXPRESSIVE_EMOTION_POSE_KEYS, type FaceScalarControl, type InputDriverContext, type InputDriverFactory, type InputDriverLifecycle, POSE_WEIGHT_INPUT_PATH_PREFIX, type PlayAnimationOptions, type PoseDefinition, type PoseGroupDefinition, type PoseRigConfig, type ProgramPlaybackState, type RootBounds, type RuntimeGraphBundle, type RuntimeOutputWrite, type RuntimeUpdatePlan, type RuntimeUpdateTier, type StopProgramOptions, VISEME_POSE_KEYS, type VizijAnimationAsset, type VizijAssetBundle, type VizijGlbAsset, type VizijGraphAsset, type VizijProgramAsset, VizijRuntimeFace, type VizijRuntimeFaceProps, VizijRuntimeProvider, type VizijRuntimeProviderProps, type VizijRuntimeStatus, buildPoseWeightInputPathSegment, buildPoseWeightPathMap, buildPoseWeightRelativePath, buildRigInputPath, buildSemanticPoseWeightPathMap, filterPosesBySemanticKind, getPoseSemanticKey, mapNormalizedControlValue, mapUnitControlValue, normalizePoseSemanticKey, resolveFaceControls, resolvePoseMembership, resolvePoseSemantics, resolveRuntimeUpdatePlan, useOptionalVizijRuntime, useRigInput, useVizijOutputs, useVizijRuntime };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,27 +1,69 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode, PropsWithChildren } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { ValueJSON } from '@vizij/value-json';
|
|
5
5
|
import { IrGraph } from '@vizij/node-graph-authoring';
|
|
6
|
-
import {
|
|
6
|
+
import { RawValue, AnimatableValue } from '@vizij/utils';
|
|
7
7
|
import { World, VizijBundleExtension, VizijProps } from '@vizij/render';
|
|
8
8
|
|
|
9
|
+
/** Value shape hint. Accepted through the public surface, unused by the device. */
|
|
10
|
+
type ShapeJSON = Record<string, unknown>;
|
|
11
|
+
/** Paths a graph reads/writes — metadata for output tracking and seeding. */
|
|
12
|
+
type GraphSubscriptions = {
|
|
13
|
+
inputs?: string[];
|
|
14
|
+
outputs?: string[];
|
|
15
|
+
};
|
|
16
|
+
/** A Vizij graph spec handled structurally (nodes/edges arrays of records). */
|
|
17
|
+
type GraphSpecLike = {
|
|
18
|
+
nodes?: Array<Record<string, unknown>>;
|
|
19
|
+
edges?: Array<Record<string, unknown>>;
|
|
20
|
+
metadata?: unknown;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
};
|
|
23
|
+
/** One graph source composed into the device's behavior. */
|
|
24
|
+
type GraphRegistrationConfig = {
|
|
25
|
+
id?: string;
|
|
26
|
+
spec: GraphSpecLike;
|
|
27
|
+
subs?: GraphSubscriptions;
|
|
28
|
+
};
|
|
29
|
+
/** Per-source merge options. Composition is last-writer-wins today (VIZ-53). */
|
|
30
|
+
type MergeStrategyOptions = Record<string, unknown>;
|
|
31
|
+
/** Player/instance setup carried by animation assets; consumed by the JS clip pipeline. */
|
|
32
|
+
type AnimationSetup = {
|
|
33
|
+
animation?: unknown;
|
|
34
|
+
player?: Record<string, unknown>;
|
|
35
|
+
instance?: Record<string, unknown>;
|
|
36
|
+
};
|
|
9
37
|
type PoseDefinition = {
|
|
10
38
|
id: string;
|
|
11
39
|
name?: string;
|
|
12
40
|
description?: string;
|
|
13
41
|
group?: string | null;
|
|
42
|
+
groupId?: string | null;
|
|
43
|
+
groupIds?: string[];
|
|
14
44
|
values: Record<string, number | undefined>;
|
|
15
45
|
};
|
|
46
|
+
type PoseBlendMode = "average" | "additive";
|
|
47
|
+
type PoseGroupDefinition = {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
path: string;
|
|
51
|
+
blendMode?: PoseBlendMode;
|
|
52
|
+
};
|
|
16
53
|
type PoseRigConfig = {
|
|
17
54
|
version: number;
|
|
18
55
|
faceId?: string | null;
|
|
19
56
|
title?: string;
|
|
20
57
|
description?: string;
|
|
58
|
+
poseGroups?: PoseGroupDefinition[];
|
|
59
|
+
crossGroupBlendMode?: PoseBlendMode;
|
|
21
60
|
neutralInputs: Record<string, number>;
|
|
22
61
|
poses: PoseDefinition[];
|
|
23
|
-
metadata?: Record<string, unknown
|
|
24
|
-
|
|
62
|
+
metadata?: Record<string, unknown> | {
|
|
63
|
+
createdAt: string;
|
|
64
|
+
updatedAt: string;
|
|
65
|
+
author?: string;
|
|
66
|
+
};
|
|
25
67
|
};
|
|
26
68
|
type RootBounds = {
|
|
27
69
|
center: {
|
|
@@ -45,8 +87,8 @@ type VizijGlbAsset = {
|
|
|
45
87
|
rootBounds?: RootBounds;
|
|
46
88
|
} | {
|
|
47
89
|
kind: "world";
|
|
48
|
-
world: World
|
|
49
|
-
animatables: Record<string, AnimatableValue>;
|
|
90
|
+
world: World | Record<string, unknown>;
|
|
91
|
+
animatables: Record<string, AnimatableValue> | Record<string, unknown>;
|
|
50
92
|
bundle?: VizijBundleExtension | null;
|
|
51
93
|
};
|
|
52
94
|
type VizijGraphAsset = {
|
|
@@ -72,10 +114,15 @@ type VizijInputMetadata = {
|
|
|
72
114
|
type AnimationKeyframeLike = {
|
|
73
115
|
time?: number;
|
|
74
116
|
value?: number;
|
|
117
|
+
inTangent?: number | null;
|
|
118
|
+
outTangent?: number | null;
|
|
119
|
+
[key: string]: unknown;
|
|
75
120
|
};
|
|
76
121
|
type AnimationTrackLike = {
|
|
77
122
|
channel: string;
|
|
78
123
|
keyframes?: AnimationKeyframeLike[];
|
|
124
|
+
interpolation?: "linear" | "step" | "cubic" | string;
|
|
125
|
+
[key: string]: unknown;
|
|
79
126
|
};
|
|
80
127
|
type AnimationClipLike = {
|
|
81
128
|
id?: string;
|
|
@@ -90,6 +137,13 @@ type VizijAnimationAsset = {
|
|
|
90
137
|
setup?: Partial<AnimationSetup>;
|
|
91
138
|
weight?: number;
|
|
92
139
|
};
|
|
140
|
+
type VizijProgramAsset = {
|
|
141
|
+
id: string;
|
|
142
|
+
label?: string;
|
|
143
|
+
graph: VizijGraphAsset;
|
|
144
|
+
resetValues?: Record<string, number>;
|
|
145
|
+
metadata?: Record<string, unknown>;
|
|
146
|
+
};
|
|
93
147
|
type VizijAssetBundle = {
|
|
94
148
|
namespace?: string;
|
|
95
149
|
faceId?: string;
|
|
@@ -101,6 +155,7 @@ type VizijAssetBundle = {
|
|
|
101
155
|
stageNeutralFilter?: (id: string, path: string) => boolean;
|
|
102
156
|
};
|
|
103
157
|
animations?: VizijAnimationAsset[];
|
|
158
|
+
programs?: VizijProgramAsset[];
|
|
104
159
|
initialInputs?: Record<string, ValueJSON>;
|
|
105
160
|
metadata?: Record<string, unknown>;
|
|
106
161
|
bundle?: VizijBundleExtension | null;
|
|
@@ -108,7 +163,7 @@ type VizijAssetBundle = {
|
|
|
108
163
|
type RuntimeError = {
|
|
109
164
|
message: string;
|
|
110
165
|
cause?: unknown;
|
|
111
|
-
phase?: "assets" | "
|
|
166
|
+
phase?: "assets" | "engine" | "registration" | "animation" | "bridge" | "driver" | "unknown";
|
|
112
167
|
timestamp: number;
|
|
113
168
|
};
|
|
114
169
|
type VizijRuntimeStatus = {
|
|
@@ -139,6 +194,22 @@ type PlayAnimationOptions = {
|
|
|
139
194
|
speed?: number;
|
|
140
195
|
reset?: boolean;
|
|
141
196
|
};
|
|
197
|
+
type StopAnimationOptions = {
|
|
198
|
+
clearOutputs?: boolean;
|
|
199
|
+
};
|
|
200
|
+
type AnimationPlaybackState = {
|
|
201
|
+
time: number;
|
|
202
|
+
duration: number;
|
|
203
|
+
playing: boolean;
|
|
204
|
+
loop: boolean;
|
|
205
|
+
speed: number;
|
|
206
|
+
};
|
|
207
|
+
type StopProgramOptions = {
|
|
208
|
+
resetOutputs?: boolean;
|
|
209
|
+
};
|
|
210
|
+
type ProgramPlaybackState = {
|
|
211
|
+
state: "playing" | "paused" | "stopped";
|
|
212
|
+
};
|
|
142
213
|
type InputDriverLifecycle = {
|
|
143
214
|
start: () => void;
|
|
144
215
|
stop: () => void;
|
|
@@ -151,23 +222,64 @@ type InputDriverContext = {
|
|
|
151
222
|
faceId?: string;
|
|
152
223
|
};
|
|
153
224
|
type InputDriverFactory = (ctx: InputDriverContext) => InputDriverLifecycle;
|
|
225
|
+
type RuntimeOutputWrite = {
|
|
226
|
+
id: string;
|
|
227
|
+
namespace: string;
|
|
228
|
+
value: RawValue;
|
|
229
|
+
currentValue?: RawValue;
|
|
230
|
+
};
|
|
154
231
|
type VizijRuntimeFaceProps = Omit<VizijProps, "rootId" | "namespace"> & {
|
|
155
232
|
namespaceOverride?: string;
|
|
156
233
|
};
|
|
157
234
|
type VizijRuntimeContextValue = VizijRuntimeStatus & {
|
|
158
235
|
assetBundle: VizijAssetBundle;
|
|
159
236
|
setInput: (path: string, value: ValueJSON, shape?: ShapeJSON) => void;
|
|
237
|
+
/** Current engine-store value of a path (read-your-own-write included). */
|
|
238
|
+
getValueSnapshot: (path: string) => ValueJSON | undefined;
|
|
239
|
+
/**
|
|
240
|
+
* A snapshot of EVERY key currently in the device store, as path → Value in
|
|
241
|
+
* arora's serde JSON shape (pass-through from the device; not `ValueJSON`).
|
|
242
|
+
* `undefined` until the device exists. For mirrors/bridges that forward the
|
|
243
|
+
* whole store (e.g. the standalone's native-store bridge), not for per-path
|
|
244
|
+
* sampling — use `getValueSnapshot` for that.
|
|
245
|
+
*/
|
|
246
|
+
getStoreSnapshot: () => Record<string, unknown> | undefined;
|
|
247
|
+
/**
|
|
248
|
+
* Notifies with each step's drained store changes (path → Value in arora's
|
|
249
|
+
* serde JSON shape; `null` for a cleared key). The change-driven counterpart
|
|
250
|
+
* to `getStoreSnapshot` for store bridges: seed from the snapshot, then stay
|
|
251
|
+
* current from these. Returns an unsubscribe function.
|
|
252
|
+
*/
|
|
253
|
+
subscribeToStoreChanges: (listener: (changes: Record<string, unknown>) => void) => () => void;
|
|
254
|
+
/**
|
|
255
|
+
* Notifies after each engine step, once the step's store changes have been
|
|
256
|
+
* applied. Pair with `getValueSnapshot` to sample values step-aligned.
|
|
257
|
+
* Returns an unsubscribe function.
|
|
258
|
+
*/
|
|
259
|
+
subscribeToStep: (listener: () => void) => () => void;
|
|
260
|
+
setGraphBundle: (bundle: RuntimeGraphBundle, options?: {
|
|
261
|
+
tier?: "auto" | "assets" | "graphs";
|
|
262
|
+
}) => void;
|
|
160
263
|
setValue: (id: string, namespace: string, value: RawValue | ((prev: RawValue | undefined) => RawValue | undefined)) => void;
|
|
161
264
|
stagePoseNeutral: (force?: boolean) => void;
|
|
162
265
|
animateValue: (path: string, target: ValueJSON, options?: AnimateValueOptions) => Promise<void>;
|
|
163
266
|
cancelAnimation: (path: string) => void;
|
|
164
267
|
registerInputDriver: (id: string, factory: InputDriverFactory) => InputDriverLifecycle;
|
|
165
268
|
playAnimation: (id: string, options?: PlayAnimationOptions) => Promise<void>;
|
|
166
|
-
|
|
269
|
+
pauseAnimation: (id: string) => void;
|
|
270
|
+
seekAnimation: (id: string, timeSeconds: number) => void;
|
|
271
|
+
setAnimationLoop: (id: string, enabled: boolean) => void;
|
|
272
|
+
getAnimationState: (id: string) => AnimationPlaybackState | null;
|
|
273
|
+
stopAnimation: (id: string, options?: StopAnimationOptions) => void;
|
|
274
|
+
playProgram: (id: string) => void;
|
|
275
|
+
pauseProgram: (id: string) => void;
|
|
276
|
+
stopProgram: (id: string, options?: StopProgramOptions) => void;
|
|
277
|
+
getProgramState: (id: string) => ProgramPlaybackState | null;
|
|
278
|
+
setAnimationActive: (active: boolean) => void;
|
|
279
|
+
isAnimationActive: () => boolean;
|
|
167
280
|
step: (dt: number, opts?: {
|
|
168
281
|
forceRuntime?: boolean;
|
|
169
282
|
}) => void;
|
|
170
|
-
advanceAnimations: (dt: number) => void;
|
|
171
283
|
inputConstraints: Record<string, {
|
|
172
284
|
min?: number;
|
|
173
285
|
max?: number;
|
|
@@ -179,29 +291,107 @@ type VizijRuntimeProviderProps = {
|
|
|
179
291
|
children: ReactNode;
|
|
180
292
|
namespace?: string;
|
|
181
293
|
faceId?: string;
|
|
294
|
+
updateTier?: RuntimeUpdateTier;
|
|
182
295
|
autoCreate?: boolean;
|
|
183
|
-
createOptions?: CreateOrchOptions;
|
|
184
296
|
autostart?: boolean;
|
|
185
|
-
|
|
297
|
+
/**
|
|
298
|
+
* Whether this provider's device paces itself: when true the device is
|
|
299
|
+
* handed to its own `run()` loop at boot and the provider only pumps its
|
|
300
|
+
* changes; when false the device advances solely on `step(dt,
|
|
301
|
+
* { forceRuntime: true })` calls from the host. A device handed to `run()`
|
|
302
|
+
* keeps its loop even if this later turns false.
|
|
303
|
+
*/
|
|
304
|
+
driveRuntime?: boolean;
|
|
186
305
|
mergeStrategy?: MergeStrategyOptions;
|
|
187
306
|
onRegisterControllers?: (ids: {
|
|
188
307
|
graphs: string[];
|
|
189
308
|
anims: string[];
|
|
190
309
|
}) => void;
|
|
191
310
|
onStatusChange?: (status: VizijRuntimeStatus) => void;
|
|
192
|
-
|
|
311
|
+
transformOutputWrite?: (write: RuntimeOutputWrite) => RuntimeOutputWrite | null;
|
|
312
|
+
};
|
|
313
|
+
type RuntimeUpdateTier = "auto" | "assets" | "graphs";
|
|
314
|
+
type RuntimeUpdatePlan = {
|
|
315
|
+
reloadAssets: boolean;
|
|
316
|
+
reregisterGraphs: boolean;
|
|
317
|
+
};
|
|
318
|
+
type RuntimeGraphBundle = {
|
|
319
|
+
rig?: VizijGraphAsset;
|
|
320
|
+
pose?: VizijAssetBundle["pose"];
|
|
321
|
+
animations?: VizijAnimationAsset[];
|
|
322
|
+
programs?: VizijProgramAsset[];
|
|
193
323
|
};
|
|
194
324
|
|
|
195
325
|
type ProviderProps = PropsWithChildren<VizijRuntimeProviderProps>;
|
|
196
|
-
declare function VizijRuntimeProvider({ assetBundle, children, namespace: namespaceProp, faceId: faceIdProp,
|
|
326
|
+
declare function VizijRuntimeProvider({ assetBundle, children, namespace: namespaceProp, faceId: faceIdProp, updateTier, autoCreate, autostart, driveRuntime, mergeStrategy, onRegisterControllers, onStatusChange, transformOutputWrite, }: ProviderProps): react_jsx_runtime.JSX.Element;
|
|
197
327
|
|
|
198
328
|
declare function VizijRuntimeFaceInner({ namespaceOverride, ...props }: VizijRuntimeFaceProps): react_jsx_runtime.JSX.Element | null;
|
|
199
329
|
declare const VizijRuntimeFace: react.MemoExoticComponent<typeof VizijRuntimeFaceInner>;
|
|
200
330
|
|
|
201
331
|
declare function useVizijRuntime(): VizijRuntimeContextValue;
|
|
202
332
|
|
|
333
|
+
declare function useOptionalVizijRuntime(): VizijRuntimeContextValue | null;
|
|
334
|
+
|
|
203
335
|
declare function useVizijOutputs(paths: string[]): Record<string, RawValue | undefined>;
|
|
204
336
|
|
|
205
337
|
declare function useRigInput(path: string): [RawValue | undefined, (value: ValueJSON, shape?: ShapeJSON) => void];
|
|
206
338
|
|
|
207
|
-
|
|
339
|
+
declare function resolveRuntimeUpdatePlan(previous: VizijAssetBundle | null, next: VizijAssetBundle, tier: RuntimeUpdateTier): RuntimeUpdatePlan;
|
|
340
|
+
|
|
341
|
+
declare const POSE_WEIGHT_INPUT_PATH_PREFIX = "/poses/";
|
|
342
|
+
declare const VISEME_POSE_KEYS: readonly ["a", "at", "b", "e", "e_2", "f", "i", "k", "m", "o", "o_2", "p", "r", "s", "t", "t_2", "u"];
|
|
343
|
+
declare const EXPRESSIVE_EMOTION_POSE_KEYS: readonly ["concerned", "happy", "sad", "sleepy", "surprise"];
|
|
344
|
+
declare const EMOTION_POSE_KEYS: readonly ["concerned", "happy", "neutral", "sad", "sleepy", "surprise", "angry"];
|
|
345
|
+
type PoseSemanticKind = "emotion" | "viseme" | "other";
|
|
346
|
+
declare function buildRigInputPath(faceId: string, path: string): string;
|
|
347
|
+
declare function buildPoseWeightInputPathSegment(poseId: string | null | undefined): string;
|
|
348
|
+
declare function buildPoseWeightRelativePath(poseId: string | null | undefined): string;
|
|
349
|
+
declare function buildPoseWeightPathMap(poses: PoseDefinition[], faceId: string | null | undefined): Map<string, string>;
|
|
350
|
+
declare function normalizePoseSemanticKey(value: string | null | undefined): string | null;
|
|
351
|
+
declare function getPoseSemanticKey(pose: Pick<PoseDefinition, "id" | "name">): string | null;
|
|
352
|
+
declare function resolvePoseMembership(pose: Pick<PoseDefinition, "group" | "groupId" | "groupIds">, groups: PoseGroupDefinition[] | undefined): {
|
|
353
|
+
groupIds: string[];
|
|
354
|
+
primaryGroupId: string | null;
|
|
355
|
+
primaryGroupPath: string | null;
|
|
356
|
+
groupPathsById: Record<string, string>;
|
|
357
|
+
};
|
|
358
|
+
declare function resolvePoseSemantics(pose: Pick<PoseDefinition, "id" | "name" | "group" | "groupId" | "groupIds">, groups: PoseGroupDefinition[] | undefined): {
|
|
359
|
+
key: string | null;
|
|
360
|
+
kind: PoseSemanticKind;
|
|
361
|
+
membership: ReturnType<typeof resolvePoseMembership>;
|
|
362
|
+
};
|
|
363
|
+
declare function filterPosesBySemanticKind(poses: PoseDefinition[], groups: PoseGroupDefinition[] | undefined, kind: PoseSemanticKind): PoseDefinition[];
|
|
364
|
+
declare function buildSemanticPoseWeightPathMap(poses: PoseDefinition[], groups: PoseGroupDefinition[] | undefined, faceId: string | null | undefined, kind: Exclude<PoseSemanticKind, "other">): Map<string, string>;
|
|
365
|
+
|
|
366
|
+
type InputConstraint = {
|
|
367
|
+
min?: number;
|
|
368
|
+
max?: number;
|
|
369
|
+
defaultValue?: number;
|
|
370
|
+
};
|
|
371
|
+
type FaceScalarControl = {
|
|
372
|
+
path: string;
|
|
373
|
+
min: number;
|
|
374
|
+
max: number;
|
|
375
|
+
defaultValue: number;
|
|
376
|
+
};
|
|
377
|
+
type ResolvedFaceControls = {
|
|
378
|
+
faceId: string;
|
|
379
|
+
gazeSource: "standard-vizij" | "standard" | "propsrig" | "coupled-gaze" | "none";
|
|
380
|
+
blinkSource: "lids" | "blink" | "none";
|
|
381
|
+
eyes: {
|
|
382
|
+
leftX: FaceScalarControl | null;
|
|
383
|
+
leftY: FaceScalarControl | null;
|
|
384
|
+
rightX: FaceScalarControl | null;
|
|
385
|
+
rightY: FaceScalarControl | null;
|
|
386
|
+
};
|
|
387
|
+
eyelids: {
|
|
388
|
+
leftUpper: FaceScalarControl | null;
|
|
389
|
+
rightUpper: FaceScalarControl | null;
|
|
390
|
+
};
|
|
391
|
+
blink: FaceScalarControl | null;
|
|
392
|
+
};
|
|
393
|
+
declare function resolveFaceControls(assetBundle: VizijAssetBundle, runtimeFaceId?: string | null, inputConstraints?: Record<string, InputConstraint>): ResolvedFaceControls;
|
|
394
|
+
declare function mapNormalizedControlValue(control: FaceScalarControl, normalizedValue: number): number;
|
|
395
|
+
declare function mapUnitControlValue(control: FaceScalarControl, unitValue: number): number;
|
|
396
|
+
|
|
397
|
+
export { type AnimateValueOptions, type AnimationClipLike, type AnimationKeyframeLike, type AnimationPlaybackState, type AnimationTrackLike, EMOTION_POSE_KEYS, EXPRESSIVE_EMOTION_POSE_KEYS, type FaceScalarControl, type InputDriverContext, type InputDriverFactory, type InputDriverLifecycle, POSE_WEIGHT_INPUT_PATH_PREFIX, type PlayAnimationOptions, type PoseDefinition, type PoseGroupDefinition, type PoseRigConfig, type ProgramPlaybackState, type RootBounds, type RuntimeGraphBundle, type RuntimeOutputWrite, type RuntimeUpdatePlan, type RuntimeUpdateTier, type StopProgramOptions, VISEME_POSE_KEYS, type VizijAnimationAsset, type VizijAssetBundle, type VizijGlbAsset, type VizijGraphAsset, type VizijProgramAsset, VizijRuntimeFace, type VizijRuntimeFaceProps, VizijRuntimeProvider, type VizijRuntimeProviderProps, type VizijRuntimeStatus, buildPoseWeightInputPathSegment, buildPoseWeightPathMap, buildPoseWeightRelativePath, buildRigInputPath, buildSemanticPoseWeightPathMap, filterPosesBySemanticKind, getPoseSemanticKey, mapNormalizedControlValue, mapUnitControlValue, normalizePoseSemanticKey, resolveFaceControls, resolvePoseMembership, resolvePoseSemantics, resolveRuntimeUpdatePlan, useOptionalVizijRuntime, useRigInput, useVizijOutputs, useVizijRuntime };
|