@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/dist/index.js CHANGED
@@ -30,22 +30,33 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.tsx
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ DEFAULT_TONE_MAPPING_MODE: () => DEFAULT_TONE_MAPPING_MODE,
33
34
  EmptyModelError: () => EmptyModelError,
34
35
  InnerVizij: () => InnerVizij,
35
36
  ShapeMaterial: () => ShapeMaterial,
37
+ TONE_MAPPING_LABELS: () => TONE_MAPPING_LABELS,
38
+ TONE_MAPPING_MODES: () => TONE_MAPPING_MODES,
36
39
  Vizij: () => Vizij,
37
40
  VizijContext: () => VizijContext,
38
41
  VizijSlice: () => VizijSlice,
39
42
  applyVizijBundle: () => applyVizijBundle,
43
+ buildSceneGraph: () => buildSceneGraph,
40
44
  createVizijStore: () => createVizijStore,
45
+ deriveMorphFeatureKeys: () => deriveMorphFeatureKeys,
46
+ deriveRootBounds: () => deriveRootBounds,
41
47
  exportScene: () => exportScene,
42
48
  extractVizijBundle: () => extractVizijBundle,
49
+ isToneMappingMode: () => isToneMappingMode,
43
50
  loadGLTF: () => loadGLTF,
44
51
  loadGLTFFromBlob: () => loadGLTFFromBlob,
45
52
  loadGLTFFromBlobWithBundle: () => loadGLTFFromBlobWithBundle,
46
53
  loadGLTFWithBundle: () => loadGLTFWithBundle,
47
- loadGltfFromBlob: () => loadGltfFromBlob,
54
+ normalizeToneMappingMode: () => normalizeToneMappingMode,
48
55
  parseGlbJsonChunk: () => parseGlbJsonChunk,
56
+ patchGlbJson: () => patchGlbJson,
57
+ patchVizijBundleMetadata: () => patchVizijBundleMetadata,
58
+ resolveToneMapping: () => resolveToneMapping,
59
+ sanitizeMorphKey: () => sanitizeMorphKey,
49
60
  useDefaultVizijStore: () => useDefaultVizijStore,
50
61
  useFeatures: () => useFeatures,
51
62
  useVizijStore: () => useVizijStore,
@@ -56,9 +67,9 @@ __export(index_exports, {
56
67
  module.exports = __toCommonJS(index_exports);
57
68
 
58
69
  // src/vizij.tsx
59
- var import_react11 = require("react");
70
+ var import_react10 = require("react");
60
71
  var import_react_error_boundary = require("react-error-boundary");
61
- var import_three2 = require("three");
72
+ var import_three3 = require("three");
62
73
  var import_fiber2 = require("@react-three/fiber");
63
74
  var import_drei3 = require("@react-three/drei");
64
75
  var import_shallow8 = require("zustand/react/shallow");
@@ -136,35 +147,33 @@ function useFeatures(namespace, features, callbacks, debugInfo) {
136
147
  }, [features, callbacks, store, debugInfo, namespace]);
137
148
  }
138
149
 
139
- // src/functions/create-stored-data.ts
140
- var import_lodash2 = require("lodash");
141
-
142
150
  // src/functions/create-stored-features.ts
143
- var import_lodash = require("lodash");
144
151
  function createStoredFeatures(objectFeatures, animatableValues) {
145
- return (0, import_lodash.mapValues)(objectFeatures, (feat) => {
146
- if (feat.animated) {
147
- const storedFeat = {
148
- animated: true,
149
- value: animatableValues[feat.value],
150
- ...feat.label ? { label: feat.label } : {}
151
- };
152
- return storedFeat;
153
- } else {
152
+ const stored = Object.entries(objectFeatures).map(
153
+ ([key, feat]) => {
154
+ if (feat.animated) {
155
+ const storedFeat = {
156
+ animated: true,
157
+ value: animatableValues[feat.value],
158
+ ...feat.label ? { label: feat.label } : {}
159
+ };
160
+ return [key, storedFeat];
161
+ }
154
162
  const staticFeature = feat;
155
- return staticFeature.label ? { ...staticFeature } : staticFeature;
163
+ return [key, staticFeature.label ? { ...staticFeature } : staticFeature];
156
164
  }
157
- });
165
+ );
166
+ return Object.fromEntries(stored);
158
167
  }
159
168
 
160
169
  // src/functions/create-stored-data.ts
161
170
  function createStoredRenderable(data, animatableValues) {
162
- const d = (0, import_lodash2.omit)(data, "refs", "geometry");
171
+ const { geometry: _geometry, ...stored } = data;
163
172
  const storedFeatures = createStoredFeatures(
164
173
  data.features,
165
174
  animatableValues
166
175
  );
167
- return { ...d, features: storedFeatures };
176
+ return { ...stored, features: storedFeatures };
168
177
  }
169
178
 
170
179
  // src/renderables/group.tsx
@@ -177,7 +186,9 @@ function InnerRenderedGroup({
177
186
  }) {
178
187
  const ref = (0, import_react4.useRef)(null);
179
188
  const group = useVizijStore((0, import_shallow2.useShallow)((state) => state.world[id]));
180
- const refIsNull = !group.refs[namespace]?.current;
189
+ const refIsNull = useVizijStore(
190
+ (state) => !state.refs[id]?.[namespace]?.current
191
+ );
181
192
  const animatables = useVizijStore((0, import_shallow2.useShallow)((state) => state.animatables));
182
193
  const setHoveredElement = useVizijStore(
183
194
  (0, import_shallow2.useShallow)((state) => state.setHoveredElement)
@@ -312,7 +323,9 @@ function InnerRenderedEllipse({
312
323
  const ellipse = useVizijStore(
313
324
  (0, import_shallow3.useShallow)((state) => state.world[id])
314
325
  );
315
- const refIsNull = !ellipse.refs[namespace]?.current;
326
+ const refIsNull = useVizijStore(
327
+ (state) => !state.refs[id]?.[namespace]?.current
328
+ );
316
329
  const animatables = useVizijStore((0, import_shallow3.useShallow)((state) => state.animatables));
317
330
  const animatableValues = (0, import_react5.useMemo)(() => {
318
331
  const av = {};
@@ -599,7 +612,9 @@ function InnerRenderedRectangle({
599
612
  const rectangle = useVizijStore(
600
613
  (0, import_shallow4.useShallow)((state) => state.world[id])
601
614
  );
602
- const refIsNull = !rectangle.refs[namespace]?.current;
615
+ const refIsNull = useVizijStore(
616
+ (state) => !state.refs[id]?.[namespace]?.current
617
+ );
603
618
  const animatables = useVizijStore((0, import_shallow4.useShallow)((state) => state.animatables));
604
619
  const animatableValues = (0, import_react6.useMemo)(() => {
605
620
  const av = {};
@@ -865,6 +880,61 @@ var import_react7 = require("react");
865
880
  var THREE2 = __toESM(require("three"));
866
881
  var import_shallow5 = require("zustand/react/shallow");
867
882
  var import_utils5 = require("@vizij/utils");
883
+
884
+ // src/functions/material-name.ts
885
+ var MATERIAL_FEATURE_KEYS = [
886
+ "color",
887
+ "opacity",
888
+ "roughness",
889
+ "metalness",
890
+ "shininess",
891
+ "emissive",
892
+ "emissiveIntensity",
893
+ "specular"
894
+ ];
895
+ var MATERIAL_NAME_SUFFIXES = [
896
+ " color",
897
+ " colours",
898
+ " colour",
899
+ " opacity",
900
+ " roughness",
901
+ " metalness",
902
+ " shininess",
903
+ " emissive intensity",
904
+ " emissive",
905
+ " specular"
906
+ ];
907
+ function deriveMaterialName(shape, values) {
908
+ for (const key of MATERIAL_FEATURE_KEYS) {
909
+ const feature = shape.features[key];
910
+ if (feature && feature.animated) {
911
+ const animatable = values[feature.value];
912
+ const candidate = extractMaterialName(animatable?.name);
913
+ if (candidate) {
914
+ return candidate;
915
+ }
916
+ }
917
+ }
918
+ return void 0;
919
+ }
920
+ function extractMaterialName(name) {
921
+ if (!name) {
922
+ return void 0;
923
+ }
924
+ const trimmed = name.trim();
925
+ if (!trimmed) {
926
+ return void 0;
927
+ }
928
+ const lowered = trimmed.toLowerCase();
929
+ for (const suffix of MATERIAL_NAME_SUFFIXES) {
930
+ if (lowered.endsWith(suffix)) {
931
+ return trimmed.slice(0, trimmed.length - suffix.length).trim();
932
+ }
933
+ }
934
+ return trimmed;
935
+ }
936
+
937
+ // src/renderables/shape.tsx
868
938
  var import_jsx_runtime4 = require("react/jsx-runtime");
869
939
  THREE2.Object3D.DEFAULT_UP.set(0, 0, 1);
870
940
  function InnerRenderedShape({
@@ -875,10 +945,9 @@ function InnerRenderedShape({
875
945
  const refGroup = (0, import_react7.useRef)(null);
876
946
  const ref = (0, import_react7.useRef)(null);
877
947
  const shape = useVizijStore((0, import_shallow5.useShallow)((state) => state.world[id]));
878
- const refs = useVizijStore(
879
- (0, import_shallow5.useShallow)((state) => state.world[id].refs)
948
+ const refIsNull = useVizijStore(
949
+ (state) => !state.refs[id]?.[namespace]?.current
880
950
  );
881
- const refIsNull = !refs[namespace]?.current;
882
951
  const animatables = useVizijStore((0, import_shallow5.useShallow)((state) => state.animatables));
883
952
  const animatableValues = (0, import_react7.useMemo)(() => {
884
953
  const av = {};
@@ -1163,57 +1232,6 @@ function InnerRenderedShape({
1163
1232
  );
1164
1233
  }
1165
1234
  var RenderedShape = (0, import_react7.memo)(InnerRenderedShape);
1166
- var MATERIAL_FEATURE_KEYS = [
1167
- "color",
1168
- "opacity",
1169
- "roughness",
1170
- "metalness",
1171
- "shininess",
1172
- "emissive",
1173
- "emissiveIntensity",
1174
- "specular"
1175
- ];
1176
- var MATERIAL_NAME_SUFFIXES = [
1177
- " color",
1178
- " colours",
1179
- " colour",
1180
- " opacity",
1181
- " roughness",
1182
- " metalness",
1183
- " shininess",
1184
- " emissive intensity",
1185
- " emissive",
1186
- " specular"
1187
- ];
1188
- function deriveMaterialName(shape, values) {
1189
- for (const key of MATERIAL_FEATURE_KEYS) {
1190
- const feature = shape.features[key];
1191
- if (feature && feature.animated) {
1192
- const animatable = values[feature.value];
1193
- const candidate = extractMaterialName(animatable?.name);
1194
- if (candidate) {
1195
- return candidate;
1196
- }
1197
- }
1198
- }
1199
- return void 0;
1200
- }
1201
- function extractMaterialName(name) {
1202
- if (!name) {
1203
- return void 0;
1204
- }
1205
- const trimmed = name.trim();
1206
- if (!trimmed) {
1207
- return void 0;
1208
- }
1209
- const lowered = trimmed.toLowerCase();
1210
- for (const suffix of MATERIAL_NAME_SUFFIXES) {
1211
- if (lowered.endsWith(suffix)) {
1212
- return trimmed.slice(0, trimmed.length - suffix.length).trim();
1213
- }
1214
- }
1215
- return trimmed;
1216
- }
1217
1235
 
1218
1236
  // src/renderables/renderable.tsx
1219
1237
  var import_jsx_runtime5 = require("react/jsx-runtime");
@@ -1223,65 +1241,35 @@ function InnerRenderable({
1223
1241
  chain
1224
1242
  }) {
1225
1243
  const type = useVizijStore((0, import_shallow6.useShallow)((state) => state.world[id].type));
1226
- const refs = useVizijStore((0, import_shallow6.useShallow)((state) => state.world[id].refs));
1227
- const resolvedNamespaces = (0, import_react8.useMemo)(() => {
1228
- let namespaces = [namespace];
1229
- if (namespace in refs) {
1230
- namespaces = [namespace];
1231
- } else {
1232
- namespaces = Object.keys(refs);
1233
- }
1234
- return namespaces;
1235
- }, [namespace, refs]);
1236
- if (resolvedNamespaces.length === 0) {
1237
- return null;
1244
+ const key = `${namespace}.${id}`;
1245
+ switch (type) {
1246
+ case "group":
1247
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RenderedGroup, { id, namespace, chain }, key);
1248
+ case "ellipse":
1249
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1250
+ RenderedEllipse,
1251
+ {
1252
+ id,
1253
+ namespace,
1254
+ chain
1255
+ },
1256
+ key
1257
+ );
1258
+ case "rectangle":
1259
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1260
+ RenderedRectangle,
1261
+ {
1262
+ id,
1263
+ namespace,
1264
+ chain
1265
+ },
1266
+ key
1267
+ );
1268
+ case "shape":
1269
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RenderedShape, { id, namespace, chain }, key);
1270
+ default:
1271
+ return null;
1238
1272
  }
1239
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: resolvedNamespaces.map((ns) => {
1240
- switch (type) {
1241
- case "group":
1242
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1243
- RenderedGroup,
1244
- {
1245
- id,
1246
- namespace: ns,
1247
- chain
1248
- },
1249
- `${ns}.${id}`
1250
- );
1251
- case "ellipse":
1252
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1253
- RenderedEllipse,
1254
- {
1255
- id,
1256
- namespace: ns,
1257
- chain
1258
- },
1259
- `${ns}.${id}`
1260
- );
1261
- case "rectangle":
1262
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1263
- RenderedRectangle,
1264
- {
1265
- id,
1266
- namespace: ns,
1267
- chain
1268
- },
1269
- `${ns}.${id}`
1270
- );
1271
- case "shape":
1272
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1273
- RenderedShape,
1274
- {
1275
- id,
1276
- namespace: ns,
1277
- chain
1278
- },
1279
- `${ns}.${id}`
1280
- );
1281
- default:
1282
- return null;
1283
- }
1284
- }) });
1285
1273
  }
1286
1274
  var Renderable = (0, import_react8.memo)(InnerRenderable);
1287
1275
 
@@ -1292,10 +1280,6 @@ var import_immer = require("immer");
1292
1280
  var THREE3 = __toESM(require("three"));
1293
1281
  var import_utils8 = require("@vizij/utils");
1294
1282
 
1295
- // src/actions/create-new-element.ts
1296
- var import_react9 = require("react");
1297
- var import_lodash3 = require("lodash");
1298
-
1299
1283
  // src/functions/create-world-element.ts
1300
1284
  var import_utils6 = require("@vizij/utils");
1301
1285
  function createDefaultGroup(partialBody) {
@@ -1307,7 +1291,6 @@ function createDefaultGroup(partialBody) {
1307
1291
  name: partialBody.name || "new-body",
1308
1292
  type: partialBody.type || "group",
1309
1293
  tags: partialBody.tags || [],
1310
- refs: partialBody.refs || {},
1311
1294
  features: { translation, rotation, scale },
1312
1295
  root: partialBody.root ?? false,
1313
1296
  children: partialBody.children || []
@@ -1324,11 +1307,9 @@ function createNewElement(state, type, root = false) {
1324
1307
  });
1325
1308
  if (Object.entries(state.world).length === 0) {
1326
1309
  const name = `New-Root`;
1327
- const refs = { default: (0, import_react9.createRef)() };
1328
1310
  const newElement = createDefaultGroup({
1329
1311
  name,
1330
- root: true,
1331
- refs
1312
+ root: true
1332
1313
  });
1333
1314
  state.world[newElement.id] = newElement;
1334
1315
  state.elementSelection = [buildSelection(newElement.id)];
@@ -1340,11 +1321,7 @@ function createNewElement(state, type, root = false) {
1340
1321
  return;
1341
1322
  }
1342
1323
  const name = `New-Body`;
1343
- const refs = (0, import_lodash3.mapValues)(
1344
- worldRootEntry.refs,
1345
- () => (0, import_react9.createRef)()
1346
- );
1347
- const newChild = createDefaultGroup({ name, root, refs });
1324
+ const newChild = createDefaultGroup({ name, root });
1348
1325
  worldRootEntry.children.push(newChild.id);
1349
1326
  state.world[newChild.id] = newChild;
1350
1327
  state.elementSelection = [buildSelection(newChild.id)];
@@ -1544,6 +1521,7 @@ THREE3.Object3D.DEFAULT_UP.set(0, 0, 1);
1544
1521
  var VizijSlice = (set, get) => ({
1545
1522
  // worldRef: createRef<THREE.Group>(),
1546
1523
  world: {},
1524
+ refs: {},
1547
1525
  animatables: {},
1548
1526
  values: /* @__PURE__ */ new Map(),
1549
1527
  renderHit: false,
@@ -1617,12 +1595,10 @@ var VizijSlice = (set, get) => ({
1617
1595
  worldData,
1618
1596
  filterIds
1619
1597
  );
1598
+ const refs = get().refs;
1620
1599
  return candidateGroups.flatMap((entry) => {
1621
- const refs = Object.values(
1622
- entry.refs ?? {}
1623
- );
1624
- const resolved = refs.find((ref) => ref?.current)?.current ?? null;
1625
- return resolved ? [resolved] : [];
1600
+ const mounted = Object.values(refs[entry.id] ?? {}).map((ref) => ref.current).find((object) => Boolean(object));
1601
+ return mounted ? [mounted] : [];
1626
1602
  });
1627
1603
  },
1628
1604
  setGeometry: (id, geometry) => {
@@ -1844,14 +1820,12 @@ var VizijSlice = (set, get) => ({
1844
1820
  }));
1845
1821
  },
1846
1822
  setReference: (id, namespace, ref) => {
1847
- set(
1848
- (0, import_immer.produce)((state) => {
1849
- state.world[id].refs[namespace].current = ref.current;
1850
- if (ref.current?.children && state.world[id].refs[namespace].current) {
1851
- state.world[id].refs[namespace].current.children = ref.current.children;
1852
- }
1853
- })
1854
- );
1823
+ set((state) => ({
1824
+ refs: {
1825
+ ...state.refs,
1826
+ [id]: { ...state.refs[id], [namespace]: ref }
1827
+ }
1828
+ }));
1855
1829
  }
1856
1830
  });
1857
1831
  var useDefaultVizijStore = (0, import_zustand2.create)()(
@@ -1866,11 +1840,55 @@ var createVizijStore = (initial) => (0, import_zustand2.create)()(
1866
1840
  }))
1867
1841
  );
1868
1842
 
1843
+ // src/types/shape.ts
1844
+ var ShapeMaterial = /* @__PURE__ */ ((ShapeMaterial2) => {
1845
+ ShapeMaterial2["Standard"] = "standard";
1846
+ ShapeMaterial2["Phong"] = "phong";
1847
+ ShapeMaterial2["Basic"] = "basic";
1848
+ ShapeMaterial2["Lambert"] = "lambert";
1849
+ ShapeMaterial2["Normal"] = "normal";
1850
+ return ShapeMaterial2;
1851
+ })(ShapeMaterial || {});
1852
+
1853
+ // src/types/tone-mapping.ts
1854
+ var import_three = require("three");
1855
+ var TONE_MAPPING_MODES = [
1856
+ "none",
1857
+ "agx",
1858
+ "aces",
1859
+ "neutral"
1860
+ ];
1861
+ var TONE_MAPPING_LABELS = {
1862
+ none: "None (web match)",
1863
+ agx: "AgX (Blender)",
1864
+ aces: "ACES Filmic",
1865
+ neutral: "Neutral"
1866
+ };
1867
+ var DEFAULT_TONE_MAPPING_MODE = "none";
1868
+ var TONE_MAPPING_CONSTANTS = {
1869
+ none: import_three.NoToneMapping,
1870
+ agx: import_three.AgXToneMapping,
1871
+ aces: import_three.ACESFilmicToneMapping,
1872
+ neutral: import_three.NeutralToneMapping
1873
+ };
1874
+ function isToneMappingMode(value) {
1875
+ return typeof value === "string" && Object.prototype.hasOwnProperty.call(TONE_MAPPING_CONSTANTS, value);
1876
+ }
1877
+ function resolveToneMapping(mode) {
1878
+ if (isToneMappingMode(mode)) {
1879
+ return TONE_MAPPING_CONSTANTS[mode];
1880
+ }
1881
+ return TONE_MAPPING_CONSTANTS[DEFAULT_TONE_MAPPING_MODE];
1882
+ }
1883
+ function normalizeToneMappingMode(value) {
1884
+ return isToneMappingMode(value) ? value : DEFAULT_TONE_MAPPING_MODE;
1885
+ }
1886
+
1869
1887
  // src/effects/selection-glow-effect.tsx
1870
- var import_react10 = require("react");
1888
+ var import_react9 = require("react");
1871
1889
  var import_fiber = require("@react-three/fiber");
1872
1890
  var import_shallow7 = require("zustand/react/shallow");
1873
- var import_three = require("three");
1891
+ var import_three2 = require("three");
1874
1892
  var import_jsx_runtime6 = require("react/jsx-runtime");
1875
1893
  function SelectionGlowEffect({
1876
1894
  enabled = false,
@@ -1886,7 +1904,7 @@ function SelectionGlowEffect({
1886
1904
  if (!enabled || selections.length === 0) {
1887
1905
  return null;
1888
1906
  }
1889
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react10.Fragment, { children: selections.map((selection) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1907
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react9.Fragment, { children: selections.map((selection) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1890
1908
  SelectionOutline,
1891
1909
  {
1892
1910
  selection,
@@ -1906,32 +1924,32 @@ function SelectionOutline({
1906
1924
  const target = useVizijStore(
1907
1925
  (0, import_shallow7.useShallow)((state) => {
1908
1926
  const entry = state.world[selection.id];
1909
- const ref = entry?.refs?.[selection.namespace];
1927
+ const ref = state.refs[selection.id]?.[selection.namespace];
1910
1928
  const geometry = entry?.geometry ?? null;
1911
1929
  return { ref, geometry };
1912
1930
  })
1913
1931
  );
1914
1932
  const sourceRef = target.ref;
1915
- const edgesGeometry = (0, import_react10.useMemo)(() => {
1933
+ const edgesGeometry = (0, import_react9.useMemo)(() => {
1916
1934
  if (!target.geometry) return null;
1917
- const edges = new import_three.EdgesGeometry(target.geometry, thresholdAngle);
1935
+ const edges = new import_three2.EdgesGeometry(target.geometry, thresholdAngle);
1918
1936
  return edges;
1919
1937
  }, [target.geometry, thresholdAngle]);
1920
- (0, import_react10.useEffect)(() => () => edgesGeometry?.dispose(), [edgesGeometry]);
1921
- const material = (0, import_react10.useMemo)(() => {
1922
- const mat = new import_three.LineBasicMaterial({
1923
- color: new import_three.Color(color),
1938
+ (0, import_react9.useEffect)(() => () => edgesGeometry?.dispose(), [edgesGeometry]);
1939
+ const material = (0, import_react9.useMemo)(() => {
1940
+ const mat = new import_three2.LineBasicMaterial({
1941
+ color: new import_three2.Color(color),
1924
1942
  transparent: true,
1925
1943
  opacity,
1926
- blending: import_three.AdditiveBlending,
1944
+ blending: import_three2.AdditiveBlending,
1927
1945
  depthTest: false,
1928
1946
  depthWrite: false,
1929
1947
  toneMapped: false
1930
1948
  });
1931
1949
  return mat;
1932
1950
  }, [color, opacity]);
1933
- (0, import_react10.useEffect)(() => () => material.dispose(), [material]);
1934
- const lineRef = (0, import_react10.useRef)(null);
1951
+ (0, import_react9.useEffect)(() => () => material.dispose(), [material]);
1952
+ const lineRef = (0, import_react9.useRef)(null);
1935
1953
  (0, import_fiber.useFrame)(() => {
1936
1954
  const source = sourceRef?.current;
1937
1955
  const line = lineRef.current;
@@ -1953,10 +1971,10 @@ function SelectionOutline({
1953
1971
  }
1954
1972
  );
1955
1973
  }
1956
- var tempMatrix = new import_three.Matrix4();
1957
- var tempPosition = new import_three.Vector3();
1958
- var tempQuaternion = new import_three.Quaternion();
1959
- var tempScale = new import_three.Vector3();
1974
+ var tempMatrix = new import_three2.Matrix4();
1975
+ var tempPosition = new import_three2.Vector3();
1976
+ var tempQuaternion = new import_three2.Quaternion();
1977
+ var tempScale = new import_three2.Vector3();
1960
1978
  function copyWorldTransform(source, target) {
1961
1979
  source.updateWorldMatrix(true, false);
1962
1980
  tempMatrix.copy(source.matrixWorld);
@@ -1969,7 +1987,7 @@ function copyWorldTransform(source, target) {
1969
1987
 
1970
1988
  // src/vizij.tsx
1971
1989
  var import_jsx_runtime7 = require("react/jsx-runtime");
1972
- import_three2.Object3D.DEFAULT_UP.set(0, 0, 1);
1990
+ import_three3.Object3D.DEFAULT_UP.set(0, 0, 1);
1973
1991
  function Vizij({
1974
1992
  style,
1975
1993
  className,
@@ -1977,10 +1995,11 @@ function Vizij({
1977
1995
  namespace = "default",
1978
1996
  showSafeArea = false,
1979
1997
  showSelectionGlow = false,
1998
+ toneMapping = "none",
1980
1999
  onPointerMissed
1981
2000
  }) {
1982
- const ctx = (0, import_react11.useContext)(VizijContext);
1983
- (0, import_react11.useEffect)(() => {
2001
+ const ctx = (0, import_react10.useContext)(VizijContext);
2002
+ (0, import_react10.useEffect)(() => {
1984
2003
  recordRenderCounter("canvasMountCount");
1985
2004
  recordRenderCounter("mountedCanvasCount");
1986
2005
  return () => {
@@ -1996,8 +2015,7 @@ function Vizij({
1996
2015
  className,
1997
2016
  onPointerMissed,
1998
2017
  gl: {
1999
- outputColorSpace: import_three2.SRGBColorSpace,
2000
- toneMapping: import_three2.NoToneMapping,
2018
+ outputColorSpace: import_three3.SRGBColorSpace,
2001
2019
  antialias: true
2002
2020
  },
2003
2021
  children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
@@ -2006,7 +2024,8 @@ function Vizij({
2006
2024
  rootId,
2007
2025
  namespace,
2008
2026
  showSafeArea,
2009
- showSelectionGlow
2027
+ showSelectionGlow,
2028
+ toneMapping
2010
2029
  }
2011
2030
  )
2012
2031
  }
@@ -2019,8 +2038,7 @@ function Vizij({
2019
2038
  className,
2020
2039
  onPointerMissed,
2021
2040
  gl: {
2022
- outputColorSpace: import_three2.SRGBColorSpace,
2023
- toneMapping: import_three2.NoToneMapping,
2041
+ outputColorSpace: import_three3.SRGBColorSpace,
2024
2042
  antialias: true
2025
2043
  },
2026
2044
  children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
@@ -2029,7 +2047,8 @@ function Vizij({
2029
2047
  rootId,
2030
2048
  namespace,
2031
2049
  showSafeArea,
2032
- showSelectionGlow
2050
+ showSelectionGlow,
2051
+ toneMapping
2033
2052
  }
2034
2053
  )
2035
2054
  }
@@ -2041,7 +2060,8 @@ function InnerVizij({
2041
2060
  namespace = "default",
2042
2061
  container,
2043
2062
  showSafeArea,
2044
- showSelectionGlow
2063
+ showSelectionGlow,
2064
+ toneMapping = "none"
2045
2065
  }) {
2046
2066
  const sceneParentSizing = container ? {
2047
2067
  width: container.width * container.resolution,
@@ -2049,6 +2069,7 @@ function InnerVizij({
2049
2069
  } : void 0;
2050
2070
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2051
2071
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ambientLight", { intensity: Math.PI / 2 }),
2072
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ToneMappingController, { mode: toneMapping }),
2052
2073
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2053
2074
  import_drei3.OrthographicCamera,
2054
2075
  {
@@ -2058,7 +2079,7 @@ function InnerVizij({
2058
2079
  far: 1e3
2059
2080
  }
2060
2081
  ),
2061
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react11.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2082
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react10.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2062
2083
  World,
2063
2084
  {
2064
2085
  rootId,
@@ -2070,7 +2091,32 @@ function InnerVizij({
2070
2091
  showSafeArea && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SafeAreaRenderer, { rootId })
2071
2092
  ] });
2072
2093
  }
2073
- var MemoizedInnerVizij = (0, import_react11.memo)(InnerVizij);
2094
+ var MemoizedInnerVizij = (0, import_react10.memo)(InnerVizij);
2095
+ function ToneMappingController({ mode }) {
2096
+ const gl = (0, import_fiber2.useThree)((state) => state.gl);
2097
+ const scene = (0, import_fiber2.useThree)((state) => state.scene);
2098
+ (0, import_react10.useEffect)(() => {
2099
+ const resolved = resolveToneMapping(mode);
2100
+ if (gl.toneMapping === resolved) {
2101
+ return;
2102
+ }
2103
+ gl.toneMapping = resolved;
2104
+ scene.traverse((object) => {
2105
+ const material = object.material;
2106
+ if (!material) {
2107
+ return;
2108
+ }
2109
+ if (Array.isArray(material)) {
2110
+ material.forEach((mat) => {
2111
+ mat.needsUpdate = true;
2112
+ });
2113
+ } else {
2114
+ material.needsUpdate = true;
2115
+ }
2116
+ });
2117
+ }, [gl, scene, mode]);
2118
+ return null;
2119
+ }
2074
2120
  function InnerWorld({
2075
2121
  rootId,
2076
2122
  namespace = "default",
@@ -2087,7 +2133,7 @@ function InnerWorld({
2087
2133
  camera: state.camera,
2088
2134
  size: state.size
2089
2135
  }));
2090
- (0, import_react11.useEffect)(() => {
2136
+ (0, import_react10.useEffect)(() => {
2091
2137
  const width = rootBounds.size.x;
2092
2138
  const height = rootBounds.size.y;
2093
2139
  if (camera && parentSizing === void 0 && camera.isOrthographicCamera) {
@@ -2130,7 +2176,7 @@ function InnerWorld({
2130
2176
  )
2131
2177
  ] });
2132
2178
  }
2133
- var World = (0, import_react11.memo)(InnerWorld);
2179
+ var World = (0, import_react10.memo)(InnerWorld);
2134
2180
  function SafeAreaRenderer({ rootId }) {
2135
2181
  const rootBounds = useVizijStore((state) => {
2136
2182
  const group = state.world[rootId];
@@ -2160,22 +2206,12 @@ var defaultRootBounds = {
2160
2206
  size: { x: 5, y: 4 }
2161
2207
  };
2162
2208
 
2163
- // src/types/shape.ts
2164
- var ShapeMaterial = /* @__PURE__ */ ((ShapeMaterial2) => {
2165
- ShapeMaterial2["Standard"] = "standard";
2166
- ShapeMaterial2["Phong"] = "phong";
2167
- ShapeMaterial2["Basic"] = "basic";
2168
- ShapeMaterial2["Lambert"] = "lambert";
2169
- ShapeMaterial2["Normal"] = "normal";
2170
- return ShapeMaterial2;
2171
- })(ShapeMaterial || {});
2172
-
2173
2209
  // src/hooks/use-vizij-store-subscription.ts
2174
- var import_react12 = require("react");
2210
+ var import_react11 = require("react");
2175
2211
  function useVizijStoreSubscription(selector, listener) {
2176
- const store = (0, import_react12.useContext)(VizijContext);
2212
+ const store = (0, import_react11.useContext)(VizijContext);
2177
2213
  if (!store) throw new Error("Missing VizijProvider in the tree");
2178
- (0, import_react12.useEffect)(() => {
2214
+ (0, import_react11.useEffect)(() => {
2179
2215
  const initialValue = selector(store.getState());
2180
2216
  listener(initialValue);
2181
2217
  return store.subscribe(selector, listener);
@@ -2183,17 +2219,17 @@ function useVizijStoreSubscription(selector, listener) {
2183
2219
  }
2184
2220
 
2185
2221
  // src/hooks/use-vizij-store-setter.ts
2186
- var import_react13 = require("react");
2222
+ var import_react12 = require("react");
2187
2223
  function useVizijStoreSetter() {
2188
- const store = (0, import_react13.useContext)(VizijContext);
2224
+ const store = (0, import_react12.useContext)(VizijContext);
2189
2225
  if (!store) throw new Error("Missing VizijProvider in the tree");
2190
2226
  return store.setState;
2191
2227
  }
2192
2228
 
2193
2229
  // src/hooks/use-vizij-store-getter.ts
2194
- var import_react14 = require("react");
2230
+ var import_react13 = require("react");
2195
2231
  function useVizijStoreGetter() {
2196
- const store = (0, import_react14.useContext)(VizijContext);
2232
+ const store = (0, import_react13.useContext)(VizijContext);
2197
2233
  if (!store) throw new Error("Missing VizijProvider in the tree");
2198
2234
  return store.getState;
2199
2235
  }
@@ -2203,7 +2239,6 @@ var THREE5 = __toESM(require("three"));
2203
2239
  var import_three_stdlib = require("three-stdlib");
2204
2240
 
2205
2241
  // src/functions/gltf-loading/traverse-three.ts
2206
- var import_react16 = require("react");
2207
2242
  var THREE4 = __toESM(require("three"));
2208
2243
 
2209
2244
  // src/functions/gltf-loading/map-features.ts
@@ -2229,28 +2264,27 @@ function mapFeatures(features) {
2229
2264
  }
2230
2265
 
2231
2266
  // src/functions/gltf-loading/import-scene.ts
2232
- var import_three5 = require("three");
2267
+ var import_three6 = require("three");
2233
2268
 
2234
2269
  // src/functions/gltf-loading/import-group.ts
2235
- var import_three4 = require("three");
2270
+ var import_three5 = require("three");
2236
2271
  var import_utils11 = require("@vizij/utils");
2237
2272
 
2238
- // src/functions/util.ts
2239
- var import_react15 = require("react");
2240
- function namespaceArrayToRefs(namespaces) {
2241
- return namespaces.reduce((acc, ns) => ({ ...acc, [ns]: (0, import_react15.createRef)() }), {});
2242
- }
2243
-
2244
2273
  // src/functions/gltf-loading/import-mesh.ts
2245
- var import_three3 = require("three");
2274
+ var import_three4 = require("three");
2246
2275
  var import_utils10 = require("@vizij/utils");
2247
2276
 
2248
2277
  // src/functions/gltf-loading/import-geometry.ts
2249
2278
  var import_utils9 = require("@vizij/utils");
2250
- function sanitizeMorphKey(name, fallbackIndex, used) {
2279
+
2280
+ // src/functions/gltf-loading/morph-keys.ts
2281
+ function slugifyMorphName(name, fallbackIndex) {
2251
2282
  const baseName = name && name.trim().length > 0 ? name.trim() : `morph_${fallbackIndex + 1}`;
2252
2283
  const slug = baseName.toLowerCase().replace(/[^a-z0-9]+/gi, "_").replace(/^_+|_+$/g, "");
2253
- const safeBase = slug.length > 0 ? slug : `morph_${fallbackIndex + 1}`;
2284
+ return slug.length > 0 ? slug : `morph_${fallbackIndex + 1}`;
2285
+ }
2286
+ function sanitizeMorphKey(name, fallbackIndex, used) {
2287
+ const safeBase = slugifyMorphName(name, fallbackIndex);
2254
2288
  let candidate = safeBase;
2255
2289
  let counter = 1;
2256
2290
  while (used.has(candidate)) {
@@ -2259,6 +2293,12 @@ function sanitizeMorphKey(name, fallbackIndex, used) {
2259
2293
  used.add(candidate);
2260
2294
  return candidate;
2261
2295
  }
2296
+ function deriveMorphFeatureKeys(names) {
2297
+ const used = /* @__PURE__ */ new Set();
2298
+ return names.map((name, index) => sanitizeMorphKey(name, index, used));
2299
+ }
2300
+
2301
+ // src/functions/gltf-loading/import-geometry.ts
2262
2302
  function importGeometry(geometry, mesh) {
2263
2303
  const features = {};
2264
2304
  const animatableValues = {};
@@ -2300,8 +2340,8 @@ function importGeometry(geometry, mesh) {
2300
2340
  }
2301
2341
 
2302
2342
  // src/functions/gltf-loading/import-mesh.ts
2303
- import_three3.Object3D.DEFAULT_UP.set(0, 0, 1);
2304
- function importMesh(mesh, namespaces, colorLookup) {
2343
+ import_three4.Object3D.DEFAULT_UP.set(0, 0, 1);
2344
+ function importMesh(mesh, colorLookup) {
2305
2345
  let world = {};
2306
2346
  let animatables = {};
2307
2347
  let newColorLookup = {};
@@ -2470,7 +2510,7 @@ function importMesh(mesh, namespaces, colorLookup) {
2470
2510
  const children = [];
2471
2511
  mesh.children.forEach((child) => {
2472
2512
  if (child.isMesh) {
2473
- const [newWorldItems, newAnimatables, childId, newMeshColors] = importMesh(child, namespaces, {
2513
+ const [newWorldItems, newAnimatables, childId, newMeshColors] = importMesh(child, {
2474
2514
  ...colorLookup,
2475
2515
  ...newColorLookup
2476
2516
  });
@@ -2479,7 +2519,7 @@ function importMesh(mesh, namespaces, colorLookup) {
2479
2519
  animatables = { ...animatables, ...newAnimatables };
2480
2520
  children.push(childId);
2481
2521
  } else if (shouldImportAsGroupChild(child)) {
2482
- const [newWorldItems, newAnimatables, childId, newMeshColors] = importGroup(child, namespaces, {
2522
+ const [newWorldItems, newAnimatables, childId, newMeshColors] = importGroup(child, {
2483
2523
  ...colorLookup,
2484
2524
  ...newColorLookup
2485
2525
  });
@@ -2516,8 +2556,7 @@ function importMesh(mesh, namespaces, colorLookup) {
2516
2556
  ...materialIds.specular ? { specular: { animated: true, value: materialIds.specular } } : {},
2517
2557
  ...geometryFeatures
2518
2558
  },
2519
- children: children.length > 0 ? children : void 0,
2520
- refs: namespaceArrayToRefs(namespaces)
2559
+ children: children.length > 0 ? children : void 0
2521
2560
  };
2522
2561
  world = { ...world, [newShape.id]: newShape };
2523
2562
  return [world, animatables, newShape.id, newColorLookup];
@@ -2558,8 +2597,8 @@ function shouldImportAsGroupChild(child) {
2558
2597
  }
2559
2598
 
2560
2599
  // src/functions/gltf-loading/import-group.ts
2561
- import_three4.Object3D.DEFAULT_UP.set(0, 0, 1);
2562
- function importGroup(group, namespaces, colorLookup, rootBounds) {
2600
+ import_three5.Object3D.DEFAULT_UP.set(0, 0, 1);
2601
+ function importGroup(group, colorLookup, rootBounds) {
2563
2602
  let world = {};
2564
2603
  let animatables = {};
2565
2604
  let newColorLookup = {};
@@ -2607,7 +2646,7 @@ function importGroup(group, namespaces, colorLookup, rootBounds) {
2607
2646
  animatables = { ...animatables, [scaleAnimatable.id]: scaleAnimatable };
2608
2647
  group.children.forEach((child) => {
2609
2648
  if (child.isMesh) {
2610
- const [newWorldItems, newAnimatables, childId, newMeshColors] = importMesh(child, namespaces, {
2649
+ const [newWorldItems, newAnimatables, childId, newMeshColors] = importMesh(child, {
2611
2650
  ...colorLookup,
2612
2651
  ...newColorLookup
2613
2652
  });
@@ -2616,7 +2655,7 @@ function importGroup(group, namespaces, colorLookup, rootBounds) {
2616
2655
  animatables = { ...animatables, ...newAnimatables };
2617
2656
  children.push(childId);
2618
2657
  } else if (shouldImportAsGroupChild2(child)) {
2619
- const [newWorldItems, newAnimatables, childId, newMeshColors] = importGroup(child, namespaces, {
2658
+ const [newWorldItems, newAnimatables, childId, newMeshColors] = importGroup(child, {
2620
2659
  ...colorLookup,
2621
2660
  ...newColorLookup
2622
2661
  });
@@ -2638,8 +2677,7 @@ function importGroup(group, namespaces, colorLookup, rootBounds) {
2638
2677
  },
2639
2678
  root: Boolean(rootBounds),
2640
2679
  rootBounds,
2641
- children,
2642
- refs: namespaceArrayToRefs(namespaces)
2680
+ children
2643
2681
  };
2644
2682
  world = { ...world, [newGroup.id]: newGroup };
2645
2683
  return [world, animatables, newGroup.id, newColorLookup];
@@ -2664,13 +2702,12 @@ function shouldImportAsGroupChild2(child) {
2664
2702
  }
2665
2703
 
2666
2704
  // src/functions/gltf-loading/import-scene.ts
2667
- import_three5.Object3D.DEFAULT_UP.set(0, 0, 1);
2668
- function importScene(scene, namespaces, rootBounds) {
2705
+ import_three6.Object3D.DEFAULT_UP.set(0, 0, 1);
2706
+ function importScene(scene, rootBounds) {
2669
2707
  let world = {};
2670
2708
  let animatables = {};
2671
2709
  const [newWorldItems, newAnimatables] = importGroup(
2672
2710
  scene,
2673
- namespaces,
2674
2711
  {},
2675
2712
  rootBounds
2676
2713
  );
@@ -2681,7 +2718,7 @@ function importScene(scene, namespaces, rootBounds) {
2681
2718
 
2682
2719
  // src/functions/gltf-loading/traverse-three.ts
2683
2720
  THREE4.Object3D.DEFAULT_UP.set(0, 0, 1);
2684
- function traverseThree(group, namespaces, aggressiveImport = false, rootBounds) {
2721
+ function traverseThree(group, aggressiveImport = false, rootBounds) {
2685
2722
  const worldData = {};
2686
2723
  const animatableData = {};
2687
2724
  let hasRobotData = false;
@@ -2704,11 +2741,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
2704
2741
  switch (data.type) {
2705
2742
  case "group":
2706
2743
  loadedData = {
2707
- ...data,
2708
- refs: namespaces.reduce(
2709
- (acc, ns) => ({ ...acc, [ns]: (0, import_react16.createRef)() }),
2710
- {}
2711
- )
2744
+ ...data
2712
2745
  };
2713
2746
  [mappedFeatures, animatableValues] = mapFeatures(data.features);
2714
2747
  isGroupFeatures(mappedFeatures);
@@ -2719,11 +2752,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
2719
2752
  case "shape":
2720
2753
  loadedData = {
2721
2754
  ...data,
2722
- geometry: child.geometry,
2723
- refs: namespaces.reduce(
2724
- (acc, ns) => ({ ...acc, [ns]: (0, import_react16.createRef)() }),
2725
- {}
2726
- )
2755
+ geometry: child.geometry
2727
2756
  };
2728
2757
  [mappedFeatures, animatableValues] = mapFeatures(data.features);
2729
2758
  isShapeFeatures(mappedFeatures);
@@ -2733,11 +2762,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
2733
2762
  break;
2734
2763
  case "ellipse":
2735
2764
  loadedData = {
2736
- ...data,
2737
- refs: namespaces.reduce(
2738
- (acc, ns) => ({ ...acc, [ns]: (0, import_react16.createRef)() }),
2739
- {}
2740
- )
2765
+ ...data
2741
2766
  };
2742
2767
  [mappedFeatures, animatableValues] = mapFeatures(data.features);
2743
2768
  isEllipseFeatures(mappedFeatures);
@@ -2747,11 +2772,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
2747
2772
  break;
2748
2773
  case "rectangle":
2749
2774
  loadedData = {
2750
- ...data,
2751
- refs: namespaces.reduce(
2752
- (acc, ns) => ({ ...acc, [ns]: (0, import_react16.createRef)() }),
2753
- {}
2754
- )
2775
+ ...data
2755
2776
  };
2756
2777
  [mappedFeatures, animatableValues] = mapFeatures(data.features);
2757
2778
  isRectangleFeatures(mappedFeatures);
@@ -2774,7 +2795,6 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
2774
2795
  }
2775
2796
  const [newWorldData, newAnimatableData] = importScene(
2776
2797
  group,
2777
- namespaces,
2778
2798
  derivedRootBounds
2779
2799
  );
2780
2800
  Object.assign(worldData, newWorldData);
@@ -3490,16 +3510,6 @@ async function resolveParserJson(parserJson, fallback) {
3490
3510
  return fromArrayBuffer;
3491
3511
  }
3492
3512
  }
3493
- if (fallback.blob) {
3494
- try {
3495
- const blobBuffer = typeof fallback.blob.arrayBuffer === "function" ? await fallback.blob.arrayBuffer() : await new Response(fallback.blob).arrayBuffer();
3496
- const fromBlob = parseGlbJsonChunk(blobBuffer);
3497
- if (fromBlob && typeof fromBlob === "object") {
3498
- return fromBlob;
3499
- }
3500
- } catch {
3501
- }
3502
- }
3503
3513
  if (fallback.url && typeof fetch === "function") {
3504
3514
  try {
3505
3515
  const response = await fetch(fallback.url);
@@ -3515,73 +3525,21 @@ async function resolveParserJson(parserJson, fallback) {
3515
3525
  }
3516
3526
  return parserJson;
3517
3527
  }
3518
- async function loadGLTF(url, namespaces, aggressiveImport = false, rootBounds) {
3519
- const asset = await loadGLTFWithBundleInternal(
3520
- url,
3521
- namespaces,
3528
+ async function loadGLTF(url, aggressiveImport = false, rootBounds) {
3529
+ const asset = await loadGLTFWithBundle(url, aggressiveImport, rootBounds);
3530
+ return [asset.world, asset.animatables, asset.animations];
3531
+ }
3532
+ async function loadGLTFFromBlob(blob, aggressiveImport = false, rootBounds) {
3533
+ const asset = await loadGLTFFromBlobWithBundle(
3534
+ blob,
3522
3535
  aggressiveImport,
3523
- rootBounds,
3524
- "url"
3536
+ rootBounds
3525
3537
  );
3526
3538
  return [asset.world, asset.animatables, asset.animations];
3527
3539
  }
3528
- async function loadGLTFFromBlob(blob, namespaces, aggressiveImport = false, rootBounds) {
3529
- const actualizedNamespaces = namespaces.length > 0 ? namespaces : ["default"];
3530
- if (typeof URL !== "undefined" && typeof URL.createObjectURL === "function") {
3531
- const objectUrl = URL.createObjectURL(blob);
3532
- try {
3533
- const asset = await loadGLTFWithBundleInternal(
3534
- objectUrl,
3535
- actualizedNamespaces,
3536
- aggressiveImport,
3537
- rootBounds,
3538
- "blob",
3539
- { blob }
3540
- );
3541
- return [asset.world, asset.animatables, asset.animations];
3542
- } finally {
3543
- URL.revokeObjectURL(objectUrl);
3544
- }
3545
- }
3546
- const arrayBuffer = typeof blob.arrayBuffer === "function" ? await blob.arrayBuffer() : await new Response(blob).arrayBuffer();
3547
- return new Promise((resolve, reject) => {
3548
- const loader = createTrackedGLTFLoader();
3549
- loader.parse(
3550
- arrayBuffer,
3551
- "",
3552
- async (gltf) => {
3553
- try {
3554
- const parserJson = await resolveParserJson(
3555
- gltf?.parser?.json,
3556
- { arrayBuffer }
3557
- );
3558
- const asset = parseScene(
3559
- gltf.scene,
3560
- actualizedNamespaces,
3561
- aggressiveImport,
3562
- rootBounds,
3563
- parserJson,
3564
- gltf.animations
3565
- );
3566
- resolve([asset.world, asset.animatables, asset.animations]);
3567
- } catch (error) {
3568
- if (error instanceof Error) {
3569
- reject(error);
3570
- } else {
3571
- reject(new Error(String(error)));
3572
- }
3573
- }
3574
- },
3575
- (error) => {
3576
- reject(new Error(`Error loading GLTF: ${error.message}`));
3577
- }
3578
- );
3579
- });
3580
- }
3581
- function parseScene(scene, namespaces, aggressiveImport, rootBounds, parserJson, clips) {
3540
+ function parseScene(scene, aggressiveImport, rootBounds, parserJson, clips) {
3582
3541
  const [world, animatables] = traverseThree(
3583
3542
  scene,
3584
- namespaces,
3585
3543
  aggressiveImport,
3586
3544
  rootBounds
3587
3545
  );
@@ -3596,125 +3554,45 @@ function createTrackedGLTFLoader() {
3596
3554
  modelLoader.setDRACOLoader(new import_three_stdlib.DRACOLoader());
3597
3555
  return modelLoader;
3598
3556
  }
3599
- async function loadGLTFWithBundleInternal(url, namespaces, aggressiveImport = false, rootBounds, sourceKind = "url", parserJsonFallback) {
3600
- if (sourceKind === "url") {
3601
- recordRenderCounter("gltfUrlLoadCount");
3602
- } else {
3603
- recordRenderCounter("gltfBlobLoadCount");
3604
- }
3557
+ async function loadGLTFWithBundle(url, aggressiveImport = false, rootBounds, parserJsonFallback) {
3558
+ recordRenderCounter("gltfUrlLoadCount");
3605
3559
  const modelLoader = createTrackedGLTFLoader();
3606
3560
  const modelData = await modelLoader.loadAsync(url);
3607
3561
  const parserJson = await resolveParserJson(modelData?.parser?.json, {
3608
3562
  url,
3609
3563
  ...parserJsonFallback
3610
3564
  });
3611
- const actualizedNamespaces = namespaces.length > 0 ? namespaces : ["default"];
3612
3565
  return parseScene(
3613
3566
  modelData.scene,
3614
- actualizedNamespaces,
3615
3567
  aggressiveImport,
3616
3568
  rootBounds,
3617
3569
  parserJson,
3618
3570
  modelData.animations
3619
3571
  );
3620
3572
  }
3621
- async function loadGLTFWithBundle(url, namespaces, aggressiveImport = false, rootBounds, parserJsonFallback) {
3622
- return loadGLTFWithBundleInternal(
3623
- url,
3624
- namespaces,
3573
+ async function loadGLTFFromBlobWithBundle(blob, aggressiveImport = false, rootBounds) {
3574
+ recordRenderCounter("gltfBlobLoadCount");
3575
+ const arrayBuffer = await blob.arrayBuffer();
3576
+ const loader = createTrackedGLTFLoader();
3577
+ const gltf = await new Promise((resolve, reject) => {
3578
+ loader.parse(arrayBuffer, "", resolve, (error) => {
3579
+ reject(new Error(`Error loading GLTF: ${error.message}`));
3580
+ });
3581
+ });
3582
+ const parserJson = await resolveParserJson(gltf?.parser?.json, {
3583
+ arrayBuffer
3584
+ });
3585
+ return parseScene(
3586
+ gltf.scene,
3625
3587
  aggressiveImport,
3626
3588
  rootBounds,
3627
- "url",
3628
- parserJsonFallback
3589
+ parserJson,
3590
+ gltf.animations
3629
3591
  );
3630
3592
  }
3631
- async function loadGLTFFromBlobWithBundle(blob, namespaces, aggressiveImport = false, rootBounds) {
3632
- const actualizedNamespaces = namespaces.length > 0 ? namespaces : ["default"];
3633
- if (typeof URL !== "undefined" && typeof URL.createObjectURL === "function") {
3634
- const objectUrl = URL.createObjectURL(blob);
3635
- try {
3636
- return await loadGLTFWithBundleInternal(
3637
- objectUrl,
3638
- actualizedNamespaces,
3639
- aggressiveImport,
3640
- rootBounds,
3641
- "blob",
3642
- { blob }
3643
- );
3644
- } finally {
3645
- URL.revokeObjectURL(objectUrl);
3646
- }
3647
- }
3648
- const arrayBuffer = typeof blob.arrayBuffer === "function" ? await blob.arrayBuffer() : await new Response(blob).arrayBuffer();
3649
- return new Promise((resolve, reject) => {
3650
- const loader = createTrackedGLTFLoader();
3651
- loader.parse(
3652
- arrayBuffer,
3653
- "",
3654
- async (gltf) => {
3655
- try {
3656
- const parserJson = await resolveParserJson(
3657
- gltf?.parser?.json,
3658
- { arrayBuffer }
3659
- );
3660
- const asset = parseScene(
3661
- gltf.scene,
3662
- actualizedNamespaces,
3663
- aggressiveImport,
3664
- rootBounds,
3665
- parserJson,
3666
- gltf.animations
3667
- );
3668
- resolve(asset);
3669
- } catch (error) {
3670
- if (error instanceof Error) {
3671
- reject(error);
3672
- } else {
3673
- reject(new Error(String(error)));
3674
- }
3675
- }
3676
- },
3677
- (error) => {
3678
- reject(new Error(`Error loading GLTF: ${error.message}`));
3679
- }
3680
- );
3681
- });
3682
- }
3683
-
3684
- // src/functions/load-gltf-blob.ts
3685
- var import_three_stdlib2 = require("three-stdlib");
3686
- var loadGltfFromBlob = (blob, namespaces) => {
3687
- recordRenderCounter("gltfLoadCount");
3688
- recordRenderCounter("gltfBlobLoadCount");
3689
- recordRenderCounter("dracoLoaderCreationCount");
3690
- return new Promise((resolve, reject) => {
3691
- const loader = new import_three_stdlib2.GLTFLoader();
3692
- loader.setDRACOLoader(new import_three_stdlib2.DRACOLoader());
3693
- const reader = new FileReader();
3694
- reader.onload = () => {
3695
- const arrayBuffer = reader.result;
3696
- loader.parse(
3697
- arrayBuffer,
3698
- "",
3699
- // Base path for resolving external resources
3700
- (gltf) => {
3701
- const actualizedNamespaces = namespaces.length > 0 ? namespaces : ["default"];
3702
- resolve(traverseThree(gltf.scene, actualizedNamespaces));
3703
- },
3704
- (error) => {
3705
- reject(new Error(`Error loading GLTF: ${error.message}`));
3706
- }
3707
- );
3708
- };
3709
- reader.onerror = () => {
3710
- reject(new Error("Failed to read Blob as ArrayBuffer."));
3711
- };
3712
- reader.readAsArrayBuffer(blob);
3713
- });
3714
- };
3715
3593
 
3716
3594
  // src/functions/export.ts
3717
- var import_three_stdlib3 = require("three-stdlib");
3595
+ var import_three_stdlib2 = require("three-stdlib");
3718
3596
  var THREE6 = __toESM(require("three"));
3719
3597
  THREE6.Object3D.DEFAULT_UP.set(0, 0, 1);
3720
3598
  function normalizeExportError(error) {
@@ -3726,17 +3604,6 @@ function normalizeExportError(error) {
3726
3604
  }
3727
3605
  return new Error("Failed to export scene.");
3728
3606
  }
3729
- function triggerBlobDownload(blob, filename) {
3730
- const url = URL.createObjectURL(blob);
3731
- const link = document.createElement("a");
3732
- link.href = url;
3733
- link.download = filename;
3734
- link.style.display = "none";
3735
- document.body.appendChild(link);
3736
- link.click();
3737
- document.body.removeChild(link);
3738
- setTimeout(() => URL.revokeObjectURL(url), 0);
3739
- }
3740
3607
  var GLB_MAGIC2 = 1179937895;
3741
3608
  var GLB_VERSION2 = 2;
3742
3609
  var GLB_JSON_CHUNK_TYPE2 = 1313821514;
@@ -3818,7 +3685,7 @@ function normalizeExportedSceneJson(json, fallbackSceneName) {
3818
3685
  }
3819
3686
  return changed;
3820
3687
  }
3821
- function sanitizeExportedGlb(buffer, fallbackSceneName) {
3688
+ function patchGlbJson(buffer, mutate) {
3822
3689
  if (buffer.byteLength < GLB_HEADER_BYTES2 + GLB_CHUNK_HEADER_BYTES2) {
3823
3690
  return buffer;
3824
3691
  }
@@ -3848,8 +3715,7 @@ function sanitizeExportedGlb(buffer, fallbackSceneName) {
3848
3715
  } catch {
3849
3716
  return buffer;
3850
3717
  }
3851
- const changed = normalizeExportedSceneJson(jsonPayload, fallbackSceneName);
3852
- if (!changed) {
3718
+ if (!mutate(jsonPayload)) {
3853
3719
  return buffer;
3854
3720
  }
3855
3721
  const encodedJson = new TextEncoder().encode(JSON.stringify(jsonPayload));
@@ -3871,12 +3737,42 @@ function sanitizeExportedGlb(buffer, fallbackSceneName) {
3871
3737
  sanitizedBytes.set(remainingChunks, jsonChunkStart + paddedJsonLength);
3872
3738
  return sanitized;
3873
3739
  }
3874
- function exportScene(data, fileNameOrOptions = "scene.glb") {
3875
- const options = typeof fileNameOrOptions === "string" ? { fileName: fileNameOrOptions } : fileNameOrOptions ?? {};
3876
- const fileName = options.fileName ?? "scene.glb";
3877
- const animationClips = Array.isArray(options.animations) ? options.animations.filter(Boolean) : [];
3878
- const shouldAttachBundle = Boolean(options.bundle);
3879
- const exporter = new import_three_stdlib3.GLTFExporter();
3740
+ function sanitizeExportedGlb(buffer, fallbackSceneName) {
3741
+ return patchGlbJson(
3742
+ buffer,
3743
+ (json) => normalizeExportedSceneJson(json, fallbackSceneName)
3744
+ );
3745
+ }
3746
+ function patchVizijBundleMetadata(glb, metadata) {
3747
+ return patchGlbJson(glb, (json) => {
3748
+ const carriers = [];
3749
+ const rootExtensions = json.extensions;
3750
+ if (rootExtensions && typeof rootExtensions === "object") {
3751
+ carriers.push(rootExtensions);
3752
+ }
3753
+ const nodes = Array.isArray(json.nodes) ? json.nodes : [];
3754
+ for (const node of nodes) {
3755
+ const extensions = node?.extensions;
3756
+ if (extensions && typeof extensions === "object") {
3757
+ carriers.push(extensions);
3758
+ }
3759
+ }
3760
+ let patched = false;
3761
+ for (const extensions of carriers) {
3762
+ const bundle = extensions.VIZIJ_bundle;
3763
+ if (!bundle || typeof bundle !== "object") {
3764
+ continue;
3765
+ }
3766
+ const record = bundle;
3767
+ const existing = record.metadata && typeof record.metadata === "object" ? record.metadata : {};
3768
+ record.metadata = { ...existing, ...metadata };
3769
+ patched = true;
3770
+ }
3771
+ return patched;
3772
+ });
3773
+ }
3774
+ async function exportScene(root, options = {}) {
3775
+ const exporter = new import_three_stdlib2.GLTFExporter();
3880
3776
  exporter.register(() => ({
3881
3777
  writeMesh(mesh, meshDef) {
3882
3778
  const meshName = mesh.name?.trim() || mesh.geometry?.name?.trim() || void 0;
@@ -3885,82 +3781,324 @@ function exportScene(data, fileNameOrOptions = "scene.glb") {
3885
3781
  }
3886
3782
  }
3887
3783
  }));
3888
- const sourceRoot = data;
3889
- const exportRoot = sourceRoot instanceof THREE6.Scene ? sourceRoot : sourceRoot.clone(true);
3784
+ const exportRoot = root instanceof THREE6.Scene ? root : root.clone(true);
3890
3785
  const exportTarget = exportRoot instanceof THREE6.Scene ? exportRoot : (() => {
3891
3786
  const scene = new THREE6.Scene();
3892
- scene.name = data.name?.trim() || "Scene";
3787
+ scene.name = root.name?.trim() || "Scene";
3893
3788
  scene.add(exportRoot);
3894
3789
  return scene;
3895
3790
  })();
3896
- const detachBundle = shouldAttachBundle && options.bundle ? applyVizijBundle(exportRoot, options.bundle) : () => {
3897
- };
3898
- const binary = options.binary ?? true;
3899
- const exporterOptions = {
3900
- trs: true,
3901
- onlyVisible: false,
3902
- binary,
3903
- includeCustomExtensions: true
3791
+ const detachBundle = options.bundle ? applyVizijBundle(exportRoot, options.bundle) : () => {
3904
3792
  };
3905
- if (animationClips.length > 0) {
3906
- exporterOptions.animations = animationClips;
3907
- }
3793
+ const animations = (options.animations ?? []).filter(Boolean);
3794
+ let gltf;
3908
3795
  try {
3909
- exporter.parse(
3910
- exportTarget,
3911
- (gltf) => {
3912
- detachBundle();
3913
- if (!(gltf instanceof ArrayBuffer)) {
3914
- const error = new Error("Failed to export scene.");
3915
- options.onError?.(error);
3916
- return;
3917
- }
3918
- const sanitizedGltf = sanitizeExportedGlb(
3919
- gltf,
3920
- data.name?.trim() || void 0
3921
- );
3922
- const trimmed = fileName.trim();
3923
- const safeFileName = trimmed.length > 0 ? trimmed : "scene.glb";
3924
- const downloadName = safeFileName.toLowerCase().endsWith(".glb") ? safeFileName : `${safeFileName}.glb`;
3925
- triggerBlobDownload(
3926
- new Blob([sanitizedGltf], {
3927
- type: "application/octet-stream"
3928
- }),
3929
- downloadName
3930
- );
3931
- options.onComplete?.();
3932
- },
3933
- (error) => {
3934
- detachBundle();
3935
- options.onError?.(normalizeExportError(error));
3936
- },
3937
- exporterOptions
3938
- );
3796
+ gltf = await exporter.parseAsync(exportTarget, {
3797
+ trs: true,
3798
+ onlyVisible: false,
3799
+ binary: true,
3800
+ includeCustomExtensions: true,
3801
+ ...animations.length > 0 ? { animations } : {}
3802
+ });
3939
3803
  } catch (error) {
3804
+ throw normalizeExportError(error);
3805
+ } finally {
3940
3806
  detachBundle();
3941
- const normalizedError = normalizeExportError(error);
3942
- options.onError?.(normalizedError);
3943
- throw normalizedError;
3807
+ }
3808
+ if (!(gltf instanceof ArrayBuffer)) {
3809
+ throw new Error("Failed to export scene.");
3810
+ }
3811
+ return sanitizeExportedGlb(gltf, root.name?.trim() || void 0);
3812
+ }
3813
+
3814
+ // src/functions/build-scene-graph.ts
3815
+ var THREE7 = __toESM(require("three"));
3816
+ var import_utils14 = require("@vizij/utils");
3817
+ THREE7.Object3D.DEFAULT_UP.set(0, 0, 1);
3818
+ function buildSceneGraph(world, animatables, rootId) {
3819
+ const entry = world[rootId];
3820
+ if (!entry) {
3821
+ throw new Error(`The world has no element "${rootId}".`);
3822
+ }
3823
+ const used = {};
3824
+ for (const feature of Object.values(entry.features)) {
3825
+ if (feature.animated) {
3826
+ used[feature.value] = animatableOf(animatables, feature.value);
3827
+ }
3828
+ }
3829
+ const robotData = createStoredRenderable(entry, used);
3830
+ switch (entry.type) {
3831
+ case "group": {
3832
+ const object = new THREE7.Group();
3833
+ object.name = entry.name;
3834
+ object.userData = { gltfExtensions: { RobotData: robotData } };
3835
+ applyFeatures(entry.features, animatables, groupTransform(object));
3836
+ for (const child of entry.children) {
3837
+ object.add(buildSceneGraph(world, animatables, child));
3838
+ }
3839
+ return object;
3840
+ }
3841
+ case "shape": {
3842
+ const geometry = entry.geometry.clone();
3843
+ if (entry.name) {
3844
+ geometry.name = entry.name;
3845
+ }
3846
+ const material = createMaterial(entry.material);
3847
+ material.name = deriveMaterialName(entry, used) ?? entry.name ?? "";
3848
+ const object = new THREE7.Mesh(geometry, material);
3849
+ object.name = entry.name;
3850
+ object.userData = { gltfExtensions: { RobotData: robotData } };
3851
+ applyFeatures(entry.features, animatables, {
3852
+ ...shapeTransform(object),
3853
+ ...materialFactors(material),
3854
+ ...morphWeights(object, entry)
3855
+ });
3856
+ for (const child of entry.children ?? []) {
3857
+ object.add(buildSceneGraph(world, animatables, child));
3858
+ }
3859
+ return object;
3860
+ }
3861
+ default:
3862
+ throw new Error(
3863
+ `Element "${rootId}" is a ${entry.type}, which has no exported form.`
3864
+ );
3865
+ }
3866
+ }
3867
+ function animatableOf(animatables, id) {
3868
+ const animatable = animatables[id];
3869
+ if (!animatable) {
3870
+ throw new Error(`No animatable "${id}".`);
3871
+ }
3872
+ return animatable;
3873
+ }
3874
+ function applyFeatures(features, animatables, handlers) {
3875
+ for (const [key, handler] of Object.entries(handlers)) {
3876
+ const feature = features[key];
3877
+ if (!feature) {
3878
+ continue;
3879
+ }
3880
+ const value = feature.animated ? authoredDefault(animatableOf(animatables, feature.value)) : feature.value;
3881
+ if (value !== void 0) {
3882
+ handler(value);
3883
+ }
3884
+ }
3885
+ }
3886
+ function groupTransform(object) {
3887
+ return {
3888
+ translation: (value) => {
3889
+ if ((0, import_utils14.instanceOfRawVector3)(value)) {
3890
+ object.position.set(value.x, value.y, value.z);
3891
+ } else if ((0, import_utils14.instanceOfRawVector2)(value)) {
3892
+ object.position.set(value.x, value.y, object.position.z);
3893
+ }
3894
+ },
3895
+ rotation: (value) => {
3896
+ if ((0, import_utils14.instanceOfRawEuler)(value)) {
3897
+ object.rotation.set(value.x, value.y, value.z, "ZYX");
3898
+ } else if ((0, import_utils14.instanceOfRawNumber)(value)) {
3899
+ object.rotation.set(0, 0, 0);
3900
+ object.rotateZ(value);
3901
+ }
3902
+ },
3903
+ scale: (value) => {
3904
+ if ((0, import_utils14.instanceOfRawVector3)(value)) {
3905
+ if (value.x === null || value.y === null || value.z === null) {
3906
+ object.scale.set(0.1, 0.1, 0.1);
3907
+ } else {
3908
+ object.scale.set(value.x, value.y, value.z);
3909
+ }
3910
+ } else if ((0, import_utils14.instanceOfRawNumber)(value)) {
3911
+ object.scale.set(value, value, value);
3912
+ } else {
3913
+ object.scale.set(1, 1, 1);
3914
+ }
3915
+ }
3916
+ };
3917
+ }
3918
+ function shapeTransform(object) {
3919
+ return {
3920
+ translation: (value) => {
3921
+ if ((0, import_utils14.instanceOfRawVector3)(value)) {
3922
+ object.position.set(value.x, value.y, value.z);
3923
+ }
3924
+ },
3925
+ rotation: (value) => {
3926
+ if ((0, import_utils14.instanceOfRawEuler)(value)) {
3927
+ object.rotation.set(value.x, value.y, value.z, "ZYX");
3928
+ }
3929
+ },
3930
+ scale: (value) => {
3931
+ if ((0, import_utils14.instanceOfRawVector3)(value)) {
3932
+ object.scale.set(value.x, value.y, value.z);
3933
+ } else if ((0, import_utils14.instanceOfRawNumber)(value)) {
3934
+ object.scale.set(value, value, value);
3935
+ } else {
3936
+ object.scale.set(1, 1, 1);
3937
+ }
3938
+ }
3939
+ };
3940
+ }
3941
+ function materialFactors(material) {
3942
+ const standard = material;
3943
+ const phong = material;
3944
+ return {
3945
+ opacity: (value) => {
3946
+ if ((0, import_utils14.instanceOfRawNumber)(value)) {
3947
+ material.opacity = value;
3948
+ material.transparent = value < 1;
3949
+ }
3950
+ },
3951
+ color: (value) => {
3952
+ if (!standard.color) {
3953
+ return;
3954
+ }
3955
+ if ((0, import_utils14.instanceOfRawRGB)(value)) {
3956
+ standard.color.setRGB(value.r, value.g, value.b);
3957
+ } else if ((0, import_utils14.instanceOfRawVector3)(value)) {
3958
+ standard.color.setRGB(value.x, value.y, value.z);
3959
+ } else if ((0, import_utils14.instanceOfRawHSL)(value)) {
3960
+ standard.color.setHSL(value.h, value.s, value.l);
3961
+ }
3962
+ },
3963
+ roughness: (value) => {
3964
+ if (standard.roughness !== void 0 && (0, import_utils14.instanceOfRawNumber)(value)) {
3965
+ standard.roughness = value;
3966
+ }
3967
+ },
3968
+ metalness: (value) => {
3969
+ if (standard.metalness !== void 0 && (0, import_utils14.instanceOfRawNumber)(value)) {
3970
+ standard.metalness = value;
3971
+ }
3972
+ },
3973
+ shininess: (value) => {
3974
+ if (phong.shininess !== void 0 && (0, import_utils14.instanceOfRawNumber)(value)) {
3975
+ phong.shininess = value;
3976
+ }
3977
+ },
3978
+ emissive: (value) => {
3979
+ if (standard.emissive && (0, import_utils14.instanceOfRawRGB)(value)) {
3980
+ standard.emissive.setRGB(value.r, value.g, value.b);
3981
+ }
3982
+ },
3983
+ emissiveIntensity: (value) => {
3984
+ if (standard.emissiveIntensity !== void 0 && (0, import_utils14.instanceOfRawNumber)(value)) {
3985
+ standard.emissiveIntensity = value;
3986
+ }
3987
+ },
3988
+ specular: (value) => {
3989
+ if (phong.specular && (0, import_utils14.instanceOfRawRGB)(value)) {
3990
+ phong.specular.setRGB(value.r, value.g, value.b);
3991
+ }
3992
+ }
3993
+ };
3994
+ }
3995
+ function morphWeights(object, shape) {
3996
+ const targets = shape.morphTargets ?? [];
3997
+ if (targets.length === 0) {
3998
+ return {};
3999
+ }
4000
+ const influences = targets.map(() => 0);
4001
+ object.morphTargetDictionary = Object.fromEntries(
4002
+ targets.map((target, index) => [target, index])
4003
+ );
4004
+ object.morphTargetInfluences = influences;
4005
+ return Object.fromEntries(
4006
+ targets.map((target, index) => [
4007
+ target,
4008
+ (value) => {
4009
+ if ((0, import_utils14.instanceOfRawNumber)(value)) {
4010
+ influences[index] = value;
4011
+ }
4012
+ }
4013
+ ])
4014
+ );
4015
+ }
4016
+ function createMaterial(kind) {
4017
+ const parameters = { side: THREE7.DoubleSide };
4018
+ switch (kind) {
4019
+ case "basic" /* Basic */:
4020
+ return new THREE7.MeshBasicMaterial(parameters);
4021
+ case "lambert" /* Lambert */:
4022
+ return new THREE7.MeshLambertMaterial(parameters);
4023
+ case "phong" /* Phong */:
4024
+ return new THREE7.MeshPhongMaterial(parameters);
4025
+ case "normal" /* Normal */:
4026
+ return new THREE7.MeshNormalMaterial(parameters);
4027
+ case "standard" /* Standard */:
4028
+ return new THREE7.MeshStandardMaterial(parameters);
4029
+ }
4030
+ }
4031
+ var SCALAR_KEYS = ["f32", "f64", "i64", "i32", "u64", "u32", "float"];
4032
+ function scalarOf(value) {
4033
+ if (typeof value === "number") {
4034
+ return value;
4035
+ }
4036
+ if (value && typeof value === "object") {
4037
+ for (const key of SCALAR_KEYS) {
4038
+ const scalar = value[key];
4039
+ if (typeof scalar === "number") {
4040
+ return scalar;
4041
+ }
4042
+ }
4043
+ }
4044
+ return void 0;
4045
+ }
4046
+ function authoredDefault(animatable) {
4047
+ const value = animatable.default;
4048
+ const scalar = scalarOf(value);
4049
+ if (scalar !== void 0) {
4050
+ return scalar;
4051
+ }
4052
+ const fields = value?.struct?.fields;
4053
+ if (!Array.isArray(fields)) {
4054
+ return value;
4055
+ }
4056
+ const n = fields.map(
4057
+ (field) => scalarOf(field?.value) ?? 0
4058
+ );
4059
+ switch (animatable.type) {
4060
+ case "vector3":
4061
+ case "euler":
4062
+ return { x: n[0], y: n[1], z: n[2] };
4063
+ case "vector2":
4064
+ return { x: n[0], y: n[1] };
4065
+ case "rgb":
4066
+ return { r: n[0], g: n[1], b: n[2] };
4067
+ case "hsl":
4068
+ return { h: n[0], s: n[1], l: n[2] };
4069
+ default:
4070
+ return void 0;
3944
4071
  }
3945
4072
  }
3946
4073
  // Annotate the CommonJS export names for ESM import in node:
3947
4074
  0 && (module.exports = {
4075
+ DEFAULT_TONE_MAPPING_MODE,
3948
4076
  EmptyModelError,
3949
4077
  InnerVizij,
3950
4078
  ShapeMaterial,
4079
+ TONE_MAPPING_LABELS,
4080
+ TONE_MAPPING_MODES,
3951
4081
  Vizij,
3952
4082
  VizijContext,
3953
4083
  VizijSlice,
3954
4084
  applyVizijBundle,
4085
+ buildSceneGraph,
3955
4086
  createVizijStore,
4087
+ deriveMorphFeatureKeys,
4088
+ deriveRootBounds,
3956
4089
  exportScene,
3957
4090
  extractVizijBundle,
4091
+ isToneMappingMode,
3958
4092
  loadGLTF,
3959
4093
  loadGLTFFromBlob,
3960
4094
  loadGLTFFromBlobWithBundle,
3961
4095
  loadGLTFWithBundle,
3962
- loadGltfFromBlob,
4096
+ normalizeToneMappingMode,
3963
4097
  parseGlbJsonChunk,
4098
+ patchGlbJson,
4099
+ patchVizijBundleMetadata,
4100
+ resolveToneMapping,
4101
+ sanitizeMorphKey,
3964
4102
  useDefaultVizijStore,
3965
4103
  useFeatures,
3966
4104
  useVizijStore,