@vizij/render 0.0.7 → 0.1.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.d.mts +56 -6
- package/dist/index.d.ts +56 -6
- package/dist/index.js +564 -108
- package/dist/index.mjs +545 -117
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
loadGLTFFromBlobWithBundle: () => loadGLTFFromBlobWithBundle,
|
|
46
46
|
loadGLTFWithBundle: () => loadGLTFWithBundle,
|
|
47
47
|
loadGltfFromBlob: () => loadGltfFromBlob,
|
|
48
|
+
parseGlbJsonChunk: () => parseGlbJsonChunk,
|
|
48
49
|
useDefaultVizijStore: () => useDefaultVizijStore,
|
|
49
50
|
useFeatures: () => useFeatures,
|
|
50
51
|
useVizijStore: () => useVizijStore,
|
|
@@ -55,12 +56,12 @@ __export(index_exports, {
|
|
|
55
56
|
module.exports = __toCommonJS(index_exports);
|
|
56
57
|
|
|
57
58
|
// src/vizij.tsx
|
|
58
|
-
var
|
|
59
|
+
var import_react11 = require("react");
|
|
59
60
|
var import_react_error_boundary = require("react-error-boundary");
|
|
60
|
-
var
|
|
61
|
-
var
|
|
61
|
+
var import_three2 = require("three");
|
|
62
|
+
var import_fiber2 = require("@react-three/fiber");
|
|
62
63
|
var import_drei3 = require("@react-three/drei");
|
|
63
|
-
var
|
|
64
|
+
var import_shallow8 = require("zustand/react/shallow");
|
|
64
65
|
|
|
65
66
|
// src/renderables/renderable.tsx
|
|
66
67
|
var import_react8 = require("react");
|
|
@@ -174,7 +175,7 @@ function InnerRenderedGroup({
|
|
|
174
175
|
namespace,
|
|
175
176
|
chain
|
|
176
177
|
}) {
|
|
177
|
-
const ref = (0, import_react4.useRef)();
|
|
178
|
+
const ref = (0, import_react4.useRef)(null);
|
|
178
179
|
const group = useVizijStore((0, import_shallow2.useShallow)((state) => state.world[id]));
|
|
179
180
|
const refIsNull = !group.refs[namespace]?.current;
|
|
180
181
|
const animatables = useVizijStore((0, import_shallow2.useShallow)((state) => state.animatables));
|
|
@@ -295,9 +296,11 @@ function InnerRenderedEllipse({
|
|
|
295
296
|
namespace,
|
|
296
297
|
chain
|
|
297
298
|
}) {
|
|
298
|
-
const ellipseRef = (0, import_react5.useRef)();
|
|
299
|
-
const materialRef = (0, import_react5.useRef)(
|
|
300
|
-
|
|
299
|
+
const ellipseRef = (0, import_react5.useRef)(null);
|
|
300
|
+
const materialRef = (0, import_react5.useRef)(
|
|
301
|
+
null
|
|
302
|
+
);
|
|
303
|
+
const lineRef = (0, import_react5.useRef)(null);
|
|
301
304
|
const strokeOffsetRef = (0, import_react5.useRef)(0);
|
|
302
305
|
const strokeWidthRef = (0, import_react5.useRef)(0);
|
|
303
306
|
const onElementClick = useVizijStore(
|
|
@@ -580,9 +583,11 @@ function InnerRenderedRectangle({
|
|
|
580
583
|
namespace,
|
|
581
584
|
chain
|
|
582
585
|
}) {
|
|
583
|
-
const rectangleRef = (0, import_react6.useRef)();
|
|
584
|
-
const materialRef = (0, import_react6.useRef)(
|
|
585
|
-
|
|
586
|
+
const rectangleRef = (0, import_react6.useRef)(null);
|
|
587
|
+
const materialRef = (0, import_react6.useRef)(
|
|
588
|
+
null
|
|
589
|
+
);
|
|
590
|
+
const lineRef = (0, import_react6.useRef)(null);
|
|
586
591
|
const strokeOffsetRef = (0, import_react6.useRef)(0);
|
|
587
592
|
const strokeWidthRef = (0, import_react6.useRef)(0);
|
|
588
593
|
const onElementClick = useVizijStore(
|
|
@@ -867,8 +872,8 @@ function InnerRenderedShape({
|
|
|
867
872
|
namespace,
|
|
868
873
|
chain
|
|
869
874
|
}) {
|
|
870
|
-
const refGroup = (0, import_react7.useRef)();
|
|
871
|
-
const ref = (0, import_react7.useRef)();
|
|
875
|
+
const refGroup = (0, import_react7.useRef)(null);
|
|
876
|
+
const ref = (0, import_react7.useRef)(null);
|
|
872
877
|
const shape = useVizijStore((0, import_shallow5.useShallow)((state) => state.world[id]));
|
|
873
878
|
const refs = useVizijStore(
|
|
874
879
|
(0, import_shallow5.useShallow)((state) => state.world[id].refs)
|
|
@@ -909,7 +914,7 @@ function InnerRenderedShape({
|
|
|
909
914
|
}),
|
|
910
915
|
[shape, animatableValues, selectionData]
|
|
911
916
|
);
|
|
912
|
-
const material = (0, import_react7.useRef)();
|
|
917
|
+
const material = (0, import_react7.useRef)(null);
|
|
913
918
|
const morphTargetSettings = (0, import_react7.useMemo)(() => {
|
|
914
919
|
if (shape.morphTargets) {
|
|
915
920
|
const dictionary = shape.morphTargets.reduce(
|
|
@@ -1430,6 +1435,35 @@ function createAnimatable(value) {
|
|
|
1430
1435
|
}
|
|
1431
1436
|
createAnimatable({ type: "euler", name: "Rotation" });
|
|
1432
1437
|
|
|
1438
|
+
// src/functions/exportable-bodies.ts
|
|
1439
|
+
function asGroupEntries(world) {
|
|
1440
|
+
return Object.values(world).filter((entry) => entry.type === "group");
|
|
1441
|
+
}
|
|
1442
|
+
function selectExportableGroupEntries(world, filterIds) {
|
|
1443
|
+
const groupEntries = asGroupEntries(world);
|
|
1444
|
+
const filterSet = Array.isArray(filterIds) && filterIds.length > 0 ? new Set(filterIds) : null;
|
|
1445
|
+
if (filterSet) {
|
|
1446
|
+
return groupEntries.filter((entry) => filterSet.has(entry.id));
|
|
1447
|
+
}
|
|
1448
|
+
const rootBoundsGroups = groupEntries.filter(
|
|
1449
|
+
(entry) => Boolean(entry.rootBounds)
|
|
1450
|
+
);
|
|
1451
|
+
if (rootBoundsGroups.length > 0) {
|
|
1452
|
+
return rootBoundsGroups;
|
|
1453
|
+
}
|
|
1454
|
+
const explicitRootGroups = groupEntries.filter(
|
|
1455
|
+
(entry) => entry.root === true
|
|
1456
|
+
);
|
|
1457
|
+
if (explicitRootGroups.length > 0) {
|
|
1458
|
+
return explicitRootGroups;
|
|
1459
|
+
}
|
|
1460
|
+
const topLevelGroups = groupEntries.filter((entry) => !entry.parent);
|
|
1461
|
+
if (topLevelGroups.length > 0) {
|
|
1462
|
+
return topLevelGroups;
|
|
1463
|
+
}
|
|
1464
|
+
return groupEntries;
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1433
1467
|
// src/store.ts
|
|
1434
1468
|
THREE3.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
1435
1469
|
(0, import_immer.enableMapSet)();
|
|
@@ -1505,23 +1539,17 @@ var VizijSlice = (set, get) => ({
|
|
|
1505
1539
|
},
|
|
1506
1540
|
getExportableBodies: (filterIds) => {
|
|
1507
1541
|
const worldData = get().world;
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
const
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
const firstNs = Object.keys(entry.refs)[0];
|
|
1520
|
-
const refGroup = entry.refs[firstNs].current;
|
|
1521
|
-
return refGroup;
|
|
1522
|
-
});
|
|
1523
|
-
return bodies;
|
|
1524
|
-
}
|
|
1542
|
+
const candidateGroups = selectExportableGroupEntries(
|
|
1543
|
+
worldData,
|
|
1544
|
+
filterIds
|
|
1545
|
+
);
|
|
1546
|
+
return candidateGroups.flatMap((entry) => {
|
|
1547
|
+
const refs = Object.values(
|
|
1548
|
+
entry.refs ?? {}
|
|
1549
|
+
);
|
|
1550
|
+
const resolved = refs.find((ref) => ref?.current)?.current ?? null;
|
|
1551
|
+
return resolved ? [resolved] : [];
|
|
1552
|
+
});
|
|
1525
1553
|
},
|
|
1526
1554
|
setGeometry: (id, geometry) => {
|
|
1527
1555
|
set(
|
|
@@ -1555,6 +1583,19 @@ var VizijSlice = (set, get) => ({
|
|
|
1555
1583
|
})
|
|
1556
1584
|
);
|
|
1557
1585
|
},
|
|
1586
|
+
setValues: (writes = []) => {
|
|
1587
|
+
if (writes.length === 0) {
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
set(
|
|
1591
|
+
(0, import_immer.produce)((state) => {
|
|
1592
|
+
writes.forEach(({ id, namespace, value }) => {
|
|
1593
|
+
const lookupId = (0, import_utils6.getLookup)(namespace, id);
|
|
1594
|
+
state.values.set(lookupId, value);
|
|
1595
|
+
});
|
|
1596
|
+
})
|
|
1597
|
+
);
|
|
1598
|
+
},
|
|
1558
1599
|
setWorldElementName: (id, value) => {
|
|
1559
1600
|
set(
|
|
1560
1601
|
(0, import_immer.produce)((state) => {
|
|
@@ -1749,59 +1790,163 @@ var createVizijStore = (initial) => (0, import_zustand2.create)()(
|
|
|
1749
1790
|
}))
|
|
1750
1791
|
);
|
|
1751
1792
|
|
|
1752
|
-
// src/
|
|
1793
|
+
// src/effects/selection-glow-effect.tsx
|
|
1794
|
+
var import_react10 = require("react");
|
|
1795
|
+
var import_fiber = require("@react-three/fiber");
|
|
1796
|
+
var import_shallow7 = require("zustand/react/shallow");
|
|
1797
|
+
var import_three = require("three");
|
|
1753
1798
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1754
|
-
|
|
1799
|
+
function SelectionGlowEffect({
|
|
1800
|
+
enabled = false,
|
|
1801
|
+
color = "#ff1010ff",
|
|
1802
|
+
opacity = 0.9,
|
|
1803
|
+
thresholdAngle = 2
|
|
1804
|
+
}) {
|
|
1805
|
+
const selections = useVizijStore(
|
|
1806
|
+
(0, import_shallow7.useShallow)(
|
|
1807
|
+
(state) => enabled ? state.elementSelection ?? [] : []
|
|
1808
|
+
)
|
|
1809
|
+
);
|
|
1810
|
+
if (!enabled || selections.length === 0) {
|
|
1811
|
+
return null;
|
|
1812
|
+
}
|
|
1813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react10.Fragment, { children: selections.map((selection) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1814
|
+
SelectionOutline,
|
|
1815
|
+
{
|
|
1816
|
+
selection,
|
|
1817
|
+
color: selection.color ?? color,
|
|
1818
|
+
opacity,
|
|
1819
|
+
thresholdAngle
|
|
1820
|
+
},
|
|
1821
|
+
`${selection.namespace}:${selection.id}`
|
|
1822
|
+
)) });
|
|
1823
|
+
}
|
|
1824
|
+
function SelectionOutline({
|
|
1825
|
+
selection,
|
|
1826
|
+
color,
|
|
1827
|
+
opacity,
|
|
1828
|
+
thresholdAngle
|
|
1829
|
+
}) {
|
|
1830
|
+
const target = useVizijStore(
|
|
1831
|
+
(0, import_shallow7.useShallow)((state) => {
|
|
1832
|
+
const entry = state.world[selection.id];
|
|
1833
|
+
const ref = entry?.refs?.[selection.namespace];
|
|
1834
|
+
const geometry = entry?.geometry ?? null;
|
|
1835
|
+
return { ref, geometry };
|
|
1836
|
+
})
|
|
1837
|
+
);
|
|
1838
|
+
const sourceRef = target.ref;
|
|
1839
|
+
const edgesGeometry = (0, import_react10.useMemo)(() => {
|
|
1840
|
+
if (!target.geometry) return null;
|
|
1841
|
+
const edges = new import_three.EdgesGeometry(target.geometry, thresholdAngle);
|
|
1842
|
+
return edges;
|
|
1843
|
+
}, [target.geometry, thresholdAngle]);
|
|
1844
|
+
(0, import_react10.useEffect)(() => () => edgesGeometry?.dispose(), [edgesGeometry]);
|
|
1845
|
+
const material = (0, import_react10.useMemo)(() => {
|
|
1846
|
+
const mat = new import_three.LineBasicMaterial({
|
|
1847
|
+
color: new import_three.Color(color),
|
|
1848
|
+
transparent: true,
|
|
1849
|
+
opacity,
|
|
1850
|
+
blending: import_three.AdditiveBlending,
|
|
1851
|
+
depthTest: false,
|
|
1852
|
+
depthWrite: false,
|
|
1853
|
+
toneMapped: false
|
|
1854
|
+
});
|
|
1855
|
+
return mat;
|
|
1856
|
+
}, [color, opacity]);
|
|
1857
|
+
(0, import_react10.useEffect)(() => () => material.dispose(), [material]);
|
|
1858
|
+
const lineRef = (0, import_react10.useRef)(null);
|
|
1859
|
+
(0, import_fiber.useFrame)(() => {
|
|
1860
|
+
const source = sourceRef?.current;
|
|
1861
|
+
const line = lineRef.current;
|
|
1862
|
+
if (!source || !line) return;
|
|
1863
|
+
copyWorldTransform(source, line);
|
|
1864
|
+
line.visible = source.visible;
|
|
1865
|
+
});
|
|
1866
|
+
if (!sourceRef || !edgesGeometry) {
|
|
1867
|
+
return null;
|
|
1868
|
+
}
|
|
1869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1870
|
+
"lineSegments",
|
|
1871
|
+
{
|
|
1872
|
+
ref: lineRef,
|
|
1873
|
+
geometry: edgesGeometry,
|
|
1874
|
+
material,
|
|
1875
|
+
frustumCulled: false,
|
|
1876
|
+
renderOrder: 1e3
|
|
1877
|
+
}
|
|
1878
|
+
);
|
|
1879
|
+
}
|
|
1880
|
+
var tempMatrix = new import_three.Matrix4();
|
|
1881
|
+
var tempPosition = new import_three.Vector3();
|
|
1882
|
+
var tempQuaternion = new import_three.Quaternion();
|
|
1883
|
+
var tempScale = new import_three.Vector3();
|
|
1884
|
+
function copyWorldTransform(source, target) {
|
|
1885
|
+
source.updateWorldMatrix(true, false);
|
|
1886
|
+
tempMatrix.copy(source.matrixWorld);
|
|
1887
|
+
tempMatrix.decompose(tempPosition, tempQuaternion, tempScale);
|
|
1888
|
+
target.position.copy(tempPosition);
|
|
1889
|
+
target.quaternion.copy(tempQuaternion);
|
|
1890
|
+
target.scale.copy(tempScale);
|
|
1891
|
+
target.updateMatrix();
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
// src/vizij.tsx
|
|
1895
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1896
|
+
import_three2.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
1755
1897
|
function Vizij({
|
|
1756
1898
|
style,
|
|
1757
1899
|
className,
|
|
1758
1900
|
rootId,
|
|
1759
1901
|
namespace = "default",
|
|
1760
1902
|
showSafeArea = false,
|
|
1903
|
+
showSelectionGlow = false,
|
|
1761
1904
|
onPointerMissed
|
|
1762
1905
|
}) {
|
|
1763
|
-
const ctx = (0,
|
|
1906
|
+
const ctx = (0, import_react11.useContext)(VizijContext);
|
|
1764
1907
|
if (ctx) {
|
|
1765
|
-
return /* @__PURE__ */ (0,
|
|
1766
|
-
|
|
1908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1909
|
+
import_fiber2.Canvas,
|
|
1767
1910
|
{
|
|
1768
1911
|
shadows: false,
|
|
1769
1912
|
style,
|
|
1770
1913
|
className,
|
|
1771
1914
|
onPointerMissed,
|
|
1772
1915
|
gl: {
|
|
1773
|
-
outputColorSpace:
|
|
1774
|
-
toneMapping:
|
|
1916
|
+
outputColorSpace: import_three2.SRGBColorSpace,
|
|
1917
|
+
toneMapping: import_three2.NoToneMapping,
|
|
1775
1918
|
antialias: true
|
|
1776
1919
|
},
|
|
1777
|
-
children: /* @__PURE__ */ (0,
|
|
1920
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1778
1921
|
MemoizedInnerVizij,
|
|
1779
1922
|
{
|
|
1780
1923
|
rootId,
|
|
1781
1924
|
namespace,
|
|
1782
|
-
showSafeArea
|
|
1925
|
+
showSafeArea,
|
|
1926
|
+
showSelectionGlow
|
|
1783
1927
|
}
|
|
1784
1928
|
)
|
|
1785
1929
|
}
|
|
1786
1930
|
);
|
|
1787
1931
|
} else {
|
|
1788
|
-
return /* @__PURE__ */ (0,
|
|
1789
|
-
|
|
1932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(VizijContext.Provider, { value: useDefaultVizijStore, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1933
|
+
import_fiber2.Canvas,
|
|
1790
1934
|
{
|
|
1791
1935
|
style,
|
|
1792
1936
|
className,
|
|
1793
1937
|
onPointerMissed,
|
|
1794
1938
|
gl: {
|
|
1795
|
-
outputColorSpace:
|
|
1796
|
-
toneMapping:
|
|
1939
|
+
outputColorSpace: import_three2.SRGBColorSpace,
|
|
1940
|
+
toneMapping: import_three2.NoToneMapping,
|
|
1797
1941
|
antialias: true
|
|
1798
1942
|
},
|
|
1799
|
-
children: /* @__PURE__ */ (0,
|
|
1943
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1800
1944
|
MemoizedInnerVizij,
|
|
1801
1945
|
{
|
|
1802
1946
|
rootId,
|
|
1803
1947
|
namespace,
|
|
1804
|
-
showSafeArea
|
|
1948
|
+
showSafeArea,
|
|
1949
|
+
showSelectionGlow
|
|
1805
1950
|
}
|
|
1806
1951
|
)
|
|
1807
1952
|
}
|
|
@@ -1812,15 +1957,16 @@ function InnerVizij({
|
|
|
1812
1957
|
rootId,
|
|
1813
1958
|
namespace = "default",
|
|
1814
1959
|
container,
|
|
1815
|
-
showSafeArea
|
|
1960
|
+
showSafeArea,
|
|
1961
|
+
showSelectionGlow
|
|
1816
1962
|
}) {
|
|
1817
1963
|
const sceneParentSizing = container ? {
|
|
1818
1964
|
width: container.width * container.resolution,
|
|
1819
1965
|
height: container.height * container.resolution
|
|
1820
1966
|
} : void 0;
|
|
1821
|
-
return /* @__PURE__ */ (0,
|
|
1822
|
-
/* @__PURE__ */ (0,
|
|
1823
|
-
/* @__PURE__ */ (0,
|
|
1967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1968
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ambientLight", { intensity: Math.PI / 2 }),
|
|
1969
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1824
1970
|
import_drei3.OrthographicCamera,
|
|
1825
1971
|
{
|
|
1826
1972
|
makeDefault: true,
|
|
@@ -1829,7 +1975,7 @@ function InnerVizij({
|
|
|
1829
1975
|
far: 101
|
|
1830
1976
|
}
|
|
1831
1977
|
),
|
|
1832
|
-
/* @__PURE__ */ (0,
|
|
1978
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react11.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1833
1979
|
World,
|
|
1834
1980
|
{
|
|
1835
1981
|
rootId,
|
|
@@ -1837,27 +1983,28 @@ function InnerVizij({
|
|
|
1837
1983
|
parentSizing: sceneParentSizing
|
|
1838
1984
|
}
|
|
1839
1985
|
) }),
|
|
1840
|
-
|
|
1986
|
+
showSelectionGlow && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SelectionGlowEffect, { enabled: true }),
|
|
1987
|
+
showSafeArea && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SafeAreaRenderer, { rootId })
|
|
1841
1988
|
] });
|
|
1842
1989
|
}
|
|
1843
|
-
var MemoizedInnerVizij = (0,
|
|
1990
|
+
var MemoizedInnerVizij = (0, import_react11.memo)(InnerVizij);
|
|
1844
1991
|
function InnerWorld({
|
|
1845
1992
|
rootId,
|
|
1846
1993
|
namespace = "default",
|
|
1847
1994
|
parentSizing
|
|
1848
1995
|
}) {
|
|
1849
1996
|
const [present, rootBounds] = useVizijStore(
|
|
1850
|
-
(0,
|
|
1997
|
+
(0, import_shallow8.useShallow)((state) => {
|
|
1851
1998
|
const group = state.world[rootId];
|
|
1852
1999
|
const bounds = group?.rootBounds ?? defaultRootBounds;
|
|
1853
2000
|
return [group !== void 0, bounds];
|
|
1854
2001
|
})
|
|
1855
2002
|
);
|
|
1856
|
-
const { camera, size } = (0,
|
|
2003
|
+
const { camera, size } = (0, import_fiber2.useThree)((state) => ({
|
|
1857
2004
|
camera: state.camera,
|
|
1858
2005
|
size: state.size
|
|
1859
2006
|
}));
|
|
1860
|
-
(0,
|
|
2007
|
+
(0, import_react11.useEffect)(() => {
|
|
1861
2008
|
const width = rootBounds.size.x;
|
|
1862
2009
|
const height = rootBounds.size.y;
|
|
1863
2010
|
if (camera && parentSizing === void 0 && camera.isOrthographicCamera) {
|
|
@@ -1885,9 +2032,9 @@ function InnerWorld({
|
|
|
1885
2032
|
camera.updateProjectionMatrix();
|
|
1886
2033
|
}
|
|
1887
2034
|
}, [rootBounds, camera, parentSizing, size]);
|
|
1888
|
-
return /* @__PURE__ */ (0,
|
|
1889
|
-
present && /* @__PURE__ */ (0,
|
|
1890
|
-
!present && /* @__PURE__ */ (0,
|
|
2035
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_error_boundary.ErrorBoundary, { fallback: null, children: [
|
|
2036
|
+
present && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Renderable, { id: rootId, namespace, chain: [] }),
|
|
2037
|
+
!present && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1891
2038
|
import_drei3.Text,
|
|
1892
2039
|
{
|
|
1893
2040
|
position: [0, 0, 0],
|
|
@@ -1900,7 +2047,7 @@ function InnerWorld({
|
|
|
1900
2047
|
)
|
|
1901
2048
|
] });
|
|
1902
2049
|
}
|
|
1903
|
-
var World = (0,
|
|
2050
|
+
var World = (0, import_react11.memo)(InnerWorld);
|
|
1904
2051
|
function SafeAreaRenderer({ rootId }) {
|
|
1905
2052
|
const rootBounds = useVizijStore((state) => {
|
|
1906
2053
|
const group = state.world[rootId];
|
|
@@ -1910,7 +2057,7 @@ function SafeAreaRenderer({ rootId }) {
|
|
|
1910
2057
|
const right = rootBounds.center.x + rootBounds.size.x / 2;
|
|
1911
2058
|
const top = rootBounds.center.y + rootBounds.size.y / 2;
|
|
1912
2059
|
const bottom = rootBounds.center.y - rootBounds.size.y / 2;
|
|
1913
|
-
return /* @__PURE__ */ (0,
|
|
2060
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1914
2061
|
import_drei3.Line,
|
|
1915
2062
|
{
|
|
1916
2063
|
points: [
|
|
@@ -1941,11 +2088,11 @@ var ShapeMaterial = /* @__PURE__ */ ((ShapeMaterial2) => {
|
|
|
1941
2088
|
})(ShapeMaterial || {});
|
|
1942
2089
|
|
|
1943
2090
|
// src/hooks/use-vizij-store-subscription.ts
|
|
1944
|
-
var
|
|
2091
|
+
var import_react12 = require("react");
|
|
1945
2092
|
function useVizijStoreSubscription(selector, listener) {
|
|
1946
|
-
const store = (0,
|
|
2093
|
+
const store = (0, import_react12.useContext)(VizijContext);
|
|
1947
2094
|
if (!store) throw new Error("Missing VizijProvider in the tree");
|
|
1948
|
-
(0,
|
|
2095
|
+
(0, import_react12.useEffect)(() => {
|
|
1949
2096
|
const initialValue = selector(store.getState());
|
|
1950
2097
|
listener(initialValue);
|
|
1951
2098
|
return store.subscribe(selector, listener);
|
|
@@ -1953,17 +2100,17 @@ function useVizijStoreSubscription(selector, listener) {
|
|
|
1953
2100
|
}
|
|
1954
2101
|
|
|
1955
2102
|
// src/hooks/use-vizij-store-setter.ts
|
|
1956
|
-
var
|
|
2103
|
+
var import_react13 = require("react");
|
|
1957
2104
|
function useVizijStoreSetter() {
|
|
1958
|
-
const store = (0,
|
|
2105
|
+
const store = (0, import_react13.useContext)(VizijContext);
|
|
1959
2106
|
if (!store) throw new Error("Missing VizijProvider in the tree");
|
|
1960
2107
|
return store.setState;
|
|
1961
2108
|
}
|
|
1962
2109
|
|
|
1963
2110
|
// src/hooks/use-vizij-store-getter.ts
|
|
1964
|
-
var
|
|
2111
|
+
var import_react14 = require("react");
|
|
1965
2112
|
function useVizijStoreGetter() {
|
|
1966
|
-
const store = (0,
|
|
2113
|
+
const store = (0, import_react14.useContext)(VizijContext);
|
|
1967
2114
|
if (!store) throw new Error("Missing VizijProvider in the tree");
|
|
1968
2115
|
return store.getState;
|
|
1969
2116
|
}
|
|
@@ -1973,7 +2120,7 @@ var THREE5 = __toESM(require("three"));
|
|
|
1973
2120
|
var import_three_stdlib = require("three-stdlib");
|
|
1974
2121
|
|
|
1975
2122
|
// src/functions/gltf-loading/traverse-three.ts
|
|
1976
|
-
var
|
|
2123
|
+
var import_react16 = require("react");
|
|
1977
2124
|
var THREE4 = __toESM(require("three"));
|
|
1978
2125
|
|
|
1979
2126
|
// src/functions/gltf-loading/map-features.ts
|
|
@@ -1999,19 +2146,19 @@ function mapFeatures(features) {
|
|
|
1999
2146
|
}
|
|
2000
2147
|
|
|
2001
2148
|
// src/functions/gltf-loading/import-scene.ts
|
|
2002
|
-
var
|
|
2149
|
+
var import_three5 = require("three");
|
|
2003
2150
|
|
|
2004
2151
|
// src/functions/gltf-loading/import-group.ts
|
|
2005
|
-
var
|
|
2152
|
+
var import_three4 = require("three");
|
|
2006
2153
|
|
|
2007
2154
|
// src/functions/util.ts
|
|
2008
|
-
var
|
|
2155
|
+
var import_react15 = require("react");
|
|
2009
2156
|
function namespaceArrayToRefs(namespaces) {
|
|
2010
|
-
return namespaces.reduce((acc, ns) => ({ ...acc, [ns]: (0,
|
|
2157
|
+
return namespaces.reduce((acc, ns) => ({ ...acc, [ns]: (0, import_react15.createRef)() }), {});
|
|
2011
2158
|
}
|
|
2012
2159
|
|
|
2013
2160
|
// src/functions/gltf-loading/import-mesh.ts
|
|
2014
|
-
var
|
|
2161
|
+
var import_three3 = require("three");
|
|
2015
2162
|
|
|
2016
2163
|
// src/functions/gltf-loading/import-geometry.ts
|
|
2017
2164
|
function sanitizeMorphKey(name, fallbackIndex, used) {
|
|
@@ -2051,7 +2198,7 @@ function importGeometry(geometry, mesh) {
|
|
|
2051
2198
|
type: "number",
|
|
2052
2199
|
default: mesh.morphTargetInfluences?.[index] ?? 0,
|
|
2053
2200
|
constraints: {
|
|
2054
|
-
min:
|
|
2201
|
+
min: -1,
|
|
2055
2202
|
max: 1
|
|
2056
2203
|
},
|
|
2057
2204
|
pub: {
|
|
@@ -2067,7 +2214,7 @@ function importGeometry(geometry, mesh) {
|
|
|
2067
2214
|
}
|
|
2068
2215
|
|
|
2069
2216
|
// src/functions/gltf-loading/import-mesh.ts
|
|
2070
|
-
|
|
2217
|
+
import_three3.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
2071
2218
|
function importMesh(mesh, namespaces, colorLookup) {
|
|
2072
2219
|
let world = {};
|
|
2073
2220
|
let animatables = {};
|
|
@@ -2181,6 +2328,15 @@ function importMesh(mesh, namespaces, colorLookup) {
|
|
|
2181
2328
|
world = { ...world, ...newWorldItems };
|
|
2182
2329
|
animatables = { ...animatables, ...newAnimatables };
|
|
2183
2330
|
children.push(childId);
|
|
2331
|
+
} else if (shouldImportAsGroupChild(child)) {
|
|
2332
|
+
const [newWorldItems, newAnimatables, childId, newMeshColors] = importGroup(child, namespaces, {
|
|
2333
|
+
...colorLookup,
|
|
2334
|
+
...newColorLookup
|
|
2335
|
+
});
|
|
2336
|
+
newColorLookup = { ...newColorLookup, ...newMeshColors };
|
|
2337
|
+
world = { ...world, ...newWorldItems };
|
|
2338
|
+
animatables = { ...animatables, ...newAnimatables };
|
|
2339
|
+
children.push(childId);
|
|
2184
2340
|
}
|
|
2185
2341
|
});
|
|
2186
2342
|
const newShape = {
|
|
@@ -2224,9 +2380,27 @@ function getShapeMaterial(mesh, useEmissive) {
|
|
|
2224
2380
|
return "standard" /* Standard */;
|
|
2225
2381
|
}
|
|
2226
2382
|
}
|
|
2383
|
+
function shouldImportAsGroupChild(child) {
|
|
2384
|
+
if (!child.isObject3D) {
|
|
2385
|
+
return false;
|
|
2386
|
+
}
|
|
2387
|
+
if (child.isMesh) {
|
|
2388
|
+
return false;
|
|
2389
|
+
}
|
|
2390
|
+
if (child.isCamera) {
|
|
2391
|
+
return false;
|
|
2392
|
+
}
|
|
2393
|
+
if (child.isLight) {
|
|
2394
|
+
return false;
|
|
2395
|
+
}
|
|
2396
|
+
if (child.isBone) {
|
|
2397
|
+
return false;
|
|
2398
|
+
}
|
|
2399
|
+
return true;
|
|
2400
|
+
}
|
|
2227
2401
|
|
|
2228
2402
|
// src/functions/gltf-loading/import-group.ts
|
|
2229
|
-
|
|
2403
|
+
import_three4.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
2230
2404
|
function importGroup(group, namespaces, colorLookup, rootBounds) {
|
|
2231
2405
|
let world = {};
|
|
2232
2406
|
let animatables = {};
|
|
@@ -2283,7 +2457,7 @@ function importGroup(group, namespaces, colorLookup, rootBounds) {
|
|
|
2283
2457
|
world = { ...world, ...newWorldItems };
|
|
2284
2458
|
animatables = { ...animatables, ...newAnimatables };
|
|
2285
2459
|
children.push(childId);
|
|
2286
|
-
} else if (child
|
|
2460
|
+
} else if (shouldImportAsGroupChild2(child)) {
|
|
2287
2461
|
const [newWorldItems, newAnimatables, childId, newMeshColors] = importGroup(child, namespaces, {
|
|
2288
2462
|
...colorLookup,
|
|
2289
2463
|
...newColorLookup
|
|
@@ -2312,9 +2486,27 @@ function importGroup(group, namespaces, colorLookup, rootBounds) {
|
|
|
2312
2486
|
world = { ...world, [newGroup.id]: newGroup };
|
|
2313
2487
|
return [world, animatables, newGroup.id, newColorLookup];
|
|
2314
2488
|
}
|
|
2489
|
+
function shouldImportAsGroupChild2(child) {
|
|
2490
|
+
if (!child.isObject3D) {
|
|
2491
|
+
return false;
|
|
2492
|
+
}
|
|
2493
|
+
if (child.isMesh) {
|
|
2494
|
+
return false;
|
|
2495
|
+
}
|
|
2496
|
+
if (child.isCamera) {
|
|
2497
|
+
return false;
|
|
2498
|
+
}
|
|
2499
|
+
if (child.isLight) {
|
|
2500
|
+
return false;
|
|
2501
|
+
}
|
|
2502
|
+
if (child.isBone) {
|
|
2503
|
+
return false;
|
|
2504
|
+
}
|
|
2505
|
+
return true;
|
|
2506
|
+
}
|
|
2315
2507
|
|
|
2316
2508
|
// src/functions/gltf-loading/import-scene.ts
|
|
2317
|
-
|
|
2509
|
+
import_three5.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
2318
2510
|
function importScene(scene, namespaces, rootBounds) {
|
|
2319
2511
|
let world = {};
|
|
2320
2512
|
let animatables = {};
|
|
@@ -2356,7 +2548,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
|
|
|
2356
2548
|
loadedData = {
|
|
2357
2549
|
...data,
|
|
2358
2550
|
refs: namespaces.reduce(
|
|
2359
|
-
(acc, ns) => ({ ...acc, [ns]: (0,
|
|
2551
|
+
(acc, ns) => ({ ...acc, [ns]: (0, import_react16.createRef)() }),
|
|
2360
2552
|
{}
|
|
2361
2553
|
)
|
|
2362
2554
|
};
|
|
@@ -2371,7 +2563,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
|
|
|
2371
2563
|
...data,
|
|
2372
2564
|
geometry: child.geometry,
|
|
2373
2565
|
refs: namespaces.reduce(
|
|
2374
|
-
(acc, ns) => ({ ...acc, [ns]: (0,
|
|
2566
|
+
(acc, ns) => ({ ...acc, [ns]: (0, import_react16.createRef)() }),
|
|
2375
2567
|
{}
|
|
2376
2568
|
)
|
|
2377
2569
|
};
|
|
@@ -2385,7 +2577,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
|
|
|
2385
2577
|
loadedData = {
|
|
2386
2578
|
...data,
|
|
2387
2579
|
refs: namespaces.reduce(
|
|
2388
|
-
(acc, ns) => ({ ...acc, [ns]: (0,
|
|
2580
|
+
(acc, ns) => ({ ...acc, [ns]: (0, import_react16.createRef)() }),
|
|
2389
2581
|
{}
|
|
2390
2582
|
)
|
|
2391
2583
|
};
|
|
@@ -2399,7 +2591,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
|
|
|
2399
2591
|
loadedData = {
|
|
2400
2592
|
...data,
|
|
2401
2593
|
refs: namespaces.reduce(
|
|
2402
|
-
(acc, ns) => ({ ...acc, [ns]: (0,
|
|
2594
|
+
(acc, ns) => ({ ...acc, [ns]: (0, import_react16.createRef)() }),
|
|
2403
2595
|
{}
|
|
2404
2596
|
)
|
|
2405
2597
|
};
|
|
@@ -2585,9 +2777,10 @@ function deriveRootBounds(group) {
|
|
|
2585
2777
|
}
|
|
2586
2778
|
|
|
2587
2779
|
// src/functions/vizij-bundle.ts
|
|
2780
|
+
var import_utils7 = require("@vizij/utils");
|
|
2588
2781
|
var BUNDLE_KEYS = ["VIZIJ_bundle"];
|
|
2589
2782
|
function cloneBundle(value) {
|
|
2590
|
-
return
|
|
2783
|
+
return (0, import_utils7.cloneDeepSafe)(value);
|
|
2591
2784
|
}
|
|
2592
2785
|
function readExtensionValue(extensionContainer) {
|
|
2593
2786
|
for (const key of BUNDLE_KEYS) {
|
|
@@ -2621,6 +2814,13 @@ function searchParserJsonForBundle(parserJson) {
|
|
|
2621
2814
|
if (!parserJson || typeof parserJson !== "object") {
|
|
2622
2815
|
return null;
|
|
2623
2816
|
}
|
|
2817
|
+
const rootExtensions = parserJson && typeof parserJson === "object" ? parserJson.extensions : null;
|
|
2818
|
+
if (rootExtensions && typeof rootExtensions === "object") {
|
|
2819
|
+
const match = readExtensionValue(rootExtensions);
|
|
2820
|
+
if (match) {
|
|
2821
|
+
return cloneBundle(match.value);
|
|
2822
|
+
}
|
|
2823
|
+
}
|
|
2624
2824
|
const nodes = Array.isArray(parserJson.nodes) ? parserJson.nodes : [];
|
|
2625
2825
|
for (const node of nodes) {
|
|
2626
2826
|
const extensions = node && typeof node === "object" ? node.extensions : null;
|
|
@@ -2685,6 +2885,7 @@ function applyVizijBundle(object, bundle) {
|
|
|
2685
2885
|
}
|
|
2686
2886
|
|
|
2687
2887
|
// src/functions/gltf-loading/extract-animations.ts
|
|
2888
|
+
var import_utils8 = require("@vizij/utils");
|
|
2688
2889
|
var CHANNEL_PATH_TO_TRACK_PROPERTY = {
|
|
2689
2890
|
translation: "position",
|
|
2690
2891
|
rotation: "quaternion",
|
|
@@ -2700,7 +2901,7 @@ function clonePlainObject(value) {
|
|
|
2700
2901
|
if (!value) {
|
|
2701
2902
|
return void 0;
|
|
2702
2903
|
}
|
|
2703
|
-
return
|
|
2904
|
+
return (0, import_utils8.cloneDeepSafe)(value);
|
|
2704
2905
|
}
|
|
2705
2906
|
function inferValueSize(valueType) {
|
|
2706
2907
|
switch (valueType) {
|
|
@@ -3055,23 +3256,94 @@ function extractVizijAnimations(parserJson, clips) {
|
|
|
3055
3256
|
|
|
3056
3257
|
// src/functions/load-gltf.ts
|
|
3057
3258
|
THREE5.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
3259
|
+
var GLB_MAGIC = 1179937895;
|
|
3260
|
+
var GLB_VERSION = 2;
|
|
3261
|
+
var GLB_HEADER_BYTES = 12;
|
|
3262
|
+
var GLB_CHUNK_HEADER_BYTES = 8;
|
|
3263
|
+
var GLB_JSON_CHUNK_TYPE = 1313821514;
|
|
3058
3264
|
var EmptyModelError = class extends Error {
|
|
3059
3265
|
constructor(message) {
|
|
3060
3266
|
super(message);
|
|
3061
3267
|
this.name = "EmptyModelError";
|
|
3062
3268
|
}
|
|
3063
3269
|
};
|
|
3270
|
+
function parseGlbJsonChunk(buffer) {
|
|
3271
|
+
if (buffer.byteLength < GLB_HEADER_BYTES + GLB_CHUNK_HEADER_BYTES) {
|
|
3272
|
+
return void 0;
|
|
3273
|
+
}
|
|
3274
|
+
const view = new DataView(buffer);
|
|
3275
|
+
const magic = view.getUint32(0, true);
|
|
3276
|
+
const version = view.getUint32(4, true);
|
|
3277
|
+
if (magic !== GLB_MAGIC || version !== GLB_VERSION) {
|
|
3278
|
+
return void 0;
|
|
3279
|
+
}
|
|
3280
|
+
const chunkLength = view.getUint32(GLB_HEADER_BYTES, true);
|
|
3281
|
+
const chunkType = view.getUint32(GLB_HEADER_BYTES + 4, true);
|
|
3282
|
+
if (chunkType !== GLB_JSON_CHUNK_TYPE) {
|
|
3283
|
+
return void 0;
|
|
3284
|
+
}
|
|
3285
|
+
const chunkStart = GLB_HEADER_BYTES + GLB_CHUNK_HEADER_BYTES;
|
|
3286
|
+
const chunkEnd = chunkStart + chunkLength;
|
|
3287
|
+
if (chunkEnd > buffer.byteLength) {
|
|
3288
|
+
return void 0;
|
|
3289
|
+
}
|
|
3290
|
+
try {
|
|
3291
|
+
const chunkBytes = new Uint8Array(buffer, chunkStart, chunkLength);
|
|
3292
|
+
const jsonText = new TextDecoder().decode(chunkBytes);
|
|
3293
|
+
return JSON.parse(jsonText);
|
|
3294
|
+
} catch {
|
|
3295
|
+
return void 0;
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
async function resolveParserJson(parserJson, fallback) {
|
|
3299
|
+
if (parserJson && typeof parserJson === "object") {
|
|
3300
|
+
return parserJson;
|
|
3301
|
+
}
|
|
3302
|
+
if (fallback.arrayBuffer) {
|
|
3303
|
+
const fromArrayBuffer = parseGlbJsonChunk(fallback.arrayBuffer);
|
|
3304
|
+
if (fromArrayBuffer && typeof fromArrayBuffer === "object") {
|
|
3305
|
+
return fromArrayBuffer;
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
if (fallback.blob) {
|
|
3309
|
+
try {
|
|
3310
|
+
const blobBuffer = typeof fallback.blob.arrayBuffer === "function" ? await fallback.blob.arrayBuffer() : await new Response(fallback.blob).arrayBuffer();
|
|
3311
|
+
const fromBlob = parseGlbJsonChunk(blobBuffer);
|
|
3312
|
+
if (fromBlob && typeof fromBlob === "object") {
|
|
3313
|
+
return fromBlob;
|
|
3314
|
+
}
|
|
3315
|
+
} catch {
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3318
|
+
if (fallback.url && typeof fetch === "function") {
|
|
3319
|
+
try {
|
|
3320
|
+
const response = await fetch(fallback.url);
|
|
3321
|
+
if (response.ok) {
|
|
3322
|
+
const binary = await response.arrayBuffer();
|
|
3323
|
+
const fromUrl = parseGlbJsonChunk(binary);
|
|
3324
|
+
if (fromUrl && typeof fromUrl === "object") {
|
|
3325
|
+
return fromUrl;
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
3328
|
+
} catch {
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3331
|
+
return parserJson;
|
|
3332
|
+
}
|
|
3064
3333
|
async function loadGLTF(url, namespaces, aggressiveImport = false, rootBounds) {
|
|
3065
3334
|
const modelLoader = new import_three_stdlib.GLTFLoader();
|
|
3066
3335
|
modelLoader.setDRACOLoader(new import_three_stdlib.DRACOLoader());
|
|
3067
3336
|
const modelData = await modelLoader.loadAsync(url);
|
|
3337
|
+
const parserJson = await resolveParserJson(modelData?.parser?.json, {
|
|
3338
|
+
url
|
|
3339
|
+
});
|
|
3068
3340
|
const actualizedNamespaces = namespaces.length > 0 ? namespaces : ["default"];
|
|
3069
3341
|
const asset = parseScene(
|
|
3070
3342
|
modelData.scene,
|
|
3071
3343
|
actualizedNamespaces,
|
|
3072
3344
|
aggressiveImport,
|
|
3073
3345
|
rootBounds,
|
|
3074
|
-
|
|
3346
|
+
parserJson,
|
|
3075
3347
|
modelData.animations
|
|
3076
3348
|
);
|
|
3077
3349
|
return [asset.world, asset.animatables, asset.animations];
|
|
@@ -3085,7 +3357,8 @@ async function loadGLTFFromBlob(blob, namespaces, aggressiveImport = false, root
|
|
|
3085
3357
|
objectUrl,
|
|
3086
3358
|
actualizedNamespaces,
|
|
3087
3359
|
aggressiveImport,
|
|
3088
|
-
rootBounds
|
|
3360
|
+
rootBounds,
|
|
3361
|
+
{ blob }
|
|
3089
3362
|
);
|
|
3090
3363
|
return [asset.world, asset.animatables, asset.animations];
|
|
3091
3364
|
} finally {
|
|
@@ -3099,14 +3372,18 @@ async function loadGLTFFromBlob(blob, namespaces, aggressiveImport = false, root
|
|
|
3099
3372
|
loader.parse(
|
|
3100
3373
|
arrayBuffer,
|
|
3101
3374
|
"",
|
|
3102
|
-
(gltf) => {
|
|
3375
|
+
async (gltf) => {
|
|
3103
3376
|
try {
|
|
3377
|
+
const parserJson = await resolveParserJson(
|
|
3378
|
+
gltf?.parser?.json,
|
|
3379
|
+
{ arrayBuffer }
|
|
3380
|
+
);
|
|
3104
3381
|
const asset = parseScene(
|
|
3105
3382
|
gltf.scene,
|
|
3106
3383
|
actualizedNamespaces,
|
|
3107
3384
|
aggressiveImport,
|
|
3108
3385
|
rootBounds,
|
|
3109
|
-
|
|
3386
|
+
parserJson,
|
|
3110
3387
|
gltf.animations
|
|
3111
3388
|
);
|
|
3112
3389
|
resolve([asset.world, asset.animatables, asset.animations]);
|
|
@@ -3133,19 +3410,23 @@ function parseScene(scene, namespaces, aggressiveImport, rootBounds, parserJson,
|
|
|
3133
3410
|
);
|
|
3134
3411
|
const bundle = extractVizijBundle(scene, parserJson);
|
|
3135
3412
|
const animations = extractVizijAnimations(parserJson, clips);
|
|
3136
|
-
return { world, animatables, bundle, animations };
|
|
3413
|
+
return { world, animatables, bundle, animations, scene };
|
|
3137
3414
|
}
|
|
3138
|
-
async function loadGLTFWithBundle(url, namespaces, aggressiveImport = false, rootBounds) {
|
|
3415
|
+
async function loadGLTFWithBundle(url, namespaces, aggressiveImport = false, rootBounds, parserJsonFallback) {
|
|
3139
3416
|
const modelLoader = new import_three_stdlib.GLTFLoader();
|
|
3140
3417
|
modelLoader.setDRACOLoader(new import_three_stdlib.DRACOLoader());
|
|
3141
3418
|
const modelData = await modelLoader.loadAsync(url);
|
|
3419
|
+
const parserJson = await resolveParserJson(modelData?.parser?.json, {
|
|
3420
|
+
url,
|
|
3421
|
+
...parserJsonFallback
|
|
3422
|
+
});
|
|
3142
3423
|
const actualizedNamespaces = namespaces.length > 0 ? namespaces : ["default"];
|
|
3143
3424
|
return parseScene(
|
|
3144
3425
|
modelData.scene,
|
|
3145
3426
|
actualizedNamespaces,
|
|
3146
3427
|
aggressiveImport,
|
|
3147
3428
|
rootBounds,
|
|
3148
|
-
|
|
3429
|
+
parserJson,
|
|
3149
3430
|
modelData.animations
|
|
3150
3431
|
);
|
|
3151
3432
|
}
|
|
@@ -3158,7 +3439,8 @@ async function loadGLTFFromBlobWithBundle(blob, namespaces, aggressiveImport = f
|
|
|
3158
3439
|
objectUrl,
|
|
3159
3440
|
actualizedNamespaces,
|
|
3160
3441
|
aggressiveImport,
|
|
3161
|
-
rootBounds
|
|
3442
|
+
rootBounds,
|
|
3443
|
+
{ blob }
|
|
3162
3444
|
);
|
|
3163
3445
|
} finally {
|
|
3164
3446
|
URL.revokeObjectURL(objectUrl);
|
|
@@ -3171,14 +3453,18 @@ async function loadGLTFFromBlobWithBundle(blob, namespaces, aggressiveImport = f
|
|
|
3171
3453
|
loader.parse(
|
|
3172
3454
|
arrayBuffer,
|
|
3173
3455
|
"",
|
|
3174
|
-
(gltf) => {
|
|
3456
|
+
async (gltf) => {
|
|
3175
3457
|
try {
|
|
3458
|
+
const parserJson = await resolveParserJson(
|
|
3459
|
+
gltf?.parser?.json,
|
|
3460
|
+
{ arrayBuffer }
|
|
3461
|
+
);
|
|
3176
3462
|
const asset = parseScene(
|
|
3177
3463
|
gltf.scene,
|
|
3178
3464
|
actualizedNamespaces,
|
|
3179
3465
|
aggressiveImport,
|
|
3180
3466
|
rootBounds,
|
|
3181
|
-
|
|
3467
|
+
parserJson,
|
|
3182
3468
|
gltf.animations
|
|
3183
3469
|
);
|
|
3184
3470
|
resolve(asset);
|
|
@@ -3230,6 +3516,160 @@ var loadGltfFromBlob = (blob, namespaces) => {
|
|
|
3230
3516
|
var import_three_stdlib3 = require("three-stdlib");
|
|
3231
3517
|
var THREE6 = __toESM(require("three"));
|
|
3232
3518
|
THREE6.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
3519
|
+
function normalizeExportError(error) {
|
|
3520
|
+
if (error instanceof Error) {
|
|
3521
|
+
return error;
|
|
3522
|
+
}
|
|
3523
|
+
if (typeof error === "string") {
|
|
3524
|
+
return new Error(error);
|
|
3525
|
+
}
|
|
3526
|
+
return new Error("Failed to export scene.");
|
|
3527
|
+
}
|
|
3528
|
+
function triggerBlobDownload(blob, filename) {
|
|
3529
|
+
const url = URL.createObjectURL(blob);
|
|
3530
|
+
const link = document.createElement("a");
|
|
3531
|
+
link.href = url;
|
|
3532
|
+
link.download = filename;
|
|
3533
|
+
link.style.display = "none";
|
|
3534
|
+
document.body.appendChild(link);
|
|
3535
|
+
link.click();
|
|
3536
|
+
document.body.removeChild(link);
|
|
3537
|
+
setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
3538
|
+
}
|
|
3539
|
+
var GLB_MAGIC2 = 1179937895;
|
|
3540
|
+
var GLB_VERSION2 = 2;
|
|
3541
|
+
var GLB_JSON_CHUNK_TYPE2 = 1313821514;
|
|
3542
|
+
var GLB_HEADER_BYTES2 = 12;
|
|
3543
|
+
var GLB_CHUNK_HEADER_BYTES2 = 8;
|
|
3544
|
+
var GLB_JSON_PADDING_BYTE = 32;
|
|
3545
|
+
function isNearlyEqual(a, b, epsilon = 1e-6) {
|
|
3546
|
+
return Math.abs(a - b) <= epsilon;
|
|
3547
|
+
}
|
|
3548
|
+
function isIdentityTransformNode(node) {
|
|
3549
|
+
const translation = node.translation;
|
|
3550
|
+
if (Array.isArray(translation) && (translation.length !== 3 || !isNearlyEqual(Number(translation[0]), 0) || !isNearlyEqual(Number(translation[1]), 0) || !isNearlyEqual(Number(translation[2]), 0))) {
|
|
3551
|
+
return false;
|
|
3552
|
+
}
|
|
3553
|
+
const rotation = node.rotation;
|
|
3554
|
+
if (Array.isArray(rotation) && (rotation.length !== 4 || !isNearlyEqual(Number(rotation[0]), 0) || !isNearlyEqual(Number(rotation[1]), 0) || !isNearlyEqual(Number(rotation[2]), 0) || !isNearlyEqual(Number(rotation[3]), 1))) {
|
|
3555
|
+
return false;
|
|
3556
|
+
}
|
|
3557
|
+
const scale = node.scale;
|
|
3558
|
+
if (Array.isArray(scale) && (scale.length !== 3 || !isNearlyEqual(Number(scale[0]), 1) || !isNearlyEqual(Number(scale[1]), 1) || !isNearlyEqual(Number(scale[2]), 1))) {
|
|
3559
|
+
return false;
|
|
3560
|
+
}
|
|
3561
|
+
return true;
|
|
3562
|
+
}
|
|
3563
|
+
function isPassThroughWrapperNode(node) {
|
|
3564
|
+
if (!node || typeof node !== "object") {
|
|
3565
|
+
return false;
|
|
3566
|
+
}
|
|
3567
|
+
if (!Array.isArray(node.children) || node.children.length === 0) {
|
|
3568
|
+
return false;
|
|
3569
|
+
}
|
|
3570
|
+
const hasOnlyNumericChildren = node.children.every(
|
|
3571
|
+
(index) => Number.isInteger(index)
|
|
3572
|
+
);
|
|
3573
|
+
if (!hasOnlyNumericChildren) {
|
|
3574
|
+
return false;
|
|
3575
|
+
}
|
|
3576
|
+
if (node.mesh !== void 0 || node.camera !== void 0 || node.skin !== void 0) {
|
|
3577
|
+
return false;
|
|
3578
|
+
}
|
|
3579
|
+
if (node.extensions && typeof node.extensions === "object" && Object.keys(node.extensions).length > 0) {
|
|
3580
|
+
return false;
|
|
3581
|
+
}
|
|
3582
|
+
return isIdentityTransformNode(node);
|
|
3583
|
+
}
|
|
3584
|
+
function normalizeExportedSceneJson(json, fallbackSceneName) {
|
|
3585
|
+
if (!json || typeof json !== "object") {
|
|
3586
|
+
return false;
|
|
3587
|
+
}
|
|
3588
|
+
if (!Array.isArray(json.scenes) || !Array.isArray(json.nodes)) {
|
|
3589
|
+
return false;
|
|
3590
|
+
}
|
|
3591
|
+
const sceneIndexRaw = json.scene;
|
|
3592
|
+
const sceneIndex = typeof sceneIndexRaw === "number" && Number.isInteger(sceneIndexRaw) ? sceneIndexRaw : 0;
|
|
3593
|
+
const sceneDef = json.scenes[sceneIndex];
|
|
3594
|
+
if (!sceneDef || typeof sceneDef !== "object") {
|
|
3595
|
+
return false;
|
|
3596
|
+
}
|
|
3597
|
+
let changed = false;
|
|
3598
|
+
let wrapperNodeName;
|
|
3599
|
+
if (Array.isArray(sceneDef.nodes) && sceneDef.nodes.length === 1) {
|
|
3600
|
+
const wrapperIndex = sceneDef.nodes[0];
|
|
3601
|
+
if (Number.isInteger(wrapperIndex)) {
|
|
3602
|
+
const wrapperNode = json.nodes[wrapperIndex];
|
|
3603
|
+
if (isPassThroughWrapperNode(wrapperNode)) {
|
|
3604
|
+
sceneDef.nodes = [...wrapperNode.children];
|
|
3605
|
+
wrapperNodeName = typeof wrapperNode.name === "string" ? wrapperNode.name : void 0;
|
|
3606
|
+
changed = true;
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
const currentSceneName = typeof sceneDef.name === "string" ? sceneDef.name.trim() : "";
|
|
3611
|
+
if (currentSceneName === "AuxScene") {
|
|
3612
|
+
const nextSceneName = (wrapperNodeName?.trim() || fallbackSceneName?.trim() || "Scene").trim();
|
|
3613
|
+
if (nextSceneName.length > 0 && nextSceneName !== currentSceneName) {
|
|
3614
|
+
sceneDef.name = nextSceneName;
|
|
3615
|
+
changed = true;
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
return changed;
|
|
3619
|
+
}
|
|
3620
|
+
function sanitizeExportedGlb(buffer, fallbackSceneName) {
|
|
3621
|
+
if (buffer.byteLength < GLB_HEADER_BYTES2 + GLB_CHUNK_HEADER_BYTES2) {
|
|
3622
|
+
return buffer;
|
|
3623
|
+
}
|
|
3624
|
+
const originalBytes = new Uint8Array(buffer);
|
|
3625
|
+
const view = new DataView(buffer);
|
|
3626
|
+
const magic = view.getUint32(0, true);
|
|
3627
|
+
const version = view.getUint32(4, true);
|
|
3628
|
+
if (magic !== GLB_MAGIC2 || version !== GLB_VERSION2) {
|
|
3629
|
+
return buffer;
|
|
3630
|
+
}
|
|
3631
|
+
const jsonChunkLength = view.getUint32(GLB_HEADER_BYTES2, true);
|
|
3632
|
+
const jsonChunkType = view.getUint32(GLB_HEADER_BYTES2 + 4, true);
|
|
3633
|
+
if (jsonChunkType !== GLB_JSON_CHUNK_TYPE2) {
|
|
3634
|
+
return buffer;
|
|
3635
|
+
}
|
|
3636
|
+
const jsonChunkStart = GLB_HEADER_BYTES2 + GLB_CHUNK_HEADER_BYTES2;
|
|
3637
|
+
const jsonChunkEnd = jsonChunkStart + jsonChunkLength;
|
|
3638
|
+
if (jsonChunkEnd > originalBytes.length) {
|
|
3639
|
+
return buffer;
|
|
3640
|
+
}
|
|
3641
|
+
let jsonPayload;
|
|
3642
|
+
try {
|
|
3643
|
+
const jsonText = new TextDecoder().decode(
|
|
3644
|
+
originalBytes.slice(jsonChunkStart, jsonChunkEnd)
|
|
3645
|
+
);
|
|
3646
|
+
jsonPayload = JSON.parse(jsonText);
|
|
3647
|
+
} catch {
|
|
3648
|
+
return buffer;
|
|
3649
|
+
}
|
|
3650
|
+
const changed = normalizeExportedSceneJson(jsonPayload, fallbackSceneName);
|
|
3651
|
+
if (!changed) {
|
|
3652
|
+
return buffer;
|
|
3653
|
+
}
|
|
3654
|
+
const encodedJson = new TextEncoder().encode(JSON.stringify(jsonPayload));
|
|
3655
|
+
const paddedJsonLength = encodedJson.length + 3 & ~3;
|
|
3656
|
+
const paddedJson = new Uint8Array(paddedJsonLength);
|
|
3657
|
+
paddedJson.fill(GLB_JSON_PADDING_BYTE);
|
|
3658
|
+
paddedJson.set(encodedJson);
|
|
3659
|
+
const remainingChunks = originalBytes.slice(jsonChunkEnd);
|
|
3660
|
+
const totalLength = GLB_HEADER_BYTES2 + GLB_CHUNK_HEADER_BYTES2 + paddedJsonLength + remainingChunks.length;
|
|
3661
|
+
const sanitized = new ArrayBuffer(totalLength);
|
|
3662
|
+
const sanitizedBytes = new Uint8Array(sanitized);
|
|
3663
|
+
const sanitizedView = new DataView(sanitized);
|
|
3664
|
+
sanitizedView.setUint32(0, GLB_MAGIC2, true);
|
|
3665
|
+
sanitizedView.setUint32(4, GLB_VERSION2, true);
|
|
3666
|
+
sanitizedView.setUint32(8, totalLength, true);
|
|
3667
|
+
sanitizedView.setUint32(GLB_HEADER_BYTES2, paddedJsonLength, true);
|
|
3668
|
+
sanitizedView.setUint32(GLB_HEADER_BYTES2 + 4, GLB_JSON_CHUNK_TYPE2, true);
|
|
3669
|
+
sanitizedBytes.set(paddedJson, jsonChunkStart);
|
|
3670
|
+
sanitizedBytes.set(remainingChunks, jsonChunkStart + paddedJsonLength);
|
|
3671
|
+
return sanitized;
|
|
3672
|
+
}
|
|
3233
3673
|
function exportScene(data, fileNameOrOptions = "scene.glb") {
|
|
3234
3674
|
const options = typeof fileNameOrOptions === "string" ? { fileName: fileNameOrOptions } : fileNameOrOptions ?? {};
|
|
3235
3675
|
const fileName = options.fileName ?? "scene.glb";
|
|
@@ -3244,7 +3684,15 @@ function exportScene(data, fileNameOrOptions = "scene.glb") {
|
|
|
3244
3684
|
}
|
|
3245
3685
|
}
|
|
3246
3686
|
}));
|
|
3247
|
-
const
|
|
3687
|
+
const sourceRoot = data;
|
|
3688
|
+
const exportRoot = sourceRoot instanceof THREE6.Scene ? sourceRoot : sourceRoot.clone(true);
|
|
3689
|
+
const exportTarget = exportRoot instanceof THREE6.Scene ? exportRoot : (() => {
|
|
3690
|
+
const scene = new THREE6.Scene();
|
|
3691
|
+
scene.name = data.name?.trim() || "Scene";
|
|
3692
|
+
scene.add(exportRoot);
|
|
3693
|
+
return scene;
|
|
3694
|
+
})();
|
|
3695
|
+
const detachBundle = shouldAttachBundle && options.bundle ? applyVizijBundle(exportRoot, options.bundle) : () => {
|
|
3248
3696
|
};
|
|
3249
3697
|
const binary = options.binary ?? true;
|
|
3250
3698
|
const exporterOptions = {
|
|
@@ -3258,33 +3706,40 @@ function exportScene(data, fileNameOrOptions = "scene.glb") {
|
|
|
3258
3706
|
}
|
|
3259
3707
|
try {
|
|
3260
3708
|
exporter.parse(
|
|
3261
|
-
|
|
3709
|
+
exportTarget,
|
|
3262
3710
|
(gltf) => {
|
|
3263
3711
|
detachBundle();
|
|
3264
3712
|
if (!(gltf instanceof ArrayBuffer)) {
|
|
3265
|
-
|
|
3713
|
+
const error = new Error("Failed to export scene.");
|
|
3714
|
+
options.onError?.(error);
|
|
3715
|
+
return;
|
|
3266
3716
|
}
|
|
3267
|
-
const
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
type: "application/octet-stream"
|
|
3271
|
-
})
|
|
3717
|
+
const sanitizedGltf = sanitizeExportedGlb(
|
|
3718
|
+
gltf,
|
|
3719
|
+
data.name?.trim() || void 0
|
|
3272
3720
|
);
|
|
3273
3721
|
const trimmed = fileName.trim();
|
|
3274
3722
|
const safeFileName = trimmed.length > 0 ? trimmed : "scene.glb";
|
|
3275
3723
|
const downloadName = safeFileName.toLowerCase().endsWith(".glb") ? safeFileName : `${safeFileName}.glb`;
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3724
|
+
triggerBlobDownload(
|
|
3725
|
+
new Blob([sanitizedGltf], {
|
|
3726
|
+
type: "application/octet-stream"
|
|
3727
|
+
}),
|
|
3728
|
+
downloadName
|
|
3729
|
+
);
|
|
3730
|
+
options.onComplete?.();
|
|
3279
3731
|
},
|
|
3280
|
-
() => {
|
|
3732
|
+
(error) => {
|
|
3281
3733
|
detachBundle();
|
|
3734
|
+
options.onError?.(normalizeExportError(error));
|
|
3282
3735
|
},
|
|
3283
3736
|
exporterOptions
|
|
3284
3737
|
);
|
|
3285
3738
|
} catch (error) {
|
|
3286
3739
|
detachBundle();
|
|
3287
|
-
|
|
3740
|
+
const normalizedError = normalizeExportError(error);
|
|
3741
|
+
options.onError?.(normalizedError);
|
|
3742
|
+
throw normalizedError;
|
|
3288
3743
|
}
|
|
3289
3744
|
}
|
|
3290
3745
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -3304,6 +3759,7 @@ function exportScene(data, fileNameOrOptions = "scene.glb") {
|
|
|
3304
3759
|
loadGLTFFromBlobWithBundle,
|
|
3305
3760
|
loadGLTFWithBundle,
|
|
3306
3761
|
loadGltfFromBlob,
|
|
3762
|
+
parseGlbJsonChunk,
|
|
3307
3763
|
useDefaultVizijStore,
|
|
3308
3764
|
useFeatures,
|
|
3309
3765
|
useVizijStore,
|