@vizij/render 0.1.2 → 1.0.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.
- package/README.md +5 -4
- package/dist/index.d.mts +293 -92
- package/dist/index.d.ts +293 -92
- package/dist/index.js +634 -496
- package/dist/index.mjs +601 -462
- package/package.json +3 -5
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ This package exposes the `Vizij` canvas component along with hooks, stores, and
|
|
|
23
23
|
|
|
24
24
|
- `Vizij` renders a fully managed `@react-three/fiber` canvas with sensible defaults for orthographic cameras and safe-area overlays.
|
|
25
25
|
- A Zustand-powered store (`useVizijStore`) tracks renderables, controllers, and transient state. Hooks let you read or mutate slices without re-rendering entire scenes.
|
|
26
|
-
-
|
|
26
|
+
- The loader (`loadGLTF`, `loadGLTFFromBlob` and their `WithBundle` forms) turns a rigged GLB into the world model; `buildSceneGraph` and `exportScene` turn the world model back into GLB bytes. Both run in Node as well as in a browser. The tuple helpers return `[world, animatables, animations]`, where `animations` contains parsed clip metadata for any channels embedded in the GLB.
|
|
27
27
|
- Controllers wrap common behaviours (e.g., pointer interaction, safe-area visualisation) so you can compose features quickly.
|
|
28
28
|
|
|
29
29
|
---
|
|
@@ -96,8 +96,8 @@ The store tracks world graph entries, controllers, debug overlays, and renderabl
|
|
|
96
96
|
## Controllers & Helpers
|
|
97
97
|
|
|
98
98
|
- Controllers under `src/controllers` encapsulate input handling, camera logic, and other behaviours. Compose them with your own React components.
|
|
99
|
-
- `loadGLTF` / `
|
|
100
|
-
- `
|
|
99
|
+
- `loadGLTF` / `loadGLTFFromBlob` load rig assets and extract the animatable metadata used by `@vizij/runtime-react`. A blob is parsed in memory, with nothing fetched.
|
|
100
|
+
- `buildSceneGraph(world, animatables, rootId)` builds the three.js graph of a world element with no renderer, and `exportScene(root, { bundle, animations })` encodes a graph as GLB bytes. Saving or uploading the bytes is the caller's job.
|
|
101
101
|
|
|
102
102
|
All exports are re-exported through `src/index.tsx`, so a simple `import { loadGLTF } from "@vizij/render"` works.
|
|
103
103
|
|
|
@@ -107,7 +107,8 @@ Vizij scenes persist authoring metadata inside GLBs so third-party tools see bak
|
|
|
107
107
|
|
|
108
108
|
- Every renderable still carries a `RobotData` extension in `userData` describing features and animatable bindings.
|
|
109
109
|
- The exporter now writes a root-level `extensions.VIZIJ_bundle` block following the schema in [`src/types/vizij-bundle.ts`](./src/types/vizij-bundle.ts). It contains rig graphs, pose configs, stored Vizij clips, and provenance hashes.
|
|
110
|
-
- Use `exportScene(
|
|
110
|
+
- Use `exportScene(root, { bundle, animations })` to embed both the Vizij bundle and optional baked `THREE.AnimationClip` instances; it resolves to the GLB as an `ArrayBuffer`. The helper attaches the bundle only for the export call and restores the original object.
|
|
111
|
+
- A graph from `buildSceneGraph` carries each element's authored values: node translation, rotation and scale, morph weights and material factors equal the `RobotData` defaults written beside them, not a runtime pose.
|
|
111
112
|
- When loading assets, prefer `loadGLTFWithBundle` / `loadGLTFFromBlobWithBundle` to retrieve `{ world, animatables, bundle, animations }`. The legacy tuple helpers return `[world, animatables, animations]` if you only need the renderer state.
|
|
112
113
|
- The new `animations` field exposes `VizijAnimationClipData[]`, which maps each glTF animation channel back to Vizij animatable ids (`RobotData.features.*.value.id`). Each track provides component-aware `times`/`values` arrays so runtimes can register clips without re-parsing the GLB.
|
|
113
114
|
- `extractVizijBundle(scene)` and `applyVizijBundle(scene, bundle)` (under `src/functions/vizij-bundle.ts`) let advanced tooling inspect or mutate bundles without triggering a fresh export.
|
package/dist/index.d.mts
CHANGED
|
@@ -2,49 +2,11 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { CSSProperties, ComponentProps, ReactNode, RefObject, MouseEvent } from 'react';
|
|
4
4
|
import { Canvas, ThreeEvent } from '@react-three/fiber';
|
|
5
|
-
import * as zustand from 'zustand';
|
|
6
5
|
import * as THREE from 'three';
|
|
7
|
-
import {
|
|
6
|
+
import { BufferGeometry, ShapeGeometry, ToneMapping, Group as Group$1, Mesh, AnimationClip, Object3D } from 'three';
|
|
7
|
+
import * as zustand from 'zustand';
|
|
8
8
|
import { RawValue, AnimatableValue, RawVector2 } from '@vizij/utils';
|
|
9
9
|
|
|
10
|
-
interface VizijProps {
|
|
11
|
-
style?: CSSProperties;
|
|
12
|
-
className?: string;
|
|
13
|
-
rootId: string;
|
|
14
|
-
namespace?: string;
|
|
15
|
-
showSafeArea?: boolean;
|
|
16
|
-
showSelectionGlow?: boolean;
|
|
17
|
-
onPointerMissed?: ComponentProps<typeof Canvas>["onPointerMissed"];
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Renders the Vizij component.
|
|
21
|
-
*
|
|
22
|
-
* @param style - The style object for the Vizij component.
|
|
23
|
-
*
|
|
24
|
-
* @param className - The CSS class name for the Vizij component
|
|
25
|
-
*
|
|
26
|
-
* @param rootId - The root identifier for the Vizij component.
|
|
27
|
-
*
|
|
28
|
-
* @param namespace - The namespace for the Vizij component
|
|
29
|
-
*
|
|
30
|
-
* @param showSafeArea - Whether to show the safe area.
|
|
31
|
-
*
|
|
32
|
-
* @returns The rendered ReactNode.
|
|
33
|
-
*/
|
|
34
|
-
declare function Vizij({ style, className, rootId, namespace, showSafeArea, showSelectionGlow, onPointerMissed, }: VizijProps): ReactNode;
|
|
35
|
-
interface InnerVizijProps {
|
|
36
|
-
rootId: string;
|
|
37
|
-
namespace: string;
|
|
38
|
-
container?: {
|
|
39
|
-
width: number;
|
|
40
|
-
height: number;
|
|
41
|
-
resolution: number;
|
|
42
|
-
};
|
|
43
|
-
showSafeArea?: boolean;
|
|
44
|
-
showSelectionGlow?: boolean;
|
|
45
|
-
}
|
|
46
|
-
declare function InnerVizij({ rootId, namespace, container, showSafeArea, showSelectionGlow, }: InnerVizijProps): react_jsx_runtime.JSX.Element;
|
|
47
|
-
|
|
48
10
|
/**
|
|
49
11
|
* A wrapping type to reference an attribute that is animatable.
|
|
50
12
|
*
|
|
@@ -92,7 +54,6 @@ interface RenderableBase {
|
|
|
92
54
|
name: string;
|
|
93
55
|
tags: string[];
|
|
94
56
|
type: string;
|
|
95
|
-
refs: Record<string, RefObject<any>>;
|
|
96
57
|
features: Record<string, Feature>;
|
|
97
58
|
}
|
|
98
59
|
|
|
@@ -109,19 +70,17 @@ interface Stored<T extends Omit<RenderableBase, "refs">> {
|
|
|
109
70
|
type StoredRenderable = Stored<RenderableBase>;
|
|
110
71
|
|
|
111
72
|
/**
|
|
112
|
-
* An object for creating
|
|
73
|
+
* An object for creating rectangles
|
|
113
74
|
*
|
|
114
|
-
* @param id - The id of the
|
|
115
|
-
* @param name - The name of the
|
|
116
|
-
* @param tags - The tags of the
|
|
75
|
+
* @param id - The id of the rectangle
|
|
76
|
+
* @param name - The name of the rectangle
|
|
77
|
+
* @param tags - The tags of the rectangle
|
|
117
78
|
* @param type - Type flag
|
|
118
|
-
* @param
|
|
119
|
-
* @param
|
|
120
|
-
* @param children - The children of the ellipse (list of ids for other bodies or shapes)
|
|
79
|
+
* @param features - The features of the rectangle (translation, rotation, and scale)
|
|
80
|
+
* @param children - The children of the rectangle (list of ids for other bodies or shapes)
|
|
121
81
|
*/
|
|
122
|
-
interface
|
|
123
|
-
type: "
|
|
124
|
-
refs: Record<string, RefObject<Mesh>>;
|
|
82
|
+
interface Rectangle extends RenderableBase {
|
|
83
|
+
type: "rectangle";
|
|
125
84
|
features: {
|
|
126
85
|
height: Feature;
|
|
127
86
|
width: Feature;
|
|
@@ -130,28 +89,27 @@ interface Ellipse extends RenderableBase {
|
|
|
130
89
|
fillColor?: Feature;
|
|
131
90
|
strokeColor?: Feature;
|
|
132
91
|
strokeWidth?: Feature;
|
|
92
|
+
strokeRadius?: Feature;
|
|
133
93
|
strokeOffset?: Feature;
|
|
134
94
|
translation: Feature;
|
|
135
95
|
rotation: Feature;
|
|
136
96
|
};
|
|
137
97
|
}
|
|
138
|
-
type
|
|
139
|
-
type
|
|
98
|
+
type RectangleFeature = keyof Rectangle["features"];
|
|
99
|
+
type StoredRectangle = Stored<Rectangle>;
|
|
140
100
|
|
|
141
101
|
/**
|
|
142
|
-
* An object for creating
|
|
102
|
+
* An object for creating hierarchies/bodies
|
|
143
103
|
*
|
|
144
|
-
* @param id - The id of the
|
|
145
|
-
* @param name - The name of the
|
|
146
|
-
* @param tags - The tags of the
|
|
104
|
+
* @param id - The id of the ellipse
|
|
105
|
+
* @param name - The name of the ellipse
|
|
106
|
+
* @param tags - The tags of the ellipse
|
|
147
107
|
* @param type - Type flag
|
|
148
|
-
* @param
|
|
149
|
-
* @param
|
|
150
|
-
* @param children - The children of the rectangle (list of ids for other bodies or shapes)
|
|
108
|
+
* @param features - The features of the ellipse (translation, rotation, and scale)
|
|
109
|
+
* @param children - The children of the ellipse (list of ids for other bodies or shapes)
|
|
151
110
|
*/
|
|
152
|
-
interface
|
|
153
|
-
type: "
|
|
154
|
-
refs: Record<string, RefObject<Mesh>>;
|
|
111
|
+
interface Ellipse extends RenderableBase {
|
|
112
|
+
type: "ellipse";
|
|
155
113
|
features: {
|
|
156
114
|
height: Feature;
|
|
157
115
|
width: Feature;
|
|
@@ -160,14 +118,13 @@ interface Rectangle extends RenderableBase {
|
|
|
160
118
|
fillColor?: Feature;
|
|
161
119
|
strokeColor?: Feature;
|
|
162
120
|
strokeWidth?: Feature;
|
|
163
|
-
strokeRadius?: Feature;
|
|
164
121
|
strokeOffset?: Feature;
|
|
165
122
|
translation: Feature;
|
|
166
123
|
rotation: Feature;
|
|
167
124
|
};
|
|
168
125
|
}
|
|
169
|
-
type
|
|
170
|
-
type
|
|
126
|
+
type EllipseFeature = keyof Ellipse["features"];
|
|
127
|
+
type StoredEllipse = Stored<Ellipse>;
|
|
171
128
|
|
|
172
129
|
/**
|
|
173
130
|
* An object for creating hierarchies/groups
|
|
@@ -176,14 +133,12 @@ type StoredRectangle = Stored<Rectangle>;
|
|
|
176
133
|
* @param name - The name of the group
|
|
177
134
|
* @param tags - The tags of the group
|
|
178
135
|
* @param type - Type flag
|
|
179
|
-
* @param refs - The reference to the group[s] in the vizij, for each namespace
|
|
180
136
|
* @param features - The features of the group (translation, rotation, and scale)
|
|
181
137
|
* @param root - Whether the group is a root node
|
|
182
138
|
* @param children - The children of the group (list of ids for other groups or shapes)
|
|
183
139
|
*/
|
|
184
140
|
interface Group extends RenderableBase {
|
|
185
141
|
type: "group";
|
|
186
|
-
refs: Record<string, RefObject<Group$1>>;
|
|
187
142
|
root: boolean;
|
|
188
143
|
features: {
|
|
189
144
|
translation: Feature;
|
|
@@ -209,7 +164,6 @@ type StoredGroup = Stored<Group>;
|
|
|
209
164
|
* @property name - Human-readable name for the shape
|
|
210
165
|
* @property tags - List of tags for categorizing and filtering
|
|
211
166
|
* @property type - Always "shape"
|
|
212
|
-
* @property refs - Map of React refs to Three.js Mesh objects
|
|
213
167
|
* @property features - Visual and transformation properties that can be animated
|
|
214
168
|
* @property material - The type of Three.js material to use for rendering
|
|
215
169
|
* @property geometry - The Three.js geometry defining the shape's structure
|
|
@@ -220,7 +174,6 @@ type StoredGroup = Stored<Group>;
|
|
|
220
174
|
*/
|
|
221
175
|
interface Shape extends RenderableBase {
|
|
222
176
|
type: "shape";
|
|
223
|
-
refs: Record<string, RefObject<Mesh>>;
|
|
224
177
|
features: {
|
|
225
178
|
shininess?: Feature;
|
|
226
179
|
opacity?: Feature;
|
|
@@ -255,8 +208,6 @@ declare enum ShapeMaterial {
|
|
|
255
208
|
type ShapeFeature = keyof Shape["features"];
|
|
256
209
|
type StoredShape = Stored<Omit<Shape, "geometry">>;
|
|
257
210
|
|
|
258
|
-
type World = Record<string, Group | Ellipse | Rectangle | Shape>;
|
|
259
|
-
|
|
260
211
|
type RenderableFeature = GroupFeature | EllipseFeature;
|
|
261
212
|
|
|
262
213
|
/**
|
|
@@ -279,6 +230,57 @@ interface Selection {
|
|
|
279
230
|
};
|
|
280
231
|
}
|
|
281
232
|
|
|
233
|
+
type World = Record<string, Group | Ellipse | Rectangle | Shape>;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Vizij-level tone-mapping selection.
|
|
237
|
+
*
|
|
238
|
+
* This is a stable, serializable string enum rather than a raw three.js
|
|
239
|
+
* constant so it can be persisted in the `VIZIJ_bundle` extension and round-trip
|
|
240
|
+
* through import/export without leaking three's numeric enum values into stored
|
|
241
|
+
* data.
|
|
242
|
+
*
|
|
243
|
+
* - `"none"` — no tone mapping. Values are written to the framebuffer as-is and
|
|
244
|
+
* clip at 1.0. This matches plain web/canvas rendering and is the historical
|
|
245
|
+
* vizij default (chosen so studio colors match the canvas).
|
|
246
|
+
* - `"agx"` — AgX, Blender 4.x's default view transform. Compresses
|
|
247
|
+
* over-1.0 emissive into soft, slightly-desaturated color; matches faces
|
|
248
|
+
* authored/exported from Blender.
|
|
249
|
+
* - `"aces"` — ACES Filmic, a punchier cinematic curve.
|
|
250
|
+
* - `"neutral"` — Khronos PBR Neutral, a mild curve that preserves hue/saturation
|
|
251
|
+
* while taming highlights.
|
|
252
|
+
*/
|
|
253
|
+
type ToneMappingMode = "none" | "agx" | "aces" | "neutral";
|
|
254
|
+
/**
|
|
255
|
+
* The set of supported tone-mapping modes, in display order. Useful for
|
|
256
|
+
* building selection UIs.
|
|
257
|
+
*/
|
|
258
|
+
declare const TONE_MAPPING_MODES: ToneMappingMode[];
|
|
259
|
+
/**
|
|
260
|
+
* Human-readable labels for each tone-mapping mode.
|
|
261
|
+
*/
|
|
262
|
+
declare const TONE_MAPPING_LABELS: Record<ToneMappingMode, string>;
|
|
263
|
+
/**
|
|
264
|
+
* The default tone-mapping mode used when a face/scene has not specified one.
|
|
265
|
+
* `"none"` preserves the historical web-matching behavior.
|
|
266
|
+
*/
|
|
267
|
+
declare const DEFAULT_TONE_MAPPING_MODE: ToneMappingMode;
|
|
268
|
+
/**
|
|
269
|
+
* Type guard: is `value` a valid {@link ToneMappingMode}?
|
|
270
|
+
*/
|
|
271
|
+
declare function isToneMappingMode(value: unknown): value is ToneMappingMode;
|
|
272
|
+
/**
|
|
273
|
+
* Resolve a {@link ToneMappingMode} (or an unknown/undefined stored value) to
|
|
274
|
+
* the corresponding three.js tone-mapping constant. Falls back to
|
|
275
|
+
* {@link DEFAULT_TONE_MAPPING_MODE} for missing/invalid input.
|
|
276
|
+
*/
|
|
277
|
+
declare function resolveToneMapping(mode: unknown): ToneMapping;
|
|
278
|
+
/**
|
|
279
|
+
* Normalize an unknown/stored value into a valid {@link ToneMappingMode},
|
|
280
|
+
* falling back to {@link DEFAULT_TONE_MAPPING_MODE}.
|
|
281
|
+
*/
|
|
282
|
+
declare function normalizeToneMappingMode(value: unknown): ToneMappingMode;
|
|
283
|
+
|
|
282
284
|
type VizijBundleVersion = 1;
|
|
283
285
|
type VizijBundleGraphKind = "rig" | "pose" | "pose-driver" | "animation-bridge" | "low-level" | string;
|
|
284
286
|
type VizijPoseId = string;
|
|
@@ -291,6 +293,40 @@ interface VizijBundleGraphMetadata {
|
|
|
291
293
|
exportedAt?: string;
|
|
292
294
|
[key: string]: unknown;
|
|
293
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* One path in a profile, with its type and constraints — arora's `KeyInfo`
|
|
298
|
+
* shape, so a profile round-trips through the descriptor the runtime already
|
|
299
|
+
* speaks.
|
|
300
|
+
*/
|
|
301
|
+
interface VizijProfileKey {
|
|
302
|
+
path: string;
|
|
303
|
+
kind?: string;
|
|
304
|
+
value_type?: string;
|
|
305
|
+
min?: number;
|
|
306
|
+
max?: number;
|
|
307
|
+
default_value?: unknown;
|
|
308
|
+
/** Standard metadata: the FACS action unit, ARKit blendshape, and tier. */
|
|
309
|
+
meta?: {
|
|
310
|
+
au?: number;
|
|
311
|
+
arkit?: string;
|
|
312
|
+
tier?: string;
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* A profile the face declares it speaks: a set of paths and their types — the
|
|
317
|
+
* vocabulary its graphs are authored against.
|
|
318
|
+
*
|
|
319
|
+
* A profile is names and types, not a graph, so it sits beside `graphs` rather
|
|
320
|
+
* than inside it. Declaring it on the asset is what lets a reader know which
|
|
321
|
+
* vocabulary to hold the face to.
|
|
322
|
+
*/
|
|
323
|
+
interface VizijBundleProfile {
|
|
324
|
+
id: string;
|
|
325
|
+
version: string;
|
|
326
|
+
title?: string;
|
|
327
|
+
description?: string;
|
|
328
|
+
keys: VizijProfileKey[];
|
|
329
|
+
}
|
|
294
330
|
interface VizijBundleGraphEntry {
|
|
295
331
|
id: VizijGraphId;
|
|
296
332
|
kind: VizijBundleGraphKind;
|
|
@@ -360,6 +396,19 @@ interface VizijBundleAnimationEntry {
|
|
|
360
396
|
[key: string]: unknown;
|
|
361
397
|
};
|
|
362
398
|
}
|
|
399
|
+
type VizijStarredKind = "driver" | "pose";
|
|
400
|
+
/**
|
|
401
|
+
* A starred reference collected into the "Starred" control surface. Points at a
|
|
402
|
+
* real driver (standard-input id) or pose (pose id) by stable id so both the
|
|
403
|
+
* source panel and the Starred panel render the same underlying object.
|
|
404
|
+
*/
|
|
405
|
+
interface VizijStarredItem {
|
|
406
|
+
kind: VizijStarredKind;
|
|
407
|
+
id: string;
|
|
408
|
+
}
|
|
409
|
+
interface VizijBundleStarredSection {
|
|
410
|
+
items: VizijStarredItem[];
|
|
411
|
+
}
|
|
363
412
|
interface VizijSpeechConfig {
|
|
364
413
|
/** TTS voice name (e.g., "Ruth") */
|
|
365
414
|
voice?: string;
|
|
@@ -388,8 +437,22 @@ interface VizijBundleExtension {
|
|
|
388
437
|
version: VizijBundleVersion;
|
|
389
438
|
exportedAt?: string;
|
|
390
439
|
graphs?: VizijBundleGraphEntry[];
|
|
440
|
+
/** The profiles this face declares it speaks (see {@link VizijBundleProfile}). */
|
|
441
|
+
profiles?: VizijBundleProfile[];
|
|
391
442
|
poses?: VizijBundlePoseSection | null;
|
|
392
443
|
animations?: VizijBundleAnimationEntry[];
|
|
444
|
+
/**
|
|
445
|
+
* Scene-level view transform this face should be rendered with. Travels with
|
|
446
|
+
* the asset so a face authored in Blender (which typically wants `"agx"`)
|
|
447
|
+
* renders consistently wherever it is loaded. Omitted/unknown falls back to
|
|
448
|
+
* the renderer default (`"none"` — web match).
|
|
449
|
+
*/
|
|
450
|
+
toneMapping?: ToneMappingMode;
|
|
451
|
+
/**
|
|
452
|
+
* Designer-curated set of starred drivers/poses (the "Starred" control
|
|
453
|
+
* surface). References real functionality by stable id.
|
|
454
|
+
*/
|
|
455
|
+
starred?: VizijBundleStarredSection | null;
|
|
393
456
|
/**
|
|
394
457
|
* Bundle-level metadata. May include `speechConfig: VizijSpeechConfig`
|
|
395
458
|
* for configuring the STT/LLM/TTS speech pipeline.
|
|
@@ -440,8 +503,59 @@ interface VizijAnimationClipData {
|
|
|
440
503
|
tracks: VizijAnimationTrackData[];
|
|
441
504
|
}
|
|
442
505
|
|
|
506
|
+
interface VizijProps {
|
|
507
|
+
style?: CSSProperties;
|
|
508
|
+
className?: string;
|
|
509
|
+
rootId: string;
|
|
510
|
+
namespace?: string;
|
|
511
|
+
showSafeArea?: boolean;
|
|
512
|
+
showSelectionGlow?: boolean;
|
|
513
|
+
/**
|
|
514
|
+
* View-transform applied by the WebGL renderer. Defaults to `"none"`
|
|
515
|
+
* (no tone mapping — matches plain web/canvas rendering). Faces authored in
|
|
516
|
+
* Blender typically want `"agx"` to compress over-driven emissive. Applied
|
|
517
|
+
* reactively, so it can be changed at runtime without remounting the canvas.
|
|
518
|
+
*/
|
|
519
|
+
toneMapping?: ToneMappingMode;
|
|
520
|
+
onPointerMissed?: ComponentProps<typeof Canvas>["onPointerMissed"];
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Renders the Vizij component.
|
|
524
|
+
*
|
|
525
|
+
* @param style - The style object for the Vizij component.
|
|
526
|
+
*
|
|
527
|
+
* @param className - The CSS class name for the Vizij component
|
|
528
|
+
*
|
|
529
|
+
* @param rootId - The root identifier for the Vizij component.
|
|
530
|
+
*
|
|
531
|
+
* @param namespace - The namespace for the Vizij component
|
|
532
|
+
*
|
|
533
|
+
* @param showSafeArea - Whether to show the safe area.
|
|
534
|
+
*
|
|
535
|
+
* @returns The rendered ReactNode.
|
|
536
|
+
*/
|
|
537
|
+
declare function Vizij({ style, className, rootId, namespace, showSafeArea, showSelectionGlow, toneMapping, onPointerMissed, }: VizijProps): ReactNode;
|
|
538
|
+
interface InnerVizijProps {
|
|
539
|
+
rootId: string;
|
|
540
|
+
namespace: string;
|
|
541
|
+
container?: {
|
|
542
|
+
width: number;
|
|
543
|
+
height: number;
|
|
544
|
+
resolution: number;
|
|
545
|
+
};
|
|
546
|
+
showSafeArea?: boolean;
|
|
547
|
+
showSelectionGlow?: boolean;
|
|
548
|
+
toneMapping?: ToneMappingMode;
|
|
549
|
+
}
|
|
550
|
+
declare function InnerVizij({ rootId, namespace, container, showSafeArea, showSelectionGlow, toneMapping, }: InnerVizijProps): react_jsx_runtime.JSX.Element;
|
|
551
|
+
|
|
443
552
|
interface VizijData {
|
|
444
553
|
world: World;
|
|
554
|
+
/**
|
|
555
|
+
* The mounted three.js object of each world element, by element id and then
|
|
556
|
+
* namespace. It lives beside `world` so that the world stays plain data.
|
|
557
|
+
*/
|
|
558
|
+
refs: Record<string, Record<string, RefObject<Group$1 | Mesh | null>>>;
|
|
445
559
|
animatables: Record<string, AnimatableValue>;
|
|
446
560
|
values: Map<string, RawValue | undefined>;
|
|
447
561
|
renderHit: boolean;
|
|
@@ -484,7 +598,7 @@ interface VizijActions {
|
|
|
484
598
|
setChildren: (id: string, children: string[]) => void;
|
|
485
599
|
setGeometry: (id: string, geometry: THREE.BufferGeometry) => void;
|
|
486
600
|
setMaterial: (id: string, material: string) => void;
|
|
487
|
-
setReference: (id: string, namespace: string, object: RefObject<Group$1 | Mesh>) => void;
|
|
601
|
+
setReference: (id: string, namespace: string, object: RefObject<Group$1 | Mesh | null>) => void;
|
|
488
602
|
createGroup: (root: boolean) => void;
|
|
489
603
|
createAnimatable: (elementId: string, featureName: string, value: Partial<AnimatableValue>) => void;
|
|
490
604
|
createStatic: (elementId: string, featureName: string, value: RawValue) => void;
|
|
@@ -494,6 +608,7 @@ type VizijStoreGetter = () => VizijData & VizijActions;
|
|
|
494
608
|
|
|
495
609
|
declare const VizijSlice: (set: VizijStoreSetter, get: VizijStoreGetter) => {
|
|
496
610
|
world: {};
|
|
611
|
+
refs: {};
|
|
497
612
|
animatables: {};
|
|
498
613
|
values: Map<any, any>;
|
|
499
614
|
renderHit: boolean;
|
|
@@ -537,7 +652,7 @@ declare const VizijSlice: (set: VizijStoreSetter, get: VizijStoreGetter) => {
|
|
|
537
652
|
setVizij: (scene: World, animatables: Record<string, AnimatableValue>) => void;
|
|
538
653
|
addWorldElements(world: World, animatables: Record<string, AnimatableValue>, replace?: boolean): void;
|
|
539
654
|
setPreferences: (preferences: Partial<VizijData["preferences"]>) => void;
|
|
540
|
-
setReference: (id: string, namespace: string, ref: RefObject<Group$1 | Mesh>) => void;
|
|
655
|
+
setReference: (id: string, namespace: string, ref: RefObject<Group$1 | Mesh | null>) => void;
|
|
541
656
|
};
|
|
542
657
|
declare const useDefaultVizijStore: zustand.UseBoundStore<Omit<zustand.StoreApi<VizijData & VizijActions>, "subscribe"> & {
|
|
543
658
|
subscribe: {
|
|
@@ -604,15 +719,14 @@ declare class EmptyModelError extends Error {
|
|
|
604
719
|
}
|
|
605
720
|
type ParserJsonFallbackSource = {
|
|
606
721
|
url?: string;
|
|
607
|
-
blob?: Blob;
|
|
608
722
|
arrayBuffer?: ArrayBuffer;
|
|
609
723
|
};
|
|
610
724
|
declare function parseGlbJsonChunk(buffer: ArrayBuffer): unknown | undefined;
|
|
611
|
-
declare function loadGLTF(url: string,
|
|
725
|
+
declare function loadGLTF(url: string, aggressiveImport?: boolean, rootBounds?: {
|
|
612
726
|
center: RawVector2;
|
|
613
727
|
size: RawVector2;
|
|
614
728
|
}): Promise<[World, Record<string, AnimatableValue>, VizijAnimationClipData[]]>;
|
|
615
|
-
declare function loadGLTFFromBlob(blob: Blob,
|
|
729
|
+
declare function loadGLTFFromBlob(blob: Blob, aggressiveImport?: boolean, rootBounds?: {
|
|
616
730
|
center: RawVector2;
|
|
617
731
|
size: RawVector2;
|
|
618
732
|
}): Promise<[World, Record<string, AnimatableValue>, VizijAnimationClipData[]]>;
|
|
@@ -623,34 +737,121 @@ type LoadedVizijAsset = {
|
|
|
623
737
|
animations: VizijAnimationClipData[];
|
|
624
738
|
scene: Group$1;
|
|
625
739
|
};
|
|
626
|
-
declare function loadGLTFWithBundle(url: string,
|
|
740
|
+
declare function loadGLTFWithBundle(url: string, aggressiveImport?: boolean, rootBounds?: {
|
|
627
741
|
center: RawVector2;
|
|
628
742
|
size: RawVector2;
|
|
629
743
|
}, parserJsonFallback?: ParserJsonFallbackSource): Promise<LoadedVizijAsset>;
|
|
630
|
-
|
|
744
|
+
/**
|
|
745
|
+
* Load a GLB or self-contained glTF from `blob`.
|
|
746
|
+
*
|
|
747
|
+
* The bytes are read into memory and parsed there; nothing is fetched, so this
|
|
748
|
+
* runs the same in a browser and in Node.
|
|
749
|
+
*/
|
|
750
|
+
declare function loadGLTFFromBlobWithBundle(blob: Blob, aggressiveImport?: boolean, rootBounds?: {
|
|
631
751
|
center: RawVector2;
|
|
632
752
|
size: RawVector2;
|
|
633
753
|
}): Promise<LoadedVizijAsset>;
|
|
634
754
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
* @returns A Promise that resolves with the THREE.Scene containing the loaded model.
|
|
640
|
-
*/
|
|
641
|
-
declare const loadGltfFromBlob: (blob: Blob, namespaces: string[]) => Promise<[World, Record<string, AnimatableValue>]>;
|
|
755
|
+
declare function deriveRootBounds(group: Group$1): {
|
|
756
|
+
center: RawVector2;
|
|
757
|
+
size: RawVector2;
|
|
758
|
+
} | null;
|
|
642
759
|
|
|
643
760
|
type ExportSceneOptions = {
|
|
644
|
-
|
|
761
|
+
/** Written into the GLB as the `VIZIJ_bundle` extension of the root node. */
|
|
645
762
|
bundle?: VizijBundleExtension | null;
|
|
763
|
+
/** Baked clips, written as glTF animations. */
|
|
646
764
|
animations?: AnimationClip[];
|
|
647
|
-
binary?: boolean;
|
|
648
|
-
onError?: (error: Error) => void;
|
|
649
|
-
onComplete?: () => void;
|
|
650
765
|
};
|
|
651
|
-
|
|
766
|
+
/**
|
|
767
|
+
* Rewrite a GLB's JSON chunk in place.
|
|
768
|
+
*
|
|
769
|
+
* `mutate` returns whether it changed anything; when it did not, the original
|
|
770
|
+
* buffer is handed back untouched rather than re-encoded. Any malformed input
|
|
771
|
+
* — wrong magic, missing JSON chunk, unparseable payload — returns the buffer
|
|
772
|
+
* as-is, since a patch is never worth corrupting an export over.
|
|
773
|
+
*
|
|
774
|
+
* Exists so a caller can amend an already-exported GLB instead of exporting
|
|
775
|
+
* twice: `GLTFExporter` is the expensive part, and running it again to change
|
|
776
|
+
* a few bytes of metadata froze the UI thread on real assets.
|
|
777
|
+
*/
|
|
778
|
+
declare function patchGlbJson(buffer: ArrayBuffer, mutate: (json: Record<string, unknown>) => boolean): ArrayBuffer;
|
|
779
|
+
/**
|
|
780
|
+
* Merge `metadata` into the `VIZIJ_bundle` extension already written into
|
|
781
|
+
* `glb`, wherever it landed — the exporter attaches it to a node, but a
|
|
782
|
+
* root-level extension is read back too, so both are handled.
|
|
783
|
+
*/
|
|
784
|
+
declare function patchVizijBundleMetadata(glb: ArrayBuffer, metadata: Record<string, unknown>): ArrayBuffer;
|
|
785
|
+
/**
|
|
786
|
+
* Encode `root` and its descendants as a GLB.
|
|
787
|
+
*
|
|
788
|
+
* Every node is written with its local translation, rotation and scale, every
|
|
789
|
+
* mesh with its morph weights, and each object's `userData` as glTF
|
|
790
|
+
* extensions and extras, which is where `RobotData` travels. A root that is
|
|
791
|
+
* not a `Scene` is cloned into one, so the caller's graph is left as it was.
|
|
792
|
+
*
|
|
793
|
+
* Only textures need a DOM; a scene without images encodes in Node.
|
|
794
|
+
*/
|
|
795
|
+
declare function exportScene(root: THREE.Object3D, options?: ExportSceneOptions): Promise<ArrayBuffer>;
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* Build the three.js graph of the world element `rootId` and its descendants,
|
|
799
|
+
* for `exportScene`.
|
|
800
|
+
*
|
|
801
|
+
* Each group becomes a `THREE.Group` and each shape a `THREE.Mesh` carrying a
|
|
802
|
+
* copy of its geometry and a material of its kind, as the renderer mounts
|
|
803
|
+
* them, with the element's `RobotData` in `userData`. No renderer is involved,
|
|
804
|
+
* so this runs in Node.
|
|
805
|
+
*
|
|
806
|
+
* Every feature takes its authored value: a static feature its value, an
|
|
807
|
+
* animated one its animatable's `default` in `animatables`. Node translation,
|
|
808
|
+
* rotation and scale, morph weights and material factors in the exported file
|
|
809
|
+
* are therefore the same numbers as the `RobotData` defaults, never a runtime
|
|
810
|
+
* pose. A caller that wants other values in the file passes them as the
|
|
811
|
+
* defaults of `animatables`.
|
|
812
|
+
*
|
|
813
|
+
* Throws when an element is missing from `world`, when an animated feature
|
|
814
|
+
* names an animatable missing from `animatables`, and for ellipse and
|
|
815
|
+
* rectangle elements, which have no exported form.
|
|
816
|
+
*/
|
|
817
|
+
declare function buildSceneGraph(world: World, animatables: Record<string, AnimatableValue>, rootId: string): THREE.Object3D;
|
|
652
818
|
|
|
653
819
|
declare function extractVizijBundle(object: Object3D, parserJson?: unknown): VizijBundleExtension | null;
|
|
654
820
|
declare function applyVizijBundle(object: Object3D, bundle: VizijBundleExtension | null): () => void;
|
|
655
821
|
|
|
656
|
-
|
|
822
|
+
/**
|
|
823
|
+
* Canonical morph-target key derivation.
|
|
824
|
+
*
|
|
825
|
+
* Morph feature keys are part of the animation binding contract: a propsrig
|
|
826
|
+
* input path is built from `(elementName, featureKey, component)`, and for a
|
|
827
|
+
* morph the feature key is derived from the morph's name. Import (building
|
|
828
|
+
* animatables from geometry) and animation channel resolution must therefore
|
|
829
|
+
* agree exactly, so both use the helpers here rather than re-deriving the rule.
|
|
830
|
+
*
|
|
831
|
+
* Note the slug is normalized twice on the path route: keys produced here are
|
|
832
|
+
* later passed through `normalizeStandardRigGroup` when the propsrig path is
|
|
833
|
+
* built, which independently lowercases and collapses separators. Casing here
|
|
834
|
+
* is therefore not load-bearing for path resolution — but it *is* the stored
|
|
835
|
+
* feature key on the renderable (and in exported `RobotData`), so changing it
|
|
836
|
+
* still changes the shape of authored data. Unit tests pin the rule directly;
|
|
837
|
+
* the corpus test cannot see a casing change because of the double pass.
|
|
838
|
+
*/
|
|
839
|
+
/**
|
|
840
|
+
* Allocates the feature key for a single morph target, deduplicating against
|
|
841
|
+
* keys already handed out for the same mesh.
|
|
842
|
+
*
|
|
843
|
+
* `used` is mutated: callers iterating a mesh's morph targets must share one
|
|
844
|
+
* set so collisions resolve deterministically in iteration order.
|
|
845
|
+
*/
|
|
846
|
+
declare function sanitizeMorphKey(name: string, fallbackIndex: number, used: Set<string>): string;
|
|
847
|
+
/**
|
|
848
|
+
* Derives feature keys for a mesh's morph targets in order, applying the same
|
|
849
|
+
* dedupe sequence `sanitizeMorphKey` applies during import.
|
|
850
|
+
*
|
|
851
|
+
* Pass morph names in the mesh's own target order (glTF
|
|
852
|
+
* `meshes[].extras.targetNames`, or `morphTargetDictionary` insertion order)
|
|
853
|
+
* so the result matches the keys import produced for that mesh.
|
|
854
|
+
*/
|
|
855
|
+
declare function deriveMorphFeatureKeys(names: ReadonlyArray<string>): string[];
|
|
856
|
+
|
|
857
|
+
export { type AnimatedFeature, DEFAULT_TONE_MAPPING_MODE, type Ellipse, type EllipseFeature, EmptyModelError, type ExportSceneOptions, type Feature, type Group, type GroupFeature, InnerVizij, type InnerVizijProps, type LoadedVizijAsset, type Rectangle, type RectangleFeature, type RenderableBase, type RenderableFeature, type Selection, type Shape, type ShapeFeature, ShapeMaterial, type StaticFeature, type Stored, type StoredAnimatedFeature, type StoredEllipse, type StoredFeatures, type StoredGroup, type StoredRectangle, type StoredRenderable, type StoredShape, TONE_MAPPING_LABELS, TONE_MAPPING_MODES, type ToneMappingMode, Vizij, type VizijActions, type VizijAnimationClipData, type VizijAnimationId, type VizijAnimationTrackData, type VizijBundleAnimationClip, type VizijBundleAnimationEntry, type VizijBundleAnimationKeyframe, type VizijBundleAnimationTrack, type VizijBundleExtension, type VizijBundleGraphEntry, type VizijBundleGraphKind, type VizijBundleGraphMetadata, type VizijBundlePoseSection, type VizijBundleProfile, type VizijBundleStarredSection, type VizijBundleVersion, VizijContext, type VizijData, type VizijGraphId, type VizijPoseDefinition, type VizijPoseId, type VizijPoseRigConfig, type VizijProfileKey, type VizijProps, VizijSlice, type VizijSpeechConfig, type VizijStarredItem, type VizijStarredKind, type VizijStore, type VizijStoreGetter, type VizijStoreSetter, type World, applyVizijBundle, buildSceneGraph, createVizijStore, deriveMorphFeatureKeys, deriveRootBounds, exportScene, extractVizijBundle, isToneMappingMode, loadGLTF, loadGLTFFromBlob, loadGLTFFromBlobWithBundle, loadGLTFWithBundle, normalizeToneMappingMode, parseGlbJsonChunk, patchGlbJson, patchVizijBundleMetadata, resolveToneMapping, sanitizeMorphKey, useDefaultVizijStore, useFeatures, useVizijStore, useVizijStoreGetter, useVizijStoreSetter, useVizijStoreSubscription };
|