@vizij/runtime-react 0.0.14 → 0.1.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 +9 -1
- package/dist/{index.mjs → index.cjs} +661 -195
- package/dist/{index.d.mts → index.d.cts} +32 -3
- package/dist/index.d.ts +32 -3
- package/dist/index.js +659 -199
- package/package.json +12 -10
|
@@ -1,27 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
VizijRuntimeFace: () => VizijRuntimeFace,
|
|
24
|
+
VizijRuntimeProvider: () => VizijRuntimeProvider,
|
|
25
|
+
useRigInput: () => useRigInput,
|
|
26
|
+
useVizijOutputs: () => useVizijOutputs,
|
|
27
|
+
useVizijRuntime: () => useVizijRuntime
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
|
|
1
31
|
// src/VizijRuntimeProvider.tsx
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
useState
|
|
8
|
-
} from "react";
|
|
9
|
-
import {
|
|
10
|
-
VizijContext,
|
|
11
|
-
createVizijStore,
|
|
12
|
-
loadGLTFWithBundle,
|
|
13
|
-
loadGLTFFromBlobWithBundle
|
|
14
|
-
} from "@vizij/render";
|
|
15
|
-
import {
|
|
16
|
-
OrchestratorProvider,
|
|
17
|
-
useOrchestrator,
|
|
18
|
-
useOrchFrame
|
|
19
|
-
} from "@vizij/orchestrator-react";
|
|
20
|
-
import { valueAsNumber as valueAsNumber2 } from "@vizij/value-json";
|
|
32
|
+
var import_react2 = require("react");
|
|
33
|
+
var import_render = require("@vizij/render");
|
|
34
|
+
var import_orchestrator_react = require("@vizij/orchestrator-react");
|
|
35
|
+
var import_node_graph_authoring = require("@vizij/node-graph-authoring");
|
|
36
|
+
var import_value_json2 = require("@vizij/value-json");
|
|
21
37
|
|
|
22
38
|
// src/context.ts
|
|
23
|
-
|
|
24
|
-
var VizijRuntimeContext = createContext(null);
|
|
39
|
+
var import_react = require("react");
|
|
40
|
+
var VizijRuntimeContext = (0, import_react.createContext)(null);
|
|
25
41
|
|
|
26
42
|
// src/utils/graph.ts
|
|
27
43
|
function getNodes(spec) {
|
|
@@ -84,15 +100,7 @@ function collectInputPathMap(spec) {
|
|
|
84
100
|
}
|
|
85
101
|
|
|
86
102
|
// src/utils/valueConversion.ts
|
|
87
|
-
|
|
88
|
-
isNormalizedValue,
|
|
89
|
-
valueAsBool,
|
|
90
|
-
valueAsColorRgba,
|
|
91
|
-
valueAsNumber,
|
|
92
|
-
valueAsText,
|
|
93
|
-
valueAsTransform,
|
|
94
|
-
valueAsVector
|
|
95
|
-
} from "@vizij/value-json";
|
|
103
|
+
var import_value_json = require("@vizij/value-json");
|
|
96
104
|
function numericArrayToRaw(arr) {
|
|
97
105
|
const normalised = arr.map((entry) => Number(entry ?? 0));
|
|
98
106
|
switch (normalised.length) {
|
|
@@ -144,20 +152,20 @@ function valueJSONToRaw(value) {
|
|
|
144
152
|
]);
|
|
145
153
|
return Object.fromEntries(entries);
|
|
146
154
|
}
|
|
147
|
-
if (!isNormalizedValue(value)) {
|
|
155
|
+
if (!(0, import_value_json.isNormalizedValue)(value)) {
|
|
148
156
|
return void 0;
|
|
149
157
|
}
|
|
150
158
|
switch (value.type) {
|
|
151
159
|
case "float": {
|
|
152
|
-
const num = valueAsNumber(value);
|
|
160
|
+
const num = (0, import_value_json.valueAsNumber)(value);
|
|
153
161
|
return typeof num === "number" ? num : void 0;
|
|
154
162
|
}
|
|
155
163
|
case "bool": {
|
|
156
|
-
const boolVal = valueAsBool(value);
|
|
164
|
+
const boolVal = (0, import_value_json.valueAsBool)(value);
|
|
157
165
|
return typeof boolVal === "boolean" ? boolVal : void 0;
|
|
158
166
|
}
|
|
159
167
|
case "text": {
|
|
160
|
-
const text = valueAsText(value);
|
|
168
|
+
const text = (0, import_value_json.valueAsText)(value);
|
|
161
169
|
return typeof text === "string" ? text : void 0;
|
|
162
170
|
}
|
|
163
171
|
case "vec2":
|
|
@@ -165,11 +173,11 @@ function valueJSONToRaw(value) {
|
|
|
165
173
|
case "vec4":
|
|
166
174
|
case "quat":
|
|
167
175
|
case "vector": {
|
|
168
|
-
const vec = valueAsVector(value);
|
|
176
|
+
const vec = (0, import_value_json.valueAsVector)(value);
|
|
169
177
|
return vec ? numericArrayToRaw(vec) : void 0;
|
|
170
178
|
}
|
|
171
179
|
case "colorrgba": {
|
|
172
|
-
const color = valueAsColorRgba(value);
|
|
180
|
+
const color = (0, import_value_json.valueAsColorRgba)(value);
|
|
173
181
|
if (!color) {
|
|
174
182
|
return void 0;
|
|
175
183
|
}
|
|
@@ -177,7 +185,7 @@ function valueJSONToRaw(value) {
|
|
|
177
185
|
return { r, g, b, a };
|
|
178
186
|
}
|
|
179
187
|
case "transform": {
|
|
180
|
-
const transform = valueAsTransform(value);
|
|
188
|
+
const transform = (0, import_value_json.valueAsTransform)(value);
|
|
181
189
|
if (!transform) {
|
|
182
190
|
return void 0;
|
|
183
191
|
}
|
|
@@ -207,7 +215,10 @@ function valueJSONToRaw(value) {
|
|
|
207
215
|
}
|
|
208
216
|
|
|
209
217
|
// src/VizijRuntimeProvider.tsx
|
|
210
|
-
|
|
218
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
219
|
+
var ACTIVE_GRACE_MS = 250;
|
|
220
|
+
var VISIBLE_IDLE_FPS = 30;
|
|
221
|
+
var HIDDEN_IDLE_FPS = 1;
|
|
211
222
|
var DEFAULT_MERGE = {
|
|
212
223
|
outputs: "add",
|
|
213
224
|
intermediate: "add"
|
|
@@ -245,6 +256,166 @@ function normalisePath(path) {
|
|
|
245
256
|
function normaliseBundleKind(kind) {
|
|
246
257
|
return typeof kind === "string" ? kind.toLowerCase() : "";
|
|
247
258
|
}
|
|
259
|
+
function addConstraintVariant(map, key, constraint) {
|
|
260
|
+
if (!key) return;
|
|
261
|
+
if (!map[key]) {
|
|
262
|
+
map[key] = constraint;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function stripRigFacePrefix(path) {
|
|
266
|
+
const trimmed = path.startsWith("/") ? path.slice(1) : path;
|
|
267
|
+
const match = /^rig\/[^/]+\/(.+)$/.exec(trimmed);
|
|
268
|
+
if (match && match[1]) {
|
|
269
|
+
return match[1];
|
|
270
|
+
}
|
|
271
|
+
if (trimmed.startsWith("rig/")) {
|
|
272
|
+
return trimmed.slice("rig/".length);
|
|
273
|
+
}
|
|
274
|
+
return trimmed;
|
|
275
|
+
}
|
|
276
|
+
function extractInputConstraints(spec, extraInputs, namespace) {
|
|
277
|
+
if (!spec || typeof spec !== "object") {
|
|
278
|
+
return {};
|
|
279
|
+
}
|
|
280
|
+
const inputs = [];
|
|
281
|
+
if (Array.isArray(extraInputs)) {
|
|
282
|
+
inputs.push(...extraInputs);
|
|
283
|
+
}
|
|
284
|
+
const entries = spec.metadata?.vizij?.inputs;
|
|
285
|
+
if (Array.isArray(entries)) {
|
|
286
|
+
entries.forEach((entry) => {
|
|
287
|
+
if (entry && typeof entry === "object") {
|
|
288
|
+
inputs.push(entry);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
if (inputs.length === 0) {
|
|
293
|
+
return {};
|
|
294
|
+
}
|
|
295
|
+
const map = {};
|
|
296
|
+
inputs.forEach((entry) => {
|
|
297
|
+
const path = entry.path;
|
|
298
|
+
if (typeof path !== "string") return;
|
|
299
|
+
const namespaced = namespaceTypedPath(path, namespace);
|
|
300
|
+
const stripped = stripRigFacePrefix(path);
|
|
301
|
+
const strippedNamespaced = stripped ? namespaceTypedPath(stripped, namespace) : stripped;
|
|
302
|
+
const min = entry.range?.min;
|
|
303
|
+
const max = entry.range?.max;
|
|
304
|
+
const defaultValue = entry.defaultValue;
|
|
305
|
+
const constraint = {
|
|
306
|
+
...Number.isFinite(Number(min)) ? { min: Number(min) } : {},
|
|
307
|
+
...Number.isFinite(Number(max)) ? { max: Number(max) } : {},
|
|
308
|
+
...Number.isFinite(Number(defaultValue)) ? { defaultValue: Number(defaultValue) } : {}
|
|
309
|
+
};
|
|
310
|
+
addConstraintVariant(map, namespaced, constraint);
|
|
311
|
+
addConstraintVariant(map, path, constraint);
|
|
312
|
+
if (stripped) {
|
|
313
|
+
addConstraintVariant(map, stripped, constraint);
|
|
314
|
+
}
|
|
315
|
+
if (strippedNamespaced) {
|
|
316
|
+
addConstraintVariant(map, strippedNamespaced, constraint);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
return map;
|
|
320
|
+
}
|
|
321
|
+
function namespaceTypedPath(path, namespace) {
|
|
322
|
+
const trimmed = typeof path === "string" ? path.trim() : "";
|
|
323
|
+
if (!trimmed) {
|
|
324
|
+
return trimmed;
|
|
325
|
+
}
|
|
326
|
+
const prefix = `${namespace}/`;
|
|
327
|
+
if (trimmed.startsWith(prefix)) {
|
|
328
|
+
return trimmed;
|
|
329
|
+
}
|
|
330
|
+
if (trimmed.startsWith("debug/")) {
|
|
331
|
+
const rest = trimmed.slice("debug/".length);
|
|
332
|
+
const namespacedRest = namespaceTypedPath(rest, namespace);
|
|
333
|
+
return namespacedRest.startsWith("debug/") ? namespacedRest : `debug/${namespacedRest}`;
|
|
334
|
+
}
|
|
335
|
+
return `${prefix}${trimmed}`;
|
|
336
|
+
}
|
|
337
|
+
function stripNamespace(path, namespace) {
|
|
338
|
+
const prefix = `${namespace}/`;
|
|
339
|
+
if (path.startsWith(prefix)) {
|
|
340
|
+
return path.slice(prefix.length);
|
|
341
|
+
}
|
|
342
|
+
const debugPrefix = `debug/${prefix}`;
|
|
343
|
+
if (path.startsWith(debugPrefix)) {
|
|
344
|
+
return path.slice(debugPrefix.length);
|
|
345
|
+
}
|
|
346
|
+
if (path.startsWith("debug/")) {
|
|
347
|
+
return path.slice("debug/".length);
|
|
348
|
+
}
|
|
349
|
+
return path;
|
|
350
|
+
}
|
|
351
|
+
function namespaceControllerId(id, namespace, kind = "graph") {
|
|
352
|
+
if (!id) {
|
|
353
|
+
return void 0;
|
|
354
|
+
}
|
|
355
|
+
const trimmed = id.trim();
|
|
356
|
+
if (!trimmed) {
|
|
357
|
+
return void 0;
|
|
358
|
+
}
|
|
359
|
+
const prefix = `${namespace}/${kind}/`;
|
|
360
|
+
if (trimmed.startsWith(prefix)) {
|
|
361
|
+
return trimmed;
|
|
362
|
+
}
|
|
363
|
+
return `${prefix}${trimmed}`;
|
|
364
|
+
}
|
|
365
|
+
function namespaceSubscriptions(subs, namespace) {
|
|
366
|
+
if (!subs) {
|
|
367
|
+
return void 0;
|
|
368
|
+
}
|
|
369
|
+
const inputs = Array.isArray(subs.inputs) ? subs.inputs.map((path) => namespaceTypedPath(path, namespace)) : void 0;
|
|
370
|
+
const outputs = Array.isArray(subs.outputs) ? subs.outputs.map((path) => namespaceTypedPath(path, namespace)) : void 0;
|
|
371
|
+
if (!inputs && !outputs) {
|
|
372
|
+
return subs;
|
|
373
|
+
}
|
|
374
|
+
return {
|
|
375
|
+
...subs,
|
|
376
|
+
...inputs ? { inputs } : {},
|
|
377
|
+
...outputs ? { outputs } : {}
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
function namespaceGraphSpec(spec, namespace) {
|
|
381
|
+
if (!spec || typeof spec !== "object") {
|
|
382
|
+
return spec;
|
|
383
|
+
}
|
|
384
|
+
const nodes = spec.nodes;
|
|
385
|
+
if (!Array.isArray(nodes)) {
|
|
386
|
+
return spec;
|
|
387
|
+
}
|
|
388
|
+
let changed = false;
|
|
389
|
+
const nextNodes = nodes.map((node) => {
|
|
390
|
+
if (!node || typeof node !== "object") {
|
|
391
|
+
return node;
|
|
392
|
+
}
|
|
393
|
+
const path = node.params?.path;
|
|
394
|
+
if (typeof path !== "string") {
|
|
395
|
+
return node;
|
|
396
|
+
}
|
|
397
|
+
const namespacedPath = namespaceTypedPath(path, namespace);
|
|
398
|
+
if (namespacedPath === path) {
|
|
399
|
+
return node;
|
|
400
|
+
}
|
|
401
|
+
changed = true;
|
|
402
|
+
return {
|
|
403
|
+
...node,
|
|
404
|
+
params: {
|
|
405
|
+
...node.params ?? {},
|
|
406
|
+
path: namespacedPath
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
});
|
|
410
|
+
if (!changed) {
|
|
411
|
+
return spec;
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
...spec,
|
|
415
|
+
nodes: nextNodes
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
var now = () => typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
248
419
|
function pickBundleGraph(bundle, preferredKinds) {
|
|
249
420
|
if (!bundle?.graphs || bundle.graphs.length === 0) {
|
|
250
421
|
return null;
|
|
@@ -264,14 +435,91 @@ function pickBundleGraph(bundle, preferredKinds) {
|
|
|
264
435
|
}
|
|
265
436
|
return null;
|
|
266
437
|
}
|
|
438
|
+
function extractIrGraph(payload) {
|
|
439
|
+
if (!payload || typeof payload !== "object") {
|
|
440
|
+
return void 0;
|
|
441
|
+
}
|
|
442
|
+
return payload;
|
|
443
|
+
}
|
|
267
444
|
function convertBundleGraph(entry) {
|
|
268
|
-
if (!entry || !entry.id
|
|
445
|
+
if (!entry || !entry.id) {
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
448
|
+
const rawSpec = entry.spec;
|
|
449
|
+
const inputMetadata = extractVizijInputMetadata(
|
|
450
|
+
rawSpec
|
|
451
|
+
);
|
|
452
|
+
const spec = rawSpec ? stripVizijMetadata(rawSpec) : void 0;
|
|
453
|
+
const ir = extractIrGraph(entry.ir);
|
|
454
|
+
if (!spec && !ir) {
|
|
269
455
|
return null;
|
|
270
456
|
}
|
|
271
457
|
return {
|
|
272
458
|
id: entry.id,
|
|
273
|
-
spec
|
|
459
|
+
spec,
|
|
460
|
+
ir: ir ?? null,
|
|
461
|
+
inputMetadata
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
function resolveGraphSpec(asset, context) {
|
|
465
|
+
if (asset.spec) {
|
|
466
|
+
return stripVizijMetadata(asset.spec);
|
|
467
|
+
}
|
|
468
|
+
if (asset.ir) {
|
|
469
|
+
try {
|
|
470
|
+
const compiled = (0, import_node_graph_authoring.compileIrGraph)(asset.ir, { preferLegacySpec: false });
|
|
471
|
+
if (compiled.issues && compiled.issues.length > 0) {
|
|
472
|
+
console.warn(
|
|
473
|
+
`[vizij-runtime] IR compile for graph "${context}" reported issues`,
|
|
474
|
+
compiled.issues
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
return stripVizijMetadata(compiled.spec);
|
|
478
|
+
} catch (error) {
|
|
479
|
+
console.warn(
|
|
480
|
+
`[vizij-runtime] Failed to compile IR graph "${context}"`,
|
|
481
|
+
error
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return null;
|
|
486
|
+
}
|
|
487
|
+
function stripVizijMetadata(spec) {
|
|
488
|
+
if (!spec || typeof spec !== "object") {
|
|
489
|
+
return spec;
|
|
490
|
+
}
|
|
491
|
+
const cloned = {
|
|
492
|
+
...spec,
|
|
493
|
+
nodes: spec.nodes ? spec.nodes.map((node) => ({ ...node })) : spec.nodes,
|
|
494
|
+
edges: spec.edges ? spec.edges.map((edge) => ({ ...edge })) : spec.edges
|
|
274
495
|
};
|
|
496
|
+
if (cloned.metadata && typeof cloned.metadata === "object") {
|
|
497
|
+
const metadata = { ...cloned.metadata };
|
|
498
|
+
if ("vizij" in metadata) {
|
|
499
|
+
delete metadata.vizij;
|
|
500
|
+
}
|
|
501
|
+
if (Object.keys(metadata).length === 0) {
|
|
502
|
+
delete cloned.metadata;
|
|
503
|
+
} else {
|
|
504
|
+
cloned.metadata = metadata;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
return cloned;
|
|
508
|
+
}
|
|
509
|
+
function extractVizijInputMetadata(spec) {
|
|
510
|
+
if (!spec || typeof spec !== "object") {
|
|
511
|
+
return [];
|
|
512
|
+
}
|
|
513
|
+
const inputs = spec.metadata?.vizij?.inputs;
|
|
514
|
+
if (!Array.isArray(inputs)) {
|
|
515
|
+
return [];
|
|
516
|
+
}
|
|
517
|
+
return inputs.map((entry) => {
|
|
518
|
+
if (!entry || typeof entry !== "object") {
|
|
519
|
+
return null;
|
|
520
|
+
}
|
|
521
|
+
return entry;
|
|
522
|
+
}).filter(Boolean);
|
|
275
523
|
}
|
|
276
524
|
function convertBundleAnimations(entries) {
|
|
277
525
|
if (!Array.isArray(entries) || entries.length === 0) {
|
|
@@ -495,36 +743,53 @@ function VizijRuntimeProvider({
|
|
|
495
743
|
autoCreate = true,
|
|
496
744
|
createOptions,
|
|
497
745
|
autostart = false,
|
|
746
|
+
driveOrchestrator = true,
|
|
498
747
|
mergeStrategy,
|
|
499
748
|
onRegisterControllers,
|
|
500
|
-
onStatusChange
|
|
749
|
+
onStatusChange,
|
|
750
|
+
orchestratorScope = "auto"
|
|
501
751
|
}) {
|
|
502
|
-
const storeRef = useRef();
|
|
752
|
+
const storeRef = (0, import_react2.useRef)(null);
|
|
503
753
|
if (!storeRef.current) {
|
|
504
|
-
storeRef.current = createVizijStore();
|
|
754
|
+
storeRef.current = (0, import_render.createVizijStore)();
|
|
505
755
|
}
|
|
506
|
-
|
|
507
|
-
|
|
756
|
+
const parentOrchestrator = (0, import_react2.useContext)(import_orchestrator_react.OrchestratorContext);
|
|
757
|
+
const hasParentOrchestrator = Boolean(parentOrchestrator);
|
|
758
|
+
const shouldProvideOrchestrator = orchestratorScope === "isolated" || !hasParentOrchestrator && orchestratorScope !== "shared";
|
|
759
|
+
if (orchestratorScope === "shared" && !hasParentOrchestrator) {
|
|
760
|
+
console.warn(
|
|
761
|
+
'[vizij-runtime] orchestratorScope="shared" requires an OrchestratorProvider higher in the tree; falling back to an isolated provider.'
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
const runtimeTree = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_render.VizijContext.Provider, { value: storeRef.current, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
765
|
+
VizijRuntimeProviderInner,
|
|
508
766
|
{
|
|
767
|
+
assetBundle,
|
|
768
|
+
namespace: namespaceProp,
|
|
769
|
+
faceId: faceIdProp,
|
|
509
770
|
autoCreate,
|
|
510
|
-
createOptions,
|
|
511
771
|
autostart,
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
mergeStrategy,
|
|
520
|
-
onRegisterControllers,
|
|
521
|
-
onStatusChange,
|
|
522
|
-
store: storeRef.current,
|
|
523
|
-
children
|
|
524
|
-
}
|
|
525
|
-
)
|
|
772
|
+
driveOrchestrator,
|
|
773
|
+
createOptions,
|
|
774
|
+
mergeStrategy,
|
|
775
|
+
onRegisterControllers,
|
|
776
|
+
onStatusChange,
|
|
777
|
+
store: storeRef.current,
|
|
778
|
+
children
|
|
526
779
|
}
|
|
527
780
|
) });
|
|
781
|
+
if (!shouldProvideOrchestrator) {
|
|
782
|
+
return runtimeTree;
|
|
783
|
+
}
|
|
784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
785
|
+
import_orchestrator_react.OrchestratorProvider,
|
|
786
|
+
{
|
|
787
|
+
autoCreate,
|
|
788
|
+
createOptions,
|
|
789
|
+
autostart: false,
|
|
790
|
+
children: runtimeTree
|
|
791
|
+
}
|
|
792
|
+
);
|
|
528
793
|
}
|
|
529
794
|
function VizijRuntimeProviderInner({
|
|
530
795
|
assetBundle: initialAssetBundle,
|
|
@@ -535,9 +800,12 @@ function VizijRuntimeProviderInner({
|
|
|
535
800
|
onStatusChange,
|
|
536
801
|
store,
|
|
537
802
|
children,
|
|
538
|
-
autoCreate
|
|
803
|
+
autoCreate,
|
|
804
|
+
autostart,
|
|
805
|
+
createOptions,
|
|
806
|
+
driveOrchestrator
|
|
539
807
|
}) {
|
|
540
|
-
const [extractedBundle, setExtractedBundle] = useState(() => {
|
|
808
|
+
const [extractedBundle, setExtractedBundle] = (0, import_react2.useState)(() => {
|
|
541
809
|
if (initialAssetBundle.bundle) {
|
|
542
810
|
return initialAssetBundle.bundle;
|
|
543
811
|
}
|
|
@@ -546,8 +814,8 @@ function VizijRuntimeProviderInner({
|
|
|
546
814
|
}
|
|
547
815
|
return null;
|
|
548
816
|
});
|
|
549
|
-
const [extractedAnimations, setExtractedAnimations] = useState([]);
|
|
550
|
-
useEffect(() => {
|
|
817
|
+
const [extractedAnimations, setExtractedAnimations] = (0, import_react2.useState)([]);
|
|
818
|
+
(0, import_react2.useEffect)(() => {
|
|
551
819
|
if (initialAssetBundle.bundle) {
|
|
552
820
|
setExtractedBundle(initialAssetBundle.bundle);
|
|
553
821
|
return;
|
|
@@ -558,7 +826,7 @@ function VizijRuntimeProviderInner({
|
|
|
558
826
|
setExtractedBundle(null);
|
|
559
827
|
}
|
|
560
828
|
}, [initialAssetBundle]);
|
|
561
|
-
const assetBundle = useMemo(
|
|
829
|
+
const assetBundle = (0, import_react2.useMemo)(
|
|
562
830
|
() => mergeAssetBundle(
|
|
563
831
|
initialAssetBundle,
|
|
564
832
|
extractedBundle,
|
|
@@ -575,14 +843,14 @@ function VizijRuntimeProviderInner({
|
|
|
575
843
|
removeGraph,
|
|
576
844
|
removeAnimation,
|
|
577
845
|
listControllers,
|
|
578
|
-
setInput,
|
|
846
|
+
setInput: orchestratorSetInput,
|
|
579
847
|
getPathSnapshot,
|
|
580
848
|
step: stepRuntime
|
|
581
|
-
} = useOrchestrator();
|
|
582
|
-
const frame = useOrchFrame();
|
|
849
|
+
} = (0, import_orchestrator_react.useOrchestrator)();
|
|
850
|
+
const frame = (0, import_orchestrator_react.useOrchFrame)();
|
|
583
851
|
const namespace = namespaceProp ?? assetBundle.namespace ?? "default";
|
|
584
852
|
const faceId = faceIdProp ?? assetBundle.faceId ?? assetBundle.pose?.config?.faceId ?? assetBundle.pose?.config?.faceId ?? void 0;
|
|
585
|
-
const [status, setStatus] = useState({
|
|
853
|
+
const [status, setStatus] = (0, import_react2.useState)({
|
|
586
854
|
loading: true,
|
|
587
855
|
ready: false,
|
|
588
856
|
error: null,
|
|
@@ -591,19 +859,98 @@ function VizijRuntimeProviderInner({
|
|
|
591
859
|
faceId,
|
|
592
860
|
rootId: null,
|
|
593
861
|
outputPaths: [],
|
|
862
|
+
stepHz: void 0,
|
|
594
863
|
controllers: { graphs: [], anims: [] }
|
|
595
864
|
});
|
|
596
|
-
const errorsRef = useRef([]);
|
|
597
|
-
const outputPathsRef = useRef(/* @__PURE__ */ new Set());
|
|
598
|
-
const
|
|
599
|
-
const
|
|
600
|
-
const
|
|
601
|
-
const
|
|
602
|
-
const
|
|
603
|
-
const
|
|
604
|
-
const
|
|
605
|
-
const
|
|
606
|
-
const
|
|
865
|
+
const errorsRef = (0, import_react2.useRef)([]);
|
|
866
|
+
const outputPathsRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
867
|
+
const baseOutputPathsRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
868
|
+
const namespacedOutputPathsRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
869
|
+
const namespaceRef = (0, import_react2.useRef)(namespace);
|
|
870
|
+
const driveOrchestratorRef = (0, import_react2.useRef)(driveOrchestrator);
|
|
871
|
+
const rigInputMapRef = (0, import_react2.useRef)({});
|
|
872
|
+
const registeredGraphsRef = (0, import_react2.useRef)([]);
|
|
873
|
+
const registeredAnimationsRef = (0, import_react2.useRef)([]);
|
|
874
|
+
const mergedGraphRef = (0, import_react2.useRef)(null);
|
|
875
|
+
const [inputConstraints, setInputConstraints] = (0, import_react2.useState)({});
|
|
876
|
+
const avgStepDtRef = (0, import_react2.useRef)(null);
|
|
877
|
+
const animationTweensRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
878
|
+
const clipPlaybackRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
879
|
+
const stagedInputsRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
880
|
+
const autostartRef = (0, import_react2.useRef)(autostart);
|
|
881
|
+
const lastActivityTimeRef = (0, import_react2.useRef)(now());
|
|
882
|
+
const [loopMode, setLoopMode] = (0, import_react2.useState)("stopped");
|
|
883
|
+
const loopModeRef = (0, import_react2.useRef)("stopped");
|
|
884
|
+
(0, import_react2.useEffect)(() => {
|
|
885
|
+
loopModeRef.current = loopMode;
|
|
886
|
+
}, [loopMode]);
|
|
887
|
+
const runtimeMountedRef = (0, import_react2.useRef)(true);
|
|
888
|
+
(0, import_react2.useEffect)(() => {
|
|
889
|
+
return () => {
|
|
890
|
+
runtimeMountedRef.current = false;
|
|
891
|
+
};
|
|
892
|
+
}, []);
|
|
893
|
+
(0, import_react2.useEffect)(() => {
|
|
894
|
+
const rigAsset = assetBundle.rig;
|
|
895
|
+
if (!rigAsset) {
|
|
896
|
+
setInputConstraints({});
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
const rigSpec = resolveGraphSpec(
|
|
900
|
+
rigAsset,
|
|
901
|
+
`${rigAsset.id ?? "rig"} graph (constraints)`
|
|
902
|
+
);
|
|
903
|
+
const constraints = extractInputConstraints(
|
|
904
|
+
rigSpec,
|
|
905
|
+
rigAsset.inputMetadata,
|
|
906
|
+
namespace
|
|
907
|
+
);
|
|
908
|
+
setInputConstraints(constraints);
|
|
909
|
+
const isDevEnv = typeof globalThis !== "undefined" && Boolean(globalThis?.process?.env?.NODE_ENV !== "production");
|
|
910
|
+
if (isDevEnv) {
|
|
911
|
+
const size = Object.keys(constraints).length;
|
|
912
|
+
console.log("[vizij-runtime] input constraints computed", size, {
|
|
913
|
+
namespace,
|
|
914
|
+
rigId: rigAsset.id
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
}, [assetBundle.rig, namespace]);
|
|
918
|
+
const requestLoopMode = (0, import_react2.useCallback)((mode) => {
|
|
919
|
+
if (!runtimeMountedRef.current) {
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
setLoopMode((prev) => prev === mode ? prev : mode);
|
|
923
|
+
}, []);
|
|
924
|
+
const hasActiveAnimations = (0, import_react2.useCallback)(() => {
|
|
925
|
+
return animationTweensRef.current.size > 0 || clipPlaybackRef.current.size > 0;
|
|
926
|
+
}, []);
|
|
927
|
+
const computeDesiredLoopMode = (0, import_react2.useCallback)(() => {
|
|
928
|
+
const hasAnimations = hasActiveAnimations();
|
|
929
|
+
const recentlyActive = now() - lastActivityTimeRef.current <= ACTIVE_GRACE_MS;
|
|
930
|
+
if (autostartRef.current && (hasAnimations || recentlyActive)) {
|
|
931
|
+
return "active";
|
|
932
|
+
}
|
|
933
|
+
if (autostartRef.current) {
|
|
934
|
+
return "idle-visible";
|
|
935
|
+
}
|
|
936
|
+
return "idle-hidden";
|
|
937
|
+
}, [hasActiveAnimations]);
|
|
938
|
+
const updateLoopMode = (0, import_react2.useCallback)(() => {
|
|
939
|
+
requestLoopMode(computeDesiredLoopMode());
|
|
940
|
+
}, [computeDesiredLoopMode, requestLoopMode]);
|
|
941
|
+
const markActivity = (0, import_react2.useCallback)(() => {
|
|
942
|
+
lastActivityTimeRef.current = now();
|
|
943
|
+
updateLoopMode();
|
|
944
|
+
}, [updateLoopMode]);
|
|
945
|
+
const setInput = (0, import_react2.useCallback)(
|
|
946
|
+
(path, value, shape) => {
|
|
947
|
+
markActivity();
|
|
948
|
+
const namespacedPath = namespaceTypedPath(path, namespaceRef.current);
|
|
949
|
+
stagedInputsRef.current.set(namespacedPath, { value, shape });
|
|
950
|
+
},
|
|
951
|
+
[markActivity]
|
|
952
|
+
);
|
|
953
|
+
const reportStatus = (0, import_react2.useCallback)(
|
|
607
954
|
(updater) => {
|
|
608
955
|
setStatus((prev) => {
|
|
609
956
|
const next = updater(prev);
|
|
@@ -613,7 +960,7 @@ function VizijRuntimeProviderInner({
|
|
|
613
960
|
},
|
|
614
961
|
[onStatusChange]
|
|
615
962
|
);
|
|
616
|
-
const pushError = useCallback(
|
|
963
|
+
const pushError = (0, import_react2.useCallback)(
|
|
617
964
|
(error) => {
|
|
618
965
|
errorsRef.current = [...errorsRef.current, error];
|
|
619
966
|
reportStatus((prev) => ({
|
|
@@ -625,7 +972,7 @@ function VizijRuntimeProviderInner({
|
|
|
625
972
|
},
|
|
626
973
|
[reportStatus]
|
|
627
974
|
);
|
|
628
|
-
const resetErrors = useCallback(() => {
|
|
975
|
+
const resetErrors = (0, import_react2.useCallback)(() => {
|
|
629
976
|
errorsRef.current = [];
|
|
630
977
|
reportStatus((prev) => ({
|
|
631
978
|
...prev,
|
|
@@ -633,7 +980,11 @@ function VizijRuntimeProviderInner({
|
|
|
633
980
|
errors: []
|
|
634
981
|
}));
|
|
635
982
|
}, [reportStatus]);
|
|
636
|
-
|
|
983
|
+
(0, import_react2.useEffect)(() => {
|
|
984
|
+
autostartRef.current = autostart;
|
|
985
|
+
updateLoopMode();
|
|
986
|
+
}, [autostart, updateLoopMode]);
|
|
987
|
+
const clearControllers = (0, import_react2.useCallback)(() => {
|
|
637
988
|
const existing = listControllers();
|
|
638
989
|
existing.graphs.forEach((id) => {
|
|
639
990
|
try {
|
|
@@ -662,17 +1013,24 @@ function VizijRuntimeProviderInner({
|
|
|
662
1013
|
registeredGraphsRef.current = [];
|
|
663
1014
|
registeredAnimationsRef.current = [];
|
|
664
1015
|
mergedGraphRef.current = null;
|
|
1016
|
+
outputPathsRef.current = /* @__PURE__ */ new Set();
|
|
1017
|
+
baseOutputPathsRef.current = /* @__PURE__ */ new Set();
|
|
1018
|
+
namespacedOutputPathsRef.current = /* @__PURE__ */ new Set();
|
|
665
1019
|
}, [listControllers, removeAnimation, removeGraph, pushError]);
|
|
666
|
-
useEffect(() => {
|
|
1020
|
+
(0, import_react2.useEffect)(() => {
|
|
1021
|
+
namespaceRef.current = namespace;
|
|
667
1022
|
reportStatus((prev) => ({
|
|
668
1023
|
...prev,
|
|
669
1024
|
namespace,
|
|
670
1025
|
faceId
|
|
671
1026
|
}));
|
|
672
1027
|
}, [namespace, faceId, reportStatus]);
|
|
1028
|
+
(0, import_react2.useEffect)(() => {
|
|
1029
|
+
driveOrchestratorRef.current = driveOrchestrator;
|
|
1030
|
+
}, [driveOrchestrator]);
|
|
673
1031
|
const glbAsset = initialAssetBundle.glb;
|
|
674
1032
|
const baseBundle = initialAssetBundle.bundle ?? null;
|
|
675
|
-
useEffect(() => {
|
|
1033
|
+
(0, import_react2.useEffect)(() => {
|
|
676
1034
|
let cancelled = false;
|
|
677
1035
|
resetErrors();
|
|
678
1036
|
reportStatus((prev) => ({
|
|
@@ -691,7 +1049,7 @@ function VizijRuntimeProviderInner({
|
|
|
691
1049
|
let bundle = baseBundle;
|
|
692
1050
|
let gltfAnimations;
|
|
693
1051
|
if (glbAsset.kind === "url") {
|
|
694
|
-
const loaded = await loadGLTFWithBundle(
|
|
1052
|
+
const loaded = await (0, import_render.loadGLTFWithBundle)(
|
|
695
1053
|
glbAsset.src,
|
|
696
1054
|
[namespace],
|
|
697
1055
|
glbAsset.aggressiveImport ?? false,
|
|
@@ -702,7 +1060,7 @@ function VizijRuntimeProviderInner({
|
|
|
702
1060
|
bundle = loaded.bundle ?? bundle;
|
|
703
1061
|
gltfAnimations = pickExtractedAnimations(loaded);
|
|
704
1062
|
} else if (glbAsset.kind === "blob") {
|
|
705
|
-
const loaded = await loadGLTFFromBlobWithBundle(
|
|
1063
|
+
const loaded = await (0, import_render.loadGLTFFromBlobWithBundle)(
|
|
706
1064
|
glbAsset.blob,
|
|
707
1065
|
[namespace],
|
|
708
1066
|
glbAsset.aggressiveImport ?? false,
|
|
@@ -764,9 +1122,9 @@ function VizijRuntimeProviderInner({
|
|
|
764
1122
|
setExtractedBundle,
|
|
765
1123
|
setExtractedAnimations
|
|
766
1124
|
]);
|
|
767
|
-
useEffect(() => {
|
|
1125
|
+
(0, import_react2.useEffect)(() => {
|
|
768
1126
|
if (!ready && autoCreate) {
|
|
769
|
-
createOrchestrator().catch((err) => {
|
|
1127
|
+
createOrchestrator(createOptions).catch((err) => {
|
|
770
1128
|
pushError({
|
|
771
1129
|
message: "Failed to create orchestrator runtime",
|
|
772
1130
|
cause: err,
|
|
@@ -775,10 +1133,20 @@ function VizijRuntimeProviderInner({
|
|
|
775
1133
|
});
|
|
776
1134
|
});
|
|
777
1135
|
}
|
|
778
|
-
}, [ready, autoCreate, createOrchestrator, pushError]);
|
|
779
|
-
const registerControllers = useCallback(async () => {
|
|
780
|
-
const normalize = (spec) => spec;
|
|
1136
|
+
}, [ready, autoCreate, createOptions, createOrchestrator, pushError]);
|
|
1137
|
+
const registerControllers = (0, import_react2.useCallback)(async () => {
|
|
781
1138
|
clearControllers();
|
|
1139
|
+
const baseOutputPaths = /* @__PURE__ */ new Set();
|
|
1140
|
+
const namespacedOutputPaths = /* @__PURE__ */ new Set();
|
|
1141
|
+
const recordOutputs = (paths) => {
|
|
1142
|
+
paths.forEach((path) => {
|
|
1143
|
+
const trimmed = path.trim();
|
|
1144
|
+
if (!trimmed) return;
|
|
1145
|
+
const basePath = stripNamespace(trimmed, namespace);
|
|
1146
|
+
baseOutputPaths.add(basePath);
|
|
1147
|
+
namespacedOutputPaths.add(namespaceTypedPath(trimmed, namespace));
|
|
1148
|
+
});
|
|
1149
|
+
};
|
|
782
1150
|
const rigAsset = assetBundle.rig;
|
|
783
1151
|
if (!rigAsset) {
|
|
784
1152
|
pushError({
|
|
@@ -788,37 +1156,67 @@ function VizijRuntimeProviderInner({
|
|
|
788
1156
|
});
|
|
789
1157
|
return;
|
|
790
1158
|
}
|
|
791
|
-
const rigSpec =
|
|
1159
|
+
const rigSpec = resolveGraphSpec(rigAsset, `${rigAsset.id ?? "rig"} graph`);
|
|
1160
|
+
if (!rigSpec) {
|
|
1161
|
+
pushError({
|
|
1162
|
+
message: "Rig graph is missing a usable spec or IR payload.",
|
|
1163
|
+
phase: "registration",
|
|
1164
|
+
timestamp: performance.now()
|
|
1165
|
+
});
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
792
1168
|
const rigOutputs = collectOutputPaths(rigSpec);
|
|
793
1169
|
const rigInputs = collectInputPaths(rigSpec);
|
|
794
1170
|
rigInputMapRef.current = collectInputPathMap(rigSpec);
|
|
795
|
-
|
|
796
|
-
const
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
subs: rigAsset.subscriptions ?? {
|
|
800
|
-
inputs: rigInputs,
|
|
801
|
-
outputs: rigOutputs
|
|
802
|
-
}
|
|
1171
|
+
recordOutputs(rigOutputs);
|
|
1172
|
+
const rigSubs = rigAsset.subscriptions ?? {
|
|
1173
|
+
inputs: rigInputs,
|
|
1174
|
+
outputs: rigOutputs
|
|
803
1175
|
};
|
|
804
|
-
const graphConfigs = [
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
1176
|
+
const graphConfigs = [
|
|
1177
|
+
{
|
|
1178
|
+
id: namespaceControllerId(rigAsset.id, namespace, "graph"),
|
|
1179
|
+
spec: namespaceGraphSpec(rigSpec, namespace),
|
|
1180
|
+
subs: namespaceSubscriptions(rigSubs, namespace)
|
|
1181
|
+
}
|
|
1182
|
+
];
|
|
1183
|
+
const poseGraphAsset = assetBundle.pose?.graph;
|
|
1184
|
+
if (poseGraphAsset) {
|
|
1185
|
+
const poseSpec = resolveGraphSpec(
|
|
1186
|
+
poseGraphAsset,
|
|
1187
|
+
`${poseGraphAsset.id ?? "pose"} graph`
|
|
1188
|
+
);
|
|
1189
|
+
if (poseSpec) {
|
|
1190
|
+
const poseOutputs = collectOutputPaths(poseSpec);
|
|
1191
|
+
const poseInputs = collectInputPaths(poseSpec);
|
|
1192
|
+
recordOutputs(poseOutputs);
|
|
1193
|
+
const poseSubs = poseGraphAsset.subscriptions ?? {
|
|
813
1194
|
inputs: poseInputs,
|
|
814
1195
|
outputs: poseOutputs
|
|
815
|
-
}
|
|
816
|
-
|
|
1196
|
+
};
|
|
1197
|
+
graphConfigs.push({
|
|
1198
|
+
id: namespaceControllerId(poseGraphAsset.id, namespace, "graph"),
|
|
1199
|
+
spec: namespaceGraphSpec(poseSpec, namespace),
|
|
1200
|
+
subs: namespaceSubscriptions(poseSubs, namespace)
|
|
1201
|
+
});
|
|
1202
|
+
} else {
|
|
1203
|
+
console.warn(
|
|
1204
|
+
"[vizij-runtime] Pose graph is missing a usable spec or IR payload; skipping registration."
|
|
1205
|
+
);
|
|
1206
|
+
}
|
|
817
1207
|
}
|
|
1208
|
+
outputPathsRef.current = namespacedOutputPaths;
|
|
1209
|
+
baseOutputPathsRef.current = baseOutputPaths;
|
|
1210
|
+
namespacedOutputPathsRef.current = namespacedOutputPaths;
|
|
818
1211
|
const graphIds = [];
|
|
819
1212
|
try {
|
|
820
1213
|
if (graphConfigs.length > 1) {
|
|
821
1214
|
const mergedId = registerMergedGraph({
|
|
1215
|
+
id: namespaceControllerId(
|
|
1216
|
+
mergedGraphRef.current ?? `merged-${namespace}`,
|
|
1217
|
+
namespace,
|
|
1218
|
+
"merged"
|
|
1219
|
+
) ?? void 0,
|
|
822
1220
|
graphs: graphConfigs,
|
|
823
1221
|
strategy: mergeStrategy ?? DEFAULT_MERGE
|
|
824
1222
|
});
|
|
@@ -842,8 +1240,9 @@ function VizijRuntimeProviderInner({
|
|
|
842
1240
|
const animationIds = [];
|
|
843
1241
|
for (const anim of assetBundle.animations ?? []) {
|
|
844
1242
|
try {
|
|
1243
|
+
const controllerId = namespaceControllerId(anim.id, namespace, "animation") ?? anim.id;
|
|
845
1244
|
const config = {
|
|
846
|
-
id:
|
|
1245
|
+
id: controllerId,
|
|
847
1246
|
setup: {
|
|
848
1247
|
animation: anim.clip,
|
|
849
1248
|
...anim.setup ?? {}
|
|
@@ -888,6 +1287,7 @@ function VizijRuntimeProviderInner({
|
|
|
888
1287
|
clearControllers,
|
|
889
1288
|
listControllers,
|
|
890
1289
|
mergeStrategy,
|
|
1290
|
+
namespace,
|
|
891
1291
|
onRegisterControllers,
|
|
892
1292
|
pushError,
|
|
893
1293
|
registerAnimation,
|
|
@@ -896,7 +1296,7 @@ function VizijRuntimeProviderInner({
|
|
|
896
1296
|
reportStatus,
|
|
897
1297
|
setInput
|
|
898
1298
|
]);
|
|
899
|
-
useEffect(() => {
|
|
1299
|
+
(0, import_react2.useEffect)(() => {
|
|
900
1300
|
if (!ready || status.loading) {
|
|
901
1301
|
return;
|
|
902
1302
|
}
|
|
@@ -909,7 +1309,7 @@ function VizijRuntimeProviderInner({
|
|
|
909
1309
|
});
|
|
910
1310
|
});
|
|
911
1311
|
}, [ready, status.loading, registerControllers, pushError]);
|
|
912
|
-
useEffect(() => {
|
|
1312
|
+
(0, import_react2.useEffect)(() => {
|
|
913
1313
|
if (!frame) {
|
|
914
1314
|
return;
|
|
915
1315
|
}
|
|
@@ -917,21 +1317,29 @@ function VizijRuntimeProviderInner({
|
|
|
917
1317
|
if (!writes.length) {
|
|
918
1318
|
return;
|
|
919
1319
|
}
|
|
920
|
-
const
|
|
1320
|
+
const setWorldValues = store.getState().setValues;
|
|
921
1321
|
const namespaceValue = status.namespace;
|
|
1322
|
+
const batched = [];
|
|
1323
|
+
const namespacedOutputs = namespacedOutputPathsRef.current;
|
|
1324
|
+
const baseOutputs = baseOutputPathsRef.current;
|
|
922
1325
|
writes.forEach((write) => {
|
|
923
1326
|
const path = normalisePath(write.path);
|
|
924
|
-
if (!
|
|
1327
|
+
if (!namespacedOutputs.has(path)) {
|
|
925
1328
|
return;
|
|
926
1329
|
}
|
|
927
1330
|
const raw = valueJSONToRaw(write.value);
|
|
928
1331
|
if (raw === void 0) {
|
|
929
1332
|
return;
|
|
930
1333
|
}
|
|
931
|
-
|
|
1334
|
+
const basePath = stripNamespace(path, namespaceValue);
|
|
1335
|
+
const targetPath = baseOutputs.has(basePath) ? basePath : path;
|
|
1336
|
+
batched.push({ id: targetPath, namespace: namespaceValue, value: raw });
|
|
932
1337
|
});
|
|
1338
|
+
if (batched.length > 0) {
|
|
1339
|
+
setWorldValues(batched);
|
|
1340
|
+
}
|
|
933
1341
|
}, [frame, status.namespace, store]);
|
|
934
|
-
const stagePoseNeutral = useCallback(
|
|
1342
|
+
const stagePoseNeutral = (0, import_react2.useCallback)(
|
|
935
1343
|
(force = false) => {
|
|
936
1344
|
const neutral = assetBundle.pose?.config?.neutralInputs ?? {};
|
|
937
1345
|
const rigMap = rigInputMapRef.current;
|
|
@@ -963,41 +1371,20 @@ function VizijRuntimeProviderInner({
|
|
|
963
1371
|
},
|
|
964
1372
|
[assetBundle.pose?.config?.neutralInputs, setInput]
|
|
965
1373
|
);
|
|
966
|
-
const setRendererValue = useCallback(
|
|
1374
|
+
const setRendererValue = (0, import_react2.useCallback)(
|
|
967
1375
|
(id, ns, value) => {
|
|
968
1376
|
store.getState().setValue(id, ns, value);
|
|
969
1377
|
},
|
|
970
1378
|
[store]
|
|
971
1379
|
);
|
|
972
|
-
const cancelAnimation = useCallback((path) => {
|
|
1380
|
+
const cancelAnimation = (0, import_react2.useCallback)((path) => {
|
|
973
1381
|
if (animationTweensRef.current.has(path)) {
|
|
974
1382
|
const entry = animationTweensRef.current.get(path);
|
|
975
1383
|
animationTweensRef.current.delete(path);
|
|
976
1384
|
entry?.resolve();
|
|
977
1385
|
}
|
|
978
1386
|
}, []);
|
|
979
|
-
const
|
|
980
|
-
if (rafHandleRef.current !== null) {
|
|
981
|
-
return;
|
|
982
|
-
}
|
|
983
|
-
const tick = (timestamp) => {
|
|
984
|
-
if (lastFrameTimeRef.current == null) {
|
|
985
|
-
lastFrameTimeRef.current = timestamp;
|
|
986
|
-
}
|
|
987
|
-
const dt = Math.max(0, (timestamp - lastFrameTimeRef.current) / 1e3);
|
|
988
|
-
lastFrameTimeRef.current = timestamp;
|
|
989
|
-
advanceAnimationTweens(dt);
|
|
990
|
-
advanceClipPlayback(dt);
|
|
991
|
-
if (animationTweensRef.current.size > 0 || clipPlaybackRef.current.size > 0) {
|
|
992
|
-
rafHandleRef.current = requestAnimationFrame(tick);
|
|
993
|
-
} else {
|
|
994
|
-
rafHandleRef.current = null;
|
|
995
|
-
lastFrameTimeRef.current = null;
|
|
996
|
-
}
|
|
997
|
-
};
|
|
998
|
-
rafHandleRef.current = requestAnimationFrame(tick);
|
|
999
|
-
}, []);
|
|
1000
|
-
const advanceAnimationTweens = useCallback(
|
|
1387
|
+
const advanceAnimationTweens = (0, import_react2.useCallback)(
|
|
1001
1388
|
(dt) => {
|
|
1002
1389
|
if (animationTweensRef.current.size === 0) {
|
|
1003
1390
|
return;
|
|
@@ -1019,7 +1406,7 @@ function VizijRuntimeProviderInner({
|
|
|
1019
1406
|
},
|
|
1020
1407
|
[setInput]
|
|
1021
1408
|
);
|
|
1022
|
-
const sampleTrack = useCallback(
|
|
1409
|
+
const sampleTrack = (0, import_react2.useCallback)(
|
|
1023
1410
|
(track, time) => {
|
|
1024
1411
|
const keyframes = Array.isArray(track.keyframes) ? track.keyframes : [];
|
|
1025
1412
|
if (!keyframes.length) {
|
|
@@ -1050,7 +1437,7 @@ function VizijRuntimeProviderInner({
|
|
|
1050
1437
|
},
|
|
1051
1438
|
[]
|
|
1052
1439
|
);
|
|
1053
|
-
const advanceClipPlayback = useCallback(
|
|
1440
|
+
const advanceClipPlayback = (0, import_react2.useCallback)(
|
|
1054
1441
|
(dt) => {
|
|
1055
1442
|
if (clipPlaybackRef.current.size === 0) {
|
|
1056
1443
|
return;
|
|
@@ -1099,21 +1486,22 @@ function VizijRuntimeProviderInner({
|
|
|
1099
1486
|
},
|
|
1100
1487
|
[assetBundle.animations, sampleTrack, setInput]
|
|
1101
1488
|
);
|
|
1102
|
-
const animateValue = useCallback(
|
|
1489
|
+
const animateValue = (0, import_react2.useCallback)(
|
|
1103
1490
|
(path, target, options) => {
|
|
1104
1491
|
const easing = resolveEasing(options?.easing);
|
|
1105
1492
|
const duration = Math.max(0, options?.duration ?? DEFAULT_DURATION);
|
|
1106
1493
|
cancelAnimation(path);
|
|
1107
|
-
const
|
|
1108
|
-
const
|
|
1109
|
-
const
|
|
1494
|
+
const namespacedPath = namespaceTypedPath(path, namespaceRef.current);
|
|
1495
|
+
const current = getPathSnapshot(namespacedPath);
|
|
1496
|
+
const fromValue = (0, import_value_json2.valueAsNumber)(current);
|
|
1497
|
+
const toValue = (0, import_value_json2.valueAsNumber)(target);
|
|
1110
1498
|
if (fromValue == null || toValue == null || duration === 0) {
|
|
1111
1499
|
setInput(path, target);
|
|
1112
1500
|
return Promise.resolve();
|
|
1113
1501
|
}
|
|
1114
1502
|
return new Promise((resolve) => {
|
|
1115
1503
|
animationTweensRef.current.set(path, {
|
|
1116
|
-
path,
|
|
1504
|
+
path: namespacedPath,
|
|
1117
1505
|
from: fromValue,
|
|
1118
1506
|
to: toValue,
|
|
1119
1507
|
duration,
|
|
@@ -1121,12 +1509,12 @@ function VizijRuntimeProviderInner({
|
|
|
1121
1509
|
easing,
|
|
1122
1510
|
resolve
|
|
1123
1511
|
});
|
|
1124
|
-
|
|
1512
|
+
markActivity();
|
|
1125
1513
|
});
|
|
1126
1514
|
},
|
|
1127
|
-
[cancelAnimation, getPathSnapshot,
|
|
1515
|
+
[cancelAnimation, getPathSnapshot, markActivity, setInput]
|
|
1128
1516
|
);
|
|
1129
|
-
const playAnimation = useCallback(
|
|
1517
|
+
const playAnimation = (0, import_react2.useCallback)(
|
|
1130
1518
|
(id, options) => {
|
|
1131
1519
|
const clip = assetBundle.animations?.find((anim) => anim.id === id);
|
|
1132
1520
|
if (!clip) {
|
|
@@ -1149,12 +1537,12 @@ function VizijRuntimeProviderInner({
|
|
|
1149
1537
|
weight,
|
|
1150
1538
|
resolve
|
|
1151
1539
|
});
|
|
1152
|
-
|
|
1540
|
+
markActivity();
|
|
1153
1541
|
});
|
|
1154
1542
|
},
|
|
1155
|
-
[assetBundle.animations,
|
|
1543
|
+
[assetBundle.animations, markActivity]
|
|
1156
1544
|
);
|
|
1157
|
-
const stopAnimation = useCallback(
|
|
1545
|
+
const stopAnimation = (0, import_react2.useCallback)(
|
|
1158
1546
|
(id) => {
|
|
1159
1547
|
const clip = assetBundle.animations?.find((anim) => anim.id === id);
|
|
1160
1548
|
const state = clipPlaybackRef.current.get(id);
|
|
@@ -1173,7 +1561,7 @@ function VizijRuntimeProviderInner({
|
|
|
1173
1561
|
},
|
|
1174
1562
|
[assetBundle.animations, setInput]
|
|
1175
1563
|
);
|
|
1176
|
-
const registerInputDriver = useCallback(
|
|
1564
|
+
const registerInputDriver = (0, import_react2.useCallback)(
|
|
1177
1565
|
(id, factory) => {
|
|
1178
1566
|
const driver = factory({
|
|
1179
1567
|
setInput,
|
|
@@ -1223,32 +1611,111 @@ function VizijRuntimeProviderInner({
|
|
|
1223
1611
|
},
|
|
1224
1612
|
[faceId, namespace, pushError, setInput, setRendererValue]
|
|
1225
1613
|
);
|
|
1226
|
-
const advanceAnimations = useCallback(
|
|
1614
|
+
const advanceAnimations = (0, import_react2.useCallback)(
|
|
1227
1615
|
(dt) => {
|
|
1228
1616
|
advanceAnimationTweens(dt);
|
|
1229
1617
|
advanceClipPlayback(dt);
|
|
1230
1618
|
},
|
|
1231
1619
|
[advanceAnimationTweens, advanceClipPlayback]
|
|
1232
1620
|
);
|
|
1233
|
-
const
|
|
1234
|
-
(
|
|
1621
|
+
const flushStagedInputs = (0, import_react2.useCallback)(() => {
|
|
1622
|
+
if (stagedInputsRef.current.size === 0) {
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1625
|
+
stagedInputsRef.current.forEach(({ value, shape }, path) => {
|
|
1626
|
+
orchestratorSetInput(path, value, shape);
|
|
1627
|
+
});
|
|
1628
|
+
stagedInputsRef.current.clear();
|
|
1629
|
+
}, [orchestratorSetInput]);
|
|
1630
|
+
const step = (0, import_react2.useCallback)(
|
|
1631
|
+
(dt, opts) => {
|
|
1632
|
+
if (dt > 0 && Number.isFinite(dt)) {
|
|
1633
|
+
const prev = avgStepDtRef.current ?? dt;
|
|
1634
|
+
const alpha = 0.1;
|
|
1635
|
+
avgStepDtRef.current = prev * (1 - alpha) + dt * alpha;
|
|
1636
|
+
}
|
|
1235
1637
|
advanceAnimations(dt);
|
|
1236
|
-
|
|
1638
|
+
flushStagedInputs();
|
|
1639
|
+
if (driveOrchestratorRef.current || opts?.forceRuntime) {
|
|
1640
|
+
stepRuntime(dt);
|
|
1641
|
+
}
|
|
1237
1642
|
},
|
|
1238
|
-
[advanceAnimations, stepRuntime]
|
|
1643
|
+
[advanceAnimations, flushStagedInputs, stepRuntime]
|
|
1239
1644
|
);
|
|
1240
|
-
useEffect(() => {
|
|
1645
|
+
(0, import_react2.useEffect)(() => {
|
|
1646
|
+
if (loopMode !== "active") {
|
|
1647
|
+
return;
|
|
1648
|
+
}
|
|
1649
|
+
let rafId = null;
|
|
1650
|
+
let lastTime = null;
|
|
1651
|
+
const tick = (timestamp) => {
|
|
1652
|
+
if (loopModeRef.current !== "active") {
|
|
1653
|
+
return;
|
|
1654
|
+
}
|
|
1655
|
+
if (lastTime == null) {
|
|
1656
|
+
lastTime = timestamp;
|
|
1657
|
+
}
|
|
1658
|
+
const dt = Math.max(0, (timestamp - lastTime) / 1e3);
|
|
1659
|
+
lastTime = timestamp;
|
|
1660
|
+
step(dt || 0);
|
|
1661
|
+
requestLoopMode(computeDesiredLoopMode());
|
|
1662
|
+
rafId = requestAnimationFrame(tick);
|
|
1663
|
+
};
|
|
1664
|
+
rafId = requestAnimationFrame(tick);
|
|
1241
1665
|
return () => {
|
|
1242
|
-
if (
|
|
1243
|
-
cancelAnimationFrame(
|
|
1244
|
-
|
|
1666
|
+
if (rafId !== null) {
|
|
1667
|
+
cancelAnimationFrame(rafId);
|
|
1668
|
+
}
|
|
1669
|
+
};
|
|
1670
|
+
}, [loopMode, computeDesiredLoopMode, requestLoopMode, step]);
|
|
1671
|
+
(0, import_react2.useEffect)(() => {
|
|
1672
|
+
if (loopMode !== "idle-visible" && loopMode !== "idle-hidden") {
|
|
1673
|
+
return;
|
|
1674
|
+
}
|
|
1675
|
+
if (typeof window === "undefined") {
|
|
1676
|
+
return;
|
|
1677
|
+
}
|
|
1678
|
+
const fps = loopMode === "idle-visible" ? VISIBLE_IDLE_FPS : HIDDEN_IDLE_FPS;
|
|
1679
|
+
if (fps <= 0) {
|
|
1680
|
+
return;
|
|
1681
|
+
}
|
|
1682
|
+
let lastTime = now();
|
|
1683
|
+
const interval = 1e3 / fps;
|
|
1684
|
+
const tick = () => {
|
|
1685
|
+
if (loopModeRef.current !== "idle-visible" && loopModeRef.current !== "idle-hidden") {
|
|
1686
|
+
return;
|
|
1245
1687
|
}
|
|
1246
|
-
|
|
1688
|
+
const current = now();
|
|
1689
|
+
const dt = Math.max(0, (current - lastTime) / 1e3);
|
|
1690
|
+
lastTime = current;
|
|
1691
|
+
step(dt || 0);
|
|
1692
|
+
requestLoopMode(computeDesiredLoopMode());
|
|
1693
|
+
};
|
|
1694
|
+
const intervalId = window.setInterval(tick, interval);
|
|
1695
|
+
return () => {
|
|
1696
|
+
window.clearInterval(intervalId);
|
|
1697
|
+
};
|
|
1698
|
+
}, [loopMode, computeDesiredLoopMode, requestLoopMode, step]);
|
|
1699
|
+
(0, import_react2.useEffect)(() => {
|
|
1700
|
+
return () => {
|
|
1247
1701
|
animationTweensRef.current.clear();
|
|
1248
1702
|
clipPlaybackRef.current.clear();
|
|
1249
1703
|
};
|
|
1250
1704
|
}, []);
|
|
1251
|
-
|
|
1705
|
+
(0, import_react2.useEffect)(() => {
|
|
1706
|
+
if (typeof window === "undefined") {
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1709
|
+
const id = window.setInterval(() => {
|
|
1710
|
+
const avg = avgStepDtRef.current;
|
|
1711
|
+
const stepHz = avg && Number.isFinite(avg) && avg > 0 ? 1 / avg : void 0;
|
|
1712
|
+
reportStatus(
|
|
1713
|
+
(prev) => prev.stepHz === stepHz ? prev : { ...prev, stepHz }
|
|
1714
|
+
);
|
|
1715
|
+
}, 500);
|
|
1716
|
+
return () => window.clearInterval(id);
|
|
1717
|
+
}, [reportStatus]);
|
|
1718
|
+
const contextValue = (0, import_react2.useMemo)(
|
|
1252
1719
|
() => ({
|
|
1253
1720
|
...status,
|
|
1254
1721
|
assetBundle,
|
|
@@ -1261,7 +1728,8 @@ function VizijRuntimeProviderInner({
|
|
|
1261
1728
|
playAnimation,
|
|
1262
1729
|
stopAnimation,
|
|
1263
1730
|
step,
|
|
1264
|
-
advanceAnimations
|
|
1731
|
+
advanceAnimations,
|
|
1732
|
+
inputConstraints
|
|
1265
1733
|
}),
|
|
1266
1734
|
[
|
|
1267
1735
|
status,
|
|
@@ -1275,20 +1743,21 @@ function VizijRuntimeProviderInner({
|
|
|
1275
1743
|
playAnimation,
|
|
1276
1744
|
stopAnimation,
|
|
1277
1745
|
step,
|
|
1278
|
-
advanceAnimations
|
|
1746
|
+
advanceAnimations,
|
|
1747
|
+
inputConstraints
|
|
1279
1748
|
]
|
|
1280
1749
|
);
|
|
1281
|
-
return /* @__PURE__ */ jsx(VizijRuntimeContext.Provider, { value: contextValue, children });
|
|
1750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VizijRuntimeContext.Provider, { value: contextValue, children });
|
|
1282
1751
|
}
|
|
1283
1752
|
|
|
1284
1753
|
// src/VizijRuntimeFace.tsx
|
|
1285
|
-
|
|
1286
|
-
|
|
1754
|
+
var import_react4 = require("react");
|
|
1755
|
+
var import_render2 = require("@vizij/render");
|
|
1287
1756
|
|
|
1288
1757
|
// src/hooks/useVizijRuntime.ts
|
|
1289
|
-
|
|
1758
|
+
var import_react3 = require("react");
|
|
1290
1759
|
function useVizijRuntime() {
|
|
1291
|
-
const ctx = useContext(VizijRuntimeContext);
|
|
1760
|
+
const ctx = (0, import_react3.useContext)(VizijRuntimeContext);
|
|
1292
1761
|
if (!ctx) {
|
|
1293
1762
|
throw new Error(
|
|
1294
1763
|
"useVizijRuntime must be used within a VizijRuntimeProvider."
|
|
@@ -1298,7 +1767,7 @@ function useVizijRuntime() {
|
|
|
1298
1767
|
}
|
|
1299
1768
|
|
|
1300
1769
|
// src/VizijRuntimeFace.tsx
|
|
1301
|
-
|
|
1770
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1302
1771
|
function VizijRuntimeFaceInner({
|
|
1303
1772
|
namespaceOverride,
|
|
1304
1773
|
...props
|
|
@@ -1307,8 +1776,8 @@ function VizijRuntimeFaceInner({
|
|
|
1307
1776
|
if (!rootId) {
|
|
1308
1777
|
return null;
|
|
1309
1778
|
}
|
|
1310
|
-
return /* @__PURE__ */
|
|
1311
|
-
Vizij,
|
|
1779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1780
|
+
import_render2.Vizij,
|
|
1312
1781
|
{
|
|
1313
1782
|
...props,
|
|
1314
1783
|
rootId,
|
|
@@ -1316,19 +1785,17 @@ function VizijRuntimeFaceInner({
|
|
|
1316
1785
|
}
|
|
1317
1786
|
);
|
|
1318
1787
|
}
|
|
1319
|
-
var VizijRuntimeFace = memo(VizijRuntimeFaceInner);
|
|
1788
|
+
var VizijRuntimeFace = (0, import_react4.memo)(VizijRuntimeFaceInner);
|
|
1320
1789
|
|
|
1321
1790
|
// src/hooks/useVizijOutputs.ts
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
} from "@vizij/render";
|
|
1325
|
-
import { getLookup } from "@vizij/utils";
|
|
1791
|
+
var import_render3 = require("@vizij/render");
|
|
1792
|
+
var import_utils = require("@vizij/utils");
|
|
1326
1793
|
function useVizijOutputs(paths) {
|
|
1327
1794
|
const { namespace } = useVizijRuntime();
|
|
1328
|
-
return useVizijStore((state) => {
|
|
1795
|
+
return (0, import_render3.useVizijStore)((state) => {
|
|
1329
1796
|
const result = {};
|
|
1330
1797
|
paths.forEach((path) => {
|
|
1331
|
-
const lookup = getLookup(namespace, path);
|
|
1798
|
+
const lookup = (0, import_utils.getLookup)(namespace, path);
|
|
1332
1799
|
result[path] = state.values.get(lookup);
|
|
1333
1800
|
});
|
|
1334
1801
|
return result;
|
|
@@ -1336,17 +1803,15 @@ function useVizijOutputs(paths) {
|
|
|
1336
1803
|
}
|
|
1337
1804
|
|
|
1338
1805
|
// src/hooks/useRigInput.ts
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
} from "@vizij/render";
|
|
1343
|
-
import { getLookup as getLookup2 } from "@vizij/utils";
|
|
1806
|
+
var import_react5 = require("react");
|
|
1807
|
+
var import_render4 = require("@vizij/render");
|
|
1808
|
+
var import_utils2 = require("@vizij/utils");
|
|
1344
1809
|
function useRigInput(path) {
|
|
1345
1810
|
const { namespace, setInput } = useVizijRuntime();
|
|
1346
|
-
const value =
|
|
1347
|
-
return state.values.get(
|
|
1811
|
+
const value = (0, import_render4.useVizijStore)((state) => {
|
|
1812
|
+
return state.values.get((0, import_utils2.getLookup)(namespace, path));
|
|
1348
1813
|
});
|
|
1349
|
-
const setter =
|
|
1814
|
+
const setter = (0, import_react5.useCallback)(
|
|
1350
1815
|
(next, shape) => {
|
|
1351
1816
|
setInput(path, next, shape);
|
|
1352
1817
|
},
|
|
@@ -1354,10 +1819,11 @@ function useRigInput(path) {
|
|
|
1354
1819
|
);
|
|
1355
1820
|
return [value, setter];
|
|
1356
1821
|
}
|
|
1357
|
-
export
|
|
1822
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1823
|
+
0 && (module.exports = {
|
|
1358
1824
|
VizijRuntimeFace,
|
|
1359
1825
|
VizijRuntimeProvider,
|
|
1360
1826
|
useRigInput,
|
|
1361
1827
|
useVizijOutputs,
|
|
1362
1828
|
useVizijRuntime
|
|
1363
|
-
};
|
|
1829
|
+
});
|