@vizij/render 1.0.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -110
- package/dist/index.d.mts +284 -163
- package/dist/index.d.ts +284 -163
- package/dist/index.js +945 -1835
- package/dist/index.mjs +920 -1833
- package/package.json +9 -16
package/dist/index.mjs
CHANGED
|
@@ -1,1241 +1,547 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import {
|
|
3
|
-
import { ErrorBoundary } from "react-error-boundary";
|
|
4
|
-
import { Object3D as Object3D4, SRGBColorSpace } from "three";
|
|
5
|
-
import { Canvas, useThree } from "@react-three/fiber";
|
|
6
|
-
import { Line as Line3, OrthographicCamera, Text } from "@react-three/drei";
|
|
7
|
-
import { useShallow as useShallow7 } from "zustand/react/shallow";
|
|
8
|
-
|
|
9
|
-
// src/renderables/renderable.tsx
|
|
10
|
-
import { memo as memo5 } from "react";
|
|
11
|
-
import { useShallow as useShallow5 } from "zustand/react/shallow";
|
|
12
|
-
|
|
13
|
-
// src/hooks/use-vizij-store.ts
|
|
14
|
-
import { useContext } from "react";
|
|
15
|
-
import { useStore } from "zustand";
|
|
16
|
-
|
|
17
|
-
// src/context.ts
|
|
18
|
-
import { createContext } from "react";
|
|
19
|
-
var VizijContext = createContext(null);
|
|
20
|
-
|
|
21
|
-
// src/hooks/use-vizij-store.ts
|
|
22
|
-
function useVizijStore(selector) {
|
|
23
|
-
const store = useContext(VizijContext);
|
|
24
|
-
if (!store) throw new Error("Missing VizijProvider in the tree");
|
|
25
|
-
return useStore(store, selector);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// src/renderables/group.tsx
|
|
29
|
-
import { memo, useCallback, useEffect as useEffect2, useRef, useMemo } from "react";
|
|
30
|
-
import * as THREE from "three";
|
|
31
|
-
import { useShallow } from "zustand/react/shallow";
|
|
1
|
+
// src/page/canvas.tsx
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
32
3
|
import {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
4
|
+
drainPicks,
|
|
5
|
+
init,
|
|
6
|
+
mount,
|
|
7
|
+
onInitProgress,
|
|
8
|
+
placeVizij,
|
|
9
|
+
ready,
|
|
10
|
+
safeArea
|
|
11
|
+
} from "@vizij/runtime";
|
|
38
12
|
|
|
39
|
-
// src/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
13
|
+
// src/page/progress.ts
|
|
14
|
+
var runtime = {
|
|
15
|
+
stage: "download",
|
|
16
|
+
loaded: 0,
|
|
17
|
+
total: null
|
|
18
|
+
};
|
|
19
|
+
var faces = /* @__PURE__ */ new Map();
|
|
20
|
+
var watchers = /* @__PURE__ */ new Set();
|
|
21
|
+
function setVizijProgress(vizijId, progress) {
|
|
22
|
+
if (progress === null) {
|
|
23
|
+
faces.delete(vizijId);
|
|
24
|
+
} else {
|
|
25
|
+
const face = faces.get(vizijId);
|
|
26
|
+
if (face) face.progress = progress;
|
|
27
|
+
else faces.set(vizijId, { progress, drawn: false });
|
|
28
|
+
}
|
|
29
|
+
notify();
|
|
30
|
+
}
|
|
31
|
+
function setRuntimeStage(stage) {
|
|
32
|
+
runtime = stage;
|
|
33
|
+
notify();
|
|
34
|
+
}
|
|
35
|
+
function markDrawn(vizijId) {
|
|
36
|
+
const face = faces.get(vizijId);
|
|
37
|
+
if (face?.drawn) return;
|
|
38
|
+
if (face) face.drawn = true;
|
|
39
|
+
else faces.set(vizijId, { progress: null, drawn: true });
|
|
40
|
+
notify();
|
|
41
|
+
}
|
|
42
|
+
function loadingStage(vizijId) {
|
|
43
|
+
const face = faces.get(vizijId);
|
|
44
|
+
if (face?.drawn) return null;
|
|
45
|
+
if (runtime?.stage === "failed") return runtime;
|
|
46
|
+
if (face?.progress?.stage === "failed") return face.progress;
|
|
47
|
+
if (runtime !== null) return runtime;
|
|
48
|
+
return face?.progress ?? { stage: "load" };
|
|
49
|
+
}
|
|
50
|
+
function watchLoading(vizijId, listener) {
|
|
51
|
+
const watcher = { vizijId, listener, last: loadingStage(vizijId) };
|
|
52
|
+
watchers.add(watcher);
|
|
53
|
+
listener(watcher.last);
|
|
54
|
+
return () => {
|
|
55
|
+
watchers.delete(watcher);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function notify() {
|
|
59
|
+
for (const watcher of [...watchers]) {
|
|
60
|
+
const next = loadingStage(watcher.vizijId);
|
|
61
|
+
if (sameStage(next, watcher.last)) continue;
|
|
62
|
+
watcher.last = next;
|
|
63
|
+
watcher.listener(next);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function sameStage(a, b) {
|
|
67
|
+
if (a === null || b === null) return a === b;
|
|
68
|
+
if (a.stage !== b.stage) return false;
|
|
69
|
+
if ("loaded" in a && "loaded" in b) {
|
|
70
|
+
return a.loaded === b.loaded && a.total === b.total;
|
|
71
|
+
}
|
|
72
|
+
if ("error" in a && "error" in b) return a.error === b.error;
|
|
73
|
+
return true;
|
|
85
74
|
}
|
|
86
75
|
|
|
87
|
-
// src/
|
|
88
|
-
function
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return [key, storedFeat];
|
|
98
|
-
}
|
|
99
|
-
const staticFeature = feat;
|
|
100
|
-
return [key, staticFeature.label ? { ...staticFeature } : staticFeature];
|
|
76
|
+
// src/page/frame.ts
|
|
77
|
+
function frame(slots2, canvas2, view2) {
|
|
78
|
+
const origin = canvas2.getBoundingClientRect();
|
|
79
|
+
const byId = /* @__PURE__ */ new Map();
|
|
80
|
+
for (const slot of slots2) {
|
|
81
|
+
byId.set(slot.vizijId, slot);
|
|
82
|
+
const rect = relative(slot.element.getBoundingClientRect(), origin);
|
|
83
|
+
if (!sameRect(rect, slot.placed)) {
|
|
84
|
+
view2.placeVizij(slot.vizijId, rect);
|
|
85
|
+
slot.placed = rect;
|
|
101
86
|
}
|
|
102
|
-
|
|
103
|
-
|
|
87
|
+
const ready2 = view2.ready(slot.vizijId);
|
|
88
|
+
if (ready2) markDrawn(slot.vizijId);
|
|
89
|
+
if (slot.element.getAttribute("data-vizij-ready") !== String(ready2)) {
|
|
90
|
+
slot.element.setAttribute("data-vizij-ready", String(ready2));
|
|
91
|
+
}
|
|
92
|
+
if (slot.safeArea) {
|
|
93
|
+
outline(slot.safeArea, view2.safeArea(slot.vizijId), origin);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
for (const pick of view2.drainPicks()) {
|
|
97
|
+
byId.get(pick.vizijId)?.onPick?.(pick);
|
|
98
|
+
}
|
|
104
99
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
100
|
+
function relative(rect, origin) {
|
|
101
|
+
return {
|
|
102
|
+
x: rect.x - origin.x,
|
|
103
|
+
y: rect.y - origin.y,
|
|
104
|
+
width: rect.width,
|
|
105
|
+
height: rect.height
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function sameRect(a, b) {
|
|
109
|
+
return b !== null && a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
|
|
110
|
+
}
|
|
111
|
+
function outline({ outline: outline2, frame: frame2 }, area, canvas2) {
|
|
112
|
+
if (!area) {
|
|
113
|
+
outline2.style.display = "none";
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const at = relative(frame2.getBoundingClientRect(), canvas2);
|
|
117
|
+
outline2.style.display = "block";
|
|
118
|
+
outline2.style.left = `${area.x - at.x}px`;
|
|
119
|
+
outline2.style.top = `${area.y - at.y}px`;
|
|
120
|
+
outline2.style.width = `${area.width}px`;
|
|
121
|
+
outline2.style.height = `${area.height}px`;
|
|
114
122
|
}
|
|
115
123
|
|
|
116
|
-
// src/
|
|
124
|
+
// src/page/canvas.tsx
|
|
117
125
|
import { jsx } from "react/jsx-runtime";
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
126
|
+
var canvas = null;
|
|
127
|
+
var mounting = null;
|
|
128
|
+
var live = false;
|
|
129
|
+
var settle;
|
|
130
|
+
var mounted = new Promise((resolve, reject) => {
|
|
131
|
+
settle = { resolve, reject };
|
|
132
|
+
});
|
|
133
|
+
var PAINT_WAIT_MS = 100;
|
|
134
|
+
var slots = /* @__PURE__ */ new Set();
|
|
135
|
+
var hosts = 0;
|
|
136
|
+
var loop = null;
|
|
137
|
+
function canvasMounted() {
|
|
138
|
+
return mounted;
|
|
139
|
+
}
|
|
140
|
+
var DEFAULT_STYLE = {
|
|
141
|
+
position: "fixed",
|
|
142
|
+
inset: 0,
|
|
143
|
+
pointerEvents: "none"
|
|
144
|
+
};
|
|
145
|
+
function VizijCanvas({
|
|
146
|
+
options,
|
|
147
|
+
className,
|
|
148
|
+
style
|
|
123
149
|
}) {
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const animatableValues = useMemo(() => {
|
|
134
|
-
const av = {};
|
|
135
|
-
Object.values(group.features).forEach((feat) => {
|
|
136
|
-
if (feat.animated) {
|
|
137
|
-
const animatable = animatables[feat.value];
|
|
138
|
-
av[animatable.id] = animatable;
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
return av;
|
|
142
|
-
}, [group.features, animatables]);
|
|
143
|
-
const userData = {
|
|
144
|
-
gltfExtensions: {
|
|
145
|
-
RobotData: createStoredRenderable(group, animatableValues)
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
useFeatures(namespace, group.features, {
|
|
149
|
-
translation: (pos) => {
|
|
150
|
-
if (ref.current?.position && instanceOfRawVector3(pos)) {
|
|
151
|
-
ref.current.position.set(
|
|
152
|
-
pos.x,
|
|
153
|
-
pos.y,
|
|
154
|
-
pos.z
|
|
155
|
-
);
|
|
156
|
-
} else if (ref.current?.position && instanceOfRawVector2(pos)) {
|
|
157
|
-
const currentZ = ref.current.position.z;
|
|
158
|
-
ref.current.position.set(pos.x, pos.y, currentZ);
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
rotation: (rot) => {
|
|
162
|
-
if (ref.current?.rotation && instanceOfRawEuler(rot)) {
|
|
163
|
-
ref.current.rotation.set(rot.x, rot.y, rot.z, "ZYX");
|
|
164
|
-
} else if (ref.current?.rotation && instanceOfRawNumber(rot)) {
|
|
165
|
-
ref.current.rotation.set(0, 0, 0);
|
|
166
|
-
ref.current.rotateZ(rot);
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
scale: (scale) => {
|
|
170
|
-
if (ref.current?.scale && instanceOfRawVector3(scale)) {
|
|
171
|
-
if (scale.x === null || scale.y === null || scale.z === null) {
|
|
172
|
-
ref.current.scale.set(0.1, 0.1, 0.1);
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
ref.current.scale.set(scale.x, scale.y, scale.z);
|
|
176
|
-
} else if (ref.current && instanceOfRawNumber(scale)) {
|
|
177
|
-
ref.current.scale.set(scale, scale, scale);
|
|
178
|
-
} else if (ref.current) {
|
|
179
|
-
ref.current.scale.set(1, 1, 1);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
const setReference = useVizijStore(
|
|
184
|
-
useShallow((state) => state.setReference)
|
|
185
|
-
);
|
|
186
|
-
useEffect2(() => {
|
|
187
|
-
if (ref.current && refIsNull) {
|
|
188
|
-
setReference(group.id, namespace, ref);
|
|
150
|
+
const host = useRef(null);
|
|
151
|
+
const firstOptions = useRef(options);
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
const element = host.current;
|
|
154
|
+
const shown = pageCanvas();
|
|
155
|
+
element.appendChild(shown);
|
|
156
|
+
if (!mounting) {
|
|
157
|
+
mounting = mountOnce(shown, firstOptions.current);
|
|
158
|
+
mounting.then(settle.resolve, settle.reject);
|
|
189
159
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
ref.current.name = group.name;
|
|
160
|
+
hosts += 1;
|
|
161
|
+
if (hosts === 1) {
|
|
162
|
+
void mounting.then(start, () => void 0);
|
|
194
163
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
return;
|
|
164
|
+
return () => {
|
|
165
|
+
hosts -= 1;
|
|
166
|
+
if (hosts === 0) {
|
|
167
|
+
stop();
|
|
200
168
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
[id, namespace, setHoveredElement]
|
|
204
|
-
);
|
|
205
|
-
const handlePointerOut = useCallback(
|
|
206
|
-
(event) => {
|
|
207
|
-
if (event.eventObject !== event.object) {
|
|
208
|
-
return;
|
|
169
|
+
if (shown.parentElement === element) {
|
|
170
|
+
element.removeChild(shown);
|
|
209
171
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
[setHoveredElement]
|
|
213
|
-
);
|
|
172
|
+
};
|
|
173
|
+
}, []);
|
|
214
174
|
return /* @__PURE__ */ jsx(
|
|
215
|
-
"
|
|
175
|
+
"div",
|
|
216
176
|
{
|
|
217
|
-
ref,
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
onPointerOver: handlePointerOver,
|
|
221
|
-
onPointerOut: handlePointerOut,
|
|
222
|
-
children: group.children.map((child) => /* @__PURE__ */ jsx(
|
|
223
|
-
Renderable,
|
|
224
|
-
{
|
|
225
|
-
id: child,
|
|
226
|
-
namespace,
|
|
227
|
-
chain: [...chain, id]
|
|
228
|
-
},
|
|
229
|
-
child
|
|
230
|
-
))
|
|
177
|
+
ref: host,
|
|
178
|
+
className,
|
|
179
|
+
style: style ?? (className ? void 0 : DEFAULT_STYLE)
|
|
231
180
|
}
|
|
232
181
|
);
|
|
233
182
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
import { memo as memo2, useCallback as useCallback2, useEffect as useEffect3, useRef as useRef2, useMemo as useMemo2 } from "react";
|
|
238
|
-
import { useShallow as useShallow2 } from "zustand/react/shallow";
|
|
239
|
-
import {
|
|
240
|
-
instanceOfRawNumber as instanceOfRawNumber2,
|
|
241
|
-
instanceOfRawVector2 as instanceOfRawVector22,
|
|
242
|
-
instanceOfRawVector3 as instanceOfRawVector32,
|
|
243
|
-
instanceOfRawEuler as instanceOfRawEuler2,
|
|
244
|
-
instanceOfRawRGB,
|
|
245
|
-
instanceOfRawHSL
|
|
246
|
-
} from "@vizij/utils";
|
|
247
|
-
import { Circle, Line } from "@react-three/drei";
|
|
248
|
-
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
249
|
-
function InnerRenderedEllipse({
|
|
250
|
-
id,
|
|
251
|
-
namespace,
|
|
252
|
-
chain
|
|
253
|
-
}) {
|
|
254
|
-
const ellipseRef = useRef2(null);
|
|
255
|
-
const materialRef = useRef2(
|
|
256
|
-
null
|
|
257
|
-
);
|
|
258
|
-
const lineRef = useRef2(null);
|
|
259
|
-
const strokeOffsetRef = useRef2(0);
|
|
260
|
-
const strokeWidthRef = useRef2(0);
|
|
261
|
-
const onElementClick = useVizijStore(
|
|
262
|
-
useShallow2((state) => state.onElementClick)
|
|
263
|
-
);
|
|
264
|
-
const setHoveredElement = useVizijStore(
|
|
265
|
-
useShallow2((state) => state.setHoveredElement)
|
|
266
|
-
);
|
|
267
|
-
const ellipse = useVizijStore(
|
|
268
|
-
useShallow2((state) => state.world[id])
|
|
269
|
-
);
|
|
270
|
-
const refIsNull = useVizijStore(
|
|
271
|
-
(state) => !state.refs[id]?.[namespace]?.current
|
|
272
|
-
);
|
|
273
|
-
const animatables = useVizijStore(useShallow2((state) => state.animatables));
|
|
274
|
-
const animatableValues = useMemo2(() => {
|
|
275
|
-
const av = {};
|
|
276
|
-
Object.values(ellipse.features).forEach((feat) => {
|
|
277
|
-
if (feat.animated) {
|
|
278
|
-
const animatable = animatables[feat.value];
|
|
279
|
-
av[animatable.id] = animatable;
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
return av;
|
|
283
|
-
}, [ellipse.features, animatables]);
|
|
284
|
-
const selectionData = useMemo2(
|
|
285
|
-
() => ({ id, namespace, type: "ellipse" }),
|
|
286
|
-
[id, namespace]
|
|
287
|
-
);
|
|
288
|
-
const userData = useMemo2(
|
|
289
|
-
() => ({
|
|
290
|
-
gltfExtensions: {
|
|
291
|
-
RobotData: createStoredRenderable(ellipse, animatableValues)
|
|
292
|
-
},
|
|
293
|
-
selection: selectionData
|
|
294
|
-
}),
|
|
295
|
-
[ellipse, animatableValues, selectionData]
|
|
296
|
-
);
|
|
297
|
-
useFeatures(namespace, ellipse.features, {
|
|
298
|
-
translation: (pos) => {
|
|
299
|
-
if (ellipseRef.current?.position && instanceOfRawVector32(pos)) {
|
|
300
|
-
ellipseRef.current.position.set(
|
|
301
|
-
pos.x,
|
|
302
|
-
pos.y,
|
|
303
|
-
pos.z
|
|
304
|
-
);
|
|
305
|
-
} else if (ellipseRef.current?.position && instanceOfRawVector22(pos)) {
|
|
306
|
-
const currentZ = ellipseRef.current.position.z;
|
|
307
|
-
ellipseRef.current.position.set(
|
|
308
|
-
pos.x,
|
|
309
|
-
pos.y,
|
|
310
|
-
currentZ
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
if (lineRef.current?.position && instanceOfRawVector32(pos)) {
|
|
314
|
-
lineRef.current.position.set(
|
|
315
|
-
pos.x,
|
|
316
|
-
pos.y,
|
|
317
|
-
pos.z
|
|
318
|
-
);
|
|
319
|
-
} else if (lineRef.current?.position && instanceOfRawVector22(pos)) {
|
|
320
|
-
const currentZ = lineRef.current.position.z;
|
|
321
|
-
lineRef.current.position.set(
|
|
322
|
-
pos.x,
|
|
323
|
-
pos.y,
|
|
324
|
-
currentZ
|
|
325
|
-
);
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
|
-
rotation: (rot) => {
|
|
329
|
-
if (ellipseRef.current?.rotation && instanceOfRawEuler2(rot)) {
|
|
330
|
-
ellipseRef.current.rotation.set(rot.x, rot.y, rot.z, "ZYX");
|
|
331
|
-
} else if (ellipseRef.current?.rotation && instanceOfRawNumber2(rot)) {
|
|
332
|
-
ellipseRef.current.rotation.set(0, 0, 0);
|
|
333
|
-
ellipseRef.current.rotateZ(rot);
|
|
334
|
-
}
|
|
335
|
-
if (lineRef.current?.rotation && instanceOfRawEuler2(rot)) {
|
|
336
|
-
lineRef.current.rotation.set(rot.x, rot.y, rot.z, "ZYX");
|
|
337
|
-
} else if (lineRef.current?.rotation && instanceOfRawNumber2(rot)) {
|
|
338
|
-
lineRef.current.rotation.set(0, 0, 0);
|
|
339
|
-
lineRef.current.rotateZ(rot);
|
|
340
|
-
}
|
|
341
|
-
},
|
|
342
|
-
fillOpacity: (op) => {
|
|
343
|
-
if (materialRef.current?.opacity !== void 0 && instanceOfRawNumber2(op)) {
|
|
344
|
-
materialRef.current.opacity = op;
|
|
345
|
-
if (op < 1) {
|
|
346
|
-
materialRef.current.transparent = true;
|
|
347
|
-
} else {
|
|
348
|
-
materialRef.current.transparent = false;
|
|
349
|
-
}
|
|
350
|
-
materialRef.current.needsUpdate = true;
|
|
351
|
-
}
|
|
352
|
-
},
|
|
353
|
-
fillColor: (color) => {
|
|
354
|
-
if (materialRef.current?.color) {
|
|
355
|
-
if (instanceOfRawRGB(color)) {
|
|
356
|
-
materialRef.current.color.setRGB(color.r, color.g, color.b);
|
|
357
|
-
materialRef.current.needsUpdate = true;
|
|
358
|
-
} else if (instanceOfRawVector32(color)) {
|
|
359
|
-
materialRef.current.color.setRGB(color.x, color.y, color.z);
|
|
360
|
-
materialRef.current.needsUpdate = true;
|
|
361
|
-
} else if (instanceOfRawHSL(color)) {
|
|
362
|
-
materialRef.current.color.setHSL(color.h, color.s, color.l);
|
|
363
|
-
materialRef.current.needsUpdate = true;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
},
|
|
367
|
-
height: (height) => {
|
|
368
|
-
if (ellipseRef.current && instanceOfRawNumber2(height)) {
|
|
369
|
-
ellipseRef.current.scale.set(ellipseRef.current.scale.x, height, 1);
|
|
370
|
-
}
|
|
371
|
-
if (ellipseRef.current && lineRef.current && instanceOfRawNumber2(height)) {
|
|
372
|
-
const offset = strokeOffsetRef.current * strokeWidthRef.current / 2 + strokeOffsetRef.current * -1;
|
|
373
|
-
lineRef.current.scale.set(
|
|
374
|
-
ellipseRef.current.scale.x + offset,
|
|
375
|
-
height + offset,
|
|
376
|
-
1
|
|
377
|
-
);
|
|
378
|
-
}
|
|
379
|
-
},
|
|
380
|
-
width: (width) => {
|
|
381
|
-
if (ellipseRef.current && instanceOfRawNumber2(width)) {
|
|
382
|
-
ellipseRef.current.scale.set(width, ellipseRef.current.scale.y, 1);
|
|
383
|
-
}
|
|
384
|
-
if (ellipseRef.current && lineRef.current && instanceOfRawNumber2(width)) {
|
|
385
|
-
const offset = strokeOffsetRef.current * strokeWidthRef.current / 2 + strokeOffsetRef.current * -1;
|
|
386
|
-
lineRef.current.scale.set(
|
|
387
|
-
width + offset,
|
|
388
|
-
ellipseRef.current.scale.y + offset,
|
|
389
|
-
1
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
},
|
|
393
|
-
strokeOpacity: (strokeOpacity) => {
|
|
394
|
-
if (lineRef.current?.material && instanceOfRawNumber2(strokeOpacity)) {
|
|
395
|
-
lineRef.current.material.opacity = strokeOpacity;
|
|
396
|
-
if (strokeOpacity < 1) {
|
|
397
|
-
lineRef.current.material.transparent = true;
|
|
398
|
-
} else {
|
|
399
|
-
lineRef.current.material.transparent = false;
|
|
400
|
-
}
|
|
401
|
-
lineRef.current.material.needsUpdate = true;
|
|
402
|
-
}
|
|
403
|
-
},
|
|
404
|
-
strokeColor: (strokeColor) => {
|
|
405
|
-
if (lineRef.current?.material.color) {
|
|
406
|
-
if (instanceOfRawRGB(strokeColor)) {
|
|
407
|
-
lineRef.current.material.color.setRGB(
|
|
408
|
-
strokeColor.r,
|
|
409
|
-
strokeColor.g,
|
|
410
|
-
strokeColor.b
|
|
411
|
-
);
|
|
412
|
-
lineRef.current.material.needsUpdate = true;
|
|
413
|
-
} else if (instanceOfRawVector32(strokeColor)) {
|
|
414
|
-
lineRef.current.material.color.setRGB(
|
|
415
|
-
strokeColor.x,
|
|
416
|
-
strokeColor.y,
|
|
417
|
-
strokeColor.z
|
|
418
|
-
);
|
|
419
|
-
lineRef.current.material.needsUpdate = true;
|
|
420
|
-
} else if (instanceOfRawHSL(strokeColor)) {
|
|
421
|
-
lineRef.current.material.color.setHSL(
|
|
422
|
-
strokeColor.h,
|
|
423
|
-
strokeColor.s,
|
|
424
|
-
strokeColor.l
|
|
425
|
-
);
|
|
426
|
-
lineRef.current.material.needsUpdate = true;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
},
|
|
430
|
-
strokeWidth: (strokeWidth) => {
|
|
431
|
-
if (lineRef.current?.material && ellipseRef.current) {
|
|
432
|
-
if (instanceOfRawNumber2(strokeWidth)) {
|
|
433
|
-
strokeWidthRef.current = strokeWidth;
|
|
434
|
-
const offset = strokeWidth * strokeOffsetRef.current / 2 + strokeOffsetRef.current * -1;
|
|
435
|
-
lineRef.current.scale.set(
|
|
436
|
-
ellipseRef.current.scale.x + offset,
|
|
437
|
-
ellipseRef.current.scale.y + offset,
|
|
438
|
-
1
|
|
439
|
-
);
|
|
440
|
-
lineRef.current.material.linewidth = strokeWidth;
|
|
441
|
-
lineRef.current.material.needsUpdate = true;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
},
|
|
445
|
-
strokeOffset: (strokeOffset) => {
|
|
446
|
-
if (lineRef.current?.material && ellipseRef.current) {
|
|
447
|
-
if (instanceOfRawNumber2(strokeOffset)) {
|
|
448
|
-
strokeOffsetRef.current = strokeOffset;
|
|
449
|
-
const offset = strokeOffset * strokeWidthRef.current / 2 + strokeOffset * -1;
|
|
450
|
-
lineRef.current.scale.set(
|
|
451
|
-
ellipseRef.current.scale.x + offset,
|
|
452
|
-
ellipseRef.current.scale.y + offset,
|
|
453
|
-
1
|
|
454
|
-
);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
183
|
+
async function mountOnce(shown, options) {
|
|
184
|
+
const unfollow = onInitProgress((progress) => {
|
|
185
|
+
setRuntimeStage(progress.stage === "ready" ? { stage: "mount" } : progress);
|
|
458
186
|
});
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
[id, namespace, setHoveredElement]
|
|
484
|
-
);
|
|
485
|
-
const handlePointerOut = useCallback2(
|
|
486
|
-
(event) => {
|
|
487
|
-
event.stopPropagation();
|
|
488
|
-
setHoveredElement(null);
|
|
489
|
-
},
|
|
490
|
-
[setHoveredElement]
|
|
491
|
-
);
|
|
492
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
493
|
-
/* @__PURE__ */ jsx2(
|
|
494
|
-
Circle,
|
|
495
|
-
{
|
|
496
|
-
ref: ellipseRef,
|
|
497
|
-
userData,
|
|
498
|
-
args: [1, 100],
|
|
499
|
-
onPointerOver: handlePointerOver,
|
|
500
|
-
onPointerOut: handlePointerOut,
|
|
501
|
-
onClick: (e) => {
|
|
502
|
-
onElementClick({ id, type: "ellipse", namespace }, [...chain, id], e);
|
|
503
|
-
},
|
|
504
|
-
children: /* @__PURE__ */ jsx2("meshStandardMaterial", { attach: "material", ref: materialRef })
|
|
505
|
-
}
|
|
506
|
-
),
|
|
507
|
-
showLine(ellipse) && /* @__PURE__ */ jsx2(
|
|
508
|
-
Line,
|
|
509
|
-
{
|
|
510
|
-
ref: lineRef,
|
|
511
|
-
points,
|
|
512
|
-
onPointerOver: handlePointerOver,
|
|
513
|
-
onPointerOut: handlePointerOut
|
|
514
|
-
}
|
|
515
|
-
)
|
|
516
|
-
] });
|
|
517
|
-
}
|
|
518
|
-
var RenderedEllipse = memo2(InnerRenderedEllipse);
|
|
519
|
-
var showLine = (ellipse) => {
|
|
520
|
-
if ("strokeOpacity" in ellipse.features) {
|
|
521
|
-
return true;
|
|
522
|
-
} else if ("strokeColor" in ellipse.features) {
|
|
523
|
-
return true;
|
|
524
|
-
} else if ("strokeWidth" in ellipse.features) {
|
|
525
|
-
return true;
|
|
526
|
-
} else if ("strokeOffset" in ellipse.features) {
|
|
527
|
-
return true;
|
|
528
|
-
}
|
|
529
|
-
return false;
|
|
530
|
-
};
|
|
531
|
-
|
|
532
|
-
// src/renderables/rectangle.tsx
|
|
533
|
-
import { memo as memo3, useCallback as useCallback3, useEffect as useEffect4, useRef as useRef3, useMemo as useMemo3 } from "react";
|
|
534
|
-
import { useShallow as useShallow3 } from "zustand/react/shallow";
|
|
535
|
-
import {
|
|
536
|
-
instanceOfRawNumber as instanceOfRawNumber3,
|
|
537
|
-
instanceOfRawVector2 as instanceOfRawVector23,
|
|
538
|
-
instanceOfRawVector3 as instanceOfRawVector33,
|
|
539
|
-
instanceOfRawEuler as instanceOfRawEuler3,
|
|
540
|
-
instanceOfRawRGB as instanceOfRawRGB2,
|
|
541
|
-
instanceOfRawHSL as instanceOfRawHSL2
|
|
542
|
-
} from "@vizij/utils";
|
|
543
|
-
import { Plane, Line as Line2 } from "@react-three/drei";
|
|
544
|
-
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
545
|
-
function InnerRenderedRectangle({
|
|
546
|
-
id,
|
|
547
|
-
namespace,
|
|
548
|
-
chain
|
|
549
|
-
}) {
|
|
550
|
-
const rectangleRef = useRef3(null);
|
|
551
|
-
const materialRef = useRef3(
|
|
552
|
-
null
|
|
553
|
-
);
|
|
554
|
-
const lineRef = useRef3(null);
|
|
555
|
-
const strokeOffsetRef = useRef3(0);
|
|
556
|
-
const strokeWidthRef = useRef3(0);
|
|
557
|
-
const onElementClick = useVizijStore(
|
|
558
|
-
useShallow3((state) => state.onElementClick)
|
|
559
|
-
);
|
|
560
|
-
const setHoveredElement = useVizijStore(
|
|
561
|
-
useShallow3((state) => state.setHoveredElement)
|
|
562
|
-
);
|
|
563
|
-
const rectangle = useVizijStore(
|
|
564
|
-
useShallow3((state) => state.world[id])
|
|
565
|
-
);
|
|
566
|
-
const refIsNull = useVizijStore(
|
|
567
|
-
(state) => !state.refs[id]?.[namespace]?.current
|
|
568
|
-
);
|
|
569
|
-
const animatables = useVizijStore(useShallow3((state) => state.animatables));
|
|
570
|
-
const animatableValues = useMemo3(() => {
|
|
571
|
-
const av = {};
|
|
572
|
-
Object.values(rectangle.features).forEach((feat) => {
|
|
573
|
-
if (feat.animated) {
|
|
574
|
-
const animatable = animatables[feat.value];
|
|
575
|
-
av[animatable.id] = animatable;
|
|
576
|
-
}
|
|
577
|
-
});
|
|
578
|
-
return av;
|
|
579
|
-
}, [rectangle.features, animatables]);
|
|
580
|
-
const selectionData = useMemo3(
|
|
581
|
-
() => ({ id, namespace, type: "rectangle" }),
|
|
582
|
-
[id, namespace]
|
|
583
|
-
);
|
|
584
|
-
const userData = useMemo3(
|
|
585
|
-
() => ({
|
|
586
|
-
gltfExtensions: {
|
|
587
|
-
RobotData: createStoredRenderable(rectangle, animatableValues)
|
|
588
|
-
},
|
|
589
|
-
selection: selectionData
|
|
590
|
-
}),
|
|
591
|
-
[rectangle, animatableValues, selectionData]
|
|
592
|
-
);
|
|
593
|
-
useFeatures(namespace, rectangle.features, {
|
|
594
|
-
translation: (pos) => {
|
|
595
|
-
if (rectangleRef.current?.position && instanceOfRawVector33(pos)) {
|
|
596
|
-
rectangleRef.current.position.set(
|
|
597
|
-
pos.x,
|
|
598
|
-
pos.y,
|
|
599
|
-
pos.z
|
|
600
|
-
);
|
|
601
|
-
} else if (rectangleRef.current?.position && instanceOfRawVector23(pos)) {
|
|
602
|
-
const currentZ = rectangleRef.current.position.z;
|
|
603
|
-
rectangleRef.current.position.set(
|
|
604
|
-
pos.x,
|
|
605
|
-
pos.y,
|
|
606
|
-
currentZ
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
if (lineRef.current?.position && instanceOfRawVector33(pos)) {
|
|
610
|
-
lineRef.current.position.set(
|
|
611
|
-
pos.x,
|
|
612
|
-
pos.y,
|
|
613
|
-
pos.z
|
|
614
|
-
);
|
|
615
|
-
} else if (lineRef.current?.position && instanceOfRawVector23(pos)) {
|
|
616
|
-
const currentZ = lineRef.current.position.z;
|
|
617
|
-
lineRef.current.position.set(
|
|
618
|
-
pos.x,
|
|
619
|
-
pos.y,
|
|
620
|
-
currentZ
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
|
-
},
|
|
624
|
-
rotation: (rot) => {
|
|
625
|
-
if (rectangleRef.current?.rotation && instanceOfRawEuler3(rot)) {
|
|
626
|
-
rectangleRef.current.rotation.set(rot.x, rot.y, rot.z, "ZYX");
|
|
627
|
-
} else if (rectangleRef.current?.rotation && instanceOfRawNumber3(rot)) {
|
|
628
|
-
rectangleRef.current.rotation.set(0, 0, 0);
|
|
629
|
-
rectangleRef.current.rotateZ(rot);
|
|
630
|
-
}
|
|
631
|
-
if (lineRef.current?.rotation && instanceOfRawEuler3(rot)) {
|
|
632
|
-
lineRef.current.rotation.set(rot.x, rot.y, rot.z, "ZYX");
|
|
633
|
-
} else if (lineRef.current?.rotation && instanceOfRawNumber3(rot)) {
|
|
634
|
-
lineRef.current.rotation.set(0, 0, 0);
|
|
635
|
-
lineRef.current.rotateZ(rot);
|
|
636
|
-
}
|
|
637
|
-
},
|
|
638
|
-
fillOpacity: (op) => {
|
|
639
|
-
if (materialRef.current?.opacity !== void 0 && instanceOfRawNumber3(op)) {
|
|
640
|
-
materialRef.current.opacity = op;
|
|
641
|
-
if (op < 1) {
|
|
642
|
-
materialRef.current.transparent = true;
|
|
643
|
-
} else {
|
|
644
|
-
materialRef.current.transparent = false;
|
|
645
|
-
}
|
|
646
|
-
materialRef.current.needsUpdate = true;
|
|
647
|
-
}
|
|
648
|
-
},
|
|
649
|
-
fillColor: (color) => {
|
|
650
|
-
if (materialRef.current?.color) {
|
|
651
|
-
if (instanceOfRawRGB2(color)) {
|
|
652
|
-
materialRef.current.color.setRGB(color.r, color.g, color.b);
|
|
653
|
-
materialRef.current.needsUpdate = true;
|
|
654
|
-
} else if (instanceOfRawVector33(color)) {
|
|
655
|
-
materialRef.current.color.setRGB(color.x, color.y, color.z);
|
|
656
|
-
materialRef.current.needsUpdate = true;
|
|
657
|
-
} else if (instanceOfRawHSL2(color)) {
|
|
658
|
-
materialRef.current.color.setHSL(color.h, color.s, color.l);
|
|
659
|
-
materialRef.current.needsUpdate = true;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
},
|
|
663
|
-
height: (height) => {
|
|
664
|
-
if (rectangleRef.current && instanceOfRawNumber3(height)) {
|
|
665
|
-
rectangleRef.current.scale.set(rectangleRef.current.scale.x, height, 1);
|
|
666
|
-
}
|
|
667
|
-
if (rectangleRef.current && lineRef.current && instanceOfRawNumber3(height)) {
|
|
668
|
-
const offset = strokeOffsetRef.current * strokeWidthRef.current / 2 + strokeOffsetRef.current * -1;
|
|
669
|
-
lineRef.current.scale.set(
|
|
670
|
-
rectangleRef.current.scale.x + offset,
|
|
671
|
-
height + offset,
|
|
672
|
-
1
|
|
673
|
-
);
|
|
674
|
-
}
|
|
675
|
-
},
|
|
676
|
-
width: (width) => {
|
|
677
|
-
if (rectangleRef.current && instanceOfRawNumber3(width)) {
|
|
678
|
-
rectangleRef.current.scale.set(width, rectangleRef.current.scale.y, 1);
|
|
679
|
-
}
|
|
680
|
-
if (rectangleRef.current && lineRef.current && instanceOfRawNumber3(width)) {
|
|
681
|
-
const offset = strokeOffsetRef.current * strokeWidthRef.current / 2 + strokeOffsetRef.current * -1;
|
|
682
|
-
lineRef.current.scale.set(
|
|
683
|
-
width + offset,
|
|
684
|
-
rectangleRef.current.scale.y + offset,
|
|
685
|
-
1
|
|
686
|
-
);
|
|
687
|
-
}
|
|
688
|
-
},
|
|
689
|
-
strokeOpacity: (strokeOpacity) => {
|
|
690
|
-
if (lineRef.current?.material && instanceOfRawNumber3(strokeOpacity)) {
|
|
691
|
-
lineRef.current.material.opacity = strokeOpacity;
|
|
692
|
-
if (strokeOpacity < 1) {
|
|
693
|
-
lineRef.current.material.transparent = true;
|
|
694
|
-
} else {
|
|
695
|
-
lineRef.current.material.transparent = false;
|
|
696
|
-
}
|
|
697
|
-
lineRef.current.material.needsUpdate = true;
|
|
698
|
-
}
|
|
699
|
-
},
|
|
700
|
-
strokeColor: (strokeColor) => {
|
|
701
|
-
if (lineRef.current?.material.color) {
|
|
702
|
-
if (instanceOfRawRGB2(strokeColor)) {
|
|
703
|
-
lineRef.current.material.color.setRGB(
|
|
704
|
-
strokeColor.r,
|
|
705
|
-
strokeColor.g,
|
|
706
|
-
strokeColor.b
|
|
707
|
-
);
|
|
708
|
-
lineRef.current.material.needsUpdate = true;
|
|
709
|
-
} else if (instanceOfRawVector33(strokeColor)) {
|
|
710
|
-
lineRef.current.material.color.setRGB(
|
|
711
|
-
strokeColor.x,
|
|
712
|
-
strokeColor.y,
|
|
713
|
-
strokeColor.z
|
|
714
|
-
);
|
|
715
|
-
lineRef.current.material.needsUpdate = true;
|
|
716
|
-
} else if (instanceOfRawHSL2(strokeColor)) {
|
|
717
|
-
lineRef.current.material.color.setHSL(
|
|
718
|
-
strokeColor.h,
|
|
719
|
-
strokeColor.s,
|
|
720
|
-
strokeColor.l
|
|
721
|
-
);
|
|
722
|
-
lineRef.current.material.needsUpdate = true;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
},
|
|
726
|
-
strokeWidth: (strokeWidth) => {
|
|
727
|
-
if (lineRef.current?.material && rectangleRef.current) {
|
|
728
|
-
if (instanceOfRawNumber3(strokeWidth)) {
|
|
729
|
-
strokeWidthRef.current = strokeWidth;
|
|
730
|
-
const offset = strokeWidth * strokeOffsetRef.current / 2 + strokeOffsetRef.current * -1;
|
|
731
|
-
lineRef.current.scale.set(
|
|
732
|
-
rectangleRef.current.scale.x + offset,
|
|
733
|
-
rectangleRef.current.scale.y + offset,
|
|
734
|
-
1
|
|
735
|
-
);
|
|
736
|
-
lineRef.current.material.linewidth = strokeWidth;
|
|
737
|
-
lineRef.current.material.needsUpdate = true;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
},
|
|
741
|
-
strokeOffset: (strokeOffset) => {
|
|
742
|
-
if (lineRef.current?.material && rectangleRef.current) {
|
|
743
|
-
if (instanceOfRawNumber3(strokeOffset)) {
|
|
744
|
-
strokeOffsetRef.current = strokeOffset;
|
|
745
|
-
const offset = strokeOffset * strokeWidthRef.current / 2 + strokeOffset * -1;
|
|
746
|
-
lineRef.current.scale.set(
|
|
747
|
-
rectangleRef.current.scale.x + offset,
|
|
748
|
-
rectangleRef.current.scale.y + offset,
|
|
749
|
-
1
|
|
750
|
-
);
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
}
|
|
187
|
+
try {
|
|
188
|
+
await init();
|
|
189
|
+
await afterPaint();
|
|
190
|
+
await mount(shown, options);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
setRuntimeStage({ stage: "failed", error: asError(error) });
|
|
193
|
+
throw error;
|
|
194
|
+
} finally {
|
|
195
|
+
unfollow();
|
|
196
|
+
}
|
|
197
|
+
live = true;
|
|
198
|
+
setRuntimeStage(null);
|
|
199
|
+
await afterPaint();
|
|
200
|
+
return shown;
|
|
201
|
+
}
|
|
202
|
+
function afterPaint() {
|
|
203
|
+
return new Promise((resolve) => {
|
|
204
|
+
const timer = setTimeout(resolve, PAINT_WAIT_MS);
|
|
205
|
+
requestAnimationFrame(
|
|
206
|
+
() => setTimeout(() => {
|
|
207
|
+
clearTimeout(timer);
|
|
208
|
+
resolve();
|
|
209
|
+
}, 0)
|
|
210
|
+
);
|
|
754
211
|
});
|
|
755
|
-
const setReference = useVizijStore(
|
|
756
|
-
useShallow3((state) => state.setReference)
|
|
757
|
-
);
|
|
758
|
-
const points = useMemo3(() => {
|
|
759
|
-
return [
|
|
760
|
-
[-0.5, 0.5, 0],
|
|
761
|
-
[0.5, 0.5, 0],
|
|
762
|
-
[0.5, -0.5, 0],
|
|
763
|
-
[-0.5, -0.5, 0],
|
|
764
|
-
[-0.5, 0.5, 0]
|
|
765
|
-
];
|
|
766
|
-
}, []);
|
|
767
|
-
useEffect4(() => {
|
|
768
|
-
if (rectangleRef.current && refIsNull)
|
|
769
|
-
setReference(rectangle.id, namespace, rectangleRef);
|
|
770
|
-
}, [rectangle.id, namespace, rectangleRef, setReference, refIsNull]);
|
|
771
|
-
const handlePointerOver = useCallback3(
|
|
772
|
-
(event) => {
|
|
773
|
-
event.stopPropagation();
|
|
774
|
-
setHoveredElement({ id, namespace, type: "rectangle" });
|
|
775
|
-
},
|
|
776
|
-
[id, namespace, setHoveredElement]
|
|
777
|
-
);
|
|
778
|
-
const handlePointerOut = useCallback3(
|
|
779
|
-
(event) => {
|
|
780
|
-
event.stopPropagation();
|
|
781
|
-
setHoveredElement(null);
|
|
782
|
-
},
|
|
783
|
-
[setHoveredElement]
|
|
784
|
-
);
|
|
785
|
-
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
786
|
-
/* @__PURE__ */ jsx3(
|
|
787
|
-
Plane,
|
|
788
|
-
{
|
|
789
|
-
ref: rectangleRef,
|
|
790
|
-
userData,
|
|
791
|
-
args: [1, 1],
|
|
792
|
-
onPointerOver: handlePointerOver,
|
|
793
|
-
onPointerOut: handlePointerOut,
|
|
794
|
-
onClick: (e) => {
|
|
795
|
-
onElementClick(
|
|
796
|
-
{ id, type: "rectangle", namespace },
|
|
797
|
-
[...chain, id],
|
|
798
|
-
e
|
|
799
|
-
);
|
|
800
|
-
},
|
|
801
|
-
children: /* @__PURE__ */ jsx3("meshStandardMaterial", { attach: "material", ref: materialRef })
|
|
802
|
-
}
|
|
803
|
-
),
|
|
804
|
-
showLine2(rectangle) && /* @__PURE__ */ jsx3(
|
|
805
|
-
Line2,
|
|
806
|
-
{
|
|
807
|
-
ref: lineRef,
|
|
808
|
-
points,
|
|
809
|
-
onPointerOver: handlePointerOver,
|
|
810
|
-
onPointerOut: handlePointerOut
|
|
811
|
-
}
|
|
812
|
-
)
|
|
813
|
-
] });
|
|
814
212
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
if ("strokeOpacity" in rectangle.features) {
|
|
818
|
-
return true;
|
|
819
|
-
} else if ("strokeColor" in rectangle.features) {
|
|
820
|
-
return true;
|
|
821
|
-
} else if ("strokeWidth" in rectangle.features) {
|
|
822
|
-
return true;
|
|
823
|
-
} else if ("strokeOffset" in rectangle.features) {
|
|
824
|
-
return true;
|
|
825
|
-
}
|
|
826
|
-
return false;
|
|
827
|
-
};
|
|
828
|
-
|
|
829
|
-
// src/renderables/shape.tsx
|
|
830
|
-
import { memo as memo4, useCallback as useCallback4, useRef as useRef4, useMemo as useMemo4, useEffect as useEffect5 } from "react";
|
|
831
|
-
import * as THREE2 from "three";
|
|
832
|
-
import { useShallow as useShallow4 } from "zustand/react/shallow";
|
|
833
|
-
import {
|
|
834
|
-
instanceOfRawEuler as instanceOfRawEuler4,
|
|
835
|
-
instanceOfRawHSL as instanceOfRawHSL3,
|
|
836
|
-
instanceOfRawNumber as instanceOfRawNumber4,
|
|
837
|
-
instanceOfRawRGB as instanceOfRawRGB3,
|
|
838
|
-
instanceOfRawVector3 as instanceOfRawVector34
|
|
839
|
-
} from "@vizij/utils";
|
|
840
|
-
|
|
841
|
-
// src/functions/material-name.ts
|
|
842
|
-
var MATERIAL_FEATURE_KEYS = [
|
|
843
|
-
"color",
|
|
844
|
-
"opacity",
|
|
845
|
-
"roughness",
|
|
846
|
-
"metalness",
|
|
847
|
-
"shininess",
|
|
848
|
-
"emissive",
|
|
849
|
-
"emissiveIntensity",
|
|
850
|
-
"specular"
|
|
851
|
-
];
|
|
852
|
-
var MATERIAL_NAME_SUFFIXES = [
|
|
853
|
-
" color",
|
|
854
|
-
" colours",
|
|
855
|
-
" colour",
|
|
856
|
-
" opacity",
|
|
857
|
-
" roughness",
|
|
858
|
-
" metalness",
|
|
859
|
-
" shininess",
|
|
860
|
-
" emissive intensity",
|
|
861
|
-
" emissive",
|
|
862
|
-
" specular"
|
|
863
|
-
];
|
|
864
|
-
function deriveMaterialName(shape, values) {
|
|
865
|
-
for (const key of MATERIAL_FEATURE_KEYS) {
|
|
866
|
-
const feature = shape.features[key];
|
|
867
|
-
if (feature && feature.animated) {
|
|
868
|
-
const animatable = values[feature.value];
|
|
869
|
-
const candidate = extractMaterialName(animatable?.name);
|
|
870
|
-
if (candidate) {
|
|
871
|
-
return candidate;
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
return void 0;
|
|
213
|
+
function asError(error) {
|
|
214
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
876
215
|
}
|
|
877
|
-
function
|
|
878
|
-
if (!
|
|
879
|
-
|
|
216
|
+
function pageCanvas() {
|
|
217
|
+
if (!canvas) {
|
|
218
|
+
canvas = document.createElement("canvas");
|
|
219
|
+
canvas.style.display = "block";
|
|
220
|
+
canvas.style.width = "100%";
|
|
221
|
+
canvas.style.height = "100%";
|
|
880
222
|
}
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
223
|
+
return canvas;
|
|
224
|
+
}
|
|
225
|
+
var view = { placeVizij, ready, safeArea, drainPicks };
|
|
226
|
+
function start() {
|
|
227
|
+
if (loop !== null || hosts === 0) return;
|
|
228
|
+
const tick = () => {
|
|
229
|
+
frame(slots, canvas, view);
|
|
230
|
+
loop = requestAnimationFrame(tick);
|
|
231
|
+
};
|
|
232
|
+
loop = requestAnimationFrame(tick);
|
|
233
|
+
}
|
|
234
|
+
function stop() {
|
|
235
|
+
if (loop !== null) {
|
|
236
|
+
cancelAnimationFrame(loop);
|
|
237
|
+
loop = null;
|
|
884
238
|
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
239
|
+
}
|
|
240
|
+
function addSlot(slot) {
|
|
241
|
+
slots.add(slot);
|
|
242
|
+
return () => {
|
|
243
|
+
slots.delete(slot);
|
|
244
|
+
if (live) {
|
|
245
|
+
placeVizij(slot.vizijId, { x: 0, y: 0, width: 0, height: 0 });
|
|
889
246
|
}
|
|
890
|
-
}
|
|
891
|
-
return trimmed;
|
|
247
|
+
};
|
|
892
248
|
}
|
|
893
249
|
|
|
894
|
-
// src/
|
|
895
|
-
import {
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
(
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
);
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
);
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
namespace,
|
|
966
|
-
shape.features,
|
|
967
|
-
{
|
|
968
|
-
translation: (pos) => {
|
|
969
|
-
if (ref.current?.position && instanceOfRawVector34(pos)) {
|
|
970
|
-
ref.current.position.set(
|
|
971
|
-
pos.x,
|
|
972
|
-
pos.y,
|
|
973
|
-
pos.z
|
|
974
|
-
);
|
|
975
|
-
}
|
|
976
|
-
if (refGroup.current?.position && instanceOfRawVector34(pos)) {
|
|
977
|
-
refGroup.current.position.set(
|
|
978
|
-
pos.x,
|
|
979
|
-
pos.y,
|
|
980
|
-
pos.z
|
|
981
|
-
);
|
|
982
|
-
}
|
|
983
|
-
},
|
|
984
|
-
rotation: (rot) => {
|
|
985
|
-
if (ref.current?.rotation && instanceOfRawEuler4(rot)) {
|
|
986
|
-
ref.current.rotation.set(rot.x, rot.y, rot.z, "ZYX");
|
|
987
|
-
}
|
|
988
|
-
if (refGroup.current?.rotation && instanceOfRawEuler4(rot)) {
|
|
989
|
-
refGroup.current.rotation.set(rot.x, rot.y, rot.z, "ZYX");
|
|
990
|
-
}
|
|
991
|
-
},
|
|
992
|
-
scale: (scale) => {
|
|
993
|
-
if (ref.current?.scale && instanceOfRawVector34(scale)) {
|
|
994
|
-
ref.current.scale.set(scale.x, scale.y, scale.z);
|
|
995
|
-
} else if (ref.current && instanceOfRawNumber4(scale)) {
|
|
996
|
-
ref.current.scale.set(scale, scale, scale);
|
|
997
|
-
} else if (ref.current) {
|
|
998
|
-
ref.current.scale.set(1, 1, 1);
|
|
999
|
-
}
|
|
1000
|
-
},
|
|
1001
|
-
opacity: (op) => {
|
|
1002
|
-
if (material.current?.opacity !== void 0 && instanceOfRawNumber4(op)) {
|
|
1003
|
-
material.current.opacity = op;
|
|
1004
|
-
if (op < 1) {
|
|
1005
|
-
material.current.transparent = true;
|
|
1006
|
-
} else {
|
|
1007
|
-
material.current.transparent = false;
|
|
1008
|
-
}
|
|
1009
|
-
material.current.needsUpdate = true;
|
|
1010
|
-
}
|
|
1011
|
-
},
|
|
1012
|
-
color: (color) => {
|
|
1013
|
-
if ((material.current || void 0)?.color && instanceOfRawRGB3(color)) {
|
|
1014
|
-
material.current.color.setRGB(
|
|
1015
|
-
color.r,
|
|
1016
|
-
color.g,
|
|
1017
|
-
color.b
|
|
1018
|
-
);
|
|
1019
|
-
material.current.needsUpdate = true;
|
|
1020
|
-
} else if ((material.current || void 0)?.color && instanceOfRawVector34(color)) {
|
|
1021
|
-
material.current.color.setRGB(
|
|
1022
|
-
color.x,
|
|
1023
|
-
color.y,
|
|
1024
|
-
color.z
|
|
1025
|
-
);
|
|
1026
|
-
material.current.needsUpdate = true;
|
|
1027
|
-
} else if (material.current && instanceOfRawHSL3(color)) {
|
|
1028
|
-
material.current.color.setHSL(
|
|
1029
|
-
color.h,
|
|
1030
|
-
color.s,
|
|
1031
|
-
color.l
|
|
1032
|
-
);
|
|
1033
|
-
}
|
|
1034
|
-
},
|
|
1035
|
-
roughness: (value) => {
|
|
1036
|
-
const standard = material.current;
|
|
1037
|
-
if (standard?.roughness !== void 0 && instanceOfRawNumber4(value)) {
|
|
1038
|
-
standard.roughness = value;
|
|
1039
|
-
standard.needsUpdate = true;
|
|
1040
|
-
}
|
|
1041
|
-
},
|
|
1042
|
-
metalness: (value) => {
|
|
1043
|
-
const standard = material.current;
|
|
1044
|
-
if (standard?.metalness !== void 0 && instanceOfRawNumber4(value)) {
|
|
1045
|
-
standard.metalness = value;
|
|
1046
|
-
standard.needsUpdate = true;
|
|
1047
|
-
}
|
|
1048
|
-
},
|
|
1049
|
-
shininess: (value) => {
|
|
1050
|
-
const phong = material.current;
|
|
1051
|
-
if (phong?.shininess !== void 0 && instanceOfRawNumber4(value)) {
|
|
1052
|
-
phong.shininess = value;
|
|
1053
|
-
phong.needsUpdate = true;
|
|
1054
|
-
}
|
|
1055
|
-
},
|
|
1056
|
-
emissive: (value) => {
|
|
1057
|
-
const standard = material.current;
|
|
1058
|
-
if (standard?.emissive && instanceOfRawRGB3(value)) {
|
|
1059
|
-
standard.emissive.setRGB(value.r, value.g, value.b);
|
|
1060
|
-
standard.needsUpdate = true;
|
|
1061
|
-
}
|
|
1062
|
-
},
|
|
1063
|
-
emissiveIntensity: (value) => {
|
|
1064
|
-
const standard = material.current;
|
|
1065
|
-
if (standard?.emissiveIntensity !== void 0 && instanceOfRawNumber4(value)) {
|
|
1066
|
-
standard.emissiveIntensity = value;
|
|
1067
|
-
standard.needsUpdate = true;
|
|
250
|
+
// src/page/vizij.tsx
|
|
251
|
+
import { useEffect as useEffect2, useRef as useRef2, useState } from "react";
|
|
252
|
+
import {
|
|
253
|
+
setSelection,
|
|
254
|
+
setView
|
|
255
|
+
} from "@vizij/runtime";
|
|
256
|
+
|
|
257
|
+
// src/page/loading.tsx
|
|
258
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
259
|
+
function describeLoading(stage) {
|
|
260
|
+
return {
|
|
261
|
+
stage,
|
|
262
|
+
label: loadingLabel(stage),
|
|
263
|
+
fraction: loadingFraction(stage)
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function loadingLabel(stage) {
|
|
267
|
+
switch (stage.stage) {
|
|
268
|
+
case "download":
|
|
269
|
+
return withBytes("Downloading the runtime", stage.loaded, stage.total);
|
|
270
|
+
case "compile":
|
|
271
|
+
return "Compiling the runtime";
|
|
272
|
+
case "start":
|
|
273
|
+
return "Starting the runtime";
|
|
274
|
+
case "mount":
|
|
275
|
+
return "Starting the view";
|
|
276
|
+
case "fetch":
|
|
277
|
+
return withBytes("Loading the face", stage.loaded, stage.total);
|
|
278
|
+
case "load":
|
|
279
|
+
return "Loading the face";
|
|
280
|
+
case "draw":
|
|
281
|
+
return "Drawing the face";
|
|
282
|
+
case "failed":
|
|
283
|
+
return "Loading failed";
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function loadingFraction(stage) {
|
|
287
|
+
if (stage.stage !== "download" && stage.stage !== "fetch") return null;
|
|
288
|
+
if (stage.total === null || stage.total <= 0) return null;
|
|
289
|
+
return Math.min(1, Math.max(0, stage.loaded / stage.total));
|
|
290
|
+
}
|
|
291
|
+
function withBytes(what, loaded, total) {
|
|
292
|
+
if (total === null) {
|
|
293
|
+
return loaded > 0 ? `${what}: ${megabytes(loaded)} MB` : what;
|
|
294
|
+
}
|
|
295
|
+
return `${what}: ${megabytes(loaded)} of ${megabytes(total)} MB`;
|
|
296
|
+
}
|
|
297
|
+
function megabytes(bytes) {
|
|
298
|
+
return (bytes / 1e6).toFixed(1);
|
|
299
|
+
}
|
|
300
|
+
var INDETERMINATE_CSS = `
|
|
301
|
+
@keyframes vizij-loading-slide {
|
|
302
|
+
from { transform: translateX(-100%); }
|
|
303
|
+
to { transform: translateX(250%); }
|
|
304
|
+
}
|
|
305
|
+
[data-vizij-loading-indeterminate] {
|
|
306
|
+
animation: vizij-loading-slide 1.4s ease-in-out infinite;
|
|
307
|
+
}
|
|
308
|
+
@media (prefers-reduced-motion: reduce) {
|
|
309
|
+
[data-vizij-loading-indeterminate] { animation: none; }
|
|
310
|
+
}
|
|
311
|
+
`;
|
|
312
|
+
function DefaultLoadingImage() {
|
|
313
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 1024 1024", width: "64", height: "64", children: [
|
|
314
|
+
/* @__PURE__ */ jsx2("circle", { cx: "447.6", cy: "486.6", r: "400.6", fill: "#50c4b6" }),
|
|
315
|
+
/* @__PURE__ */ jsxs("g", { fillOpacity: "0.894", children: [
|
|
316
|
+
/* @__PURE__ */ jsx2(
|
|
317
|
+
"path",
|
|
318
|
+
{
|
|
319
|
+
fill: "#f56b29",
|
|
320
|
+
d: "M471.3 495.5L846.5 488A14.8 14.8 0 0 1 861.5 503.8L835.3 869.7A60.5 60.5 0 0 1 767.6 925.4L469.8 888.9A14.8 14.8 0 0 1 456.8 874.2L456.8 510.3A14.8 14.8 0 0 1 471.3 495.5Z"
|
|
1068
321
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
322
|
+
),
|
|
323
|
+
/* @__PURE__ */ jsx2(
|
|
324
|
+
"path",
|
|
325
|
+
{
|
|
326
|
+
fill: "#ff9e00",
|
|
327
|
+
d: "M824.3 339L983.4 619.9A14.8 14.8 0 0 1 970.7 642L790 644.2A14.8 14.8 0 0 1 775 628.3L796.7 345.1A14.8 14.8 0 0 1 824.3 339Z"
|
|
1075
328
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
);
|
|
1088
|
-
useEffect5(() => {
|
|
1089
|
-
if (ref.current && refIsNull) setReference(shape.id, namespace, ref);
|
|
1090
|
-
}, [shape.id, namespace, ref, setReference, refIsNull]);
|
|
1091
|
-
useEffect5(() => {
|
|
1092
|
-
if (ref.current) {
|
|
1093
|
-
ref.current.name = shape.name;
|
|
1094
|
-
}
|
|
1095
|
-
}, [shape.name]);
|
|
1096
|
-
useEffect5(() => {
|
|
1097
|
-
if (!material.current) {
|
|
1098
|
-
return;
|
|
1099
|
-
}
|
|
1100
|
-
if (materialName) {
|
|
1101
|
-
material.current.name = materialName;
|
|
1102
|
-
} else if (shape.name) {
|
|
1103
|
-
material.current.name = shape.name;
|
|
1104
|
-
}
|
|
1105
|
-
}, [materialName, shape.name]);
|
|
1106
|
-
const handlePointerOver = useCallback4(
|
|
1107
|
-
(event) => {
|
|
1108
|
-
event.stopPropagation();
|
|
1109
|
-
setHoveredElement({ id, namespace, type: "shape" });
|
|
1110
|
-
},
|
|
1111
|
-
[id, namespace, setHoveredElement]
|
|
1112
|
-
);
|
|
1113
|
-
const handlePointerOut = useCallback4(
|
|
1114
|
-
(event) => {
|
|
1115
|
-
event.stopPropagation();
|
|
1116
|
-
setHoveredElement(null);
|
|
1117
|
-
},
|
|
1118
|
-
[setHoveredElement]
|
|
1119
|
-
);
|
|
1120
|
-
return /* @__PURE__ */ jsxs3(
|
|
1121
|
-
"mesh",
|
|
329
|
+
)
|
|
330
|
+
] })
|
|
331
|
+
] });
|
|
332
|
+
}
|
|
333
|
+
function DefaultLoading({
|
|
334
|
+
loading,
|
|
335
|
+
image
|
|
336
|
+
}) {
|
|
337
|
+
const { stage, label, fraction } = loading;
|
|
338
|
+
return /* @__PURE__ */ jsxs(
|
|
339
|
+
"div",
|
|
1122
340
|
{
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
onClick: (e) => {
|
|
1134
|
-
console.log("Clicked element", shape);
|
|
1135
|
-
onElementClick({ id, type: "shape", namespace }, [...chain, id], e);
|
|
341
|
+
style: {
|
|
342
|
+
width: "100%",
|
|
343
|
+
height: "100%",
|
|
344
|
+
display: "flex",
|
|
345
|
+
flexDirection: "column",
|
|
346
|
+
alignItems: "center",
|
|
347
|
+
justifyContent: "center",
|
|
348
|
+
gap: 12,
|
|
349
|
+
font: "13px/1.4 system-ui, sans-serif",
|
|
350
|
+
textAlign: "center"
|
|
1136
351
|
},
|
|
1137
352
|
children: [
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
353
|
+
image !== null && /* @__PURE__ */ jsx2("div", { "aria-hidden": "true", children: image ?? /* @__PURE__ */ jsx2(DefaultLoadingImage, {}) }),
|
|
354
|
+
stage.stage === "failed" ? /* @__PURE__ */ jsx2("div", { role: "status", children: label }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
355
|
+
/* @__PURE__ */ jsxs(
|
|
356
|
+
"div",
|
|
357
|
+
{
|
|
358
|
+
role: "progressbar",
|
|
359
|
+
"aria-label": "Loading the face",
|
|
360
|
+
"aria-valuetext": label,
|
|
361
|
+
...fraction === null ? {} : {
|
|
362
|
+
"aria-valuemin": 0,
|
|
363
|
+
"aria-valuemax": 100,
|
|
364
|
+
"aria-valuenow": Math.round(fraction * 100)
|
|
365
|
+
},
|
|
366
|
+
style: {
|
|
367
|
+
position: "relative",
|
|
368
|
+
width: 160,
|
|
369
|
+
maxWidth: "60%",
|
|
370
|
+
height: 4,
|
|
371
|
+
borderRadius: 2,
|
|
372
|
+
overflow: "hidden"
|
|
373
|
+
},
|
|
374
|
+
children: [
|
|
375
|
+
/* @__PURE__ */ jsx2(
|
|
376
|
+
"div",
|
|
377
|
+
{
|
|
378
|
+
style: {
|
|
379
|
+
position: "absolute",
|
|
380
|
+
inset: 0,
|
|
381
|
+
background: "currentColor",
|
|
382
|
+
opacity: 0.2
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
),
|
|
386
|
+
fraction === null ? /* @__PURE__ */ jsx2(
|
|
387
|
+
"div",
|
|
388
|
+
{
|
|
389
|
+
"data-vizij-loading-indeterminate": "",
|
|
390
|
+
style: {
|
|
391
|
+
position: "absolute",
|
|
392
|
+
top: 0,
|
|
393
|
+
bottom: 0,
|
|
394
|
+
left: 0,
|
|
395
|
+
width: "40%",
|
|
396
|
+
background: "currentColor"
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
) : /* @__PURE__ */ jsx2(
|
|
400
|
+
"div",
|
|
401
|
+
{
|
|
402
|
+
style: {
|
|
403
|
+
position: "absolute",
|
|
404
|
+
top: 0,
|
|
405
|
+
bottom: 0,
|
|
406
|
+
left: 0,
|
|
407
|
+
width: `${fraction * 100}%`,
|
|
408
|
+
background: "currentColor"
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
)
|
|
412
|
+
]
|
|
413
|
+
}
|
|
414
|
+
),
|
|
415
|
+
/* @__PURE__ */ jsx2("div", { "aria-hidden": "true", style: { opacity: 0.8 }, children: label }),
|
|
416
|
+
fraction === null && /* @__PURE__ */ jsx2("style", { children: INDETERMINATE_CSS })
|
|
417
|
+
] })
|
|
1187
418
|
]
|
|
1188
419
|
}
|
|
1189
420
|
);
|
|
1190
421
|
}
|
|
1191
|
-
var RenderedShape = memo4(InnerRenderedShape);
|
|
1192
422
|
|
|
1193
|
-
// src/
|
|
1194
|
-
import { jsx as
|
|
1195
|
-
function
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
423
|
+
// src/page/vizij.tsx
|
|
424
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
425
|
+
function Vizij({
|
|
426
|
+
vizijId,
|
|
427
|
+
className,
|
|
428
|
+
style,
|
|
429
|
+
toneMapping,
|
|
430
|
+
fit,
|
|
431
|
+
zoom,
|
|
432
|
+
bounds,
|
|
433
|
+
showSafeArea = false,
|
|
434
|
+
selection,
|
|
435
|
+
onPick,
|
|
436
|
+
loadingImage,
|
|
437
|
+
loading
|
|
1199
438
|
}) {
|
|
1200
|
-
const
|
|
1201
|
-
const
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
439
|
+
const element = useRef2(null);
|
|
440
|
+
const frame2 = useRef2(null);
|
|
441
|
+
const outline2 = useRef2(null);
|
|
442
|
+
const slot = useRef2(null);
|
|
443
|
+
useEffect2(() => {
|
|
444
|
+
const registered = {
|
|
445
|
+
vizijId,
|
|
446
|
+
element: element.current,
|
|
447
|
+
safeArea: null,
|
|
448
|
+
onPick: void 0,
|
|
449
|
+
placed: null
|
|
450
|
+
};
|
|
451
|
+
registered.element.setAttribute("data-vizij-ready", "false");
|
|
452
|
+
slot.current = registered;
|
|
453
|
+
const remove = addSlot(registered);
|
|
454
|
+
return () => {
|
|
455
|
+
slot.current = null;
|
|
456
|
+
remove();
|
|
457
|
+
};
|
|
458
|
+
}, [vizijId]);
|
|
459
|
+
useEffect2(() => {
|
|
460
|
+
if (slot.current) slot.current.onPick = onPick;
|
|
461
|
+
}, [onPick, vizijId]);
|
|
462
|
+
useEffect2(() => {
|
|
463
|
+
if (!slot.current) return;
|
|
464
|
+
slot.current.safeArea = showSafeArea && outline2.current && frame2.current ? { outline: outline2.current, frame: frame2.current } : null;
|
|
465
|
+
}, [showSafeArea, vizijId]);
|
|
466
|
+
const view2 = JSON.stringify({ toneMapping, fit, zoom, bounds });
|
|
467
|
+
useEffect2(
|
|
468
|
+
() => onceMounted(() => setView(vizijId, JSON.parse(view2))),
|
|
469
|
+
[vizijId, view2]
|
|
470
|
+
);
|
|
471
|
+
const selected = selection === void 0 ? null : JSON.stringify(selection);
|
|
472
|
+
useEffect2(
|
|
473
|
+
() => selected === null ? void 0 : onceMounted(() => setSelection(vizijId, JSON.parse(selected))),
|
|
474
|
+
[vizijId, selected]
|
|
475
|
+
);
|
|
476
|
+
const stage = useLoadingStage(vizijId);
|
|
477
|
+
const loadingView = stage === null || loading === null ? null : loading ? loading(describeLoading(stage)) : /* @__PURE__ */ jsx3(DefaultLoading, { loading: describeLoading(stage), image: loadingImage });
|
|
478
|
+
return /* @__PURE__ */ jsx3(
|
|
479
|
+
"div",
|
|
480
|
+
{
|
|
481
|
+
ref: element,
|
|
482
|
+
className,
|
|
483
|
+
style,
|
|
484
|
+
"data-vizij-id": vizijId,
|
|
485
|
+
children: (showSafeArea || loadingView !== null) && /* @__PURE__ */ jsxs2(
|
|
486
|
+
"div",
|
|
1218
487
|
{
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
488
|
+
ref: frame2,
|
|
489
|
+
style: {
|
|
490
|
+
position: "relative",
|
|
491
|
+
width: "100%",
|
|
492
|
+
height: "100%",
|
|
493
|
+
pointerEvents: "none"
|
|
494
|
+
},
|
|
495
|
+
children: [
|
|
496
|
+
loadingView !== null && /* @__PURE__ */ jsx3(
|
|
497
|
+
"div",
|
|
498
|
+
{
|
|
499
|
+
"data-vizij-loading": "",
|
|
500
|
+
style: { position: "absolute", inset: 0 },
|
|
501
|
+
children: loadingView
|
|
502
|
+
}
|
|
503
|
+
),
|
|
504
|
+
showSafeArea && /* @__PURE__ */ jsx3(
|
|
505
|
+
"div",
|
|
506
|
+
{
|
|
507
|
+
ref: outline2,
|
|
508
|
+
style: {
|
|
509
|
+
position: "absolute",
|
|
510
|
+
display: "none",
|
|
511
|
+
boxSizing: "border-box",
|
|
512
|
+
border: "2px solid red"
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
)
|
|
516
|
+
]
|
|
517
|
+
}
|
|
518
|
+
)
|
|
519
|
+
}
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
function useLoadingStage(vizijId) {
|
|
523
|
+
const [stage, setStage] = useState(() => loadingStage(vizijId));
|
|
524
|
+
useEffect2(() => watchLoading(vizijId, setStage), [vizijId]);
|
|
525
|
+
return stage;
|
|
526
|
+
}
|
|
527
|
+
function onceMounted(apply) {
|
|
528
|
+
let current = true;
|
|
529
|
+
canvasMounted().then(
|
|
530
|
+
() => {
|
|
531
|
+
if (current) apply();
|
|
532
|
+
},
|
|
533
|
+
() => void 0
|
|
534
|
+
);
|
|
535
|
+
return () => {
|
|
536
|
+
current = false;
|
|
537
|
+
};
|
|
1230
538
|
}
|
|
1231
|
-
var Renderable = memo5(InnerRenderable);
|
|
1232
539
|
|
|
1233
540
|
// src/store.ts
|
|
1234
541
|
import { create } from "zustand";
|
|
1235
542
|
import { subscribeWithSelector } from "zustand/middleware";
|
|
1236
543
|
import { produce, enableMapSet } from "immer";
|
|
1237
|
-
import
|
|
1238
|
-
import { getLookup as getLookup2 } from "@vizij/utils";
|
|
544
|
+
import { getLookup } from "@vizij/utils";
|
|
1239
545
|
|
|
1240
546
|
// src/functions/create-world-element.ts
|
|
1241
547
|
import { createBrowserSafeId } from "@vizij/utils";
|
|
@@ -1298,30 +604,6 @@ function removeFromTree(state, nodesToRemove) {
|
|
|
1298
604
|
});
|
|
1299
605
|
}
|
|
1300
606
|
|
|
1301
|
-
// src/memoryInvestigation.ts
|
|
1302
|
-
function getGlobalMemoryInvestigation() {
|
|
1303
|
-
return globalThis;
|
|
1304
|
-
}
|
|
1305
|
-
function updateRenderState(updater) {
|
|
1306
|
-
const globalObj = getGlobalMemoryInvestigation();
|
|
1307
|
-
if (!globalObj.__VIZIJ_MEMORY_INVESTIGATION__?.enabled) {
|
|
1308
|
-
return;
|
|
1309
|
-
}
|
|
1310
|
-
if (!globalObj.__vizijMemoryDebugState) {
|
|
1311
|
-
globalObj.__vizijMemoryDebugState = {};
|
|
1312
|
-
}
|
|
1313
|
-
if (!globalObj.__vizijMemoryDebugState.render) {
|
|
1314
|
-
globalObj.__vizijMemoryDebugState.render = {};
|
|
1315
|
-
}
|
|
1316
|
-
updater(globalObj.__vizijMemoryDebugState.render);
|
|
1317
|
-
}
|
|
1318
|
-
function recordRenderCounter(key, delta = 1) {
|
|
1319
|
-
updateRenderState((renderState) => {
|
|
1320
|
-
const current = typeof renderState[key] === "number" ? Number(renderState[key]) : 0;
|
|
1321
|
-
renderState[key] = current + delta;
|
|
1322
|
-
});
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
607
|
// src/functions/create-animatable.ts
|
|
1326
608
|
import { createBrowserSafeId as createBrowserSafeId2 } from "@vizij/utils";
|
|
1327
609
|
function createAnimatable(value) {
|
|
@@ -1443,51 +725,16 @@ function createAnimatable(value) {
|
|
|
1443
725
|
}
|
|
1444
726
|
createAnimatable({ type: "euler", name: "Rotation" });
|
|
1445
727
|
|
|
1446
|
-
// src/functions/exportable-bodies.ts
|
|
1447
|
-
function asGroupEntries(world) {
|
|
1448
|
-
return Object.values(world).filter((entry) => entry.type === "group");
|
|
1449
|
-
}
|
|
1450
|
-
function selectExportableGroupEntries(world, filterIds) {
|
|
1451
|
-
const groupEntries = asGroupEntries(world);
|
|
1452
|
-
const filterSet = Array.isArray(filterIds) && filterIds.length > 0 ? new Set(filterIds) : null;
|
|
1453
|
-
if (filterSet) {
|
|
1454
|
-
return groupEntries.filter((entry) => filterSet.has(entry.id));
|
|
1455
|
-
}
|
|
1456
|
-
const rootBoundsGroups = groupEntries.filter(
|
|
1457
|
-
(entry) => Boolean(entry.rootBounds)
|
|
1458
|
-
);
|
|
1459
|
-
if (rootBoundsGroups.length > 0) {
|
|
1460
|
-
return rootBoundsGroups;
|
|
1461
|
-
}
|
|
1462
|
-
const explicitRootGroups = groupEntries.filter(
|
|
1463
|
-
(entry) => entry.root === true
|
|
1464
|
-
);
|
|
1465
|
-
if (explicitRootGroups.length > 0) {
|
|
1466
|
-
return explicitRootGroups;
|
|
1467
|
-
}
|
|
1468
|
-
const topLevelGroups = groupEntries.filter((entry) => !entry.parent);
|
|
1469
|
-
if (topLevelGroups.length > 0) {
|
|
1470
|
-
return topLevelGroups;
|
|
1471
|
-
}
|
|
1472
|
-
return groupEntries;
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1475
728
|
// src/store.ts
|
|
1476
|
-
THREE3.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
1477
729
|
enableMapSet();
|
|
1478
|
-
var VizijSlice = (set,
|
|
1479
|
-
// worldRef: createRef<THREE.Group>(),
|
|
730
|
+
var VizijSlice = (set, _get) => ({
|
|
1480
731
|
world: {},
|
|
1481
|
-
refs: {},
|
|
1482
732
|
animatables: {},
|
|
1483
733
|
values: /* @__PURE__ */ new Map(),
|
|
1484
|
-
renderHit: false,
|
|
1485
734
|
preferences: {
|
|
1486
735
|
damping: false
|
|
1487
736
|
},
|
|
1488
737
|
elementSelection: [],
|
|
1489
|
-
hoveredElement: null,
|
|
1490
|
-
slotConfig: {},
|
|
1491
738
|
clearSelection: () => {
|
|
1492
739
|
set({ elementSelection: [] });
|
|
1493
740
|
},
|
|
@@ -1498,66 +745,6 @@ var VizijSlice = (set, get) => ({
|
|
|
1498
745
|
})
|
|
1499
746
|
);
|
|
1500
747
|
},
|
|
1501
|
-
setHoveredElement: (selection) => {
|
|
1502
|
-
set({ hoveredElement: selection });
|
|
1503
|
-
},
|
|
1504
|
-
onElementClick: (selection, _chain, event) => {
|
|
1505
|
-
event.stopPropagation();
|
|
1506
|
-
const makeKey = (sel) => `${sel.namespace}__${sel.type}__${sel.id}`;
|
|
1507
|
-
const stack = [];
|
|
1508
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1509
|
-
const push = (sel) => {
|
|
1510
|
-
if (!sel) return;
|
|
1511
|
-
if (!sel.id || !sel.namespace || !sel.type) return;
|
|
1512
|
-
const key = makeKey(sel);
|
|
1513
|
-
if (seen.has(key)) return;
|
|
1514
|
-
seen.add(key);
|
|
1515
|
-
stack.push(sel);
|
|
1516
|
-
};
|
|
1517
|
-
const intersections = event.intersections ?? [];
|
|
1518
|
-
intersections.forEach((hit) => {
|
|
1519
|
-
const hitSelection = hit.object?.userData?.selection;
|
|
1520
|
-
push(hitSelection);
|
|
1521
|
-
});
|
|
1522
|
-
if (stack.length === 0) {
|
|
1523
|
-
push(selection);
|
|
1524
|
-
}
|
|
1525
|
-
const stackKeys = new Set(stack.map(makeKey));
|
|
1526
|
-
const primary = stack[0];
|
|
1527
|
-
const primaryKey = makeKey(primary);
|
|
1528
|
-
set(
|
|
1529
|
-
produce((state) => {
|
|
1530
|
-
if (event.metaKey) {
|
|
1531
|
-
const existing = state.elementSelection ?? [];
|
|
1532
|
-
const alreadySelected = existing.some(
|
|
1533
|
-
(item) => makeKey(item) === primaryKey
|
|
1534
|
-
);
|
|
1535
|
-
const existingWithoutStack = existing.filter(
|
|
1536
|
-
(item) => !stackKeys.has(makeKey(item))
|
|
1537
|
-
);
|
|
1538
|
-
if (alreadySelected) {
|
|
1539
|
-
state.elementSelection = existingWithoutStack;
|
|
1540
|
-
} else {
|
|
1541
|
-
state.elementSelection = [...stack, ...existingWithoutStack];
|
|
1542
|
-
}
|
|
1543
|
-
} else {
|
|
1544
|
-
state.elementSelection = stack;
|
|
1545
|
-
}
|
|
1546
|
-
})
|
|
1547
|
-
);
|
|
1548
|
-
},
|
|
1549
|
-
getExportableBodies: (filterIds) => {
|
|
1550
|
-
const worldData = get().world;
|
|
1551
|
-
const candidateGroups = selectExportableGroupEntries(
|
|
1552
|
-
worldData,
|
|
1553
|
-
filterIds
|
|
1554
|
-
);
|
|
1555
|
-
const refs = get().refs;
|
|
1556
|
-
return candidateGroups.flatMap((entry) => {
|
|
1557
|
-
const mounted = Object.values(refs[entry.id] ?? {}).map((ref) => ref.current).find((object) => Boolean(object));
|
|
1558
|
-
return mounted ? [mounted] : [];
|
|
1559
|
-
});
|
|
1560
|
-
},
|
|
1561
748
|
setGeometry: (id, geometry) => {
|
|
1562
749
|
set(
|
|
1563
750
|
produce((state) => {
|
|
@@ -1568,21 +755,12 @@ var VizijSlice = (set, get) => ({
|
|
|
1568
755
|
setValue: (id, namespace, value) => {
|
|
1569
756
|
set(
|
|
1570
757
|
produce((state) => {
|
|
1571
|
-
const lookupId =
|
|
758
|
+
const lookupId = getLookup(namespace, id);
|
|
1572
759
|
if (typeof value === "function") {
|
|
1573
|
-
const current = state.values.get(lookupId);
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
}
|
|
1578
|
-
} else {
|
|
1579
|
-
const animatableLookup = state.animatables[id];
|
|
1580
|
-
const updatedValue = value(
|
|
1581
|
-
animatableLookup !== void 0 ? animatableLookup.default : void 0
|
|
1582
|
-
);
|
|
1583
|
-
if (updatedValue !== void 0) {
|
|
1584
|
-
state.values.set(lookupId, updatedValue);
|
|
1585
|
-
}
|
|
760
|
+
const current = state.values.get(lookupId) ?? state.animatables[id]?.default;
|
|
761
|
+
const updatedValue = value(current);
|
|
762
|
+
if (updatedValue !== void 0) {
|
|
763
|
+
state.values.set(lookupId, updatedValue);
|
|
1586
764
|
}
|
|
1587
765
|
} else {
|
|
1588
766
|
state.values.set(lookupId, value);
|
|
@@ -1597,7 +775,7 @@ var VizijSlice = (set, get) => ({
|
|
|
1597
775
|
set(
|
|
1598
776
|
produce((state) => {
|
|
1599
777
|
writes.forEach(({ id, namespace, value }) => {
|
|
1600
|
-
const lookupId =
|
|
778
|
+
const lookupId = getLookup(namespace, id);
|
|
1601
779
|
state.values.set(lookupId, value);
|
|
1602
780
|
});
|
|
1603
781
|
})
|
|
@@ -1725,36 +903,7 @@ var VizijSlice = (set, get) => ({
|
|
|
1725
903
|
})
|
|
1726
904
|
);
|
|
1727
905
|
},
|
|
1728
|
-
setSlot: (parentId, parentNamespace, childId, childNamespace) => {
|
|
1729
|
-
set(
|
|
1730
|
-
produce((state) => {
|
|
1731
|
-
const parentLookupId = getLookup2(parentNamespace, parentId);
|
|
1732
|
-
const childLookupId = getLookup2(childNamespace, childId);
|
|
1733
|
-
state.slotConfig[parentLookupId] = childLookupId;
|
|
1734
|
-
})
|
|
1735
|
-
);
|
|
1736
|
-
},
|
|
1737
|
-
setSlots: (slots, replace) => {
|
|
1738
|
-
set(
|
|
1739
|
-
produce((state) => {
|
|
1740
|
-
if (replace) {
|
|
1741
|
-
state.slotConfig = slots;
|
|
1742
|
-
} else {
|
|
1743
|
-
state.slotConfig = { ...state.slotConfig, ...slots };
|
|
1744
|
-
}
|
|
1745
|
-
})
|
|
1746
|
-
);
|
|
1747
|
-
},
|
|
1748
|
-
clearSlot: (parentId, parentNamespace) => {
|
|
1749
|
-
set(
|
|
1750
|
-
produce((state) => {
|
|
1751
|
-
const parentLookupId = getLookup2(parentNamespace, parentId);
|
|
1752
|
-
delete state.slotConfig[parentLookupId];
|
|
1753
|
-
})
|
|
1754
|
-
);
|
|
1755
|
-
},
|
|
1756
906
|
setVizij: (scene, animatables) => {
|
|
1757
|
-
recordRenderCounter("rootReplacementCount");
|
|
1758
907
|
set({
|
|
1759
908
|
world: scene,
|
|
1760
909
|
animatables
|
|
@@ -1762,7 +911,6 @@ var VizijSlice = (set, get) => ({
|
|
|
1762
911
|
},
|
|
1763
912
|
addWorldElements(world, animatables, replace) {
|
|
1764
913
|
if (replace) {
|
|
1765
|
-
recordRenderCounter("rootReplacementCount");
|
|
1766
914
|
set({ world, animatables });
|
|
1767
915
|
} else {
|
|
1768
916
|
set((state) => ({
|
|
@@ -1775,14 +923,6 @@ var VizijSlice = (set, get) => ({
|
|
|
1775
923
|
set((state) => ({
|
|
1776
924
|
preferences: { ...state.preferences, ...preferences }
|
|
1777
925
|
}));
|
|
1778
|
-
},
|
|
1779
|
-
setReference: (id, namespace, ref) => {
|
|
1780
|
-
set((state) => ({
|
|
1781
|
-
refs: {
|
|
1782
|
-
...state.refs,
|
|
1783
|
-
[id]: { ...state.refs[id], [namespace]: ref }
|
|
1784
|
-
}
|
|
1785
|
-
}));
|
|
1786
926
|
}
|
|
1787
927
|
});
|
|
1788
928
|
var useDefaultVizijStore = create()(
|
|
@@ -1808,12 +948,6 @@ var ShapeMaterial = /* @__PURE__ */ ((ShapeMaterial2) => {
|
|
|
1808
948
|
})(ShapeMaterial || {});
|
|
1809
949
|
|
|
1810
950
|
// src/types/tone-mapping.ts
|
|
1811
|
-
import {
|
|
1812
|
-
ACESFilmicToneMapping,
|
|
1813
|
-
AgXToneMapping,
|
|
1814
|
-
NeutralToneMapping,
|
|
1815
|
-
NoToneMapping
|
|
1816
|
-
} from "three";
|
|
1817
951
|
var TONE_MAPPING_MODES = [
|
|
1818
952
|
"none",
|
|
1819
953
|
"agx",
|
|
@@ -1825,363 +959,34 @@ var TONE_MAPPING_LABELS = {
|
|
|
1825
959
|
agx: "AgX (Blender)",
|
|
1826
960
|
aces: "ACES Filmic",
|
|
1827
961
|
neutral: "Neutral"
|
|
1828
|
-
};
|
|
1829
|
-
var DEFAULT_TONE_MAPPING_MODE = "none";
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
agx: AgXToneMapping,
|
|
1833
|
-
aces: ACESFilmicToneMapping,
|
|
1834
|
-
neutral: NeutralToneMapping
|
|
1835
|
-
};
|
|
1836
|
-
function isToneMappingMode(value) {
|
|
1837
|
-
return typeof value === "string" && Object.prototype.hasOwnProperty.call(TONE_MAPPING_CONSTANTS, value);
|
|
1838
|
-
}
|
|
1839
|
-
function resolveToneMapping(mode) {
|
|
1840
|
-
if (isToneMappingMode(mode)) {
|
|
1841
|
-
return TONE_MAPPING_CONSTANTS[mode];
|
|
1842
|
-
}
|
|
1843
|
-
return TONE_MAPPING_CONSTANTS[DEFAULT_TONE_MAPPING_MODE];
|
|
1844
|
-
}
|
|
1845
|
-
function normalizeToneMappingMode(value) {
|
|
1846
|
-
return isToneMappingMode(value) ? value : DEFAULT_TONE_MAPPING_MODE;
|
|
1847
|
-
}
|
|
1848
|
-
|
|
1849
|
-
// src/effects/selection-glow-effect.tsx
|
|
1850
|
-
import { Fragment as Fragment3, useEffect as useEffect6, useMemo as useMemo5, useRef as useRef5 } from "react";
|
|
1851
|
-
import { useFrame } from "@react-three/fiber";
|
|
1852
|
-
import { useShallow as useShallow6 } from "zustand/react/shallow";
|
|
1853
|
-
import {
|
|
1854
|
-
AdditiveBlending,
|
|
1855
|
-
Color,
|
|
1856
|
-
EdgesGeometry,
|
|
1857
|
-
LineBasicMaterial,
|
|
1858
|
-
Matrix4,
|
|
1859
|
-
Quaternion,
|
|
1860
|
-
Vector3
|
|
1861
|
-
} from "three";
|
|
1862
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1863
|
-
function SelectionGlowEffect({
|
|
1864
|
-
enabled = false,
|
|
1865
|
-
color = "#ff1010",
|
|
1866
|
-
opacity = 0.9,
|
|
1867
|
-
thresholdAngle = 2
|
|
1868
|
-
}) {
|
|
1869
|
-
const selections = useVizijStore(
|
|
1870
|
-
useShallow6(
|
|
1871
|
-
(state) => enabled ? state.elementSelection ?? [] : []
|
|
1872
|
-
)
|
|
1873
|
-
);
|
|
1874
|
-
if (!enabled || selections.length === 0) {
|
|
1875
|
-
return null;
|
|
1876
|
-
}
|
|
1877
|
-
return /* @__PURE__ */ jsx6(Fragment3, { children: selections.map((selection) => /* @__PURE__ */ jsx6(
|
|
1878
|
-
SelectionOutline,
|
|
1879
|
-
{
|
|
1880
|
-
selection,
|
|
1881
|
-
color: selection.color ?? color,
|
|
1882
|
-
opacity,
|
|
1883
|
-
thresholdAngle
|
|
1884
|
-
},
|
|
1885
|
-
`${selection.namespace}:${selection.id}`
|
|
1886
|
-
)) });
|
|
1887
|
-
}
|
|
1888
|
-
function SelectionOutline({
|
|
1889
|
-
selection,
|
|
1890
|
-
color,
|
|
1891
|
-
opacity,
|
|
1892
|
-
thresholdAngle
|
|
1893
|
-
}) {
|
|
1894
|
-
const target = useVizijStore(
|
|
1895
|
-
useShallow6((state) => {
|
|
1896
|
-
const entry = state.world[selection.id];
|
|
1897
|
-
const ref = state.refs[selection.id]?.[selection.namespace];
|
|
1898
|
-
const geometry = entry?.geometry ?? null;
|
|
1899
|
-
return { ref, geometry };
|
|
1900
|
-
})
|
|
1901
|
-
);
|
|
1902
|
-
const sourceRef = target.ref;
|
|
1903
|
-
const edgesGeometry = useMemo5(() => {
|
|
1904
|
-
if (!target.geometry) return null;
|
|
1905
|
-
const edges = new EdgesGeometry(target.geometry, thresholdAngle);
|
|
1906
|
-
return edges;
|
|
1907
|
-
}, [target.geometry, thresholdAngle]);
|
|
1908
|
-
useEffect6(() => () => edgesGeometry?.dispose(), [edgesGeometry]);
|
|
1909
|
-
const material = useMemo5(() => {
|
|
1910
|
-
const mat = new LineBasicMaterial({
|
|
1911
|
-
color: new Color(color),
|
|
1912
|
-
transparent: true,
|
|
1913
|
-
opacity,
|
|
1914
|
-
blending: AdditiveBlending,
|
|
1915
|
-
depthTest: false,
|
|
1916
|
-
depthWrite: false,
|
|
1917
|
-
toneMapped: false
|
|
1918
|
-
});
|
|
1919
|
-
return mat;
|
|
1920
|
-
}, [color, opacity]);
|
|
1921
|
-
useEffect6(() => () => material.dispose(), [material]);
|
|
1922
|
-
const lineRef = useRef5(null);
|
|
1923
|
-
useFrame(() => {
|
|
1924
|
-
const source = sourceRef?.current;
|
|
1925
|
-
const line = lineRef.current;
|
|
1926
|
-
if (!source || !line) return;
|
|
1927
|
-
copyWorldTransform(source, line);
|
|
1928
|
-
line.visible = source.visible;
|
|
1929
|
-
});
|
|
1930
|
-
if (!sourceRef || !edgesGeometry) {
|
|
1931
|
-
return null;
|
|
1932
|
-
}
|
|
1933
|
-
return /* @__PURE__ */ jsx6(
|
|
1934
|
-
"lineSegments",
|
|
1935
|
-
{
|
|
1936
|
-
ref: lineRef,
|
|
1937
|
-
geometry: edgesGeometry,
|
|
1938
|
-
material,
|
|
1939
|
-
frustumCulled: false,
|
|
1940
|
-
renderOrder: 1e3
|
|
1941
|
-
}
|
|
1942
|
-
);
|
|
1943
|
-
}
|
|
1944
|
-
var tempMatrix = new Matrix4();
|
|
1945
|
-
var tempPosition = new Vector3();
|
|
1946
|
-
var tempQuaternion = new Quaternion();
|
|
1947
|
-
var tempScale = new Vector3();
|
|
1948
|
-
function copyWorldTransform(source, target) {
|
|
1949
|
-
source.updateWorldMatrix(true, false);
|
|
1950
|
-
tempMatrix.copy(source.matrixWorld);
|
|
1951
|
-
tempMatrix.decompose(tempPosition, tempQuaternion, tempScale);
|
|
1952
|
-
target.position.copy(tempPosition);
|
|
1953
|
-
target.quaternion.copy(tempQuaternion);
|
|
1954
|
-
target.scale.copy(tempScale);
|
|
1955
|
-
target.updateMatrix();
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
// src/vizij.tsx
|
|
1959
|
-
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1960
|
-
Object3D4.DEFAULT_UP.set(0, 0, 1);
|
|
1961
|
-
function Vizij({
|
|
1962
|
-
style,
|
|
1963
|
-
className,
|
|
1964
|
-
rootId,
|
|
1965
|
-
namespace = "default",
|
|
1966
|
-
showSafeArea = false,
|
|
1967
|
-
showSelectionGlow = false,
|
|
1968
|
-
toneMapping = "none",
|
|
1969
|
-
onPointerMissed
|
|
1970
|
-
}) {
|
|
1971
|
-
const ctx = useContext3(VizijContext);
|
|
1972
|
-
useEffect7(() => {
|
|
1973
|
-
recordRenderCounter("canvasMountCount");
|
|
1974
|
-
recordRenderCounter("mountedCanvasCount");
|
|
1975
|
-
return () => {
|
|
1976
|
-
recordRenderCounter("mountedCanvasCount", -1);
|
|
1977
|
-
};
|
|
1978
|
-
}, []);
|
|
1979
|
-
if (ctx) {
|
|
1980
|
-
return /* @__PURE__ */ jsx7(
|
|
1981
|
-
Canvas,
|
|
1982
|
-
{
|
|
1983
|
-
shadows: false,
|
|
1984
|
-
style,
|
|
1985
|
-
className,
|
|
1986
|
-
onPointerMissed,
|
|
1987
|
-
gl: {
|
|
1988
|
-
outputColorSpace: SRGBColorSpace,
|
|
1989
|
-
antialias: true
|
|
1990
|
-
},
|
|
1991
|
-
children: /* @__PURE__ */ jsx7(
|
|
1992
|
-
MemoizedInnerVizij,
|
|
1993
|
-
{
|
|
1994
|
-
rootId,
|
|
1995
|
-
namespace,
|
|
1996
|
-
showSafeArea,
|
|
1997
|
-
showSelectionGlow,
|
|
1998
|
-
toneMapping
|
|
1999
|
-
}
|
|
2000
|
-
)
|
|
2001
|
-
}
|
|
2002
|
-
);
|
|
2003
|
-
} else {
|
|
2004
|
-
return /* @__PURE__ */ jsx7(VizijContext.Provider, { value: useDefaultVizijStore, children: /* @__PURE__ */ jsx7(
|
|
2005
|
-
Canvas,
|
|
2006
|
-
{
|
|
2007
|
-
style,
|
|
2008
|
-
className,
|
|
2009
|
-
onPointerMissed,
|
|
2010
|
-
gl: {
|
|
2011
|
-
outputColorSpace: SRGBColorSpace,
|
|
2012
|
-
antialias: true
|
|
2013
|
-
},
|
|
2014
|
-
children: /* @__PURE__ */ jsx7(
|
|
2015
|
-
MemoizedInnerVizij,
|
|
2016
|
-
{
|
|
2017
|
-
rootId,
|
|
2018
|
-
namespace,
|
|
2019
|
-
showSafeArea,
|
|
2020
|
-
showSelectionGlow,
|
|
2021
|
-
toneMapping
|
|
2022
|
-
}
|
|
2023
|
-
)
|
|
2024
|
-
}
|
|
2025
|
-
) });
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
function InnerVizij({
|
|
2029
|
-
rootId,
|
|
2030
|
-
namespace = "default",
|
|
2031
|
-
container,
|
|
2032
|
-
showSafeArea,
|
|
2033
|
-
showSelectionGlow,
|
|
2034
|
-
toneMapping = "none"
|
|
2035
|
-
}) {
|
|
2036
|
-
const sceneParentSizing = container ? {
|
|
2037
|
-
width: container.width * container.resolution,
|
|
2038
|
-
height: container.height * container.resolution
|
|
2039
|
-
} : void 0;
|
|
2040
|
-
return /* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
2041
|
-
/* @__PURE__ */ jsx7("ambientLight", { intensity: Math.PI / 2 }),
|
|
2042
|
-
/* @__PURE__ */ jsx7(ToneMappingController, { mode: toneMapping }),
|
|
2043
|
-
/* @__PURE__ */ jsx7(
|
|
2044
|
-
OrthographicCamera,
|
|
2045
|
-
{
|
|
2046
|
-
makeDefault: true,
|
|
2047
|
-
position: [0, 0, 100],
|
|
2048
|
-
near: 0.1,
|
|
2049
|
-
far: 1e3
|
|
2050
|
-
}
|
|
2051
|
-
),
|
|
2052
|
-
/* @__PURE__ */ jsx7(Suspense, { fallback: null, children: /* @__PURE__ */ jsx7(
|
|
2053
|
-
World,
|
|
2054
|
-
{
|
|
2055
|
-
rootId,
|
|
2056
|
-
namespace,
|
|
2057
|
-
parentSizing: sceneParentSizing
|
|
2058
|
-
}
|
|
2059
|
-
) }),
|
|
2060
|
-
showSelectionGlow && /* @__PURE__ */ jsx7(SelectionGlowEffect, { enabled: true }),
|
|
2061
|
-
showSafeArea && /* @__PURE__ */ jsx7(SafeAreaRenderer, { rootId })
|
|
2062
|
-
] });
|
|
2063
|
-
}
|
|
2064
|
-
var MemoizedInnerVizij = memo6(InnerVizij);
|
|
2065
|
-
function ToneMappingController({ mode }) {
|
|
2066
|
-
const gl = useThree((state) => state.gl);
|
|
2067
|
-
const scene = useThree((state) => state.scene);
|
|
2068
|
-
useEffect7(() => {
|
|
2069
|
-
const resolved = resolveToneMapping(mode);
|
|
2070
|
-
if (gl.toneMapping === resolved) {
|
|
2071
|
-
return;
|
|
2072
|
-
}
|
|
2073
|
-
gl.toneMapping = resolved;
|
|
2074
|
-
scene.traverse((object) => {
|
|
2075
|
-
const material = object.material;
|
|
2076
|
-
if (!material) {
|
|
2077
|
-
return;
|
|
2078
|
-
}
|
|
2079
|
-
if (Array.isArray(material)) {
|
|
2080
|
-
material.forEach((mat) => {
|
|
2081
|
-
mat.needsUpdate = true;
|
|
2082
|
-
});
|
|
2083
|
-
} else {
|
|
2084
|
-
material.needsUpdate = true;
|
|
2085
|
-
}
|
|
2086
|
-
});
|
|
2087
|
-
}, [gl, scene, mode]);
|
|
2088
|
-
return null;
|
|
2089
|
-
}
|
|
2090
|
-
function InnerWorld({
|
|
2091
|
-
rootId,
|
|
2092
|
-
namespace = "default",
|
|
2093
|
-
parentSizing
|
|
2094
|
-
}) {
|
|
2095
|
-
const [present, rootBounds] = useVizijStore(
|
|
2096
|
-
useShallow7((state) => {
|
|
2097
|
-
const group = state.world[rootId];
|
|
2098
|
-
const bounds = group?.rootBounds ?? defaultRootBounds;
|
|
2099
|
-
return [group !== void 0, bounds];
|
|
2100
|
-
})
|
|
2101
|
-
);
|
|
2102
|
-
const { camera, size } = useThree((state) => ({
|
|
2103
|
-
camera: state.camera,
|
|
2104
|
-
size: state.size
|
|
2105
|
-
}));
|
|
2106
|
-
useEffect7(() => {
|
|
2107
|
-
const width = rootBounds.size.x;
|
|
2108
|
-
const height = rootBounds.size.y;
|
|
2109
|
-
if (camera && parentSizing === void 0 && camera.isOrthographicCamera) {
|
|
2110
|
-
const zoom = Math.min(size.width / width, size.height / height);
|
|
2111
|
-
const center = rootBounds.center;
|
|
2112
|
-
if (camera.zoom !== zoom) {
|
|
2113
|
-
camera.zoom = zoom;
|
|
2114
|
-
camera.updateProjectionMatrix();
|
|
2115
|
-
}
|
|
2116
|
-
if (camera.position.x !== center.x || camera.position.y !== center.y) {
|
|
2117
|
-
camera.position.x = center.x;
|
|
2118
|
-
camera.position.y = center.y;
|
|
2119
|
-
camera.updateProjectionMatrix();
|
|
2120
|
-
}
|
|
2121
|
-
} else if (camera && parentSizing !== void 0 && camera.isOrthographicCamera) {
|
|
2122
|
-
const zoom = Math.min(
|
|
2123
|
-
parentSizing.width / width,
|
|
2124
|
-
parentSizing.height / height
|
|
2125
|
-
);
|
|
2126
|
-
const center = rootBounds.center;
|
|
2127
|
-
camera.left = -0.5 * parentSizing.width / zoom + center.x;
|
|
2128
|
-
camera.right = 0.5 * parentSizing.width / zoom + center.x;
|
|
2129
|
-
camera.top = 0.5 * parentSizing.height / zoom + center.y;
|
|
2130
|
-
camera.bottom = -0.5 * parentSizing.height / zoom + center.y;
|
|
2131
|
-
camera.updateProjectionMatrix();
|
|
2132
|
-
}
|
|
2133
|
-
}, [rootBounds, camera, parentSizing, size]);
|
|
2134
|
-
return /* @__PURE__ */ jsxs4(ErrorBoundary, { fallback: null, children: [
|
|
2135
|
-
present && /* @__PURE__ */ jsx7(Renderable, { id: rootId, namespace, chain: [] }),
|
|
2136
|
-
!present && /* @__PURE__ */ jsx7(
|
|
2137
|
-
Text,
|
|
2138
|
-
{
|
|
2139
|
-
position: [0, 0, 0],
|
|
2140
|
-
color: "white",
|
|
2141
|
-
anchorX: "center",
|
|
2142
|
-
anchorY: "middle",
|
|
2143
|
-
fontSize: 0.7,
|
|
2144
|
-
children: "No Output"
|
|
2145
|
-
}
|
|
2146
|
-
)
|
|
2147
|
-
] });
|
|
962
|
+
};
|
|
963
|
+
var DEFAULT_TONE_MAPPING_MODE = "none";
|
|
964
|
+
function isToneMappingMode(value) {
|
|
965
|
+
return typeof value === "string" && TONE_MAPPING_MODES.includes(value);
|
|
2148
966
|
}
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
[right, top, 99],
|
|
2165
|
-
[right, bottom, 99],
|
|
2166
|
-
[left, bottom, 99],
|
|
2167
|
-
[left, top, 99]
|
|
2168
|
-
],
|
|
2169
|
-
color: "red",
|
|
2170
|
-
lineWidth: 2
|
|
2171
|
-
}
|
|
2172
|
-
);
|
|
967
|
+
function normalizeToneMappingMode(value) {
|
|
968
|
+
return isToneMappingMode(value) ? value : DEFAULT_TONE_MAPPING_MODE;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
// src/context.ts
|
|
972
|
+
import { createContext } from "react";
|
|
973
|
+
var VizijContext = createContext(null);
|
|
974
|
+
|
|
975
|
+
// src/hooks/use-vizij-store.ts
|
|
976
|
+
import { useContext } from "react";
|
|
977
|
+
import { useStore } from "zustand";
|
|
978
|
+
function useVizijStore(selector) {
|
|
979
|
+
const store = useContext(VizijContext);
|
|
980
|
+
if (!store) throw new Error("Missing VizijProvider in the tree");
|
|
981
|
+
return useStore(store, selector);
|
|
2173
982
|
}
|
|
2174
|
-
var defaultRootBounds = {
|
|
2175
|
-
center: { x: 0, y: 0 },
|
|
2176
|
-
size: { x: 5, y: 4 }
|
|
2177
|
-
};
|
|
2178
983
|
|
|
2179
984
|
// src/hooks/use-vizij-store-subscription.ts
|
|
2180
|
-
import { useContext as
|
|
985
|
+
import { useContext as useContext2, useEffect as useEffect3 } from "react";
|
|
2181
986
|
function useVizijStoreSubscription(selector, listener) {
|
|
2182
|
-
const store =
|
|
987
|
+
const store = useContext2(VizijContext);
|
|
2183
988
|
if (!store) throw new Error("Missing VizijProvider in the tree");
|
|
2184
|
-
|
|
989
|
+
useEffect3(() => {
|
|
2185
990
|
const initialValue = selector(store.getState());
|
|
2186
991
|
listener(initialValue);
|
|
2187
992
|
return store.subscribe(selector, listener);
|
|
@@ -2189,27 +994,59 @@ function useVizijStoreSubscription(selector, listener) {
|
|
|
2189
994
|
}
|
|
2190
995
|
|
|
2191
996
|
// src/hooks/use-vizij-store-setter.ts
|
|
2192
|
-
import { useContext as
|
|
997
|
+
import { useContext as useContext3 } from "react";
|
|
2193
998
|
function useVizijStoreSetter() {
|
|
2194
|
-
const store =
|
|
999
|
+
const store = useContext3(VizijContext);
|
|
2195
1000
|
if (!store) throw new Error("Missing VizijProvider in the tree");
|
|
2196
1001
|
return store.setState;
|
|
2197
1002
|
}
|
|
2198
1003
|
|
|
2199
1004
|
// src/hooks/use-vizij-store-getter.ts
|
|
2200
|
-
import { useContext as
|
|
1005
|
+
import { useContext as useContext4 } from "react";
|
|
2201
1006
|
function useVizijStoreGetter() {
|
|
2202
|
-
const store =
|
|
1007
|
+
const store = useContext4(VizijContext);
|
|
2203
1008
|
if (!store) throw new Error("Missing VizijProvider in the tree");
|
|
2204
1009
|
return store.getState;
|
|
2205
1010
|
}
|
|
2206
1011
|
|
|
2207
1012
|
// src/functions/load-gltf.ts
|
|
2208
|
-
import * as
|
|
1013
|
+
import * as THREE2 from "three";
|
|
2209
1014
|
import { GLTFLoader, DRACOLoader } from "three-stdlib";
|
|
2210
1015
|
|
|
1016
|
+
// src/memoryInvestigation.ts
|
|
1017
|
+
function getGlobalMemoryInvestigation() {
|
|
1018
|
+
return globalThis;
|
|
1019
|
+
}
|
|
1020
|
+
function updateRenderState(updater) {
|
|
1021
|
+
const globalObj = getGlobalMemoryInvestigation();
|
|
1022
|
+
if (!globalObj.__VIZIJ_MEMORY_INVESTIGATION__?.enabled) {
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
if (!globalObj.__vizijMemoryDebugState) {
|
|
1026
|
+
globalObj.__vizijMemoryDebugState = {};
|
|
1027
|
+
}
|
|
1028
|
+
if (!globalObj.__vizijMemoryDebugState.render) {
|
|
1029
|
+
globalObj.__vizijMemoryDebugState.render = {};
|
|
1030
|
+
}
|
|
1031
|
+
updater(globalObj.__vizijMemoryDebugState.render);
|
|
1032
|
+
}
|
|
1033
|
+
function recordRenderCounter(key, delta = 1) {
|
|
1034
|
+
updateRenderState((renderState) => {
|
|
1035
|
+
const current = typeof renderState[key] === "number" ? Number(renderState[key]) : 0;
|
|
1036
|
+
renderState[key] = current + delta;
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
|
|
2211
1040
|
// src/functions/gltf-loading/traverse-three.ts
|
|
2212
|
-
import * as
|
|
1041
|
+
import * as THREE from "three";
|
|
1042
|
+
|
|
1043
|
+
// src/functions/empty-model-error.ts
|
|
1044
|
+
var EmptyModelError = class extends Error {
|
|
1045
|
+
constructor(message) {
|
|
1046
|
+
super(message);
|
|
1047
|
+
this.name = "EmptyModelError";
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
2213
1050
|
|
|
2214
1051
|
// src/functions/gltf-loading/map-features.ts
|
|
2215
1052
|
function mapFeatures(features) {
|
|
@@ -2234,14 +1071,14 @@ function mapFeatures(features) {
|
|
|
2234
1071
|
}
|
|
2235
1072
|
|
|
2236
1073
|
// src/functions/gltf-loading/import-scene.ts
|
|
2237
|
-
import { Object3D as
|
|
1074
|
+
import { Object3D as Object3D3 } from "three";
|
|
2238
1075
|
|
|
2239
1076
|
// src/functions/gltf-loading/import-group.ts
|
|
2240
|
-
import { Object3D as
|
|
1077
|
+
import { Object3D as Object3D2 } from "three";
|
|
2241
1078
|
import { createBrowserSafeId as createBrowserSafeId5 } from "@vizij/utils";
|
|
2242
1079
|
|
|
2243
1080
|
// src/functions/gltf-loading/import-mesh.ts
|
|
2244
|
-
import { Object3D
|
|
1081
|
+
import { Object3D } from "three";
|
|
2245
1082
|
import { createBrowserSafeId as createBrowserSafeId4 } from "@vizij/utils";
|
|
2246
1083
|
|
|
2247
1084
|
// src/functions/gltf-loading/import-geometry.ts
|
|
@@ -2312,7 +1149,7 @@ function importGeometry(geometry, mesh) {
|
|
|
2312
1149
|
}
|
|
2313
1150
|
|
|
2314
1151
|
// src/functions/gltf-loading/import-mesh.ts
|
|
2315
|
-
|
|
1152
|
+
Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
2316
1153
|
function importMesh(mesh, colorLookup) {
|
|
2317
1154
|
let world = {};
|
|
2318
1155
|
let animatables = {};
|
|
@@ -2569,7 +1406,7 @@ function shouldImportAsGroupChild(child) {
|
|
|
2569
1406
|
}
|
|
2570
1407
|
|
|
2571
1408
|
// src/functions/gltf-loading/import-group.ts
|
|
2572
|
-
|
|
1409
|
+
Object3D2.DEFAULT_UP.set(0, 0, 1);
|
|
2573
1410
|
function importGroup(group, colorLookup, rootBounds) {
|
|
2574
1411
|
let world = {};
|
|
2575
1412
|
let animatables = {};
|
|
@@ -2674,7 +1511,7 @@ function shouldImportAsGroupChild2(child) {
|
|
|
2674
1511
|
}
|
|
2675
1512
|
|
|
2676
1513
|
// src/functions/gltf-loading/import-scene.ts
|
|
2677
|
-
|
|
1514
|
+
Object3D3.DEFAULT_UP.set(0, 0, 1);
|
|
2678
1515
|
function importScene(scene, rootBounds) {
|
|
2679
1516
|
let world = {};
|
|
2680
1517
|
let animatables = {};
|
|
@@ -2689,7 +1526,7 @@ function importScene(scene, rootBounds) {
|
|
|
2689
1526
|
}
|
|
2690
1527
|
|
|
2691
1528
|
// src/functions/gltf-loading/traverse-three.ts
|
|
2692
|
-
|
|
1529
|
+
THREE.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
2693
1530
|
function traverseThree(group, aggressiveImport = false, rootBounds) {
|
|
2694
1531
|
const worldData = {};
|
|
2695
1532
|
const animatableData = {};
|
|
@@ -2763,7 +1600,9 @@ function traverseThree(group, aggressiveImport = false, rootBounds) {
|
|
|
2763
1600
|
} else {
|
|
2764
1601
|
const derivedRootBounds = rootBounds ?? deriveRootBounds(group);
|
|
2765
1602
|
if (!derivedRootBounds) {
|
|
2766
|
-
throw new
|
|
1603
|
+
throw new EmptyModelError(
|
|
1604
|
+
"The GLB has no RobotData and no mesh, ellipse or rectangle to import"
|
|
1605
|
+
);
|
|
2767
1606
|
}
|
|
2768
1607
|
const [newWorldData, newAnimatableData] = importScene(
|
|
2769
1608
|
group,
|
|
@@ -2784,7 +1623,7 @@ var MATERIAL_NAME_FEATURE_KEYS = [
|
|
|
2784
1623
|
"emissiveIntensity",
|
|
2785
1624
|
"specular"
|
|
2786
1625
|
];
|
|
2787
|
-
var
|
|
1626
|
+
var MATERIAL_NAME_SUFFIXES = [
|
|
2788
1627
|
" color",
|
|
2789
1628
|
" colours",
|
|
2790
1629
|
" colour",
|
|
@@ -2858,7 +1697,7 @@ function extractMaterialNameFromFeature(feature) {
|
|
|
2858
1697
|
function stripMaterialSuffixes(name) {
|
|
2859
1698
|
const trimmed = name.trim();
|
|
2860
1699
|
const lowered = trimmed.toLowerCase();
|
|
2861
|
-
for (const suffix of
|
|
1700
|
+
for (const suffix of MATERIAL_NAME_SUFFIXES) {
|
|
2862
1701
|
if (lowered.endsWith(suffix)) {
|
|
2863
1702
|
return trimmed.slice(0, trimmed.length - suffix.length).trim();
|
|
2864
1703
|
}
|
|
@@ -2868,44 +1707,69 @@ function stripMaterialSuffixes(name) {
|
|
|
2868
1707
|
function isStoredAnimatedFeature(feature) {
|
|
2869
1708
|
return Boolean(feature) && typeof feature === "object" && feature.animated === true && "value" in feature;
|
|
2870
1709
|
}
|
|
2871
|
-
|
|
1710
|
+
var TRANSFORM = [
|
|
1711
|
+
["translation", ["x", "y", "z"]],
|
|
1712
|
+
["rotation", ["r", "p", "y"]]
|
|
1713
|
+
];
|
|
1714
|
+
var REQUIRED_FEATURES = {
|
|
1715
|
+
group: TRANSFORM,
|
|
1716
|
+
shape: TRANSFORM,
|
|
1717
|
+
ellipse: [...TRANSFORM, ["width", []], ["height", []]],
|
|
1718
|
+
rectangle: [...TRANSFORM, ["width", []], ["height", []]]
|
|
1719
|
+
};
|
|
1720
|
+
function assertRequiredFeatures(kind, value) {
|
|
2872
1721
|
if (!value || typeof value !== "object") {
|
|
2873
1722
|
throw new Error("Expected object");
|
|
2874
1723
|
}
|
|
2875
|
-
|
|
2876
|
-
|
|
1724
|
+
const missing = REQUIRED_FEATURES[kind].filter(
|
|
1725
|
+
([name, axes]) => !(name in value) && !axes.some((axis) => `${name}.${axis}` in value)
|
|
1726
|
+
).map(([name]) => name);
|
|
1727
|
+
if (missing.length > 0) {
|
|
1728
|
+
throw new Error(
|
|
1729
|
+
`An element of type ${kind} lacks ${missing.join(", ")} in its features`
|
|
1730
|
+
);
|
|
2877
1731
|
}
|
|
2878
1732
|
}
|
|
1733
|
+
function isGroupFeatures(value) {
|
|
1734
|
+
assertRequiredFeatures("group", value);
|
|
1735
|
+
}
|
|
2879
1736
|
function isShapeFeatures(value) {
|
|
2880
|
-
|
|
2881
|
-
throw new Error("Expected object");
|
|
2882
|
-
}
|
|
2883
|
-
if (!["translation", "rotation"].every((key) => key in value)) {
|
|
2884
|
-
throw new Error("Expected translation and rotation keys in features");
|
|
2885
|
-
}
|
|
1737
|
+
assertRequiredFeatures("shape", value);
|
|
2886
1738
|
}
|
|
2887
1739
|
function isEllipseFeatures(value) {
|
|
2888
|
-
|
|
2889
|
-
throw new Error("Expected object");
|
|
2890
|
-
}
|
|
2891
|
-
if (!["translation", "rotation", "height", "width"].every((key) => key in value)) {
|
|
2892
|
-
throw new Error(
|
|
2893
|
-
"Expected translation, rotation, width, and height keys in features"
|
|
2894
|
-
);
|
|
2895
|
-
}
|
|
1740
|
+
assertRequiredFeatures("ellipse", value);
|
|
2896
1741
|
}
|
|
2897
1742
|
function isRectangleFeatures(value) {
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
1743
|
+
assertRequiredFeatures("rectangle", value);
|
|
1744
|
+
}
|
|
1745
|
+
var PRIMITIVE_HALF_EXTENT = {
|
|
1746
|
+
ellipse: 1,
|
|
1747
|
+
rectangle: 0.5
|
|
1748
|
+
};
|
|
1749
|
+
function expandByPrimitives(box, root) {
|
|
1750
|
+
const center = new THREE.Vector3();
|
|
1751
|
+
const half = new THREE.Vector3();
|
|
1752
|
+
root.traverse((object) => {
|
|
1753
|
+
if (object.isMesh) {
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1756
|
+
const type = object.userData?.gltfExtensions?.RobotData?.type;
|
|
1757
|
+
const extent = typeof type === "string" ? PRIMITIVE_HALF_EXTENT[type] : void 0;
|
|
1758
|
+
if (extent === void 0) {
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1761
|
+
const e = object.matrixWorld.elements;
|
|
1762
|
+
const along = type === "ellipse" ? (a, b) => Math.hypot(a, b) : (a, b) => Math.abs(a) + Math.abs(b);
|
|
1763
|
+
half.set(along(e[0], e[4]), along(e[1], e[5]), along(e[2], e[6]));
|
|
1764
|
+
half.multiplyScalar(extent);
|
|
1765
|
+
center.setFromMatrixPosition(object.matrixWorld);
|
|
1766
|
+
box.expandByPoint(center.clone().sub(half));
|
|
1767
|
+
box.expandByPoint(center.clone().add(half));
|
|
1768
|
+
});
|
|
2906
1769
|
}
|
|
2907
1770
|
function deriveRootBounds(group) {
|
|
2908
|
-
const boundingBox = new
|
|
1771
|
+
const boundingBox = new THREE.Box3().setFromObject(group);
|
|
1772
|
+
expandByPrimitives(boundingBox, group);
|
|
2909
1773
|
if (boundingBox.isEmpty()) {
|
|
2910
1774
|
return null;
|
|
2911
1775
|
}
|
|
@@ -3432,30 +2296,24 @@ function extractVizijAnimations(parserJson, clips) {
|
|
|
3432
2296
|
}
|
|
3433
2297
|
|
|
3434
2298
|
// src/functions/load-gltf.ts
|
|
3435
|
-
|
|
2299
|
+
THREE2.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
3436
2300
|
var GLB_MAGIC = 1179937895;
|
|
3437
2301
|
var GLB_VERSION = 2;
|
|
3438
2302
|
var GLB_HEADER_BYTES = 12;
|
|
3439
2303
|
var GLB_CHUNK_HEADER_BYTES = 8;
|
|
3440
2304
|
var GLB_JSON_CHUNK_TYPE = 1313821514;
|
|
3441
|
-
var EmptyModelError = class extends Error {
|
|
3442
|
-
constructor(message) {
|
|
3443
|
-
super(message);
|
|
3444
|
-
this.name = "EmptyModelError";
|
|
3445
|
-
}
|
|
3446
|
-
};
|
|
3447
2305
|
function parseGlbJsonChunk(buffer) {
|
|
3448
2306
|
if (buffer.byteLength < GLB_HEADER_BYTES + GLB_CHUNK_HEADER_BYTES) {
|
|
3449
2307
|
return void 0;
|
|
3450
2308
|
}
|
|
3451
|
-
const
|
|
3452
|
-
const magic =
|
|
3453
|
-
const version =
|
|
2309
|
+
const view2 = new DataView(buffer);
|
|
2310
|
+
const magic = view2.getUint32(0, true);
|
|
2311
|
+
const version = view2.getUint32(4, true);
|
|
3454
2312
|
if (magic !== GLB_MAGIC || version !== GLB_VERSION) {
|
|
3455
2313
|
return void 0;
|
|
3456
2314
|
}
|
|
3457
|
-
const chunkLength =
|
|
3458
|
-
const chunkType =
|
|
2315
|
+
const chunkLength = view2.getUint32(GLB_HEADER_BYTES, true);
|
|
2316
|
+
const chunkType = view2.getUint32(GLB_HEADER_BYTES + 4, true);
|
|
3459
2317
|
if (chunkType !== GLB_JSON_CHUNK_TYPE) {
|
|
3460
2318
|
return void 0;
|
|
3461
2319
|
}
|
|
@@ -3565,8 +2423,8 @@ async function loadGLTFFromBlobWithBundle(blob, aggressiveImport = false, rootBo
|
|
|
3565
2423
|
|
|
3566
2424
|
// src/functions/export.ts
|
|
3567
2425
|
import { GLTFExporter } from "three-stdlib";
|
|
3568
|
-
import * as
|
|
3569
|
-
|
|
2426
|
+
import * as THREE3 from "three";
|
|
2427
|
+
THREE3.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
3570
2428
|
function normalizeExportError(error) {
|
|
3571
2429
|
if (error instanceof Error) {
|
|
3572
2430
|
return error;
|
|
@@ -3662,14 +2520,14 @@ function patchGlbJson(buffer, mutate) {
|
|
|
3662
2520
|
return buffer;
|
|
3663
2521
|
}
|
|
3664
2522
|
const originalBytes = new Uint8Array(buffer);
|
|
3665
|
-
const
|
|
3666
|
-
const magic =
|
|
3667
|
-
const version =
|
|
2523
|
+
const view2 = new DataView(buffer);
|
|
2524
|
+
const magic = view2.getUint32(0, true);
|
|
2525
|
+
const version = view2.getUint32(4, true);
|
|
3668
2526
|
if (magic !== GLB_MAGIC2 || version !== GLB_VERSION2) {
|
|
3669
2527
|
return buffer;
|
|
3670
2528
|
}
|
|
3671
|
-
const jsonChunkLength =
|
|
3672
|
-
const jsonChunkType =
|
|
2529
|
+
const jsonChunkLength = view2.getUint32(GLB_HEADER_BYTES2, true);
|
|
2530
|
+
const jsonChunkType = view2.getUint32(GLB_HEADER_BYTES2 + 4, true);
|
|
3673
2531
|
if (jsonChunkType !== GLB_JSON_CHUNK_TYPE2) {
|
|
3674
2532
|
return buffer;
|
|
3675
2533
|
}
|
|
@@ -3753,9 +2611,9 @@ async function exportScene(root, options = {}) {
|
|
|
3753
2611
|
}
|
|
3754
2612
|
}
|
|
3755
2613
|
}));
|
|
3756
|
-
const exportRoot = root instanceof
|
|
3757
|
-
const exportTarget = exportRoot instanceof
|
|
3758
|
-
const scene = new
|
|
2614
|
+
const exportRoot = root instanceof THREE3.Scene ? root : root.clone(true);
|
|
2615
|
+
const exportTarget = exportRoot instanceof THREE3.Scene ? exportRoot : (() => {
|
|
2616
|
+
const scene = new THREE3.Scene();
|
|
3759
2617
|
scene.name = root.name?.trim() || "Scene";
|
|
3760
2618
|
scene.add(exportRoot);
|
|
3761
2619
|
return scene;
|
|
@@ -3783,17 +2641,171 @@ async function exportScene(root, options = {}) {
|
|
|
3783
2641
|
return sanitizeExportedGlb(gltf, root.name?.trim() || void 0);
|
|
3784
2642
|
}
|
|
3785
2643
|
|
|
2644
|
+
// src/functions/export-animation.ts
|
|
2645
|
+
import {
|
|
2646
|
+
AnimationClip,
|
|
2647
|
+
NumberKeyframeTrack,
|
|
2648
|
+
QuaternionKeyframeTrack,
|
|
2649
|
+
VectorKeyframeTrack
|
|
2650
|
+
} from "three";
|
|
2651
|
+
function findByName(root, name) {
|
|
2652
|
+
let found = null;
|
|
2653
|
+
root.traverse((child) => {
|
|
2654
|
+
if (!found && child.name === name) {
|
|
2655
|
+
found = child;
|
|
2656
|
+
}
|
|
2657
|
+
});
|
|
2658
|
+
return found;
|
|
2659
|
+
}
|
|
2660
|
+
function parseMorphTargetName(trackName) {
|
|
2661
|
+
const match = /\.morphTargetInfluences\[(.+)\]$/.exec(trackName);
|
|
2662
|
+
return match ? match[1] : null;
|
|
2663
|
+
}
|
|
2664
|
+
function createExportAnimation(options) {
|
|
2665
|
+
const { name, duration, tracks, root } = options;
|
|
2666
|
+
const issues = [];
|
|
2667
|
+
const built = [];
|
|
2668
|
+
for (const spec of tracks) {
|
|
2669
|
+
const node = findByName(root, spec.elementName);
|
|
2670
|
+
if (!node) {
|
|
2671
|
+
issues.push({
|
|
2672
|
+
trackName: spec.name,
|
|
2673
|
+
reason: "node-not-found",
|
|
2674
|
+
detail: spec.elementName
|
|
2675
|
+
});
|
|
2676
|
+
continue;
|
|
2677
|
+
}
|
|
2678
|
+
if (spec.values.length !== spec.times.length * spec.stride) {
|
|
2679
|
+
issues.push({
|
|
2680
|
+
trackName: spec.name,
|
|
2681
|
+
reason: "bad-stride",
|
|
2682
|
+
detail: `${spec.values.length} values for ${spec.times.length} times at stride ${spec.stride}`
|
|
2683
|
+
});
|
|
2684
|
+
continue;
|
|
2685
|
+
}
|
|
2686
|
+
if (spec.property === "morphTargetInfluences") {
|
|
2687
|
+
const morphName = parseMorphTargetName(spec.name);
|
|
2688
|
+
const dictionary = node.morphTargetDictionary;
|
|
2689
|
+
if (!morphName || !dictionary || !(morphName in dictionary)) {
|
|
2690
|
+
issues.push({
|
|
2691
|
+
trackName: spec.name,
|
|
2692
|
+
reason: "morph-target-not-found",
|
|
2693
|
+
detail: morphName ?? void 0
|
|
2694
|
+
});
|
|
2695
|
+
continue;
|
|
2696
|
+
}
|
|
2697
|
+
built.push(new NumberKeyframeTrack(spec.name, spec.times, spec.values));
|
|
2698
|
+
continue;
|
|
2699
|
+
}
|
|
2700
|
+
if (spec.property === "quaternion") {
|
|
2701
|
+
built.push(
|
|
2702
|
+
new QuaternionKeyframeTrack(spec.name, spec.times, spec.values)
|
|
2703
|
+
);
|
|
2704
|
+
continue;
|
|
2705
|
+
}
|
|
2706
|
+
built.push(new VectorKeyframeTrack(spec.name, spec.times, spec.values));
|
|
2707
|
+
}
|
|
2708
|
+
if (built.length === 0) {
|
|
2709
|
+
return { animation: null, issues };
|
|
2710
|
+
}
|
|
2711
|
+
return { animation: new AnimationClip(name, duration, built), issues };
|
|
2712
|
+
}
|
|
2713
|
+
|
|
3786
2714
|
// src/functions/build-scene-graph.ts
|
|
3787
|
-
import * as
|
|
2715
|
+
import * as THREE4 from "three";
|
|
3788
2716
|
import {
|
|
3789
|
-
instanceOfRawEuler
|
|
3790
|
-
instanceOfRawHSL
|
|
3791
|
-
instanceOfRawNumber
|
|
3792
|
-
instanceOfRawRGB
|
|
3793
|
-
instanceOfRawVector2
|
|
3794
|
-
instanceOfRawVector3
|
|
2717
|
+
instanceOfRawEuler,
|
|
2718
|
+
instanceOfRawHSL,
|
|
2719
|
+
instanceOfRawNumber,
|
|
2720
|
+
instanceOfRawRGB,
|
|
2721
|
+
instanceOfRawVector2,
|
|
2722
|
+
instanceOfRawVector3
|
|
3795
2723
|
} from "@vizij/utils";
|
|
3796
|
-
|
|
2724
|
+
|
|
2725
|
+
// src/functions/create-stored-features.ts
|
|
2726
|
+
function createStoredFeatures(objectFeatures, animatableValues) {
|
|
2727
|
+
const stored = Object.entries(objectFeatures).map(
|
|
2728
|
+
([key, feat]) => {
|
|
2729
|
+
if (feat.animated) {
|
|
2730
|
+
const storedFeat = {
|
|
2731
|
+
animated: true,
|
|
2732
|
+
value: animatableValues[feat.value],
|
|
2733
|
+
...feat.label ? { label: feat.label } : {}
|
|
2734
|
+
};
|
|
2735
|
+
return [key, storedFeat];
|
|
2736
|
+
}
|
|
2737
|
+
const staticFeature = feat;
|
|
2738
|
+
return [key, staticFeature.label ? { ...staticFeature } : staticFeature];
|
|
2739
|
+
}
|
|
2740
|
+
);
|
|
2741
|
+
return Object.fromEntries(stored);
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
// src/functions/create-stored-data.ts
|
|
2745
|
+
function createStoredRenderable(data, animatableValues) {
|
|
2746
|
+
const { geometry: _geometry, ...stored } = data;
|
|
2747
|
+
const storedFeatures = createStoredFeatures(
|
|
2748
|
+
data.features,
|
|
2749
|
+
animatableValues
|
|
2750
|
+
);
|
|
2751
|
+
return { ...stored, features: storedFeatures };
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2754
|
+
// src/functions/material-name.ts
|
|
2755
|
+
var MATERIAL_FEATURE_KEYS = [
|
|
2756
|
+
"color",
|
|
2757
|
+
"opacity",
|
|
2758
|
+
"roughness",
|
|
2759
|
+
"metalness",
|
|
2760
|
+
"shininess",
|
|
2761
|
+
"emissive",
|
|
2762
|
+
"emissiveIntensity",
|
|
2763
|
+
"specular"
|
|
2764
|
+
];
|
|
2765
|
+
var MATERIAL_NAME_SUFFIXES2 = [
|
|
2766
|
+
" color",
|
|
2767
|
+
" colours",
|
|
2768
|
+
" colour",
|
|
2769
|
+
" opacity",
|
|
2770
|
+
" roughness",
|
|
2771
|
+
" metalness",
|
|
2772
|
+
" shininess",
|
|
2773
|
+
" emissive intensity",
|
|
2774
|
+
" emissive",
|
|
2775
|
+
" specular"
|
|
2776
|
+
];
|
|
2777
|
+
function deriveMaterialName(shape, values) {
|
|
2778
|
+
for (const key of MATERIAL_FEATURE_KEYS) {
|
|
2779
|
+
const feature = shape.features[key];
|
|
2780
|
+
if (feature && feature.animated) {
|
|
2781
|
+
const animatable = values[feature.value];
|
|
2782
|
+
const candidate = extractMaterialName(animatable?.name);
|
|
2783
|
+
if (candidate) {
|
|
2784
|
+
return candidate;
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
return void 0;
|
|
2789
|
+
}
|
|
2790
|
+
function extractMaterialName(name) {
|
|
2791
|
+
if (!name) {
|
|
2792
|
+
return void 0;
|
|
2793
|
+
}
|
|
2794
|
+
const trimmed = name.trim();
|
|
2795
|
+
if (!trimmed) {
|
|
2796
|
+
return void 0;
|
|
2797
|
+
}
|
|
2798
|
+
const lowered = trimmed.toLowerCase();
|
|
2799
|
+
for (const suffix of MATERIAL_NAME_SUFFIXES2) {
|
|
2800
|
+
if (lowered.endsWith(suffix)) {
|
|
2801
|
+
return trimmed.slice(0, trimmed.length - suffix.length).trim();
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
return trimmed;
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2807
|
+
// src/functions/build-scene-graph.ts
|
|
2808
|
+
THREE4.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
3797
2809
|
function buildSceneGraph(world, animatables, rootId) {
|
|
3798
2810
|
const entry = world[rootId];
|
|
3799
2811
|
if (!entry) {
|
|
@@ -3808,10 +2820,13 @@ function buildSceneGraph(world, animatables, rootId) {
|
|
|
3808
2820
|
const robotData = createStoredRenderable(entry, used);
|
|
3809
2821
|
switch (entry.type) {
|
|
3810
2822
|
case "group": {
|
|
3811
|
-
const object = new
|
|
2823
|
+
const object = new THREE4.Group();
|
|
3812
2824
|
object.name = entry.name;
|
|
3813
2825
|
object.userData = { gltfExtensions: { RobotData: robotData } };
|
|
3814
|
-
applyFeatures(entry.features, animatables,
|
|
2826
|
+
applyFeatures(entry.features, animatables, {
|
|
2827
|
+
...groupTransform(object),
|
|
2828
|
+
...perAxisTransform(object, { scale: true })
|
|
2829
|
+
});
|
|
3815
2830
|
for (const child of entry.children) {
|
|
3816
2831
|
object.add(buildSceneGraph(world, animatables, child));
|
|
3817
2832
|
}
|
|
@@ -3824,12 +2839,14 @@ function buildSceneGraph(world, animatables, rootId) {
|
|
|
3824
2839
|
}
|
|
3825
2840
|
const material = createMaterial(entry.material);
|
|
3826
2841
|
material.name = deriveMaterialName(entry, used) ?? entry.name ?? "";
|
|
3827
|
-
const object = new
|
|
2842
|
+
const object = new THREE4.Mesh(geometry, material);
|
|
3828
2843
|
object.name = entry.name;
|
|
3829
2844
|
object.userData = { gltfExtensions: { RobotData: robotData } };
|
|
3830
2845
|
applyFeatures(entry.features, animatables, {
|
|
3831
2846
|
...shapeTransform(object),
|
|
2847
|
+
...perAxisTransform(object, { scale: true }),
|
|
3832
2848
|
...materialFactors(material),
|
|
2849
|
+
...perAxisMaterialFactors(material),
|
|
3833
2850
|
...morphWeights(object, entry)
|
|
3834
2851
|
});
|
|
3835
2852
|
for (const child of entry.children ?? []) {
|
|
@@ -3837,10 +2854,25 @@ function buildSceneGraph(world, animatables, rootId) {
|
|
|
3837
2854
|
}
|
|
3838
2855
|
return object;
|
|
3839
2856
|
}
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
2857
|
+
case "ellipse":
|
|
2858
|
+
case "rectangle": {
|
|
2859
|
+
const object = new THREE4.Group();
|
|
2860
|
+
object.name = entry.name;
|
|
2861
|
+
object.userData = { gltfExtensions: { RobotData: robotData } };
|
|
2862
|
+
const { translation, rotation } = groupTransform(object);
|
|
2863
|
+
applyFeatures(entry.features, animatables, {
|
|
2864
|
+
translation,
|
|
2865
|
+
rotation,
|
|
2866
|
+
...perAxisTransform(object, { scale: false }),
|
|
2867
|
+
width: (value) => {
|
|
2868
|
+
if (instanceOfRawNumber(value)) object.scale.x = value;
|
|
2869
|
+
},
|
|
2870
|
+
height: (value) => {
|
|
2871
|
+
if (instanceOfRawNumber(value)) object.scale.y = value;
|
|
2872
|
+
}
|
|
2873
|
+
});
|
|
2874
|
+
return object;
|
|
2875
|
+
}
|
|
3844
2876
|
}
|
|
3845
2877
|
}
|
|
3846
2878
|
function animatableOf(animatables, id) {
|
|
@@ -3865,28 +2897,29 @@ function applyFeatures(features, animatables, handlers) {
|
|
|
3865
2897
|
function groupTransform(object) {
|
|
3866
2898
|
return {
|
|
3867
2899
|
translation: (value) => {
|
|
3868
|
-
if (
|
|
2900
|
+
if (instanceOfRawVector3(value)) {
|
|
3869
2901
|
object.position.set(value.x, value.y, value.z);
|
|
3870
|
-
} else if (
|
|
2902
|
+
} else if (instanceOfRawVector2(value)) {
|
|
3871
2903
|
object.position.set(value.x, value.y, object.position.z);
|
|
3872
2904
|
}
|
|
3873
2905
|
},
|
|
3874
2906
|
rotation: (value) => {
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
2907
|
+
const euler = eulerOf(value);
|
|
2908
|
+
if (euler) {
|
|
2909
|
+
object.rotation.set(...euler, "ZYX");
|
|
2910
|
+
} else if (instanceOfRawNumber(value)) {
|
|
3878
2911
|
object.rotation.set(0, 0, 0);
|
|
3879
2912
|
object.rotateZ(value);
|
|
3880
2913
|
}
|
|
3881
2914
|
},
|
|
3882
2915
|
scale: (value) => {
|
|
3883
|
-
if (
|
|
2916
|
+
if (instanceOfRawVector3(value)) {
|
|
3884
2917
|
if (value.x === null || value.y === null || value.z === null) {
|
|
3885
2918
|
object.scale.set(0.1, 0.1, 0.1);
|
|
3886
2919
|
} else {
|
|
3887
2920
|
object.scale.set(value.x, value.y, value.z);
|
|
3888
2921
|
}
|
|
3889
|
-
} else if (
|
|
2922
|
+
} else if (instanceOfRawNumber(value)) {
|
|
3890
2923
|
object.scale.set(value, value, value);
|
|
3891
2924
|
} else {
|
|
3892
2925
|
object.scale.set(1, 1, 1);
|
|
@@ -3897,19 +2930,20 @@ function groupTransform(object) {
|
|
|
3897
2930
|
function shapeTransform(object) {
|
|
3898
2931
|
return {
|
|
3899
2932
|
translation: (value) => {
|
|
3900
|
-
if (
|
|
2933
|
+
if (instanceOfRawVector3(value)) {
|
|
3901
2934
|
object.position.set(value.x, value.y, value.z);
|
|
3902
2935
|
}
|
|
3903
2936
|
},
|
|
3904
2937
|
rotation: (value) => {
|
|
3905
|
-
|
|
3906
|
-
|
|
2938
|
+
const euler = eulerOf(value);
|
|
2939
|
+
if (euler) {
|
|
2940
|
+
object.rotation.set(...euler, "ZYX");
|
|
3907
2941
|
}
|
|
3908
2942
|
},
|
|
3909
2943
|
scale: (value) => {
|
|
3910
|
-
if (
|
|
2944
|
+
if (instanceOfRawVector3(value)) {
|
|
3911
2945
|
object.scale.set(value.x, value.y, value.z);
|
|
3912
|
-
} else if (
|
|
2946
|
+
} else if (instanceOfRawNumber(value)) {
|
|
3913
2947
|
object.scale.set(value, value, value);
|
|
3914
2948
|
} else {
|
|
3915
2949
|
object.scale.set(1, 1, 1);
|
|
@@ -3917,12 +2951,64 @@ function shapeTransform(object) {
|
|
|
3917
2951
|
}
|
|
3918
2952
|
};
|
|
3919
2953
|
}
|
|
2954
|
+
function eulerOf(value) {
|
|
2955
|
+
if (instanceOfRawEuler(value)) {
|
|
2956
|
+
return [value.x, value.y, value.z];
|
|
2957
|
+
}
|
|
2958
|
+
const rpy = value;
|
|
2959
|
+
if (rpy !== null && typeof rpy === "object" && typeof rpy.r === "number" && typeof rpy.p === "number" && typeof rpy.y === "number") {
|
|
2960
|
+
return [rpy.r, rpy.p, rpy.y];
|
|
2961
|
+
}
|
|
2962
|
+
return void 0;
|
|
2963
|
+
}
|
|
2964
|
+
function perAxis(name, axes, set) {
|
|
2965
|
+
return Object.fromEntries(
|
|
2966
|
+
axes.map((axis, index) => [
|
|
2967
|
+
`${name}.${axis}`,
|
|
2968
|
+
(value) => {
|
|
2969
|
+
if (instanceOfRawNumber(value)) {
|
|
2970
|
+
set(index, value);
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
])
|
|
2974
|
+
);
|
|
2975
|
+
}
|
|
2976
|
+
function perAxisTransform(object, { scale }) {
|
|
2977
|
+
return {
|
|
2978
|
+
...perAxis("translation", ["x", "y", "z"], (index, value) => {
|
|
2979
|
+
object.position.setComponent(index, value);
|
|
2980
|
+
}),
|
|
2981
|
+
...perAxis("rotation", ["r", "p", "y"], (index, value) => {
|
|
2982
|
+
const euler = [object.rotation.x, object.rotation.y, object.rotation.z];
|
|
2983
|
+
euler[index] = value;
|
|
2984
|
+
object.rotation.set(euler[0], euler[1], euler[2], "ZYX");
|
|
2985
|
+
}),
|
|
2986
|
+
...scale ? perAxis("scale", ["x", "y", "z"], (index, value) => {
|
|
2987
|
+
object.scale.setComponent(index, value);
|
|
2988
|
+
}) : {}
|
|
2989
|
+
};
|
|
2990
|
+
}
|
|
2991
|
+
function perAxisMaterialFactors(material) {
|
|
2992
|
+
const standard = material;
|
|
2993
|
+
const phong = material;
|
|
2994
|
+
const channels = ["r", "g", "b"];
|
|
2995
|
+
const component = (color) => (index, value) => {
|
|
2996
|
+
if (color) {
|
|
2997
|
+
color[channels[index]] = value;
|
|
2998
|
+
}
|
|
2999
|
+
};
|
|
3000
|
+
return {
|
|
3001
|
+
...perAxis("color", channels, component(standard.color)),
|
|
3002
|
+
...perAxis("emissive", channels, component(standard.emissive)),
|
|
3003
|
+
...perAxis("specular", channels, component(phong.specular))
|
|
3004
|
+
};
|
|
3005
|
+
}
|
|
3920
3006
|
function materialFactors(material) {
|
|
3921
3007
|
const standard = material;
|
|
3922
3008
|
const phong = material;
|
|
3923
3009
|
return {
|
|
3924
3010
|
opacity: (value) => {
|
|
3925
|
-
if (
|
|
3011
|
+
if (instanceOfRawNumber(value)) {
|
|
3926
3012
|
material.opacity = value;
|
|
3927
3013
|
material.transparent = value < 1;
|
|
3928
3014
|
}
|
|
@@ -3931,41 +3017,41 @@ function materialFactors(material) {
|
|
|
3931
3017
|
if (!standard.color) {
|
|
3932
3018
|
return;
|
|
3933
3019
|
}
|
|
3934
|
-
if (
|
|
3020
|
+
if (instanceOfRawRGB(value)) {
|
|
3935
3021
|
standard.color.setRGB(value.r, value.g, value.b);
|
|
3936
|
-
} else if (
|
|
3022
|
+
} else if (instanceOfRawVector3(value)) {
|
|
3937
3023
|
standard.color.setRGB(value.x, value.y, value.z);
|
|
3938
|
-
} else if (
|
|
3024
|
+
} else if (instanceOfRawHSL(value)) {
|
|
3939
3025
|
standard.color.setHSL(value.h, value.s, value.l);
|
|
3940
3026
|
}
|
|
3941
3027
|
},
|
|
3942
3028
|
roughness: (value) => {
|
|
3943
|
-
if (standard.roughness !== void 0 &&
|
|
3029
|
+
if (standard.roughness !== void 0 && instanceOfRawNumber(value)) {
|
|
3944
3030
|
standard.roughness = value;
|
|
3945
3031
|
}
|
|
3946
3032
|
},
|
|
3947
3033
|
metalness: (value) => {
|
|
3948
|
-
if (standard.metalness !== void 0 &&
|
|
3034
|
+
if (standard.metalness !== void 0 && instanceOfRawNumber(value)) {
|
|
3949
3035
|
standard.metalness = value;
|
|
3950
3036
|
}
|
|
3951
3037
|
},
|
|
3952
3038
|
shininess: (value) => {
|
|
3953
|
-
if (phong.shininess !== void 0 &&
|
|
3039
|
+
if (phong.shininess !== void 0 && instanceOfRawNumber(value)) {
|
|
3954
3040
|
phong.shininess = value;
|
|
3955
3041
|
}
|
|
3956
3042
|
},
|
|
3957
3043
|
emissive: (value) => {
|
|
3958
|
-
if (standard.emissive &&
|
|
3044
|
+
if (standard.emissive && instanceOfRawRGB(value)) {
|
|
3959
3045
|
standard.emissive.setRGB(value.r, value.g, value.b);
|
|
3960
3046
|
}
|
|
3961
3047
|
},
|
|
3962
3048
|
emissiveIntensity: (value) => {
|
|
3963
|
-
if (standard.emissiveIntensity !== void 0 &&
|
|
3049
|
+
if (standard.emissiveIntensity !== void 0 && instanceOfRawNumber(value)) {
|
|
3964
3050
|
standard.emissiveIntensity = value;
|
|
3965
3051
|
}
|
|
3966
3052
|
},
|
|
3967
3053
|
specular: (value) => {
|
|
3968
|
-
if (phong.specular &&
|
|
3054
|
+
if (phong.specular && instanceOfRawRGB(value)) {
|
|
3969
3055
|
phong.specular.setRGB(value.r, value.g, value.b);
|
|
3970
3056
|
}
|
|
3971
3057
|
}
|
|
@@ -3985,7 +3071,7 @@ function morphWeights(object, shape) {
|
|
|
3985
3071
|
targets.map((target, index) => [
|
|
3986
3072
|
target,
|
|
3987
3073
|
(value) => {
|
|
3988
|
-
if (
|
|
3074
|
+
if (instanceOfRawNumber(value)) {
|
|
3989
3075
|
influences[index] = value;
|
|
3990
3076
|
}
|
|
3991
3077
|
}
|
|
@@ -3993,18 +3079,18 @@ function morphWeights(object, shape) {
|
|
|
3993
3079
|
);
|
|
3994
3080
|
}
|
|
3995
3081
|
function createMaterial(kind) {
|
|
3996
|
-
const parameters = { side:
|
|
3082
|
+
const parameters = { side: THREE4.DoubleSide };
|
|
3997
3083
|
switch (kind) {
|
|
3998
3084
|
case "basic" /* Basic */:
|
|
3999
|
-
return new
|
|
3085
|
+
return new THREE4.MeshBasicMaterial(parameters);
|
|
4000
3086
|
case "lambert" /* Lambert */:
|
|
4001
|
-
return new
|
|
3087
|
+
return new THREE4.MeshLambertMaterial(parameters);
|
|
4002
3088
|
case "phong" /* Phong */:
|
|
4003
|
-
return new
|
|
3089
|
+
return new THREE4.MeshPhongMaterial(parameters);
|
|
4004
3090
|
case "normal" /* Normal */:
|
|
4005
|
-
return new
|
|
3091
|
+
return new THREE4.MeshNormalMaterial(parameters);
|
|
4006
3092
|
case "standard" /* Standard */:
|
|
4007
|
-
return new
|
|
3093
|
+
return new THREE4.MeshStandardMaterial(parameters);
|
|
4008
3094
|
}
|
|
4009
3095
|
}
|
|
4010
3096
|
var SCALAR_KEYS = ["f32", "f64", "i64", "i32", "u64", "u32", "float"];
|
|
@@ -4052,15 +3138,17 @@ function authoredDefault(animatable) {
|
|
|
4052
3138
|
export {
|
|
4053
3139
|
DEFAULT_TONE_MAPPING_MODE,
|
|
4054
3140
|
EmptyModelError,
|
|
4055
|
-
InnerVizij,
|
|
4056
3141
|
ShapeMaterial,
|
|
4057
3142
|
TONE_MAPPING_LABELS,
|
|
4058
3143
|
TONE_MAPPING_MODES,
|
|
4059
3144
|
Vizij,
|
|
3145
|
+
VizijCanvas,
|
|
4060
3146
|
VizijContext,
|
|
4061
3147
|
VizijSlice,
|
|
4062
3148
|
applyVizijBundle,
|
|
4063
3149
|
buildSceneGraph,
|
|
3150
|
+
canvasMounted,
|
|
3151
|
+
createExportAnimation,
|
|
4064
3152
|
createVizijStore,
|
|
4065
3153
|
deriveMorphFeatureKeys,
|
|
4066
3154
|
deriveRootBounds,
|
|
@@ -4075,10 +3163,9 @@ export {
|
|
|
4075
3163
|
parseGlbJsonChunk,
|
|
4076
3164
|
patchGlbJson,
|
|
4077
3165
|
patchVizijBundleMetadata,
|
|
4078
|
-
resolveToneMapping,
|
|
4079
3166
|
sanitizeMorphKey,
|
|
3167
|
+
setVizijProgress,
|
|
4080
3168
|
useDefaultVizijStore,
|
|
4081
|
-
useFeatures,
|
|
4082
3169
|
useVizijStore,
|
|
4083
3170
|
useVizijStoreGetter,
|
|
4084
3171
|
useVizijStoreSetter,
|