@react-three/fiber 10.0.0-alpha.1 → 10.0.0-canary.1b98c17
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/LICENSE +21 -21
- package/dist/index.cjs +1499 -614
- package/dist/index.d.cts +2130 -1274
- package/dist/index.d.mts +2130 -1274
- package/dist/index.d.ts +2130 -1274
- package/dist/index.mjs +1483 -618
- package/dist/legacy.cjs +1481 -621
- package/dist/legacy.d.cts +2131 -1275
- package/dist/legacy.d.mts +2131 -1275
- package/dist/legacy.d.ts +2131 -1275
- package/dist/legacy.mjs +1465 -625
- package/dist/webgpu/index.cjs +2098 -601
- package/dist/webgpu/index.d.cts +2391 -1300
- package/dist/webgpu/index.d.mts +2391 -1300
- package/dist/webgpu/index.d.ts +2391 -1300
- package/dist/webgpu/index.mjs +2074 -604
- package/package.json +7 -5
- package/react-reconciler/constants.js +1 -9
- package/react-reconciler/index.js +4 -20
- package/readme.md +244 -318
package/dist/webgpu/index.mjs
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import * as webgpu from 'three/webgpu';
|
|
2
|
-
import { RenderTarget, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1,
|
|
2
|
+
import { RenderTarget, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, Scene, WebGLCubeRenderTarget, HalfFloatType, Color, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, SRGBColorSpace, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1, CanvasTarget, Raycaster, OrthographicCamera, PerspectiveCamera, PCFShadowMap, VSMShadowMap, BasicShadowMap, ACESFilmicToneMapping, WebGPURenderer, Vector4, PostProcessing } from 'three/webgpu';
|
|
3
3
|
import { Inspector } from 'three/addons/inspector/Inspector.js';
|
|
4
|
-
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
4
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
5
5
|
import * as React from 'react';
|
|
6
|
-
import React__default, {
|
|
6
|
+
import React__default, { useLayoutEffect, useRef, useMemo, useEffect, useContext, useImperativeHandle, useCallback, useState } from 'react';
|
|
7
7
|
import useMeasure from 'react-use-measure';
|
|
8
8
|
import { useFiber, useContextBridge, traverseFiber, FiberProvider } from 'its-fine';
|
|
9
|
+
import { useThree as useThree$1, useLoader as useLoader$1, useFrame as useFrame$1, createPortal as createPortal$1, applyProps as applyProps$1, extend as extend$1 } from '@react-three/fiber';
|
|
10
|
+
import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
|
|
11
|
+
import { HDRLoader } from 'three/examples/jsm/loaders/HDRLoader.js';
|
|
12
|
+
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
|
|
13
|
+
import { UltraHDRLoader } from 'three/examples/jsm/loaders/UltraHDRLoader.js';
|
|
14
|
+
import { GainMapLoader } from '@monogrid/gainmap-js';
|
|
9
15
|
import Tb, { unstable_scheduleCallback, unstable_IdlePriority } from 'scheduler';
|
|
10
16
|
import { createWithEqualityFn } from 'zustand/traditional';
|
|
11
17
|
import { suspend, preload, clear } from 'suspend-react';
|
|
@@ -46,9 +52,392 @@ const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
|
46
52
|
WebGLRenderer: WebGLRenderer
|
|
47
53
|
}, [webgpu]);
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
56
|
+
const pendingSubscribers = /* @__PURE__ */ new Map();
|
|
57
|
+
function registerPrimary(id, renderer, store) {
|
|
58
|
+
if (primaryRegistry.has(id)) {
|
|
59
|
+
console.warn(`Canvas with id="${id}" already registered. Overwriting.`);
|
|
60
|
+
}
|
|
61
|
+
const entry = { renderer, store };
|
|
62
|
+
primaryRegistry.set(id, entry);
|
|
63
|
+
const subscribers = pendingSubscribers.get(id);
|
|
64
|
+
if (subscribers) {
|
|
65
|
+
subscribers.forEach((callback) => callback(entry));
|
|
66
|
+
pendingSubscribers.delete(id);
|
|
67
|
+
}
|
|
68
|
+
return () => {
|
|
69
|
+
const currentEntry = primaryRegistry.get(id);
|
|
70
|
+
if (currentEntry?.renderer === renderer) {
|
|
71
|
+
primaryRegistry.delete(id);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function getPrimary(id) {
|
|
76
|
+
return primaryRegistry.get(id);
|
|
77
|
+
}
|
|
78
|
+
function waitForPrimary(id, timeout = 5e3) {
|
|
79
|
+
const existing = primaryRegistry.get(id);
|
|
80
|
+
if (existing) {
|
|
81
|
+
return Promise.resolve(existing);
|
|
82
|
+
}
|
|
83
|
+
return new Promise((resolve, reject) => {
|
|
84
|
+
const timeoutId = setTimeout(() => {
|
|
85
|
+
const subscribers = pendingSubscribers.get(id);
|
|
86
|
+
if (subscribers) {
|
|
87
|
+
const index = subscribers.indexOf(callback);
|
|
88
|
+
if (index !== -1) subscribers.splice(index, 1);
|
|
89
|
+
if (subscribers.length === 0) pendingSubscribers.delete(id);
|
|
90
|
+
}
|
|
91
|
+
reject(new Error(`Timeout waiting for canvas with id="${id}". Make sure a <Canvas id="${id}"> is mounted.`));
|
|
92
|
+
}, timeout);
|
|
93
|
+
const callback = (entry) => {
|
|
94
|
+
clearTimeout(timeoutId);
|
|
95
|
+
resolve(entry);
|
|
96
|
+
};
|
|
97
|
+
if (!pendingSubscribers.has(id)) {
|
|
98
|
+
pendingSubscribers.set(id, []);
|
|
99
|
+
}
|
|
100
|
+
pendingSubscribers.get(id).push(callback);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function hasPrimary(id) {
|
|
104
|
+
return primaryRegistry.has(id);
|
|
105
|
+
}
|
|
106
|
+
function unregisterPrimary(id) {
|
|
107
|
+
primaryRegistry.delete(id);
|
|
108
|
+
}
|
|
109
|
+
function getPrimaryIds() {
|
|
110
|
+
return Array.from(primaryRegistry.keys());
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const presetsObj = {
|
|
114
|
+
apartment: "lebombo_1k.hdr",
|
|
115
|
+
city: "potsdamer_platz_1k.hdr",
|
|
116
|
+
dawn: "kiara_1_dawn_1k.hdr",
|
|
117
|
+
forest: "forest_slope_1k.hdr",
|
|
118
|
+
lobby: "st_fagans_interior_1k.hdr",
|
|
119
|
+
night: "dikhololo_night_1k.hdr",
|
|
120
|
+
park: "rooitou_park_1k.hdr",
|
|
121
|
+
studio: "studio_small_03_1k.hdr",
|
|
122
|
+
sunset: "venice_sunset_1k.hdr",
|
|
123
|
+
warehouse: "empty_warehouse_01_1k.hdr"
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
|
|
127
|
+
const isArray = (arr) => Array.isArray(arr);
|
|
128
|
+
const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
|
|
129
|
+
function useEnvironment({
|
|
130
|
+
files = defaultFiles,
|
|
131
|
+
path = "",
|
|
132
|
+
preset = void 0,
|
|
133
|
+
colorSpace = void 0,
|
|
134
|
+
extensions
|
|
135
|
+
} = {}) {
|
|
136
|
+
if (preset) {
|
|
137
|
+
validatePreset(preset);
|
|
138
|
+
files = presetsObj[preset];
|
|
139
|
+
path = CUBEMAP_ROOT;
|
|
140
|
+
}
|
|
141
|
+
const multiFile = isArray(files);
|
|
142
|
+
const { extension, isCubemap } = getExtension(files);
|
|
143
|
+
const loader = getLoader$1(extension);
|
|
144
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
145
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
146
|
+
useLayoutEffect(() => {
|
|
147
|
+
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
148
|
+
function clearGainmapTexture() {
|
|
149
|
+
useLoader$1.clear(loader, multiFile ? [files] : files);
|
|
150
|
+
}
|
|
151
|
+
renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
|
|
152
|
+
}, [extension, files, loader, multiFile, renderer.domElement]);
|
|
153
|
+
const loaderResult = useLoader$1(
|
|
154
|
+
loader,
|
|
155
|
+
multiFile ? [files] : files,
|
|
156
|
+
(loader2) => {
|
|
157
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
158
|
+
loader2.setRenderer?.(renderer);
|
|
159
|
+
}
|
|
160
|
+
loader2.setPath?.(path);
|
|
161
|
+
if (extensions) extensions(loader2);
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
let texture = multiFile ? (
|
|
165
|
+
// @ts-ignore
|
|
166
|
+
loaderResult[0]
|
|
167
|
+
) : loaderResult;
|
|
168
|
+
if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
|
|
169
|
+
texture = texture.renderTarget?.texture;
|
|
170
|
+
}
|
|
171
|
+
texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
|
|
172
|
+
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
173
|
+
return texture;
|
|
174
|
+
}
|
|
175
|
+
const preloadDefaultOptions = {
|
|
176
|
+
files: defaultFiles,
|
|
177
|
+
path: "",
|
|
178
|
+
preset: void 0,
|
|
179
|
+
extensions: void 0
|
|
180
|
+
};
|
|
181
|
+
useEnvironment.preload = (preloadOptions) => {
|
|
182
|
+
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
183
|
+
let { files, path = "" } = options;
|
|
184
|
+
const { preset, extensions } = options;
|
|
185
|
+
if (preset) {
|
|
186
|
+
validatePreset(preset);
|
|
187
|
+
files = presetsObj[preset];
|
|
188
|
+
path = CUBEMAP_ROOT;
|
|
189
|
+
}
|
|
190
|
+
const { extension } = getExtension(files);
|
|
191
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
192
|
+
throw new Error("useEnvironment: Preloading gainmaps is not supported");
|
|
193
|
+
}
|
|
194
|
+
const loader = getLoader$1(extension);
|
|
195
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
196
|
+
useLoader$1.preload(loader, isArray(files) ? [files] : files, (loader2) => {
|
|
197
|
+
loader2.setPath?.(path);
|
|
198
|
+
if (extensions) extensions(loader2);
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
const clearDefaultOptins = {
|
|
202
|
+
files: defaultFiles,
|
|
203
|
+
preset: void 0
|
|
204
|
+
};
|
|
205
|
+
useEnvironment.clear = (clearOptions) => {
|
|
206
|
+
const options = { ...clearDefaultOptins, ...clearOptions };
|
|
207
|
+
let { files } = options;
|
|
208
|
+
const { preset } = options;
|
|
209
|
+
if (preset) {
|
|
210
|
+
validatePreset(preset);
|
|
211
|
+
files = presetsObj[preset];
|
|
212
|
+
}
|
|
213
|
+
const { extension } = getExtension(files);
|
|
214
|
+
const loader = getLoader$1(extension);
|
|
215
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
216
|
+
useLoader$1.clear(loader, isArray(files) ? [files] : files);
|
|
217
|
+
};
|
|
218
|
+
function validatePreset(preset) {
|
|
219
|
+
if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
|
|
220
|
+
}
|
|
221
|
+
function getExtension(files) {
|
|
222
|
+
const isCubemap = isArray(files) && files.length === 6;
|
|
223
|
+
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
224
|
+
const firstEntry = isArray(files) ? files[0] : files;
|
|
225
|
+
const extension = isCubemap ? "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
226
|
+
return { extension, isCubemap, isGainmap };
|
|
227
|
+
}
|
|
228
|
+
function getLoader$1(extension) {
|
|
229
|
+
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
230
|
+
return loader;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const isRef$1 = (obj) => obj.current && obj.current.isScene;
|
|
234
|
+
const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
|
|
235
|
+
function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
|
|
236
|
+
sceneProps = {
|
|
237
|
+
backgroundBlurriness: 0,
|
|
238
|
+
backgroundIntensity: 1,
|
|
239
|
+
backgroundRotation: [0, 0, 0],
|
|
240
|
+
environmentIntensity: 1,
|
|
241
|
+
environmentRotation: [0, 0, 0],
|
|
242
|
+
...sceneProps
|
|
243
|
+
};
|
|
244
|
+
const target = resolveScene(scene || defaultScene);
|
|
245
|
+
const oldbg = target.background;
|
|
246
|
+
const oldenv = target.environment;
|
|
247
|
+
const oldSceneProps = {
|
|
248
|
+
// @ts-ignore
|
|
249
|
+
backgroundBlurriness: target.backgroundBlurriness,
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
backgroundIntensity: target.backgroundIntensity,
|
|
252
|
+
// @ts-ignore
|
|
253
|
+
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
254
|
+
// @ts-ignore
|
|
255
|
+
environmentIntensity: target.environmentIntensity,
|
|
256
|
+
// @ts-ignore
|
|
257
|
+
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
258
|
+
};
|
|
259
|
+
if (background !== "only") target.environment = texture;
|
|
260
|
+
if (background) target.background = texture;
|
|
261
|
+
applyProps$1(target, sceneProps);
|
|
262
|
+
return () => {
|
|
263
|
+
if (background !== "only") target.environment = oldenv;
|
|
264
|
+
if (background) target.background = oldbg;
|
|
265
|
+
applyProps$1(target, oldSceneProps);
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
function EnvironmentMap({ scene, background = false, map, ...config }) {
|
|
269
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
270
|
+
React.useLayoutEffect(() => {
|
|
271
|
+
if (map) return setEnvProps(background, scene, defaultScene, map, config);
|
|
272
|
+
});
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
function EnvironmentCube({
|
|
276
|
+
background = false,
|
|
277
|
+
scene,
|
|
278
|
+
blur,
|
|
279
|
+
backgroundBlurriness,
|
|
280
|
+
backgroundIntensity,
|
|
281
|
+
backgroundRotation,
|
|
282
|
+
environmentIntensity,
|
|
283
|
+
environmentRotation,
|
|
284
|
+
...rest
|
|
285
|
+
}) {
|
|
286
|
+
const texture = useEnvironment(rest);
|
|
287
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
288
|
+
React.useLayoutEffect(() => {
|
|
289
|
+
return setEnvProps(background, scene, defaultScene, texture, {
|
|
290
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
291
|
+
backgroundIntensity,
|
|
292
|
+
backgroundRotation,
|
|
293
|
+
environmentIntensity,
|
|
294
|
+
environmentRotation
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
React.useEffect(() => {
|
|
298
|
+
return () => {
|
|
299
|
+
texture.dispose();
|
|
300
|
+
};
|
|
301
|
+
}, [texture]);
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
function EnvironmentPortal({
|
|
305
|
+
children,
|
|
306
|
+
near = 0.1,
|
|
307
|
+
far = 1e3,
|
|
308
|
+
resolution = 256,
|
|
309
|
+
frames = 1,
|
|
310
|
+
map,
|
|
311
|
+
background = false,
|
|
312
|
+
blur,
|
|
313
|
+
backgroundBlurriness,
|
|
314
|
+
backgroundIntensity,
|
|
315
|
+
backgroundRotation,
|
|
316
|
+
environmentIntensity,
|
|
317
|
+
environmentRotation,
|
|
318
|
+
scene,
|
|
319
|
+
files,
|
|
320
|
+
path,
|
|
321
|
+
preset = void 0,
|
|
322
|
+
extensions
|
|
323
|
+
}) {
|
|
324
|
+
const gl = useThree$1((state) => state.gl);
|
|
325
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
326
|
+
const camera = React.useRef(null);
|
|
327
|
+
const [virtualScene] = React.useState(() => new Scene());
|
|
328
|
+
const fbo = React.useMemo(() => {
|
|
329
|
+
const fbo2 = new WebGLCubeRenderTarget(resolution);
|
|
330
|
+
fbo2.texture.type = HalfFloatType;
|
|
331
|
+
return fbo2;
|
|
332
|
+
}, [resolution]);
|
|
333
|
+
React.useEffect(() => {
|
|
334
|
+
return () => {
|
|
335
|
+
fbo.dispose();
|
|
336
|
+
};
|
|
337
|
+
}, [fbo]);
|
|
338
|
+
React.useLayoutEffect(() => {
|
|
339
|
+
if (frames === 1) {
|
|
340
|
+
const autoClear = gl.autoClear;
|
|
341
|
+
gl.autoClear = true;
|
|
342
|
+
camera.current.update(gl, virtualScene);
|
|
343
|
+
gl.autoClear = autoClear;
|
|
344
|
+
}
|
|
345
|
+
return setEnvProps(background, scene, defaultScene, fbo.texture, {
|
|
346
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
347
|
+
backgroundIntensity,
|
|
348
|
+
backgroundRotation,
|
|
349
|
+
environmentIntensity,
|
|
350
|
+
environmentRotation
|
|
351
|
+
});
|
|
352
|
+
}, [
|
|
353
|
+
children,
|
|
354
|
+
virtualScene,
|
|
355
|
+
fbo.texture,
|
|
356
|
+
scene,
|
|
357
|
+
defaultScene,
|
|
358
|
+
background,
|
|
359
|
+
frames,
|
|
360
|
+
gl,
|
|
361
|
+
blur,
|
|
362
|
+
backgroundBlurriness,
|
|
363
|
+
backgroundIntensity,
|
|
364
|
+
backgroundRotation,
|
|
365
|
+
environmentIntensity,
|
|
366
|
+
environmentRotation
|
|
367
|
+
]);
|
|
368
|
+
let count = 1;
|
|
369
|
+
useFrame$1(() => {
|
|
370
|
+
if (frames === Infinity || count < frames) {
|
|
371
|
+
const autoClear = gl.autoClear;
|
|
372
|
+
gl.autoClear = true;
|
|
373
|
+
camera.current.update(gl, virtualScene);
|
|
374
|
+
gl.autoClear = autoClear;
|
|
375
|
+
count++;
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
return /* @__PURE__ */ jsx(Fragment, { children: createPortal$1(
|
|
379
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
380
|
+
children,
|
|
381
|
+
/* @__PURE__ */ jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
|
|
382
|
+
files || preset ? /* @__PURE__ */ jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsx(EnvironmentMap, { background: true, map, extensions }) : null
|
|
383
|
+
] }),
|
|
384
|
+
virtualScene
|
|
385
|
+
) });
|
|
386
|
+
}
|
|
387
|
+
function EnvironmentGround(props) {
|
|
388
|
+
const textureDefault = useEnvironment(props);
|
|
389
|
+
const texture = props.map || textureDefault;
|
|
390
|
+
React.useMemo(() => extend$1({ GroundProjectedEnvImpl: GroundedSkybox }), []);
|
|
391
|
+
React.useEffect(() => {
|
|
392
|
+
return () => {
|
|
393
|
+
textureDefault.dispose();
|
|
394
|
+
};
|
|
395
|
+
}, [textureDefault]);
|
|
396
|
+
const height = props.ground?.height ?? 15;
|
|
397
|
+
const radius = props.ground?.radius ?? 60;
|
|
398
|
+
const scale = props.ground?.scale ?? 1e3;
|
|
399
|
+
const args = React.useMemo(
|
|
400
|
+
() => [texture, height, radius],
|
|
401
|
+
[texture, height, radius]
|
|
402
|
+
);
|
|
403
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
404
|
+
/* @__PURE__ */ jsx(EnvironmentMap, { ...props, map: texture }),
|
|
405
|
+
/* @__PURE__ */ jsx("groundProjectedEnvImpl", { args, scale })
|
|
406
|
+
] });
|
|
407
|
+
}
|
|
408
|
+
function EnvironmentColor({ color, scene }) {
|
|
409
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
410
|
+
React.useLayoutEffect(() => {
|
|
411
|
+
if (color === void 0) return;
|
|
412
|
+
const target = resolveScene(scene || defaultScene);
|
|
413
|
+
const oldBg = target.background;
|
|
414
|
+
target.background = new Color(color);
|
|
415
|
+
return () => {
|
|
416
|
+
target.background = oldBg;
|
|
417
|
+
};
|
|
418
|
+
});
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
function EnvironmentDualSource(props) {
|
|
422
|
+
const { backgroundFiles, ...envProps } = props;
|
|
423
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
424
|
+
/* @__PURE__ */ jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
425
|
+
/* @__PURE__ */ jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
|
|
426
|
+
] });
|
|
427
|
+
}
|
|
428
|
+
function Environment(props) {
|
|
429
|
+
if (props.color && !props.files && !props.preset && !props.map) {
|
|
430
|
+
return /* @__PURE__ */ jsx(EnvironmentColor, { ...props });
|
|
431
|
+
}
|
|
432
|
+
if (props.backgroundFiles && props.backgroundFiles !== props.files) {
|
|
433
|
+
return /* @__PURE__ */ jsx(EnvironmentDualSource, { ...props });
|
|
434
|
+
}
|
|
435
|
+
return props.ground ? /* @__PURE__ */ jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsx(EnvironmentCube, { ...props });
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
var __defProp$3 = Object.defineProperty;
|
|
439
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
440
|
+
var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
52
441
|
const act = React["act"];
|
|
53
442
|
const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React.useLayoutEffect : React.useEffect;
|
|
54
443
|
function useMutableCallback(fn) {
|
|
@@ -80,7 +469,7 @@ const ErrorBoundary = /* @__PURE__ */ (() => {
|
|
|
80
469
|
return _a = class extends React.Component {
|
|
81
470
|
constructor() {
|
|
82
471
|
super(...arguments);
|
|
83
|
-
__publicField$
|
|
472
|
+
__publicField$3(this, "state", { error: false });
|
|
84
473
|
}
|
|
85
474
|
componentDidCatch(err) {
|
|
86
475
|
this.props.set(err);
|
|
@@ -88,7 +477,7 @@ const ErrorBoundary = /* @__PURE__ */ (() => {
|
|
|
88
477
|
render() {
|
|
89
478
|
return this.state.error ? null : this.props.children;
|
|
90
479
|
}
|
|
91
|
-
}, __publicField$
|
|
480
|
+
}, __publicField$3(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
|
|
92
481
|
})();
|
|
93
482
|
|
|
94
483
|
const is = {
|
|
@@ -225,7 +614,8 @@ function prepare(target, root, type, props) {
|
|
|
225
614
|
object,
|
|
226
615
|
eventCount: 0,
|
|
227
616
|
handlers: {},
|
|
228
|
-
isHidden: false
|
|
617
|
+
isHidden: false,
|
|
618
|
+
deferredRefs: []
|
|
229
619
|
};
|
|
230
620
|
if (object) object.__r3f = instance;
|
|
231
621
|
}
|
|
@@ -274,7 +664,7 @@ function createOcclusionObserverNode(store, uniform) {
|
|
|
274
664
|
let occlusionSetupPromise = null;
|
|
275
665
|
function enableOcclusion(store) {
|
|
276
666
|
const state = store.getState();
|
|
277
|
-
const { internal, renderer
|
|
667
|
+
const { internal, renderer } = state;
|
|
278
668
|
if (internal.occlusionEnabled || occlusionSetupPromise) return;
|
|
279
669
|
const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
|
|
280
670
|
if (!hasOcclusionSupport) {
|
|
@@ -437,6 +827,22 @@ function hasVisibilityHandlers(handlers) {
|
|
|
437
827
|
return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
|
|
438
828
|
}
|
|
439
829
|
|
|
830
|
+
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
831
|
+
function fromRef(ref) {
|
|
832
|
+
return { [FROM_REF]: ref };
|
|
833
|
+
}
|
|
834
|
+
function isFromRef(value) {
|
|
835
|
+
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
const ONCE = Symbol.for("@react-three/fiber.once");
|
|
839
|
+
function once(...args) {
|
|
840
|
+
return { [ONCE]: args.length ? args : true };
|
|
841
|
+
}
|
|
842
|
+
function isOnce(value) {
|
|
843
|
+
return value !== null && typeof value === "object" && ONCE in value;
|
|
844
|
+
}
|
|
845
|
+
|
|
440
846
|
const RESERVED_PROPS = [
|
|
441
847
|
"children",
|
|
442
848
|
"key",
|
|
@@ -507,7 +913,7 @@ function getMemoizedPrototype(root) {
|
|
|
507
913
|
ctor = new root.constructor();
|
|
508
914
|
MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
|
|
509
915
|
}
|
|
510
|
-
} catch
|
|
916
|
+
} catch {
|
|
511
917
|
}
|
|
512
918
|
return ctor;
|
|
513
919
|
}
|
|
@@ -538,7 +944,7 @@ function applyProps(object, props) {
|
|
|
538
944
|
const rootState = instance && findInitialRoot(instance).getState();
|
|
539
945
|
const prevHandlers = instance?.eventCount;
|
|
540
946
|
for (const prop in props) {
|
|
541
|
-
|
|
947
|
+
const value = props[prop];
|
|
542
948
|
if (RESERVED_PROPS.includes(prop)) continue;
|
|
543
949
|
if (instance && EVENT_REGEX.test(prop)) {
|
|
544
950
|
if (typeof value === "function") instance.handlers[prop] = value;
|
|
@@ -553,6 +959,25 @@ function applyProps(object, props) {
|
|
|
553
959
|
continue;
|
|
554
960
|
}
|
|
555
961
|
if (value === void 0) continue;
|
|
962
|
+
if (isFromRef(value)) {
|
|
963
|
+
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
if (isOnce(value)) {
|
|
967
|
+
if (instance?.appliedOnce?.has(prop)) continue;
|
|
968
|
+
if (instance) {
|
|
969
|
+
instance.appliedOnce ?? (instance.appliedOnce = /* @__PURE__ */ new Set());
|
|
970
|
+
instance.appliedOnce.add(prop);
|
|
971
|
+
}
|
|
972
|
+
const { root: targetRoot, key: targetKey } = resolve(object, prop);
|
|
973
|
+
const args = value[ONCE];
|
|
974
|
+
if (typeof targetRoot[targetKey] === "function") {
|
|
975
|
+
targetRoot[targetKey](...args === true ? [] : args);
|
|
976
|
+
} else if (args !== true && args.length > 0) {
|
|
977
|
+
targetRoot[targetKey] = args[0];
|
|
978
|
+
}
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
556
981
|
let { root, key, target } = resolve(object, prop);
|
|
557
982
|
if (target === void 0 && (typeof root !== "object" || root === null)) {
|
|
558
983
|
throw Error(`R3F: Cannot set "${prop}". Ensure it is an object before setting "${key}".`);
|
|
@@ -575,7 +1000,10 @@ function applyProps(object, props) {
|
|
|
575
1000
|
else target.set(value);
|
|
576
1001
|
} else {
|
|
577
1002
|
root[key] = value;
|
|
578
|
-
if (
|
|
1003
|
+
if (key.endsWith("Node") && root.isMaterial) {
|
|
1004
|
+
root.needsUpdate = true;
|
|
1005
|
+
}
|
|
1006
|
+
if (rootState && rootState.renderer?.outputColorSpace === SRGBColorSpace && colorMaps.includes(key) && isTexture(value) && root[key]?.isTexture && // sRGB textures must be RGBA8 since r137 https://github.com/mrdoob/three.js/pull/23129
|
|
579
1007
|
root[key].format === RGBAFormat && root[key].type === UnsignedByteType) {
|
|
580
1008
|
root[key].colorSpace = rootState.textureColorSpace;
|
|
581
1009
|
}
|
|
@@ -608,38 +1036,60 @@ function applyProps(object, props) {
|
|
|
608
1036
|
return object;
|
|
609
1037
|
}
|
|
610
1038
|
|
|
1039
|
+
const DEFAULT_POINTER_ID = 0;
|
|
1040
|
+
const XR_POINTER_ID_START = 1e3;
|
|
1041
|
+
function getPointerState(internal, pointerId) {
|
|
1042
|
+
let state = internal.pointerMap.get(pointerId);
|
|
1043
|
+
if (!state) {
|
|
1044
|
+
state = {
|
|
1045
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
1046
|
+
captured: /* @__PURE__ */ new Map(),
|
|
1047
|
+
initialClick: [0, 0],
|
|
1048
|
+
initialHits: []
|
|
1049
|
+
};
|
|
1050
|
+
internal.pointerMap.set(pointerId, state);
|
|
1051
|
+
}
|
|
1052
|
+
return state;
|
|
1053
|
+
}
|
|
1054
|
+
function getPointerId(event) {
|
|
1055
|
+
return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
|
|
1056
|
+
}
|
|
611
1057
|
function makeId(event) {
|
|
612
1058
|
return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
|
|
613
1059
|
}
|
|
614
|
-
function releaseInternalPointerCapture(
|
|
615
|
-
const
|
|
1060
|
+
function releaseInternalPointerCapture(internal, obj, pointerId) {
|
|
1061
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1062
|
+
if (!pointerState) return;
|
|
1063
|
+
const captureData = pointerState.captured.get(obj);
|
|
616
1064
|
if (captureData) {
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
capturedMap.delete(pointerId);
|
|
620
|
-
captureData.target.releasePointerCapture(pointerId);
|
|
621
|
-
}
|
|
1065
|
+
pointerState.captured.delete(obj);
|
|
1066
|
+
captureData.target.releasePointerCapture(pointerId);
|
|
622
1067
|
}
|
|
623
1068
|
}
|
|
624
1069
|
function removeInteractivity(store, object) {
|
|
625
1070
|
const { internal } = store.getState();
|
|
626
1071
|
internal.interaction = internal.interaction.filter((o) => o !== object);
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
1072
|
+
for (const [pointerId, pointerState] of internal.pointerMap) {
|
|
1073
|
+
pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
|
|
1074
|
+
pointerState.hovered.forEach((value, key) => {
|
|
1075
|
+
if (value.eventObject === object || value.object === object) {
|
|
1076
|
+
pointerState.hovered.delete(key);
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1079
|
+
if (pointerState.captured.has(object)) {
|
|
1080
|
+
releaseInternalPointerCapture(internal, object, pointerId);
|
|
631
1081
|
}
|
|
632
|
-
}
|
|
633
|
-
internal.capturedMap.forEach((captures, pointerId) => {
|
|
634
|
-
releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
|
|
635
|
-
});
|
|
1082
|
+
}
|
|
636
1083
|
unregisterVisibility(store, object);
|
|
637
1084
|
}
|
|
638
1085
|
function createEvents(store) {
|
|
639
|
-
function calculateDistance(event) {
|
|
1086
|
+
function calculateDistance(event, pointerId) {
|
|
640
1087
|
const { internal } = store.getState();
|
|
641
|
-
const
|
|
642
|
-
|
|
1088
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1089
|
+
if (!pointerState) return 0;
|
|
1090
|
+
const [initialX, initialY] = pointerState.initialClick;
|
|
1091
|
+
const dx = event.offsetX - initialX;
|
|
1092
|
+
const dy = event.offsetY - initialY;
|
|
643
1093
|
return Math.round(Math.sqrt(dx * dx + dy * dy));
|
|
644
1094
|
}
|
|
645
1095
|
function filterPointerEvents(objects) {
|
|
@@ -675,6 +1125,15 @@ function createEvents(store) {
|
|
|
675
1125
|
return state2.raycaster.camera ? state2.raycaster.intersectObject(obj, true) : [];
|
|
676
1126
|
}
|
|
677
1127
|
let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
|
|
1128
|
+
const aInteractivePriority = a.object.userData?.interactivePriority;
|
|
1129
|
+
const bInteractivePriority = b.object.userData?.interactivePriority;
|
|
1130
|
+
if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
|
|
1131
|
+
if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
|
|
1132
|
+
if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
|
|
1133
|
+
if (aInteractivePriority !== bInteractivePriority) {
|
|
1134
|
+
return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
678
1137
|
const aState = getRootState(a.object);
|
|
679
1138
|
const bState = getRootState(b.object);
|
|
680
1139
|
const aPriority = aState?.events?.priority ?? 1;
|
|
@@ -690,14 +1149,19 @@ function createEvents(store) {
|
|
|
690
1149
|
for (const hit of hits) {
|
|
691
1150
|
let eventObject = hit.object;
|
|
692
1151
|
while (eventObject) {
|
|
693
|
-
if (eventObject.__r3f?.eventCount)
|
|
1152
|
+
if (eventObject.__r3f?.eventCount) {
|
|
694
1153
|
intersections.push({ ...hit, eventObject });
|
|
1154
|
+
}
|
|
695
1155
|
eventObject = eventObject.parent;
|
|
696
1156
|
}
|
|
697
1157
|
}
|
|
698
|
-
if ("pointerId" in event
|
|
699
|
-
|
|
700
|
-
|
|
1158
|
+
if ("pointerId" in event) {
|
|
1159
|
+
const pointerId = event.pointerId;
|
|
1160
|
+
const pointerState = state.internal.pointerMap.get(pointerId);
|
|
1161
|
+
if (pointerState?.captured.size) {
|
|
1162
|
+
for (const captureData of pointerState.captured.values()) {
|
|
1163
|
+
if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
|
|
1164
|
+
}
|
|
701
1165
|
}
|
|
702
1166
|
}
|
|
703
1167
|
return intersections;
|
|
@@ -710,28 +1174,26 @@ function createEvents(store) {
|
|
|
710
1174
|
if (state) {
|
|
711
1175
|
const { raycaster, pointer, camera, internal } = state;
|
|
712
1176
|
const unprojectedPoint = new Vector3(pointer.x, pointer.y, 0).unproject(camera);
|
|
713
|
-
const hasPointerCapture = (id) =>
|
|
1177
|
+
const hasPointerCapture = (id) => {
|
|
1178
|
+
const pointerState = internal.pointerMap.get(id);
|
|
1179
|
+
return pointerState?.captured.has(hit.eventObject) ?? false;
|
|
1180
|
+
};
|
|
714
1181
|
const setPointerCapture = (id) => {
|
|
715
1182
|
const captureData = { intersection: hit, target: event.target };
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
} else {
|
|
719
|
-
internal.capturedMap.set(id, /* @__PURE__ */ new Map([[hit.eventObject, captureData]]));
|
|
720
|
-
}
|
|
1183
|
+
const pointerState = getPointerState(internal, id);
|
|
1184
|
+
pointerState.captured.set(hit.eventObject, captureData);
|
|
721
1185
|
event.target.setPointerCapture(id);
|
|
722
1186
|
};
|
|
723
1187
|
const releasePointerCapture = (id) => {
|
|
724
|
-
|
|
725
|
-
if (captures) {
|
|
726
|
-
releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
|
|
727
|
-
}
|
|
1188
|
+
releaseInternalPointerCapture(internal, hit.eventObject, id);
|
|
728
1189
|
};
|
|
729
|
-
|
|
730
|
-
for (
|
|
731
|
-
|
|
1190
|
+
const extractEventProps = {};
|
|
1191
|
+
for (const prop in event) {
|
|
1192
|
+
const property = event[prop];
|
|
732
1193
|
if (typeof property !== "function") extractEventProps[prop] = property;
|
|
733
1194
|
}
|
|
734
|
-
|
|
1195
|
+
const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
|
|
1196
|
+
const raycastEvent = {
|
|
735
1197
|
...hit,
|
|
736
1198
|
...extractEventProps,
|
|
737
1199
|
pointer,
|
|
@@ -741,18 +1203,19 @@ function createEvents(store) {
|
|
|
741
1203
|
unprojectedPoint,
|
|
742
1204
|
ray: raycaster.ray,
|
|
743
1205
|
camera,
|
|
1206
|
+
pointerId: eventPointerId,
|
|
744
1207
|
// Hijack stopPropagation, which just sets a flag
|
|
745
1208
|
stopPropagation() {
|
|
746
|
-
const
|
|
1209
|
+
const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
|
|
747
1210
|
if (
|
|
748
1211
|
// ...if this pointer hasn't been captured
|
|
749
|
-
!
|
|
750
|
-
|
|
1212
|
+
!pointerState?.captured.size || // ... or if the hit object is capturing the pointer
|
|
1213
|
+
pointerState.captured.has(hit.eventObject)
|
|
751
1214
|
) {
|
|
752
1215
|
raycastEvent.stopped = localState.stopped = true;
|
|
753
|
-
if (
|
|
1216
|
+
if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
|
|
754
1217
|
const higher = intersections.slice(0, intersections.indexOf(hit));
|
|
755
|
-
cancelPointer([...higher, hit]);
|
|
1218
|
+
cancelPointer([...higher, hit], eventPointerId);
|
|
756
1219
|
}
|
|
757
1220
|
}
|
|
758
1221
|
},
|
|
@@ -768,15 +1231,18 @@ function createEvents(store) {
|
|
|
768
1231
|
}
|
|
769
1232
|
return intersections;
|
|
770
1233
|
}
|
|
771
|
-
function cancelPointer(intersections) {
|
|
1234
|
+
function cancelPointer(intersections, pointerId) {
|
|
772
1235
|
const { internal } = store.getState();
|
|
773
|
-
|
|
1236
|
+
const pid = pointerId ?? DEFAULT_POINTER_ID;
|
|
1237
|
+
const pointerState = internal.pointerMap.get(pid);
|
|
1238
|
+
if (!pointerState) return;
|
|
1239
|
+
for (const [hoveredId, hoveredObj] of pointerState.hovered) {
|
|
774
1240
|
if (!intersections.length || !intersections.find(
|
|
775
1241
|
(hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
|
|
776
1242
|
)) {
|
|
777
1243
|
const eventObject = hoveredObj.eventObject;
|
|
778
1244
|
const instance = eventObject.__r3f;
|
|
779
|
-
|
|
1245
|
+
pointerState.hovered.delete(hoveredId);
|
|
780
1246
|
if (instance?.eventCount) {
|
|
781
1247
|
const handlers = instance.handlers;
|
|
782
1248
|
const data = { ...hoveredObj, intersections };
|
|
@@ -805,41 +1271,118 @@ function createEvents(store) {
|
|
|
805
1271
|
instance?.handlers.onDropMissed?.(event);
|
|
806
1272
|
}
|
|
807
1273
|
}
|
|
1274
|
+
function cleanupPointer(pointerId) {
|
|
1275
|
+
const { internal } = store.getState();
|
|
1276
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1277
|
+
if (pointerState) {
|
|
1278
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
1279
|
+
const eventObject = hoveredObj.eventObject;
|
|
1280
|
+
const instance = eventObject.__r3f;
|
|
1281
|
+
if (instance?.eventCount) {
|
|
1282
|
+
const handlers = instance.handlers;
|
|
1283
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
1284
|
+
handlers.onPointerOut?.(data);
|
|
1285
|
+
handlers.onPointerLeave?.(data);
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
internal.pointerMap.delete(pointerId);
|
|
1289
|
+
}
|
|
1290
|
+
internal.pointerDirty.delete(pointerId);
|
|
1291
|
+
}
|
|
1292
|
+
function processDeferredPointer(event, pointerId) {
|
|
1293
|
+
const state = store.getState();
|
|
1294
|
+
const { internal } = state;
|
|
1295
|
+
if (!state.events.enabled) return;
|
|
1296
|
+
const filter = filterPointerEvents;
|
|
1297
|
+
const hits = intersect(event, filter);
|
|
1298
|
+
cancelPointer(hits, pointerId);
|
|
1299
|
+
function onIntersect(data) {
|
|
1300
|
+
const eventObject = data.eventObject;
|
|
1301
|
+
const instance = eventObject.__r3f;
|
|
1302
|
+
if (!instance?.eventCount) return;
|
|
1303
|
+
const handlers = instance.handlers;
|
|
1304
|
+
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
1305
|
+
const id = makeId(data);
|
|
1306
|
+
const pointerState = getPointerState(internal, pointerId);
|
|
1307
|
+
const hoveredItem = pointerState.hovered.get(id);
|
|
1308
|
+
if (!hoveredItem) {
|
|
1309
|
+
pointerState.hovered.set(id, data);
|
|
1310
|
+
handlers.onPointerOver?.(data);
|
|
1311
|
+
handlers.onPointerEnter?.(data);
|
|
1312
|
+
} else if (hoveredItem.stopped) {
|
|
1313
|
+
data.stopPropagation();
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
handlers.onPointerMove?.(data);
|
|
1317
|
+
}
|
|
1318
|
+
handleIntersects(hits, event, 0, onIntersect);
|
|
1319
|
+
}
|
|
808
1320
|
function handlePointer(name) {
|
|
809
1321
|
switch (name) {
|
|
810
1322
|
case "onPointerLeave":
|
|
811
|
-
case "onPointerCancel":
|
|
812
1323
|
case "onDragLeave":
|
|
813
1324
|
return () => cancelPointer([]);
|
|
1325
|
+
// Global cancel of these events
|
|
1326
|
+
case "onPointerCancel":
|
|
1327
|
+
return (event) => {
|
|
1328
|
+
const pointerId = getPointerId(event);
|
|
1329
|
+
cleanupPointer(pointerId);
|
|
1330
|
+
};
|
|
814
1331
|
case "onLostPointerCapture":
|
|
815
1332
|
return (event) => {
|
|
816
1333
|
const { internal } = store.getState();
|
|
817
|
-
|
|
1334
|
+
const pointerId = getPointerId(event);
|
|
1335
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1336
|
+
if (pointerState?.captured.size) {
|
|
818
1337
|
requestAnimationFrame(() => {
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
1338
|
+
const pointerState2 = internal.pointerMap.get(pointerId);
|
|
1339
|
+
if (pointerState2?.captured.size) {
|
|
1340
|
+
pointerState2.captured.clear();
|
|
822
1341
|
}
|
|
1342
|
+
cancelPointer([], pointerId);
|
|
823
1343
|
});
|
|
824
1344
|
}
|
|
825
1345
|
};
|
|
826
1346
|
}
|
|
827
1347
|
return function handleEvent(event) {
|
|
828
1348
|
const state = store.getState();
|
|
829
|
-
const { onPointerMissed, onDragOverMissed, onDropMissed, internal } = state;
|
|
1349
|
+
const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
|
|
1350
|
+
const pointerId = getPointerId(event);
|
|
830
1351
|
internal.lastEvent.current = event;
|
|
831
|
-
if (!
|
|
1352
|
+
if (!events.enabled) return;
|
|
832
1353
|
const isPointerMove = name === "onPointerMove";
|
|
833
1354
|
const isDragOver = name === "onDragOver";
|
|
834
1355
|
const isDrop = name === "onDrop";
|
|
835
1356
|
const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
|
|
1357
|
+
const isPointerDown = name === "onPointerDown";
|
|
1358
|
+
const isPointerUp = name === "onPointerUp";
|
|
1359
|
+
const isWheel = name === "onWheel";
|
|
1360
|
+
const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
|
|
1361
|
+
if (isPointerMove && canDeferRaycasts) {
|
|
1362
|
+
events.compute?.(event, state);
|
|
1363
|
+
internal.pointerDirty.set(pointerId, event);
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
|
|
1367
|
+
events.compute?.(event, state);
|
|
1368
|
+
internal.pointerDirty.set(pointerId, event);
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
|
|
1372
|
+
const deferredEvent = internal.pointerDirty.get(pointerId);
|
|
1373
|
+
internal.pointerDirty.delete(pointerId);
|
|
1374
|
+
processDeferredPointer(deferredEvent, pointerId);
|
|
1375
|
+
}
|
|
836
1376
|
const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
|
|
837
1377
|
const hits = intersect(event, filter);
|
|
838
|
-
const delta = isClickEvent ? calculateDistance(event) : 0;
|
|
839
|
-
if (
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
1378
|
+
const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
|
|
1379
|
+
if (isPointerDown) {
|
|
1380
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1381
|
+
pointerState2.initialClick = [event.offsetX, event.offsetY];
|
|
1382
|
+
pointerState2.initialHits = hits.map((hit) => hit.eventObject);
|
|
1383
|
+
}
|
|
1384
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1385
|
+
const initialHits = pointerState?.initialHits ?? [];
|
|
843
1386
|
if (isClickEvent && !hits.length) {
|
|
844
1387
|
if (delta <= 2) {
|
|
845
1388
|
pointerMissed(event, internal.interaction);
|
|
@@ -854,7 +1397,9 @@ function createEvents(store) {
|
|
|
854
1397
|
dropMissed(event, internal.interaction);
|
|
855
1398
|
if (onDropMissed) onDropMissed(event);
|
|
856
1399
|
}
|
|
857
|
-
if (isPointerMove || isDragOver)
|
|
1400
|
+
if (isPointerMove || isDragOver) {
|
|
1401
|
+
cancelPointer(hits, pointerId);
|
|
1402
|
+
}
|
|
858
1403
|
function onIntersect(data) {
|
|
859
1404
|
const eventObject = data.eventObject;
|
|
860
1405
|
const instance = eventObject.__r3f;
|
|
@@ -863,9 +1408,10 @@ function createEvents(store) {
|
|
|
863
1408
|
if (isPointerMove) {
|
|
864
1409
|
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
865
1410
|
const id = makeId(data);
|
|
866
|
-
const
|
|
1411
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1412
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
867
1413
|
if (!hoveredItem) {
|
|
868
|
-
|
|
1414
|
+
pointerState2.hovered.set(id, data);
|
|
869
1415
|
handlers.onPointerOver?.(data);
|
|
870
1416
|
handlers.onPointerEnter?.(data);
|
|
871
1417
|
} else if (hoveredItem.stopped) {
|
|
@@ -875,9 +1421,10 @@ function createEvents(store) {
|
|
|
875
1421
|
handlers.onPointerMove?.(data);
|
|
876
1422
|
} else if (isDragOver) {
|
|
877
1423
|
const id = makeId(data);
|
|
878
|
-
const
|
|
1424
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1425
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
879
1426
|
if (!hoveredItem) {
|
|
880
|
-
|
|
1427
|
+
pointerState2.hovered.set(id, data);
|
|
881
1428
|
handlers.onDragOverEnter?.(data);
|
|
882
1429
|
} else if (hoveredItem.stopped) {
|
|
883
1430
|
data.stopPropagation();
|
|
@@ -888,18 +1435,18 @@ function createEvents(store) {
|
|
|
888
1435
|
} else {
|
|
889
1436
|
const handler = handlers[name];
|
|
890
1437
|
if (handler) {
|
|
891
|
-
if (!isClickEvent ||
|
|
1438
|
+
if (!isClickEvent || initialHits.includes(eventObject)) {
|
|
892
1439
|
pointerMissed(
|
|
893
1440
|
event,
|
|
894
|
-
internal.interaction.filter((object) => !
|
|
1441
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
895
1442
|
);
|
|
896
1443
|
handler(data);
|
|
897
1444
|
}
|
|
898
1445
|
} else {
|
|
899
|
-
if (isClickEvent &&
|
|
1446
|
+
if (isClickEvent && initialHits.includes(eventObject)) {
|
|
900
1447
|
pointerMissed(
|
|
901
1448
|
event,
|
|
902
|
-
internal.interaction.filter((object) => !
|
|
1449
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
903
1450
|
);
|
|
904
1451
|
}
|
|
905
1452
|
}
|
|
@@ -908,7 +1455,15 @@ function createEvents(store) {
|
|
|
908
1455
|
handleIntersects(hits, event, delta, onIntersect);
|
|
909
1456
|
};
|
|
910
1457
|
}
|
|
911
|
-
|
|
1458
|
+
function flushDeferredPointers() {
|
|
1459
|
+
const { internal, events } = store.getState();
|
|
1460
|
+
if (!events.frameTimedRaycasts) return;
|
|
1461
|
+
for (const [pointerId, event] of internal.pointerDirty) {
|
|
1462
|
+
processDeferredPointer(event, pointerId);
|
|
1463
|
+
}
|
|
1464
|
+
internal.pointerDirty.clear();
|
|
1465
|
+
}
|
|
1466
|
+
return { handlePointer, flushDeferredPointers, processDeferredPointer };
|
|
912
1467
|
}
|
|
913
1468
|
const DOM_EVENTS = {
|
|
914
1469
|
onClick: ["click", false],
|
|
@@ -927,11 +1482,16 @@ const DOM_EVENTS = {
|
|
|
927
1482
|
onLostPointerCapture: ["lostpointercapture", true]
|
|
928
1483
|
};
|
|
929
1484
|
function createPointerEvents(store) {
|
|
930
|
-
const { handlePointer } = createEvents(store);
|
|
1485
|
+
const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
|
|
1486
|
+
let nextXRPointerId = XR_POINTER_ID_START;
|
|
1487
|
+
const xrPointers = /* @__PURE__ */ new Map();
|
|
931
1488
|
return {
|
|
932
1489
|
priority: 1,
|
|
933
1490
|
enabled: true,
|
|
934
|
-
|
|
1491
|
+
frameTimedRaycasts: true,
|
|
1492
|
+
alwaysFireOnScroll: true,
|
|
1493
|
+
updateOnFrame: false,
|
|
1494
|
+
compute(event, state) {
|
|
935
1495
|
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
936
1496
|
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
937
1497
|
},
|
|
@@ -940,11 +1500,33 @@ function createPointerEvents(store) {
|
|
|
940
1500
|
(acc, key) => ({ ...acc, [key]: handlePointer(key) }),
|
|
941
1501
|
{}
|
|
942
1502
|
),
|
|
943
|
-
update: () => {
|
|
1503
|
+
update: (pointerId) => {
|
|
1504
|
+
const { events, internal } = store.getState();
|
|
1505
|
+
if (!events.handlers) return;
|
|
1506
|
+
if (pointerId !== void 0) {
|
|
1507
|
+
const event = internal.pointerDirty.get(pointerId);
|
|
1508
|
+
if (event) {
|
|
1509
|
+
internal.pointerDirty.delete(pointerId);
|
|
1510
|
+
processDeferredPointer(event, pointerId);
|
|
1511
|
+
} else if (internal.lastEvent?.current) {
|
|
1512
|
+
processDeferredPointer(internal.lastEvent.current, pointerId);
|
|
1513
|
+
}
|
|
1514
|
+
} else {
|
|
1515
|
+
flushDeferredPointers();
|
|
1516
|
+
if (internal.lastEvent?.current) {
|
|
1517
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
},
|
|
1521
|
+
flush: () => {
|
|
944
1522
|
const { events, internal } = store.getState();
|
|
945
|
-
|
|
1523
|
+
flushDeferredPointers();
|
|
1524
|
+
if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
|
|
1525
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1526
|
+
}
|
|
946
1527
|
},
|
|
947
1528
|
connect: (target) => {
|
|
1529
|
+
if (!target) return;
|
|
948
1530
|
const { set, events } = store.getState();
|
|
949
1531
|
events.disconnect?.();
|
|
950
1532
|
set((state) => ({ events: { ...state.events, connected: target } }));
|
|
@@ -968,6 +1550,32 @@ function createPointerEvents(store) {
|
|
|
968
1550
|
}
|
|
969
1551
|
set((state) => ({ events: { ...state.events, connected: void 0 } }));
|
|
970
1552
|
}
|
|
1553
|
+
},
|
|
1554
|
+
registerPointer: (config) => {
|
|
1555
|
+
const pointerId = nextXRPointerId++;
|
|
1556
|
+
xrPointers.set(pointerId, config);
|
|
1557
|
+
const { internal } = store.getState();
|
|
1558
|
+
getPointerState(internal, pointerId);
|
|
1559
|
+
return pointerId;
|
|
1560
|
+
},
|
|
1561
|
+
unregisterPointer: (pointerId) => {
|
|
1562
|
+
xrPointers.delete(pointerId);
|
|
1563
|
+
const { internal } = store.getState();
|
|
1564
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1565
|
+
if (pointerState) {
|
|
1566
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
1567
|
+
const eventObject = hoveredObj.eventObject;
|
|
1568
|
+
const instance = eventObject.__r3f;
|
|
1569
|
+
if (instance?.eventCount) {
|
|
1570
|
+
const handlers = instance.handlers;
|
|
1571
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
1572
|
+
handlers.onPointerOut?.(data);
|
|
1573
|
+
handlers.onPointerLeave?.(data);
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
internal.pointerMap.delete(pointerId);
|
|
1577
|
+
}
|
|
1578
|
+
internal.pointerDirty.delete(pointerId);
|
|
971
1579
|
}
|
|
972
1580
|
};
|
|
973
1581
|
}
|
|
@@ -1029,300 +1637,26 @@ function notifyAlpha({ message, link }) {
|
|
|
1029
1637
|
}
|
|
1030
1638
|
}
|
|
1031
1639
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
let performanceTimeout = void 0;
|
|
1055
|
-
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
1056
|
-
const pointer = new Vector2();
|
|
1057
|
-
const rootState = {
|
|
1058
|
-
set,
|
|
1059
|
-
get,
|
|
1060
|
-
// Mock objects that have to be configured
|
|
1061
|
-
gl: null,
|
|
1062
|
-
renderer: null,
|
|
1063
|
-
camera: null,
|
|
1064
|
-
frustum: new Frustum(),
|
|
1065
|
-
autoUpdateFrustum: true,
|
|
1066
|
-
raycaster: null,
|
|
1067
|
-
events: { priority: 1, enabled: true, connected: false },
|
|
1068
|
-
scene: null,
|
|
1069
|
-
rootScene: null,
|
|
1070
|
-
xr: null,
|
|
1071
|
-
inspector: null,
|
|
1072
|
-
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
1073
|
-
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1074
|
-
legacy: false,
|
|
1075
|
-
linear: false,
|
|
1076
|
-
flat: false,
|
|
1077
|
-
textureColorSpace: "srgb",
|
|
1078
|
-
isLegacy: false,
|
|
1079
|
-
webGPUSupported: false,
|
|
1080
|
-
isNative: false,
|
|
1081
|
-
controls: null,
|
|
1082
|
-
pointer,
|
|
1083
|
-
mouse: pointer,
|
|
1084
|
-
frameloop: "always",
|
|
1085
|
-
onPointerMissed: void 0,
|
|
1086
|
-
onDragOverMissed: void 0,
|
|
1087
|
-
onDropMissed: void 0,
|
|
1088
|
-
performance: {
|
|
1089
|
-
current: 1,
|
|
1090
|
-
min: 0.5,
|
|
1091
|
-
max: 1,
|
|
1092
|
-
debounce: 200,
|
|
1093
|
-
regress: () => {
|
|
1094
|
-
const state2 = get();
|
|
1095
|
-
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
1096
|
-
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
1097
|
-
performanceTimeout = setTimeout(
|
|
1098
|
-
() => setPerformanceCurrent(get().performance.max),
|
|
1099
|
-
state2.performance.debounce
|
|
1100
|
-
);
|
|
1101
|
-
}
|
|
1102
|
-
},
|
|
1103
|
-
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
1104
|
-
viewport: {
|
|
1105
|
-
initialDpr: 0,
|
|
1106
|
-
dpr: 0,
|
|
1107
|
-
width: 0,
|
|
1108
|
-
height: 0,
|
|
1109
|
-
top: 0,
|
|
1110
|
-
left: 0,
|
|
1111
|
-
aspect: 0,
|
|
1112
|
-
distance: 0,
|
|
1113
|
-
factor: 0,
|
|
1114
|
-
getCurrentViewport
|
|
1115
|
-
},
|
|
1116
|
-
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
1117
|
-
setSize: (width, height, top = 0, left = 0) => {
|
|
1118
|
-
const camera = get().camera;
|
|
1119
|
-
const size = { width, height, top, left };
|
|
1120
|
-
set((state2) => ({ size, viewport: { ...state2.viewport, ...getCurrentViewport(camera, defaultTarget, size) } }));
|
|
1121
|
-
},
|
|
1122
|
-
setDpr: (dpr) => set((state2) => {
|
|
1123
|
-
const resolved = calculateDpr(dpr);
|
|
1124
|
-
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
1125
|
-
}),
|
|
1126
|
-
setFrameloop: (frameloop = "always") => {
|
|
1127
|
-
set(() => ({ frameloop }));
|
|
1128
|
-
},
|
|
1129
|
-
setError: (error) => set(() => ({ error })),
|
|
1130
|
-
error: null,
|
|
1131
|
-
//* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
|
|
1132
|
-
uniforms: {},
|
|
1133
|
-
nodes: {},
|
|
1134
|
-
textures: /* @__PURE__ */ new Map(),
|
|
1135
|
-
postProcessing: null,
|
|
1136
|
-
passes: {},
|
|
1137
|
-
previousRoot: void 0,
|
|
1138
|
-
internal: {
|
|
1139
|
-
// Events
|
|
1140
|
-
interaction: [],
|
|
1141
|
-
hovered: /* @__PURE__ */ new Map(),
|
|
1142
|
-
subscribers: [],
|
|
1143
|
-
initialClick: [0, 0],
|
|
1144
|
-
initialHits: [],
|
|
1145
|
-
capturedMap: /* @__PURE__ */ new Map(),
|
|
1146
|
-
lastEvent: React.createRef(),
|
|
1147
|
-
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
1148
|
-
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
1149
|
-
// Occlusion system (WebGPU only)
|
|
1150
|
-
occlusionEnabled: false,
|
|
1151
|
-
occlusionObserver: null,
|
|
1152
|
-
occlusionCache: /* @__PURE__ */ new Map(),
|
|
1153
|
-
helperGroup: null,
|
|
1154
|
-
// Updates
|
|
1155
|
-
active: false,
|
|
1156
|
-
frames: 0,
|
|
1157
|
-
priority: 0,
|
|
1158
|
-
subscribe: (ref, priority, store) => {
|
|
1159
|
-
const internal = get().internal;
|
|
1160
|
-
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
1161
|
-
internal.subscribers.push({ ref, priority, store });
|
|
1162
|
-
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
1163
|
-
return () => {
|
|
1164
|
-
const internal2 = get().internal;
|
|
1165
|
-
if (internal2?.subscribers) {
|
|
1166
|
-
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
1167
|
-
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
1168
|
-
}
|
|
1169
|
-
};
|
|
1170
|
-
},
|
|
1171
|
-
// Renderer Storage (single source of truth)
|
|
1172
|
-
actualRenderer: null,
|
|
1173
|
-
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
1174
|
-
scheduler: null
|
|
1175
|
-
}
|
|
1176
|
-
};
|
|
1177
|
-
return rootState;
|
|
1178
|
-
});
|
|
1179
|
-
const state = rootStore.getState();
|
|
1180
|
-
Object.defineProperty(state, "gl", {
|
|
1181
|
-
get() {
|
|
1182
|
-
const currentState = rootStore.getState();
|
|
1183
|
-
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1184
|
-
const stack = new Error().stack || "";
|
|
1185
|
-
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
1186
|
-
if (!isInternalAccess) {
|
|
1187
|
-
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1188
|
-
notifyDepreciated({
|
|
1189
|
-
heading: "Accessing state.gl in WebGPU mode",
|
|
1190
|
-
body: "Please use state.renderer instead. state.gl is deprecated and will be removed in future versions.\n\nFor backwards compatibility, state.gl currently maps to state.renderer, but this may cause issues with libraries expecting WebGLRenderer.\n\nAccessed from:\n" + cleanedStack
|
|
1191
|
-
});
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
return currentState.internal.actualRenderer;
|
|
1195
|
-
},
|
|
1196
|
-
set(value) {
|
|
1197
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1198
|
-
},
|
|
1199
|
-
enumerable: true,
|
|
1200
|
-
configurable: true
|
|
1201
|
-
});
|
|
1202
|
-
Object.defineProperty(state, "renderer", {
|
|
1203
|
-
get() {
|
|
1204
|
-
return rootStore.getState().internal.actualRenderer;
|
|
1205
|
-
},
|
|
1206
|
-
set(value) {
|
|
1207
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1208
|
-
},
|
|
1209
|
-
enumerable: true,
|
|
1210
|
-
configurable: true
|
|
1211
|
-
});
|
|
1212
|
-
let oldScene = state.scene;
|
|
1213
|
-
rootStore.subscribe(() => {
|
|
1214
|
-
const currentState = rootStore.getState();
|
|
1215
|
-
const { scene, rootScene, set } = currentState;
|
|
1216
|
-
if (scene !== oldScene) {
|
|
1217
|
-
oldScene = scene;
|
|
1218
|
-
if (scene?.isScene && scene !== rootScene) {
|
|
1219
|
-
set({ rootScene: scene });
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
});
|
|
1223
|
-
let oldSize = state.size;
|
|
1224
|
-
let oldDpr = state.viewport.dpr;
|
|
1225
|
-
let oldCamera = state.camera;
|
|
1226
|
-
rootStore.subscribe(() => {
|
|
1227
|
-
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
1228
|
-
const actualRenderer = internal.actualRenderer;
|
|
1229
|
-
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
1230
|
-
oldSize = size;
|
|
1231
|
-
oldDpr = viewport.dpr;
|
|
1232
|
-
updateCamera(camera, size);
|
|
1233
|
-
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1234
|
-
const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
|
|
1235
|
-
actualRenderer.setSize(size.width, size.height, updateStyle);
|
|
1236
|
-
}
|
|
1237
|
-
if (camera !== oldCamera) {
|
|
1238
|
-
oldCamera = camera;
|
|
1239
|
-
const { rootScene } = rootStore.getState();
|
|
1240
|
-
if (camera && rootScene && !camera.parent) {
|
|
1241
|
-
rootScene.add(camera);
|
|
1242
|
-
}
|
|
1243
|
-
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
1244
|
-
const currentState = rootStore.getState();
|
|
1245
|
-
if (currentState.autoUpdateFrustum && camera) {
|
|
1246
|
-
updateFrustum(camera, currentState.frustum);
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
});
|
|
1250
|
-
rootStore.subscribe((state2) => invalidate(state2));
|
|
1251
|
-
return rootStore;
|
|
1252
|
-
};
|
|
1253
|
-
|
|
1254
|
-
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
1255
|
-
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
1256
|
-
function getLoader(Proto) {
|
|
1257
|
-
if (isConstructor$1(Proto)) {
|
|
1258
|
-
let loader = memoizedLoaders.get(Proto);
|
|
1259
|
-
if (!loader) {
|
|
1260
|
-
loader = new Proto();
|
|
1261
|
-
memoizedLoaders.set(Proto, loader);
|
|
1262
|
-
}
|
|
1263
|
-
return loader;
|
|
1264
|
-
}
|
|
1265
|
-
return Proto;
|
|
1266
|
-
}
|
|
1267
|
-
function loadingFn(extensions, onProgress) {
|
|
1268
|
-
return function(Proto, input) {
|
|
1269
|
-
const loader = getLoader(Proto);
|
|
1270
|
-
if (extensions) extensions(loader);
|
|
1271
|
-
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
1272
|
-
return loader.loadAsync(input, onProgress).then((data) => {
|
|
1273
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1274
|
-
return data;
|
|
1275
|
-
});
|
|
1276
|
-
}
|
|
1277
|
-
return new Promise(
|
|
1278
|
-
(res, reject) => loader.load(
|
|
1279
|
-
input,
|
|
1280
|
-
(data) => {
|
|
1281
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1282
|
-
res(data);
|
|
1283
|
-
},
|
|
1284
|
-
onProgress,
|
|
1285
|
-
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
1286
|
-
)
|
|
1287
|
-
);
|
|
1288
|
-
};
|
|
1289
|
-
}
|
|
1290
|
-
function useLoader(loader, input, extensions, onProgress) {
|
|
1291
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1292
|
-
const fn = loadingFn(extensions, onProgress);
|
|
1293
|
-
const results = keys.map((key) => suspend(fn, [loader, key], { equal: is.equ }));
|
|
1294
|
-
return Array.isArray(input) ? results : results[0];
|
|
1295
|
-
}
|
|
1296
|
-
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
1297
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1298
|
-
keys.forEach((key) => preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
1299
|
-
};
|
|
1300
|
-
useLoader.clear = function(loader, input) {
|
|
1301
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1302
|
-
keys.forEach((key) => clear([loader, key]));
|
|
1303
|
-
};
|
|
1304
|
-
useLoader.loader = getLoader;
|
|
1305
|
-
|
|
1306
|
-
var __defProp$1 = Object.defineProperty;
|
|
1307
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1308
|
-
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1309
|
-
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1310
|
-
class PhaseGraph {
|
|
1311
|
-
constructor() {
|
|
1312
|
-
/** Ordered list of phase nodes */
|
|
1313
|
-
__publicField$1(this, "phases", []);
|
|
1314
|
-
/** Quick lookup by name */
|
|
1315
|
-
__publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1316
|
-
/** Cached ordered names (invalidated on changes) */
|
|
1317
|
-
__publicField$1(this, "orderedNamesCache", null);
|
|
1318
|
-
this.initializeDefaultPhases();
|
|
1319
|
-
}
|
|
1320
|
-
//* Initialization --------------------------------
|
|
1321
|
-
initializeDefaultPhases() {
|
|
1322
|
-
for (const name of DEFAULT_PHASES) {
|
|
1323
|
-
const node = { name, isAutoGenerated: false };
|
|
1324
|
-
this.phases.push(node);
|
|
1325
|
-
this.phaseMap.set(name, node);
|
|
1640
|
+
var __defProp$2 = Object.defineProperty;
|
|
1641
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1642
|
+
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1643
|
+
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1644
|
+
class PhaseGraph {
|
|
1645
|
+
constructor() {
|
|
1646
|
+
/** Ordered list of phase nodes */
|
|
1647
|
+
__publicField$2(this, "phases", []);
|
|
1648
|
+
/** Quick lookup by name */
|
|
1649
|
+
__publicField$2(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1650
|
+
/** Cached ordered names (invalidated on changes) */
|
|
1651
|
+
__publicField$2(this, "orderedNamesCache", null);
|
|
1652
|
+
this.initializeDefaultPhases();
|
|
1653
|
+
}
|
|
1654
|
+
//* Initialization --------------------------------
|
|
1655
|
+
initializeDefaultPhases() {
|
|
1656
|
+
for (const name of DEFAULT_PHASES) {
|
|
1657
|
+
const node = { name, isAutoGenerated: false };
|
|
1658
|
+
this.phases.push(node);
|
|
1659
|
+
this.phaseMap.set(name, node);
|
|
1326
1660
|
}
|
|
1327
1661
|
this.invalidateCache();
|
|
1328
1662
|
}
|
|
@@ -1341,8 +1675,9 @@ class PhaseGraph {
|
|
|
1341
1675
|
const node = { name, isAutoGenerated: false };
|
|
1342
1676
|
let insertIndex = this.phases.length;
|
|
1343
1677
|
const targetIndex = this.getPhaseIndex(before ?? after);
|
|
1344
|
-
if (targetIndex !== -1)
|
|
1345
|
-
|
|
1678
|
+
if (targetIndex !== -1) {
|
|
1679
|
+
insertIndex = before ? targetIndex : targetIndex + 1;
|
|
1680
|
+
} else {
|
|
1346
1681
|
const constraintType = before ? "before" : "after";
|
|
1347
1682
|
console.warn(`[useFrame] Phase "${before ?? after}" not found for '${constraintType}' constraint`);
|
|
1348
1683
|
}
|
|
@@ -1554,7 +1889,7 @@ function shouldRun(job, now) {
|
|
|
1554
1889
|
const minInterval = 1e3 / job.fps;
|
|
1555
1890
|
const lastRun = job.lastRun ?? 0;
|
|
1556
1891
|
const elapsed = now - lastRun;
|
|
1557
|
-
if (elapsed < minInterval) return false;
|
|
1892
|
+
if (elapsed < minInterval - 1) return false;
|
|
1558
1893
|
if (job.drop) {
|
|
1559
1894
|
job.lastRun = now;
|
|
1560
1895
|
} else {
|
|
@@ -1570,9 +1905,9 @@ function resetJobTiming(job) {
|
|
|
1570
1905
|
job.lastRun = void 0;
|
|
1571
1906
|
}
|
|
1572
1907
|
|
|
1573
|
-
var __defProp = Object.defineProperty;
|
|
1574
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1575
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1908
|
+
var __defProp$1 = Object.defineProperty;
|
|
1909
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1910
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1576
1911
|
const hmrData = (() => {
|
|
1577
1912
|
if (typeof process !== "undefined" && process.env.NODE_ENV === "test") return void 0;
|
|
1578
1913
|
if (typeof import_meta_hot !== "undefined") return import_meta_hot;
|
|
@@ -1586,9 +1921,9 @@ const _Scheduler = class _Scheduler {
|
|
|
1586
1921
|
//* Constructor ================================
|
|
1587
1922
|
constructor() {
|
|
1588
1923
|
//* Critical State ================================
|
|
1589
|
-
__publicField(this, "roots", /* @__PURE__ */ new Map());
|
|
1590
|
-
__publicField(this, "phaseGraph");
|
|
1591
|
-
__publicField(this, "loopState", {
|
|
1924
|
+
__publicField$1(this, "roots", /* @__PURE__ */ new Map());
|
|
1925
|
+
__publicField$1(this, "phaseGraph");
|
|
1926
|
+
__publicField$1(this, "loopState", {
|
|
1592
1927
|
running: false,
|
|
1593
1928
|
rafHandle: null,
|
|
1594
1929
|
lastTime: null,
|
|
@@ -1597,21 +1932,21 @@ const _Scheduler = class _Scheduler {
|
|
|
1597
1932
|
elapsedTime: 0,
|
|
1598
1933
|
createdAt: performance.now()
|
|
1599
1934
|
});
|
|
1600
|
-
__publicField(this, "stoppedTime", 0);
|
|
1935
|
+
__publicField$1(this, "stoppedTime", 0);
|
|
1601
1936
|
//* Private State ================================
|
|
1602
|
-
__publicField(this, "nextRootIndex", 0);
|
|
1603
|
-
__publicField(this, "globalBeforeJobs", /* @__PURE__ */ new Map());
|
|
1604
|
-
__publicField(this, "globalAfterJobs", /* @__PURE__ */ new Map());
|
|
1605
|
-
__publicField(this, "nextGlobalIndex", 0);
|
|
1606
|
-
__publicField(this, "idleCallbacks", /* @__PURE__ */ new Set());
|
|
1607
|
-
__publicField(this, "nextJobIndex", 0);
|
|
1608
|
-
__publicField(this, "jobStateListeners", /* @__PURE__ */ new Map());
|
|
1609
|
-
__publicField(this, "pendingFrames", 0);
|
|
1610
|
-
__publicField(this, "_frameloop", "always");
|
|
1937
|
+
__publicField$1(this, "nextRootIndex", 0);
|
|
1938
|
+
__publicField$1(this, "globalBeforeJobs", /* @__PURE__ */ new Map());
|
|
1939
|
+
__publicField$1(this, "globalAfterJobs", /* @__PURE__ */ new Map());
|
|
1940
|
+
__publicField$1(this, "nextGlobalIndex", 0);
|
|
1941
|
+
__publicField$1(this, "idleCallbacks", /* @__PURE__ */ new Set());
|
|
1942
|
+
__publicField$1(this, "nextJobIndex", 0);
|
|
1943
|
+
__publicField$1(this, "jobStateListeners", /* @__PURE__ */ new Map());
|
|
1944
|
+
__publicField$1(this, "pendingFrames", 0);
|
|
1945
|
+
__publicField$1(this, "_frameloop", "always");
|
|
1611
1946
|
//* Independent Mode & Error Handling State ================================
|
|
1612
|
-
__publicField(this, "_independent", false);
|
|
1613
|
-
__publicField(this, "errorHandler", null);
|
|
1614
|
-
__publicField(this, "rootReadyCallbacks", /* @__PURE__ */ new Set());
|
|
1947
|
+
__publicField$1(this, "_independent", false);
|
|
1948
|
+
__publicField$1(this, "errorHandler", null);
|
|
1949
|
+
__publicField$1(this, "rootReadyCallbacks", /* @__PURE__ */ new Set());
|
|
1615
1950
|
//* Core Loop Execution Methods ================================
|
|
1616
1951
|
/**
|
|
1617
1952
|
* Main RAF loop callback.
|
|
@@ -1620,7 +1955,7 @@ const _Scheduler = class _Scheduler {
|
|
|
1620
1955
|
* @returns {void}
|
|
1621
1956
|
* @private
|
|
1622
1957
|
*/
|
|
1623
|
-
__publicField(this, "loop", (timestamp) => {
|
|
1958
|
+
__publicField$1(this, "loop", (timestamp) => {
|
|
1624
1959
|
if (!this.loopState.running) return;
|
|
1625
1960
|
this.executeFrame(timestamp);
|
|
1626
1961
|
if (this._frameloop === "demand") {
|
|
@@ -2327,56 +2662,384 @@ const _Scheduler = class _Scheduler {
|
|
|
2327
2662
|
//* Cross-Bundle Singleton Key ==============================
|
|
2328
2663
|
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2329
2664
|
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2330
|
-
__publicField(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2665
|
+
__publicField$1(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2331
2666
|
let Scheduler = _Scheduler;
|
|
2332
2667
|
const getScheduler = () => Scheduler.get();
|
|
2333
2668
|
if (hmrData) {
|
|
2334
2669
|
hmrData.accept?.();
|
|
2335
2670
|
}
|
|
2336
2671
|
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
const
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
const isLegacyPriority = typeof priorityOrOptions === "number" && priorityOrOptions > 0;
|
|
2358
|
-
useIsomorphicLayoutEffect(() => {
|
|
2359
|
-
if (!callback) return;
|
|
2360
|
-
if (isInsideCanvas) {
|
|
2361
|
-
const state = store.getState();
|
|
2362
|
-
const rootId = state.internal.rootId;
|
|
2363
|
-
if (isLegacyPriority) {
|
|
2364
|
-
state.internal.priority++;
|
|
2365
|
-
let parentRoot = state.previousRoot;
|
|
2366
|
-
while (parentRoot) {
|
|
2367
|
-
const parentState = parentRoot.getState();
|
|
2368
|
-
if (parentState?.internal) parentState.internal.priority++;
|
|
2369
|
-
parentRoot = parentState?.previousRoot;
|
|
2370
|
-
}
|
|
2371
|
-
notifyDepreciated({
|
|
2372
|
-
heading: "useFrame with numeric priority is deprecated",
|
|
2373
|
-
body: 'Using useFrame(callback, number) to control render order is deprecated.\n\nFor custom rendering, use: useFrame(callback, { phase: "render" })\nFor execution order within update phase, use: useFrame(callback, { priority: number })',
|
|
2374
|
-
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
2375
|
-
});
|
|
2672
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
2673
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React.createContext(null));
|
|
2674
|
+
const createStore = (invalidate, advance) => {
|
|
2675
|
+
const rootStore = createWithEqualityFn((set, get) => {
|
|
2676
|
+
const position = new Vector3();
|
|
2677
|
+
const defaultTarget = new Vector3();
|
|
2678
|
+
const tempTarget = new Vector3();
|
|
2679
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
2680
|
+
const { width, height, top, left } = size;
|
|
2681
|
+
const aspect = width / height;
|
|
2682
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
2683
|
+
else tempTarget.set(...target);
|
|
2684
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
2685
|
+
if (isOrthographicCamera(camera)) {
|
|
2686
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
2687
|
+
} else {
|
|
2688
|
+
const fov = camera.fov * Math.PI / 180;
|
|
2689
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
2690
|
+
const w = h * (width / height);
|
|
2691
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
2376
2692
|
}
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2693
|
+
}
|
|
2694
|
+
let performanceTimeout = void 0;
|
|
2695
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
2696
|
+
const pointer = new Vector2();
|
|
2697
|
+
const rootState = {
|
|
2698
|
+
set,
|
|
2699
|
+
get,
|
|
2700
|
+
// Mock objects that have to be configured
|
|
2701
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
2702
|
+
primaryStore: null,
|
|
2703
|
+
gl: null,
|
|
2704
|
+
renderer: null,
|
|
2705
|
+
camera: null,
|
|
2706
|
+
frustum: new Frustum(),
|
|
2707
|
+
autoUpdateFrustum: true,
|
|
2708
|
+
raycaster: null,
|
|
2709
|
+
events: {
|
|
2710
|
+
priority: 1,
|
|
2711
|
+
enabled: true,
|
|
2712
|
+
connected: false,
|
|
2713
|
+
frameTimedRaycasts: true,
|
|
2714
|
+
alwaysFireOnScroll: true,
|
|
2715
|
+
updateOnFrame: false
|
|
2716
|
+
},
|
|
2717
|
+
scene: null,
|
|
2718
|
+
rootScene: null,
|
|
2719
|
+
xr: null,
|
|
2720
|
+
inspector: null,
|
|
2721
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
2722
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
2723
|
+
textureColorSpace: SRGBColorSpace,
|
|
2724
|
+
isLegacy: false,
|
|
2725
|
+
webGPUSupported: false,
|
|
2726
|
+
isNative: false,
|
|
2727
|
+
controls: null,
|
|
2728
|
+
pointer,
|
|
2729
|
+
mouse: pointer,
|
|
2730
|
+
frameloop: "always",
|
|
2731
|
+
onPointerMissed: void 0,
|
|
2732
|
+
onDragOverMissed: void 0,
|
|
2733
|
+
onDropMissed: void 0,
|
|
2734
|
+
performance: {
|
|
2735
|
+
current: 1,
|
|
2736
|
+
min: 0.5,
|
|
2737
|
+
max: 1,
|
|
2738
|
+
debounce: 200,
|
|
2739
|
+
regress: () => {
|
|
2740
|
+
const state2 = get();
|
|
2741
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
2742
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
2743
|
+
performanceTimeout = setTimeout(
|
|
2744
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
2745
|
+
state2.performance.debounce
|
|
2746
|
+
);
|
|
2747
|
+
}
|
|
2748
|
+
},
|
|
2749
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
2750
|
+
viewport: {
|
|
2751
|
+
initialDpr: 0,
|
|
2752
|
+
dpr: 0,
|
|
2753
|
+
width: 0,
|
|
2754
|
+
height: 0,
|
|
2755
|
+
top: 0,
|
|
2756
|
+
left: 0,
|
|
2757
|
+
aspect: 0,
|
|
2758
|
+
distance: 0,
|
|
2759
|
+
factor: 0,
|
|
2760
|
+
getCurrentViewport
|
|
2761
|
+
},
|
|
2762
|
+
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
2763
|
+
setSize: (width, height, top, left) => {
|
|
2764
|
+
const state2 = get();
|
|
2765
|
+
if (width === void 0) {
|
|
2766
|
+
set({ _sizeImperative: false });
|
|
2767
|
+
if (state2._sizeProps) {
|
|
2768
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
2769
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
2770
|
+
const currentSize = state2.size;
|
|
2771
|
+
const newSize = {
|
|
2772
|
+
width: propW ?? currentSize.width,
|
|
2773
|
+
height: propH ?? currentSize.height,
|
|
2774
|
+
top: currentSize.top,
|
|
2775
|
+
left: currentSize.left
|
|
2776
|
+
};
|
|
2777
|
+
set((s) => ({
|
|
2778
|
+
size: newSize,
|
|
2779
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
2780
|
+
}));
|
|
2781
|
+
getScheduler().invalidate();
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
return;
|
|
2785
|
+
}
|
|
2786
|
+
const w = width;
|
|
2787
|
+
const h = height ?? width;
|
|
2788
|
+
const t = top ?? state2.size.top;
|
|
2789
|
+
const l = left ?? state2.size.left;
|
|
2790
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
2791
|
+
set((s) => ({
|
|
2792
|
+
size,
|
|
2793
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
2794
|
+
_sizeImperative: true
|
|
2795
|
+
}));
|
|
2796
|
+
getScheduler().invalidate();
|
|
2797
|
+
},
|
|
2798
|
+
setDpr: (dpr) => set((state2) => {
|
|
2799
|
+
const resolved = calculateDpr(dpr);
|
|
2800
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
2801
|
+
}),
|
|
2802
|
+
setFrameloop: (frameloop = "always") => {
|
|
2803
|
+
set(() => ({ frameloop }));
|
|
2804
|
+
},
|
|
2805
|
+
setError: (error) => set(() => ({ error })),
|
|
2806
|
+
error: null,
|
|
2807
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useBuffers, useGPUStorage, useTextures, useRenderPipeline) ==============================
|
|
2808
|
+
uniforms: {},
|
|
2809
|
+
nodes: {},
|
|
2810
|
+
buffers: {},
|
|
2811
|
+
gpuStorage: {},
|
|
2812
|
+
textures: /* @__PURE__ */ new Map(),
|
|
2813
|
+
renderPipeline: null,
|
|
2814
|
+
passes: {},
|
|
2815
|
+
_hmrVersion: 0,
|
|
2816
|
+
_sizeImperative: false,
|
|
2817
|
+
_sizeProps: null,
|
|
2818
|
+
previousRoot: void 0,
|
|
2819
|
+
internal: {
|
|
2820
|
+
// Events
|
|
2821
|
+
interaction: [],
|
|
2822
|
+
subscribers: [],
|
|
2823
|
+
// Per-pointer state (new unified structure)
|
|
2824
|
+
pointerMap: /* @__PURE__ */ new Map(),
|
|
2825
|
+
pointerDirty: /* @__PURE__ */ new Map(),
|
|
2826
|
+
lastEvent: React.createRef(),
|
|
2827
|
+
// Deprecated but kept for backwards compatibility
|
|
2828
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
2829
|
+
initialClick: [0, 0],
|
|
2830
|
+
initialHits: [],
|
|
2831
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
2832
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
2833
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
2834
|
+
// Occlusion system (WebGPU only)
|
|
2835
|
+
occlusionEnabled: false,
|
|
2836
|
+
occlusionObserver: null,
|
|
2837
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
2838
|
+
helperGroup: null,
|
|
2839
|
+
// Updates
|
|
2840
|
+
active: false,
|
|
2841
|
+
frames: 0,
|
|
2842
|
+
priority: 0,
|
|
2843
|
+
subscribe: (ref, priority, store) => {
|
|
2844
|
+
const internal = get().internal;
|
|
2845
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
2846
|
+
internal.subscribers.push({ ref, priority, store });
|
|
2847
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
2848
|
+
return () => {
|
|
2849
|
+
const internal2 = get().internal;
|
|
2850
|
+
if (internal2?.subscribers) {
|
|
2851
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
2852
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
2853
|
+
}
|
|
2854
|
+
};
|
|
2855
|
+
},
|
|
2856
|
+
// Renderer Storage (single source of truth)
|
|
2857
|
+
actualRenderer: null,
|
|
2858
|
+
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
2859
|
+
scheduler: null
|
|
2860
|
+
}
|
|
2861
|
+
};
|
|
2862
|
+
return rootState;
|
|
2863
|
+
});
|
|
2864
|
+
const state = rootStore.getState();
|
|
2865
|
+
Object.defineProperty(state, "gl", {
|
|
2866
|
+
get() {
|
|
2867
|
+
const currentState = rootStore.getState();
|
|
2868
|
+
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
2869
|
+
const stack = new Error().stack || "";
|
|
2870
|
+
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
2871
|
+
if (!isInternalAccess) {
|
|
2872
|
+
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
2873
|
+
notifyDepreciated({
|
|
2874
|
+
heading: "Accessing state.gl in WebGPU mode",
|
|
2875
|
+
body: "Please use state.renderer instead. state.gl is deprecated and will be removed in future versions.\n\nFor backwards compatibility, state.gl currently maps to state.renderer, but this may cause issues with libraries expecting WebGLRenderer.\n\nAccessed from:\n" + cleanedStack
|
|
2876
|
+
});
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
return currentState.internal.actualRenderer;
|
|
2880
|
+
},
|
|
2881
|
+
set(value) {
|
|
2882
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2883
|
+
},
|
|
2884
|
+
enumerable: true,
|
|
2885
|
+
configurable: true
|
|
2886
|
+
});
|
|
2887
|
+
Object.defineProperty(state, "renderer", {
|
|
2888
|
+
get() {
|
|
2889
|
+
return rootStore.getState().internal.actualRenderer;
|
|
2890
|
+
},
|
|
2891
|
+
set(value) {
|
|
2892
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2893
|
+
},
|
|
2894
|
+
enumerable: true,
|
|
2895
|
+
configurable: true
|
|
2896
|
+
});
|
|
2897
|
+
let oldScene = state.scene;
|
|
2898
|
+
rootStore.subscribe(() => {
|
|
2899
|
+
const currentState = rootStore.getState();
|
|
2900
|
+
const { scene, rootScene, set } = currentState;
|
|
2901
|
+
if (scene !== oldScene) {
|
|
2902
|
+
oldScene = scene;
|
|
2903
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
2904
|
+
set({ rootScene: scene });
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
});
|
|
2908
|
+
let oldSize = state.size;
|
|
2909
|
+
let oldDpr = state.viewport.dpr;
|
|
2910
|
+
let oldCamera = state.camera;
|
|
2911
|
+
rootStore.subscribe(() => {
|
|
2912
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
2913
|
+
const actualRenderer = internal.actualRenderer;
|
|
2914
|
+
const canvasTarget = internal.canvasTarget;
|
|
2915
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
2916
|
+
oldSize = size;
|
|
2917
|
+
oldDpr = viewport.dpr;
|
|
2918
|
+
updateCamera(camera, size);
|
|
2919
|
+
if (internal.isSecondary && canvasTarget) {
|
|
2920
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2921
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
2922
|
+
} else {
|
|
2923
|
+
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
2924
|
+
actualRenderer.setSize(size.width, size.height, false);
|
|
2925
|
+
if (canvasTarget) {
|
|
2926
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2927
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
if (camera !== oldCamera) {
|
|
2932
|
+
oldCamera = camera;
|
|
2933
|
+
const { rootScene } = rootStore.getState();
|
|
2934
|
+
if (camera && rootScene && !camera.parent) {
|
|
2935
|
+
rootScene.add(camera);
|
|
2936
|
+
}
|
|
2937
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
2938
|
+
const currentState = rootStore.getState();
|
|
2939
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
2940
|
+
updateFrustum(camera, currentState.frustum);
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
});
|
|
2944
|
+
rootStore.subscribe((state2) => invalidate(state2));
|
|
2945
|
+
return rootStore;
|
|
2946
|
+
};
|
|
2947
|
+
|
|
2948
|
+
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
2949
|
+
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
2950
|
+
function getLoader(Proto) {
|
|
2951
|
+
if (isConstructor$1(Proto)) {
|
|
2952
|
+
let loader = memoizedLoaders.get(Proto);
|
|
2953
|
+
if (!loader) {
|
|
2954
|
+
loader = new Proto();
|
|
2955
|
+
memoizedLoaders.set(Proto, loader);
|
|
2956
|
+
}
|
|
2957
|
+
return loader;
|
|
2958
|
+
}
|
|
2959
|
+
return Proto;
|
|
2960
|
+
}
|
|
2961
|
+
function loadingFn(extensions, onProgress) {
|
|
2962
|
+
return function(Proto, input) {
|
|
2963
|
+
const loader = getLoader(Proto);
|
|
2964
|
+
if (extensions) extensions(loader);
|
|
2965
|
+
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
2966
|
+
return loader.loadAsync(input, onProgress).then((data) => {
|
|
2967
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2968
|
+
return data;
|
|
2969
|
+
});
|
|
2970
|
+
}
|
|
2971
|
+
return new Promise(
|
|
2972
|
+
(res, reject) => loader.load(
|
|
2973
|
+
input,
|
|
2974
|
+
(data) => {
|
|
2975
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2976
|
+
res(data);
|
|
2977
|
+
},
|
|
2978
|
+
onProgress,
|
|
2979
|
+
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
2980
|
+
)
|
|
2981
|
+
);
|
|
2982
|
+
};
|
|
2983
|
+
}
|
|
2984
|
+
function useLoader(loader, input, extensions, onProgress) {
|
|
2985
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2986
|
+
const fn = loadingFn(extensions, onProgress);
|
|
2987
|
+
const results = keys.map((key) => suspend(fn, [loader, key], { equal: is.equ }));
|
|
2988
|
+
return Array.isArray(input) ? results : results[0];
|
|
2989
|
+
}
|
|
2990
|
+
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
2991
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2992
|
+
keys.forEach((key) => preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
2993
|
+
};
|
|
2994
|
+
useLoader.clear = function(loader, input) {
|
|
2995
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2996
|
+
keys.forEach((key) => clear([loader, key]));
|
|
2997
|
+
};
|
|
2998
|
+
useLoader.loader = getLoader;
|
|
2999
|
+
|
|
3000
|
+
function useFrame(callback, priorityOrOptions) {
|
|
3001
|
+
const store = React.useContext(context);
|
|
3002
|
+
const isInsideCanvas = store !== null;
|
|
3003
|
+
const scheduler = getScheduler();
|
|
3004
|
+
const optionsKey = typeof priorityOrOptions === "number" ? `p:${priorityOrOptions}` : priorityOrOptions ? JSON.stringify({
|
|
3005
|
+
id: priorityOrOptions.id,
|
|
3006
|
+
phase: priorityOrOptions.phase,
|
|
3007
|
+
priority: priorityOrOptions.priority,
|
|
3008
|
+
fps: priorityOrOptions.fps,
|
|
3009
|
+
drop: priorityOrOptions.drop,
|
|
3010
|
+
enabled: priorityOrOptions.enabled,
|
|
3011
|
+
before: priorityOrOptions.before,
|
|
3012
|
+
after: priorityOrOptions.after
|
|
3013
|
+
}) : "";
|
|
3014
|
+
const options = React.useMemo(() => {
|
|
3015
|
+
return typeof priorityOrOptions === "number" ? { priority: priorityOrOptions } : priorityOrOptions ?? {};
|
|
3016
|
+
}, [optionsKey]);
|
|
3017
|
+
const reactId = React.useId();
|
|
3018
|
+
const id = options.id ?? reactId;
|
|
3019
|
+
const callbackRef = useMutableCallback(callback);
|
|
3020
|
+
const isLegacyPriority = typeof priorityOrOptions === "number" && priorityOrOptions > 0;
|
|
3021
|
+
useIsomorphicLayoutEffect(() => {
|
|
3022
|
+
if (!callback) return;
|
|
3023
|
+
if (isInsideCanvas) {
|
|
3024
|
+
const state = store.getState();
|
|
3025
|
+
const rootId = state.internal.rootId;
|
|
3026
|
+
if (isLegacyPriority) {
|
|
3027
|
+
state.internal.priority++;
|
|
3028
|
+
let parentRoot = state.previousRoot;
|
|
3029
|
+
while (parentRoot) {
|
|
3030
|
+
const parentState = parentRoot.getState();
|
|
3031
|
+
if (parentState?.internal) parentState.internal.priority++;
|
|
3032
|
+
parentRoot = parentState?.previousRoot;
|
|
3033
|
+
}
|
|
3034
|
+
notifyDepreciated({
|
|
3035
|
+
heading: "useFrame with numeric priority is deprecated",
|
|
3036
|
+
body: 'Using useFrame(callback, number) to control render order is deprecated.\n\nFor custom rendering, use: useFrame(callback, { phase: "render" })\nFor execution order within update phase, use: useFrame(callback, { priority: number })',
|
|
3037
|
+
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
3038
|
+
});
|
|
3039
|
+
}
|
|
3040
|
+
const wrappedCallback = (frameState, delta) => {
|
|
3041
|
+
const localState = store.getState();
|
|
3042
|
+
const mergedState = {
|
|
2380
3043
|
...localState,
|
|
2381
3044
|
time: frameState.time,
|
|
2382
3045
|
delta: frameState.delta,
|
|
@@ -2513,6 +3176,9 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2513
3176
|
const textureCache = useThree((state) => state.textures);
|
|
2514
3177
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
2515
3178
|
const { onLoad, cache = false } = options;
|
|
3179
|
+
const onLoadRef = useRef(onLoad);
|
|
3180
|
+
onLoadRef.current = onLoad;
|
|
3181
|
+
const onLoadCalledForRef = useRef(null);
|
|
2516
3182
|
const urls = useMemo(() => getUrls(input), [input]);
|
|
2517
3183
|
const cachedResult = useMemo(() => {
|
|
2518
3184
|
if (!cache) return null;
|
|
@@ -2523,9 +3189,13 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2523
3189
|
TextureLoader,
|
|
2524
3190
|
IsObject(input) ? Object.values(input) : input
|
|
2525
3191
|
);
|
|
3192
|
+
const inputKey = urls.join("\0");
|
|
2526
3193
|
useLayoutEffect(() => {
|
|
2527
|
-
if (
|
|
2528
|
-
|
|
3194
|
+
if (cachedResult) return;
|
|
3195
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
3196
|
+
onLoadCalledForRef.current = inputKey;
|
|
3197
|
+
onLoadRef.current?.(loadedTextures);
|
|
3198
|
+
}, [cachedResult, loadedTextures, inputKey]);
|
|
2529
3199
|
useEffect(() => {
|
|
2530
3200
|
if (cachedResult) return;
|
|
2531
3201
|
if ("initTexture" in renderer) {
|
|
@@ -2692,14 +3362,31 @@ function useTextures() {
|
|
|
2692
3362
|
}, [store]);
|
|
2693
3363
|
}
|
|
2694
3364
|
|
|
2695
|
-
function useRenderTarget(
|
|
3365
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
2696
3366
|
const isLegacy = useThree((s) => s.isLegacy);
|
|
2697
3367
|
const size = useThree((s) => s.size);
|
|
3368
|
+
let width;
|
|
3369
|
+
let height;
|
|
3370
|
+
let opts;
|
|
3371
|
+
if (typeof widthOrOptions === "object") {
|
|
3372
|
+
opts = widthOrOptions;
|
|
3373
|
+
} else if (typeof widthOrOptions === "number") {
|
|
3374
|
+
width = widthOrOptions;
|
|
3375
|
+
if (typeof heightOrOptions === "object") {
|
|
3376
|
+
height = widthOrOptions;
|
|
3377
|
+
opts = heightOrOptions;
|
|
3378
|
+
} else if (typeof heightOrOptions === "number") {
|
|
3379
|
+
height = heightOrOptions;
|
|
3380
|
+
opts = options;
|
|
3381
|
+
} else {
|
|
3382
|
+
height = widthOrOptions;
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
2698
3385
|
return useMemo(() => {
|
|
2699
3386
|
const w = width ?? size.width;
|
|
2700
3387
|
const h = height ?? size.height;
|
|
2701
|
-
return new RenderTarget(w, h,
|
|
2702
|
-
}, [width, height, size.width, size.height,
|
|
3388
|
+
return new RenderTarget(w, h, opts);
|
|
3389
|
+
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
2703
3390
|
}
|
|
2704
3391
|
|
|
2705
3392
|
function useStore() {
|
|
@@ -2749,28 +3436,18 @@ function addTail(callback) {
|
|
|
2749
3436
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
2750
3437
|
getScheduler().invalidate(frames, stackFrames);
|
|
2751
3438
|
}
|
|
2752
|
-
function advance(timestamp
|
|
3439
|
+
function advance(timestamp) {
|
|
2753
3440
|
getScheduler().step(timestamp);
|
|
2754
3441
|
}
|
|
2755
3442
|
|
|
2756
|
-
const version = "10.0.0-alpha.
|
|
3443
|
+
const version = "10.0.0-alpha.2";
|
|
2757
3444
|
const packageData = {
|
|
2758
3445
|
version: version};
|
|
2759
3446
|
|
|
2760
3447
|
function Xb(Tt) {
|
|
2761
3448
|
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
2762
3449
|
}
|
|
2763
|
-
var Rm = { exports: {} }, Og = { exports: {} };
|
|
2764
|
-
/**
|
|
2765
|
-
* @license React
|
|
2766
|
-
* react-reconciler.production.js
|
|
2767
|
-
*
|
|
2768
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2769
|
-
*
|
|
2770
|
-
* This source code is licensed under the MIT license found in the
|
|
2771
|
-
* LICENSE file in the root directory of this source tree.
|
|
2772
|
-
*/
|
|
2773
|
-
var _b;
|
|
3450
|
+
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
2774
3451
|
function Kb() {
|
|
2775
3452
|
return _b || (_b = 1, (function(Tt) {
|
|
2776
3453
|
Tt.exports = function(m) {
|
|
@@ -3842,7 +4519,6 @@ Error generating stack: ` + l.message + `
|
|
|
3842
4519
|
if (J === cl || J === jc) throw J;
|
|
3843
4520
|
var Ge = Yn(29, J, null, P.mode);
|
|
3844
4521
|
return Ge.lanes = H, Ge.return = P, Ge;
|
|
3845
|
-
} finally {
|
|
3846
4522
|
}
|
|
3847
4523
|
};
|
|
3848
4524
|
}
|
|
@@ -4496,7 +5172,6 @@ Error generating stack: ` + l.message + `
|
|
|
4496
5172
|
var h = r.lastRenderedState, y = d(h, a);
|
|
4497
5173
|
if (c.hasEagerState = true, c.eagerState = y, jn(y, h)) return go(t, r, c, 0), Ne === null && Bn(), false;
|
|
4498
5174
|
} catch {
|
|
4499
|
-
} finally {
|
|
4500
5175
|
}
|
|
4501
5176
|
if (a = yo(t, r, c, l), a !== null) return nt(a, t, l), ns(a, r, l), true;
|
|
4502
5177
|
}
|
|
@@ -6917,10 +7592,7 @@ Error generating stack: ` + l.message + `
|
|
|
6917
7592
|
function vr(t, r) {
|
|
6918
7593
|
Sf(t, r), (t = t.alternate) && Sf(t, r);
|
|
6919
7594
|
}
|
|
6920
|
-
var ie = {}, Fm = React__default, tt = Tb, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy");
|
|
6921
|
-
var gc = Symbol.for("react.activity");
|
|
6922
|
-
var $r = Symbol.for("react.memo_cache_sentinel");
|
|
6923
|
-
var Pf = Symbol.iterator, xf = Symbol.for("react.client.reference"), ca = Array.isArray, M = Fm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Yp = m.rendererVersion, zf = m.rendererPackageName, Cf = m.extraDevToolsConfig, Ts = m.getPublicInstance, Hm = m.getRootHostContext, Xp = m.getChildHostContext, Am = m.prepareForCommit, _s = m.resetAfterCommit, Vr = m.createInstance;
|
|
7595
|
+
var ie = {}, Fm = React__default, tt = Tb, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy"), gc = Symbol.for("react.activity"), $r = Symbol.for("react.memo_cache_sentinel"), Pf = Symbol.iterator, xf = Symbol.for("react.client.reference"), ca = Array.isArray, M = Fm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Yp = m.rendererVersion, zf = m.rendererPackageName, Cf = m.extraDevToolsConfig, Ts = m.getPublicInstance, Hm = m.getRootHostContext, Xp = m.getChildHostContext, Am = m.prepareForCommit, _s = m.resetAfterCommit, Vr = m.createInstance;
|
|
6924
7596
|
m.cloneMutableInstance;
|
|
6925
7597
|
var yc = m.appendInitialChild, Kp = m.finalizeInitialChildren, Rs = m.shouldSetTextContent, bc = m.createTextInstance;
|
|
6926
7598
|
m.cloneMutableTextInstance;
|
|
@@ -7289,17 +7961,7 @@ No matching component was found for:
|
|
|
7289
7961
|
}, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true });
|
|
7290
7962
|
})(Og)), Og.exports;
|
|
7291
7963
|
}
|
|
7292
|
-
var Mg = { exports: {} };
|
|
7293
|
-
/**
|
|
7294
|
-
* @license React
|
|
7295
|
-
* react-reconciler.development.js
|
|
7296
|
-
*
|
|
7297
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
7298
|
-
*
|
|
7299
|
-
* This source code is licensed under the MIT license found in the
|
|
7300
|
-
* LICENSE file in the root directory of this source tree.
|
|
7301
|
-
*/
|
|
7302
|
-
var Rb;
|
|
7964
|
+
var Mg = { exports: {} }, Rb;
|
|
7303
7965
|
function e0() {
|
|
7304
7966
|
return Rb || (Rb = 1, (function(Tt) {
|
|
7305
7967
|
process.env.NODE_ENV !== "production" && (Tt.exports = function(m) {
|
|
@@ -13066,10 +13728,7 @@ Check the render method of %s.`, G(di) || "Unknown")), i = zo(n), i.payload = {
|
|
|
13066
13728
|
function Ic() {
|
|
13067
13729
|
return di;
|
|
13068
13730
|
}
|
|
13069
|
-
var le = {}, qm = React__default, St = Tb, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy");
|
|
13070
|
-
var Ds = Symbol.for("react.activity");
|
|
13071
|
-
var Bh = Symbol.for("react.memo_cache_sentinel");
|
|
13072
|
-
var ni = Symbol.iterator, il = Symbol.for("react.client.reference"), fn = Array.isArray, x = qm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Jt = m.rendererVersion, Zt = m.rendererPackageName, jo = m.extraDevToolsConfig, ot = m.getPublicInstance, Zr = m.getRootHostContext, Dn = m.getChildHostContext, Ws = m.prepareForCommit, pa = m.resetAfterCommit, Fc = m.createInstance;
|
|
13731
|
+
var le = {}, qm = React__default, St = Tb, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy"), Ds = Symbol.for("react.activity"), Bh = Symbol.for("react.memo_cache_sentinel"), ni = Symbol.iterator, il = Symbol.for("react.client.reference"), fn = Array.isArray, x = qm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Jt = m.rendererVersion, Zt = m.rendererPackageName, jo = m.extraDevToolsConfig, ot = m.getPublicInstance, Zr = m.getRootHostContext, Dn = m.getChildHostContext, Ws = m.prepareForCommit, pa = m.resetAfterCommit, Fc = m.createInstance;
|
|
13073
13732
|
m.cloneMutableInstance;
|
|
13074
13733
|
var bn = m.appendInitialChild, Ue = m.finalizeInitialChildren, ue = m.shouldSetTextContent, Do = m.createTextInstance;
|
|
13075
13734
|
m.cloneMutableTextInstance;
|
|
@@ -14037,15 +14696,6 @@ function n0() {
|
|
|
14037
14696
|
var t0 = n0();
|
|
14038
14697
|
const r0 = Xb(t0);
|
|
14039
14698
|
|
|
14040
|
-
/**
|
|
14041
|
-
* @license React
|
|
14042
|
-
* react-reconciler-constants.production.js
|
|
14043
|
-
*
|
|
14044
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14045
|
-
*
|
|
14046
|
-
* This source code is licensed under the MIT license found in the
|
|
14047
|
-
* LICENSE file in the root directory of this source tree.
|
|
14048
|
-
*/
|
|
14049
14699
|
const t = 1, o = 8, r = 32, e = 2;
|
|
14050
14700
|
|
|
14051
14701
|
function createReconciler(config) {
|
|
@@ -14072,10 +14722,11 @@ function extend(objects) {
|
|
|
14072
14722
|
function validateInstance(type, props) {
|
|
14073
14723
|
const name = toPascalCase(type);
|
|
14074
14724
|
const target = catalogue[name];
|
|
14075
|
-
if (type !== "primitive" && !target)
|
|
14725
|
+
if (type !== "primitive" && !target) {
|
|
14076
14726
|
throw new Error(
|
|
14077
14727
|
`R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`
|
|
14078
14728
|
);
|
|
14729
|
+
}
|
|
14079
14730
|
if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
|
|
14080
14731
|
if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
|
|
14081
14732
|
}
|
|
@@ -14239,6 +14890,7 @@ function swapInstances() {
|
|
|
14239
14890
|
instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
|
|
14240
14891
|
instance.object.__r3f = instance;
|
|
14241
14892
|
setFiberRef(fiber, instance.object);
|
|
14893
|
+
delete instance.appliedOnce;
|
|
14242
14894
|
applyProps(instance.object, instance.props);
|
|
14243
14895
|
if (instance.props.attach) {
|
|
14244
14896
|
attach(parent, instance);
|
|
@@ -14312,8 +14964,22 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14312
14964
|
const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
|
|
14313
14965
|
if (isTailSibling) swapInstances();
|
|
14314
14966
|
},
|
|
14315
|
-
finalizeInitialChildren: () =>
|
|
14316
|
-
|
|
14967
|
+
finalizeInitialChildren: (instance) => {
|
|
14968
|
+
for (const prop in instance.props) {
|
|
14969
|
+
if (isFromRef(instance.props[prop])) return true;
|
|
14970
|
+
}
|
|
14971
|
+
return false;
|
|
14972
|
+
},
|
|
14973
|
+
commitMount(instance) {
|
|
14974
|
+
const resolved = {};
|
|
14975
|
+
for (const prop in instance.props) {
|
|
14976
|
+
const value = instance.props[prop];
|
|
14977
|
+
if (isFromRef(value)) {
|
|
14978
|
+
const ref = value[FROM_REF];
|
|
14979
|
+
if (ref.current != null) resolved[prop] = ref.current;
|
|
14980
|
+
}
|
|
14981
|
+
}
|
|
14982
|
+
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
14317
14983
|
},
|
|
14318
14984
|
getPublicInstance: (instance) => instance?.object,
|
|
14319
14985
|
prepareForCommit: () => null,
|
|
@@ -14526,14 +15192,17 @@ function createRoot(canvas) {
|
|
|
14526
15192
|
if (!prevRoot) _roots.set(canvas, { fiber, store });
|
|
14527
15193
|
let onCreated;
|
|
14528
15194
|
let lastCamera;
|
|
14529
|
-
|
|
15195
|
+
const lastConfiguredProps = {};
|
|
14530
15196
|
let configured = false;
|
|
14531
15197
|
let pending = null;
|
|
14532
15198
|
return {
|
|
14533
15199
|
async configure(props = {}) {
|
|
14534
15200
|
let resolve;
|
|
14535
15201
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14536
|
-
|
|
15202
|
+
const {
|
|
15203
|
+
id: canvasId,
|
|
15204
|
+
primaryCanvas,
|
|
15205
|
+
scheduler: schedulerConfig,
|
|
14537
15206
|
gl: glConfig,
|
|
14538
15207
|
renderer: rendererConfig,
|
|
14539
15208
|
size: propsSize,
|
|
@@ -14541,10 +15210,6 @@ function createRoot(canvas) {
|
|
|
14541
15210
|
events,
|
|
14542
15211
|
onCreated: onCreatedCallback,
|
|
14543
15212
|
shadows = false,
|
|
14544
|
-
linear = false,
|
|
14545
|
-
flat = false,
|
|
14546
|
-
textureColorSpace = SRGBColorSpace,
|
|
14547
|
-
legacy = false,
|
|
14548
15213
|
orthographic = false,
|
|
14549
15214
|
frameloop = "always",
|
|
14550
15215
|
dpr = [1, 2],
|
|
@@ -14555,11 +15220,15 @@ function createRoot(canvas) {
|
|
|
14555
15220
|
onDragOverMissed,
|
|
14556
15221
|
onDropMissed,
|
|
14557
15222
|
autoUpdateFrustum = true,
|
|
14558
|
-
occlusion = false
|
|
15223
|
+
occlusion = false,
|
|
15224
|
+
_sizeProps,
|
|
15225
|
+
forceEven
|
|
14559
15226
|
} = props;
|
|
14560
|
-
|
|
15227
|
+
const textureColorSpace = is.obj(glConfig) && !is.fun(glConfig) && !isRenderer(glConfig) && glConfig.textureColorSpace || is.obj(rendererConfig) && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && rendererConfig.textureColorSpace || SRGBColorSpace;
|
|
15228
|
+
const state = store.getState();
|
|
14561
15229
|
const defaultGPUProps = {
|
|
14562
|
-
canvas
|
|
15230
|
+
canvas,
|
|
15231
|
+
antialias: true
|
|
14563
15232
|
};
|
|
14564
15233
|
if (glConfig && !R3F_BUILD_LEGACY) {
|
|
14565
15234
|
throw new Error(
|
|
@@ -14570,22 +15239,61 @@ function createRoot(canvas) {
|
|
|
14570
15239
|
throw new Error("Cannot use both gl and renderer props at the same time");
|
|
14571
15240
|
}
|
|
14572
15241
|
let renderer = state.internal.actualRenderer;
|
|
14573
|
-
if (!state.internal.actualRenderer) {
|
|
15242
|
+
if (primaryCanvas && !state.internal.actualRenderer) {
|
|
15243
|
+
const primary = await waitForPrimary(primaryCanvas);
|
|
15244
|
+
renderer = primary.renderer;
|
|
15245
|
+
state.internal.actualRenderer = renderer;
|
|
15246
|
+
const canvasTarget = new CanvasTarget(canvas);
|
|
15247
|
+
primary.store.setState((prev) => ({
|
|
15248
|
+
internal: { ...prev.internal, isMultiCanvas: true }
|
|
15249
|
+
}));
|
|
15250
|
+
state.set((prev) => ({
|
|
15251
|
+
webGPUSupported: primary.store.getState().webGPUSupported,
|
|
15252
|
+
renderer,
|
|
15253
|
+
primaryStore: primary.store,
|
|
15254
|
+
internal: {
|
|
15255
|
+
...prev.internal,
|
|
15256
|
+
canvasTarget,
|
|
15257
|
+
isMultiCanvas: true,
|
|
15258
|
+
isSecondary: true,
|
|
15259
|
+
targetId: primaryCanvas
|
|
15260
|
+
}
|
|
15261
|
+
}));
|
|
15262
|
+
} else if (!state.internal.actualRenderer) {
|
|
14574
15263
|
renderer = await resolveRenderer(rendererConfig, defaultGPUProps, WebGPURenderer);
|
|
14575
15264
|
if (!renderer.hasInitialized?.()) {
|
|
15265
|
+
const size2 = computeInitialSize(canvas, propsSize);
|
|
15266
|
+
if (size2.width > 0 && size2.height > 0) {
|
|
15267
|
+
const pixelRatio = calculateDpr(dpr);
|
|
15268
|
+
canvas.width = size2.width * pixelRatio;
|
|
15269
|
+
canvas.height = size2.height * pixelRatio;
|
|
15270
|
+
}
|
|
14576
15271
|
await renderer.init();
|
|
14577
15272
|
}
|
|
14578
15273
|
const backend = renderer.backend;
|
|
14579
15274
|
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
14580
15275
|
state.internal.actualRenderer = renderer;
|
|
14581
|
-
state.set({ webGPUSupported: isWebGPUBackend, renderer });
|
|
15276
|
+
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
15277
|
+
if (canvasId && !state.internal.isSecondary) {
|
|
15278
|
+
const canvasTarget = new CanvasTarget(canvas);
|
|
15279
|
+
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
15280
|
+
state.set((prev) => ({
|
|
15281
|
+
internal: {
|
|
15282
|
+
...prev.internal,
|
|
15283
|
+
canvasTarget,
|
|
15284
|
+
unregisterPrimary
|
|
15285
|
+
}
|
|
15286
|
+
}));
|
|
15287
|
+
}
|
|
14582
15288
|
}
|
|
14583
15289
|
let raycaster = state.raycaster;
|
|
14584
15290
|
if (!raycaster) state.set({ raycaster: raycaster = new Raycaster() });
|
|
14585
15291
|
const { params, ...options } = raycastOptions || {};
|
|
14586
15292
|
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options });
|
|
14587
|
-
if (!is.equ(params, raycaster.params, shallowLoose))
|
|
15293
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) {
|
|
14588
15294
|
applyProps(raycaster, { params: { ...raycaster.params, ...params } });
|
|
15295
|
+
}
|
|
15296
|
+
let tempCamera = state.camera;
|
|
14589
15297
|
if (!state.camera || state.camera === lastCamera && !is.equ(lastCamera, cameraOptions, shallowLoose)) {
|
|
14590
15298
|
lastCamera = cameraOptions;
|
|
14591
15299
|
const isCamera = cameraOptions?.isCamera;
|
|
@@ -14605,6 +15313,7 @@ function createRoot(canvas) {
|
|
|
14605
15313
|
if (!state.camera && !cameraOptions?.rotation) camera.lookAt(0, 0, 0);
|
|
14606
15314
|
}
|
|
14607
15315
|
state.set({ camera });
|
|
15316
|
+
tempCamera = camera;
|
|
14608
15317
|
raycaster.camera = camera;
|
|
14609
15318
|
}
|
|
14610
15319
|
if (!state.scene) {
|
|
@@ -14622,7 +15331,7 @@ function createRoot(canvas) {
|
|
|
14622
15331
|
rootScene: scene,
|
|
14623
15332
|
internal: { ...prev.internal, container: scene }
|
|
14624
15333
|
}));
|
|
14625
|
-
const camera =
|
|
15334
|
+
const camera = tempCamera;
|
|
14626
15335
|
if (camera && !camera.parent) scene.add(camera);
|
|
14627
15336
|
}
|
|
14628
15337
|
if (events && !state.events.handlers) {
|
|
@@ -14636,9 +15345,17 @@ function createRoot(canvas) {
|
|
|
14636
15345
|
wasEnabled = enabled;
|
|
14637
15346
|
});
|
|
14638
15347
|
}
|
|
15348
|
+
if (_sizeProps !== void 0) {
|
|
15349
|
+
state.set({ _sizeProps });
|
|
15350
|
+
}
|
|
15351
|
+
if (forceEven !== void 0 && state.internal.forceEven !== forceEven) {
|
|
15352
|
+
state.set((prev) => ({ internal: { ...prev.internal, forceEven } }));
|
|
15353
|
+
}
|
|
14639
15354
|
const size = computeInitialSize(canvas, propsSize);
|
|
14640
|
-
if (!is.equ(size, state.size, shallowLoose)) {
|
|
15355
|
+
if (!state._sizeImperative && !is.equ(size, state.size, shallowLoose)) {
|
|
15356
|
+
const wasImperative = state._sizeImperative;
|
|
14641
15357
|
state.setSize(size.width, size.height, size.top, size.left);
|
|
15358
|
+
if (!wasImperative) state.set({ _sizeImperative: false });
|
|
14642
15359
|
}
|
|
14643
15360
|
if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
|
|
14644
15361
|
state.setDpr(dpr);
|
|
@@ -14660,10 +15377,10 @@ function createRoot(canvas) {
|
|
|
14660
15377
|
lastConfiguredProps.performance = performance;
|
|
14661
15378
|
}
|
|
14662
15379
|
if (!state.xr) {
|
|
14663
|
-
const handleXRFrame = (timestamp,
|
|
15380
|
+
const handleXRFrame = (timestamp, _frame) => {
|
|
14664
15381
|
const state2 = store.getState();
|
|
14665
15382
|
if (state2.frameloop === "never") return;
|
|
14666
|
-
advance(timestamp
|
|
15383
|
+
advance(timestamp);
|
|
14667
15384
|
};
|
|
14668
15385
|
const actualRenderer = state.internal.actualRenderer;
|
|
14669
15386
|
const handleSessionChange = () => {
|
|
@@ -14675,16 +15392,16 @@ function createRoot(canvas) {
|
|
|
14675
15392
|
};
|
|
14676
15393
|
const xr = {
|
|
14677
15394
|
connect() {
|
|
14678
|
-
const { gl, renderer: renderer2
|
|
14679
|
-
const
|
|
14680
|
-
|
|
14681
|
-
|
|
15395
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15396
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15397
|
+
xrManager.addEventListener("sessionstart", handleSessionChange);
|
|
15398
|
+
xrManager.addEventListener("sessionend", handleSessionChange);
|
|
14682
15399
|
},
|
|
14683
15400
|
disconnect() {
|
|
14684
|
-
const { gl, renderer: renderer2
|
|
14685
|
-
const
|
|
14686
|
-
|
|
14687
|
-
|
|
15401
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15402
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15403
|
+
xrManager.removeEventListener("sessionstart", handleSessionChange);
|
|
15404
|
+
xrManager.removeEventListener("sessionend", handleSessionChange);
|
|
14688
15405
|
}
|
|
14689
15406
|
};
|
|
14690
15407
|
if (typeof renderer.xr?.addEventListener === "function") xr.connect();
|
|
@@ -14696,41 +15413,92 @@ function createRoot(canvas) {
|
|
|
14696
15413
|
const oldType = renderer.shadowMap.type;
|
|
14697
15414
|
renderer.shadowMap.enabled = !!shadows;
|
|
14698
15415
|
if (is.boo(shadows)) {
|
|
14699
|
-
renderer.shadowMap.type =
|
|
15416
|
+
renderer.shadowMap.type = PCFShadowMap;
|
|
14700
15417
|
} else if (is.str(shadows)) {
|
|
15418
|
+
if (shadows === "soft") {
|
|
15419
|
+
notifyDepreciated({
|
|
15420
|
+
heading: 'shadows="soft" is deprecated',
|
|
15421
|
+
body: "Three has depreciated soft and improved basic PCFShadows, we converted for you.",
|
|
15422
|
+
link: "https://github.com/mrdoob/three.js/wiki/Migration-Guide?utm_source=chatgpt.com#181--182"
|
|
15423
|
+
});
|
|
15424
|
+
}
|
|
14701
15425
|
const types = {
|
|
14702
15426
|
basic: BasicShadowMap,
|
|
14703
15427
|
percentage: PCFShadowMap,
|
|
14704
|
-
soft:
|
|
15428
|
+
soft: PCFShadowMap,
|
|
14705
15429
|
variance: VSMShadowMap
|
|
14706
15430
|
};
|
|
14707
|
-
renderer.shadowMap.type = types[shadows] ??
|
|
15431
|
+
renderer.shadowMap.type = types[shadows] ?? PCFShadowMap;
|
|
14708
15432
|
} else if (is.obj(shadows)) {
|
|
14709
15433
|
Object.assign(renderer.shadowMap, shadows);
|
|
14710
15434
|
}
|
|
14711
|
-
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type)
|
|
15435
|
+
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type) {
|
|
14712
15436
|
renderer.shadowMap.needsUpdate = true;
|
|
15437
|
+
}
|
|
15438
|
+
}
|
|
15439
|
+
if (!configured) {
|
|
15440
|
+
renderer.outputColorSpace = SRGBColorSpace;
|
|
15441
|
+
renderer.toneMapping = ACESFilmicToneMapping;
|
|
14713
15442
|
}
|
|
14714
15443
|
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
14715
15444
|
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
14716
15445
|
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
14717
15446
|
}
|
|
14718
|
-
|
|
14719
|
-
|
|
15447
|
+
const r3fProps = ["textureColorSpace"];
|
|
15448
|
+
const constructorOnlyProps = ["samples", "antialias", "alpha", "canvas", "powerPreference"];
|
|
15449
|
+
const nonApplyProps = [...r3fProps, ...constructorOnlyProps];
|
|
15450
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
|
|
15451
|
+
const glProps = {};
|
|
15452
|
+
for (const key in glConfig) {
|
|
15453
|
+
if (!nonApplyProps.includes(key)) glProps[key] = glConfig[key];
|
|
15454
|
+
}
|
|
15455
|
+
applyProps(renderer, glProps);
|
|
15456
|
+
}
|
|
14720
15457
|
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
|
|
14721
15458
|
const currentRenderer = state.renderer;
|
|
14722
15459
|
if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
|
|
14723
|
-
|
|
15460
|
+
const rendererProps = {};
|
|
15461
|
+
for (const key in rendererConfig) {
|
|
15462
|
+
if (!nonApplyProps.includes(key)) rendererProps[key] = rendererConfig[key];
|
|
15463
|
+
}
|
|
15464
|
+
applyProps(currentRenderer, rendererProps);
|
|
14724
15465
|
}
|
|
14725
15466
|
}
|
|
14726
15467
|
const scheduler = getScheduler();
|
|
14727
15468
|
const rootId = state.internal.rootId;
|
|
14728
15469
|
if (!rootId) {
|
|
14729
|
-
const newRootId = scheduler.generateRootId();
|
|
15470
|
+
const newRootId = canvasId || scheduler.generateRootId();
|
|
14730
15471
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14731
15472
|
getState: () => store.getState(),
|
|
14732
15473
|
onError: (err) => store.getState().setError(err)
|
|
14733
15474
|
});
|
|
15475
|
+
const unregisterCanvasTarget = scheduler.register(
|
|
15476
|
+
() => {
|
|
15477
|
+
const state2 = store.getState();
|
|
15478
|
+
if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
|
|
15479
|
+
const renderer2 = state2.internal.actualRenderer;
|
|
15480
|
+
renderer2.setCanvasTarget(state2.internal.canvasTarget);
|
|
15481
|
+
}
|
|
15482
|
+
},
|
|
15483
|
+
{
|
|
15484
|
+
id: `${newRootId}_canvasTarget`,
|
|
15485
|
+
rootId: newRootId,
|
|
15486
|
+
phase: "start",
|
|
15487
|
+
system: true
|
|
15488
|
+
}
|
|
15489
|
+
);
|
|
15490
|
+
const unregisterEventsFlush = scheduler.register(
|
|
15491
|
+
() => {
|
|
15492
|
+
const state2 = store.getState();
|
|
15493
|
+
state2.events.flush?.();
|
|
15494
|
+
},
|
|
15495
|
+
{
|
|
15496
|
+
id: `${newRootId}_events`,
|
|
15497
|
+
rootId: newRootId,
|
|
15498
|
+
phase: "input",
|
|
15499
|
+
system: true
|
|
15500
|
+
}
|
|
15501
|
+
);
|
|
14734
15502
|
const unregisterFrustum = scheduler.register(
|
|
14735
15503
|
() => {
|
|
14736
15504
|
const state2 = store.getState();
|
|
@@ -14765,18 +15533,22 @@ function createRoot(canvas) {
|
|
|
14765
15533
|
const userHandlesRender = scheduler.hasUserJobsInPhase("render", newRootId);
|
|
14766
15534
|
if (userHandlesRender || state2.internal.priority) return;
|
|
14767
15535
|
try {
|
|
14768
|
-
if (state2.
|
|
15536
|
+
if (state2.renderPipeline?.render) state2.renderPipeline.render();
|
|
14769
15537
|
else if (renderer2?.render) renderer2.render(state2.scene, state2.camera);
|
|
14770
15538
|
} catch (error) {
|
|
14771
15539
|
state2.setError(error instanceof Error ? error : new Error(String(error)));
|
|
14772
15540
|
}
|
|
14773
15541
|
},
|
|
14774
15542
|
{
|
|
14775
|
-
|
|
15543
|
+
// Use canvas ID directly as job ID if available, otherwise use generated rootId
|
|
15544
|
+
id: canvasId || `${newRootId}_render`,
|
|
14776
15545
|
rootId: newRootId,
|
|
14777
15546
|
phase: "render",
|
|
14778
|
-
system: true
|
|
15547
|
+
system: true,
|
|
14779
15548
|
// Internal flag: this is a system job, not user-controlled
|
|
15549
|
+
// Apply scheduler config for render ordering and rate limiting
|
|
15550
|
+
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
15551
|
+
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14780
15552
|
}
|
|
14781
15553
|
);
|
|
14782
15554
|
state.set((state2) => ({
|
|
@@ -14785,6 +15557,8 @@ function createRoot(canvas) {
|
|
|
14785
15557
|
rootId: newRootId,
|
|
14786
15558
|
unregisterRoot: () => {
|
|
14787
15559
|
unregisterRoot();
|
|
15560
|
+
unregisterCanvasTarget();
|
|
15561
|
+
unregisterEventsFlush();
|
|
14788
15562
|
unregisterFrustum();
|
|
14789
15563
|
unregisterVisibility();
|
|
14790
15564
|
unregisterRender();
|
|
@@ -14843,15 +15617,24 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14843
15617
|
const renderer = state.internal.actualRenderer;
|
|
14844
15618
|
const unregisterRoot = state.internal.unregisterRoot;
|
|
14845
15619
|
if (unregisterRoot) unregisterRoot();
|
|
15620
|
+
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
15621
|
+
if (unregisterPrimary) unregisterPrimary();
|
|
15622
|
+
const canvasTarget = state.internal.canvasTarget;
|
|
15623
|
+
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14846
15624
|
state.events.disconnect?.();
|
|
14847
15625
|
cleanupHelperGroup(root.store);
|
|
14848
|
-
renderer
|
|
14849
|
-
|
|
14850
|
-
|
|
15626
|
+
if (state.isLegacy && renderer) {
|
|
15627
|
+
;
|
|
15628
|
+
renderer.renderLists?.dispose?.();
|
|
15629
|
+
renderer.forceContextLoss?.();
|
|
15630
|
+
}
|
|
15631
|
+
if (!state.internal.isSecondary) {
|
|
15632
|
+
if (renderer?.xr) state.xr.disconnect();
|
|
15633
|
+
}
|
|
14851
15634
|
dispose(state.scene);
|
|
14852
15635
|
_roots.delete(canvas);
|
|
14853
15636
|
if (callback) callback(canvas);
|
|
14854
|
-
} catch
|
|
15637
|
+
} catch {
|
|
14855
15638
|
}
|
|
14856
15639
|
}, 500);
|
|
14857
15640
|
}
|
|
@@ -14859,36 +15642,34 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14859
15642
|
}
|
|
14860
15643
|
}
|
|
14861
15644
|
function createPortal(children, container, state) {
|
|
14862
|
-
return /* @__PURE__ */ jsx(
|
|
15645
|
+
return /* @__PURE__ */ jsx(Portal, { children, container, state });
|
|
14863
15646
|
}
|
|
14864
|
-
function
|
|
15647
|
+
function Portal({ children, container, state }) {
|
|
14865
15648
|
const isRef = useCallback((obj) => obj && "current" in obj, []);
|
|
14866
|
-
const [resolvedContainer,
|
|
15649
|
+
const [resolvedContainer, _setResolvedContainer] = useState(() => {
|
|
14867
15650
|
if (isRef(container)) return container.current ?? null;
|
|
14868
15651
|
return container;
|
|
14869
15652
|
});
|
|
15653
|
+
const setResolvedContainer = useCallback(
|
|
15654
|
+
(newContainer) => {
|
|
15655
|
+
if (!newContainer || newContainer === resolvedContainer) return;
|
|
15656
|
+
_setResolvedContainer(isRef(newContainer) ? newContainer.current : newContainer);
|
|
15657
|
+
},
|
|
15658
|
+
[resolvedContainer, _setResolvedContainer, isRef]
|
|
15659
|
+
);
|
|
14870
15660
|
useMemo(() => {
|
|
14871
|
-
if (isRef(container)) {
|
|
14872
|
-
|
|
14873
|
-
|
|
14874
|
-
|
|
14875
|
-
const updated = container.current;
|
|
14876
|
-
if (updated && updated !== resolvedContainer) {
|
|
14877
|
-
setResolvedContainer(updated);
|
|
14878
|
-
}
|
|
14879
|
-
});
|
|
14880
|
-
} else if (current !== resolvedContainer) {
|
|
14881
|
-
setResolvedContainer(current);
|
|
14882
|
-
}
|
|
14883
|
-
} else if (container !== resolvedContainer) {
|
|
14884
|
-
setResolvedContainer(container);
|
|
15661
|
+
if (isRef(container) && !container.current) {
|
|
15662
|
+
return queueMicrotask(() => {
|
|
15663
|
+
setResolvedContainer(container.current);
|
|
15664
|
+
});
|
|
14885
15665
|
}
|
|
14886
|
-
|
|
15666
|
+
setResolvedContainer(container);
|
|
15667
|
+
}, [container, isRef, setResolvedContainer]);
|
|
14887
15668
|
if (!resolvedContainer) return /* @__PURE__ */ jsx(Fragment, {});
|
|
14888
15669
|
const portalKey = resolvedContainer.uuid ?? `portal-${resolvedContainer.id ?? "unknown"}`;
|
|
14889
|
-
return /* @__PURE__ */ jsx(
|
|
15670
|
+
return /* @__PURE__ */ jsx(PortalInner, { children, container: resolvedContainer, state }, portalKey);
|
|
14890
15671
|
}
|
|
14891
|
-
function
|
|
15672
|
+
function PortalInner({ state = {}, children, container }) {
|
|
14892
15673
|
const { events, size, injectScene = true, ...rest } = state;
|
|
14893
15674
|
const previousRoot = useStore();
|
|
14894
15675
|
const [raycaster] = useState(() => new Raycaster());
|
|
@@ -14909,11 +15690,12 @@ function Portal({ state = {}, children, container }) {
|
|
|
14909
15690
|
};
|
|
14910
15691
|
}, [portalScene, container, injectScene]);
|
|
14911
15692
|
const inject = useMutableCallback((rootState, injectState) => {
|
|
15693
|
+
const resolvedSize = { ...rootState.size, ...injectState.size, ...size };
|
|
14912
15694
|
let viewport = void 0;
|
|
14913
|
-
if (injectState.camera && size) {
|
|
15695
|
+
if (injectState.camera && (size || injectState.size)) {
|
|
14914
15696
|
const camera = injectState.camera;
|
|
14915
|
-
viewport = rootState.viewport.getCurrentViewport(camera, new Vector3(),
|
|
14916
|
-
if (camera !== rootState.camera) updateCamera(camera,
|
|
15697
|
+
viewport = rootState.viewport.getCurrentViewport(camera, new Vector3(), resolvedSize);
|
|
15698
|
+
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14917
15699
|
}
|
|
14918
15700
|
return {
|
|
14919
15701
|
// The intersect consists of the previous root state
|
|
@@ -14930,7 +15712,7 @@ function Portal({ state = {}, children, container }) {
|
|
|
14930
15712
|
previousRoot,
|
|
14931
15713
|
// Events, size and viewport can be overridden by the inject layer
|
|
14932
15714
|
events: { ...rootState.events, ...injectState.events, ...events },
|
|
14933
|
-
size:
|
|
15715
|
+
size: resolvedSize,
|
|
14934
15716
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14935
15717
|
// Layers are allowed to override events
|
|
14936
15718
|
setEvents: (events2) => injectState.set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
@@ -14942,9 +15724,13 @@ function Portal({ state = {}, children, container }) {
|
|
|
14942
15724
|
const store = createWithEqualityFn((set, get) => ({ ...rest, set, get }));
|
|
14943
15725
|
const onMutate = (prev) => store.setState((state2) => inject.current(prev, state2));
|
|
14944
15726
|
onMutate(previousRoot.getState());
|
|
14945
|
-
previousRoot.subscribe(onMutate);
|
|
14946
15727
|
return store;
|
|
14947
15728
|
}, [previousRoot, container]);
|
|
15729
|
+
useIsomorphicLayoutEffect(() => {
|
|
15730
|
+
const onMutate = (prev) => usePortalStore.setState((state2) => inject.current(prev, state2));
|
|
15731
|
+
const unsubscribe = previousRoot.subscribe(onMutate);
|
|
15732
|
+
return unsubscribe;
|
|
15733
|
+
}, [previousRoot, usePortalStore]);
|
|
14948
15734
|
return (
|
|
14949
15735
|
// @ts-ignore, reconciler types are not maintained
|
|
14950
15736
|
/* @__PURE__ */ jsx(Fragment, { children: reconciler.createPortal(
|
|
@@ -14964,15 +15750,13 @@ function CanvasImpl({
|
|
|
14964
15750
|
fallback,
|
|
14965
15751
|
resize,
|
|
14966
15752
|
style,
|
|
15753
|
+
id,
|
|
14967
15754
|
gl,
|
|
14968
|
-
renderer,
|
|
15755
|
+
renderer: rendererProp,
|
|
14969
15756
|
events = createPointerEvents,
|
|
14970
15757
|
eventSource,
|
|
14971
15758
|
eventPrefix,
|
|
14972
15759
|
shadows,
|
|
14973
|
-
linear,
|
|
14974
|
-
flat,
|
|
14975
|
-
legacy,
|
|
14976
15760
|
orthographic,
|
|
14977
15761
|
frameloop,
|
|
14978
15762
|
dpr,
|
|
@@ -14984,10 +15768,56 @@ function CanvasImpl({
|
|
|
14984
15768
|
onDragOverMissed,
|
|
14985
15769
|
onDropMissed,
|
|
14986
15770
|
onCreated,
|
|
15771
|
+
hmr,
|
|
15772
|
+
width,
|
|
15773
|
+
height,
|
|
15774
|
+
background,
|
|
15775
|
+
forceEven,
|
|
14987
15776
|
...props
|
|
14988
15777
|
}) {
|
|
15778
|
+
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
15779
|
+
let primaryCanvas;
|
|
15780
|
+
let scheduler;
|
|
15781
|
+
let renderer;
|
|
15782
|
+
if (isRendererConfig) {
|
|
15783
|
+
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
15784
|
+
primaryCanvas = pc;
|
|
15785
|
+
scheduler = sc;
|
|
15786
|
+
renderer = Object.keys(rest).length > 0 ? rest : rendererProp;
|
|
15787
|
+
} else {
|
|
15788
|
+
renderer = rendererProp;
|
|
15789
|
+
}
|
|
14989
15790
|
React.useMemo(() => extend(THREE), []);
|
|
14990
15791
|
const Bridge = useBridge();
|
|
15792
|
+
const backgroundProps = React.useMemo(() => {
|
|
15793
|
+
if (!background) return null;
|
|
15794
|
+
if (typeof background === "object" && !background.isColor) {
|
|
15795
|
+
const { backgroundMap, envMap, files, preset, ...rest } = background;
|
|
15796
|
+
return {
|
|
15797
|
+
...rest,
|
|
15798
|
+
preset,
|
|
15799
|
+
files: envMap || files,
|
|
15800
|
+
backgroundFiles: backgroundMap,
|
|
15801
|
+
background: true
|
|
15802
|
+
};
|
|
15803
|
+
}
|
|
15804
|
+
if (typeof background === "number") {
|
|
15805
|
+
return { color: background, background: true };
|
|
15806
|
+
}
|
|
15807
|
+
if (typeof background === "string") {
|
|
15808
|
+
if (background in presetsObj) {
|
|
15809
|
+
return { preset: background, background: true };
|
|
15810
|
+
}
|
|
15811
|
+
if (/^(https?:\/\/|\/|\.\/|\.\.\/)|\\.(hdr|exr|jpg|jpeg|png|webp|gif)$/i.test(background)) {
|
|
15812
|
+
return { files: background, background: true };
|
|
15813
|
+
}
|
|
15814
|
+
return { color: background, background: true };
|
|
15815
|
+
}
|
|
15816
|
+
if (background.isColor) {
|
|
15817
|
+
return { color: background, background: true };
|
|
15818
|
+
}
|
|
15819
|
+
return null;
|
|
15820
|
+
}, [background]);
|
|
14991
15821
|
const hasInitialSizeRef = React.useRef(false);
|
|
14992
15822
|
const measureConfig = React.useMemo(() => {
|
|
14993
15823
|
if (!hasInitialSizeRef.current) {
|
|
@@ -15004,7 +15834,21 @@ function CanvasImpl({
|
|
|
15004
15834
|
};
|
|
15005
15835
|
}, [resize, hasInitialSizeRef.current]);
|
|
15006
15836
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
15007
|
-
|
|
15837
|
+
const effectiveSize = React.useMemo(() => {
|
|
15838
|
+
let w = width ?? containerRect.width;
|
|
15839
|
+
let h = height ?? containerRect.height;
|
|
15840
|
+
if (forceEven) {
|
|
15841
|
+
w = Math.ceil(w / 2) * 2;
|
|
15842
|
+
h = Math.ceil(h / 2) * 2;
|
|
15843
|
+
}
|
|
15844
|
+
return {
|
|
15845
|
+
width: w,
|
|
15846
|
+
height: h,
|
|
15847
|
+
top: containerRect.top,
|
|
15848
|
+
left: containerRect.left
|
|
15849
|
+
};
|
|
15850
|
+
}, [width, height, containerRect, forceEven]);
|
|
15851
|
+
if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
|
|
15008
15852
|
hasInitialSizeRef.current = true;
|
|
15009
15853
|
}
|
|
15010
15854
|
const canvasRef = React.useRef(null);
|
|
@@ -15023,7 +15867,7 @@ function CanvasImpl({
|
|
|
15023
15867
|
useIsomorphicLayoutEffect(() => {
|
|
15024
15868
|
effectActiveRef.current = true;
|
|
15025
15869
|
const canvas = canvasRef.current;
|
|
15026
|
-
if (
|
|
15870
|
+
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
15027
15871
|
if (!root.current) {
|
|
15028
15872
|
root.current = createRoot(canvas);
|
|
15029
15873
|
notifyAlpha({
|
|
@@ -15043,21 +15887,24 @@ function CanvasImpl({
|
|
|
15043
15887
|
async function run() {
|
|
15044
15888
|
if (!effectActiveRef.current || !root.current) return;
|
|
15045
15889
|
await root.current.configure({
|
|
15890
|
+
id,
|
|
15891
|
+
primaryCanvas,
|
|
15892
|
+
scheduler,
|
|
15046
15893
|
gl,
|
|
15047
15894
|
renderer,
|
|
15048
15895
|
scene,
|
|
15049
15896
|
events,
|
|
15050
15897
|
shadows,
|
|
15051
|
-
linear,
|
|
15052
|
-
flat,
|
|
15053
|
-
legacy,
|
|
15054
15898
|
orthographic,
|
|
15055
15899
|
frameloop,
|
|
15056
15900
|
dpr,
|
|
15057
15901
|
performance,
|
|
15058
15902
|
raycaster,
|
|
15059
15903
|
camera,
|
|
15060
|
-
size:
|
|
15904
|
+
size: effectiveSize,
|
|
15905
|
+
// Store size props for reset functionality
|
|
15906
|
+
_sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
|
|
15907
|
+
forceEven,
|
|
15061
15908
|
// Pass mutable reference to onPointerMissed so it's free to update
|
|
15062
15909
|
onPointerMissed: (...args) => handlePointerMissed.current?.(...args),
|
|
15063
15910
|
onDragOverMissed: (...args) => handleDragOverMissed.current?.(...args),
|
|
@@ -15081,7 +15928,10 @@ function CanvasImpl({
|
|
|
15081
15928
|
});
|
|
15082
15929
|
if (!effectActiveRef.current || !root.current) return;
|
|
15083
15930
|
root.current.render(
|
|
15084
|
-
/* @__PURE__ */ jsx(Bridge, { children: /* @__PURE__ */ jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */
|
|
15931
|
+
/* @__PURE__ */ jsx(Bridge, { children: /* @__PURE__ */ jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxs(React.Suspense, { fallback: /* @__PURE__ */ jsx(Block, { set: setBlock }), children: [
|
|
15932
|
+
backgroundProps && /* @__PURE__ */ jsx(Environment, { ...backgroundProps }),
|
|
15933
|
+
children ?? null
|
|
15934
|
+
] }) }) })
|
|
15085
15935
|
);
|
|
15086
15936
|
}
|
|
15087
15937
|
run();
|
|
@@ -15102,7 +15952,36 @@ function CanvasImpl({
|
|
|
15102
15952
|
root.current = null;
|
|
15103
15953
|
};
|
|
15104
15954
|
}
|
|
15105
|
-
}, []);
|
|
15955
|
+
}, []);
|
|
15956
|
+
React.useEffect(() => {
|
|
15957
|
+
if (hmr === false) return;
|
|
15958
|
+
const canvas = canvasRef.current;
|
|
15959
|
+
if (!canvas) return;
|
|
15960
|
+
const handleHMR = () => {
|
|
15961
|
+
queueMicrotask(() => {
|
|
15962
|
+
const rootEntry = _roots.get(canvas);
|
|
15963
|
+
if (rootEntry?.store) {
|
|
15964
|
+
console.log("[R3F] HMR detected \u2014 rebuilding nodes/uniforms");
|
|
15965
|
+
rootEntry.store.setState((state) => ({
|
|
15966
|
+
nodes: {},
|
|
15967
|
+
uniforms: {},
|
|
15968
|
+
_hmrVersion: state._hmrVersion + 1
|
|
15969
|
+
}));
|
|
15970
|
+
}
|
|
15971
|
+
});
|
|
15972
|
+
};
|
|
15973
|
+
if (typeof import.meta !== "undefined" && import.meta.hot) {
|
|
15974
|
+
const hot = import.meta.hot;
|
|
15975
|
+
hot.on("vite:afterUpdate", handleHMR);
|
|
15976
|
+
return () => hot.off?.("vite:afterUpdate", handleHMR);
|
|
15977
|
+
}
|
|
15978
|
+
if (typeof module !== "undefined" && module.hot) {
|
|
15979
|
+
const hot = module.hot;
|
|
15980
|
+
hot.addStatusHandler((status) => {
|
|
15981
|
+
if (status === "idle") handleHMR();
|
|
15982
|
+
});
|
|
15983
|
+
}
|
|
15984
|
+
}, [hmr]);
|
|
15106
15985
|
const pointerEvents = eventSource ? "none" : "auto";
|
|
15107
15986
|
return /* @__PURE__ */ jsx(
|
|
15108
15987
|
"div",
|
|
@@ -15117,7 +15996,16 @@ function CanvasImpl({
|
|
|
15117
15996
|
...style
|
|
15118
15997
|
},
|
|
15119
15998
|
...props,
|
|
15120
|
-
children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(
|
|
15999
|
+
children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(
|
|
16000
|
+
"canvas",
|
|
16001
|
+
{
|
|
16002
|
+
ref: canvasRef,
|
|
16003
|
+
id,
|
|
16004
|
+
className: "r3f-canvas",
|
|
16005
|
+
style: { display: "block", width: "100%", height: "100%" },
|
|
16006
|
+
children: fallback
|
|
16007
|
+
}
|
|
16008
|
+
) })
|
|
15121
16009
|
}
|
|
15122
16010
|
);
|
|
15123
16011
|
}
|
|
@@ -15125,6 +16013,100 @@ function Canvas(props) {
|
|
|
15125
16013
|
return /* @__PURE__ */ jsx(FiberProvider, { children: /* @__PURE__ */ jsx(CanvasImpl, { ...props }) });
|
|
15126
16014
|
}
|
|
15127
16015
|
|
|
16016
|
+
var __defProp = Object.defineProperty;
|
|
16017
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
16018
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
16019
|
+
var _a;
|
|
16020
|
+
const INTERNAL_DATA = Symbol("ScopedStore.data");
|
|
16021
|
+
_a = INTERNAL_DATA;
|
|
16022
|
+
const _ScopedStore = class _ScopedStore {
|
|
16023
|
+
constructor(data) {
|
|
16024
|
+
__publicField(this, _a);
|
|
16025
|
+
this[INTERNAL_DATA] = data;
|
|
16026
|
+
return new Proxy(this, {
|
|
16027
|
+
get(target, prop, receiver) {
|
|
16028
|
+
if (typeof prop === "string") {
|
|
16029
|
+
if (prop === "scope" || prop === "has" || prop === "keys") {
|
|
16030
|
+
return Reflect.get(target, prop, receiver);
|
|
16031
|
+
}
|
|
16032
|
+
return target[INTERNAL_DATA][prop];
|
|
16033
|
+
}
|
|
16034
|
+
return Reflect.get(target, prop, receiver);
|
|
16035
|
+
},
|
|
16036
|
+
has(target, prop) {
|
|
16037
|
+
return typeof prop === "string" ? prop in target[INTERNAL_DATA] : Reflect.has(target, prop);
|
|
16038
|
+
},
|
|
16039
|
+
ownKeys(target) {
|
|
16040
|
+
return Reflect.ownKeys(target[INTERNAL_DATA]);
|
|
16041
|
+
},
|
|
16042
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
16043
|
+
if (typeof prop === "string" && prop in target[INTERNAL_DATA]) {
|
|
16044
|
+
return {
|
|
16045
|
+
configurable: true,
|
|
16046
|
+
enumerable: true,
|
|
16047
|
+
value: target[INTERNAL_DATA][prop]
|
|
16048
|
+
};
|
|
16049
|
+
}
|
|
16050
|
+
return void 0;
|
|
16051
|
+
}
|
|
16052
|
+
});
|
|
16053
|
+
}
|
|
16054
|
+
/**
|
|
16055
|
+
* Access a nested scope by key.
|
|
16056
|
+
* If the key doesn't exist or isn't a scope object, returns an empty ScopedStore.
|
|
16057
|
+
*/
|
|
16058
|
+
scope(key) {
|
|
16059
|
+
const data = this[INTERNAL_DATA][key];
|
|
16060
|
+
return new _ScopedStore(
|
|
16061
|
+
data && typeof data === "object" ? data : {}
|
|
16062
|
+
);
|
|
16063
|
+
}
|
|
16064
|
+
/**
|
|
16065
|
+
* Check if a key exists in the store.
|
|
16066
|
+
*/
|
|
16067
|
+
has(key) {
|
|
16068
|
+
return key in this[INTERNAL_DATA];
|
|
16069
|
+
}
|
|
16070
|
+
/**
|
|
16071
|
+
* Get all keys in the store.
|
|
16072
|
+
*/
|
|
16073
|
+
keys() {
|
|
16074
|
+
return Object.keys(this[INTERNAL_DATA]);
|
|
16075
|
+
}
|
|
16076
|
+
};
|
|
16077
|
+
let ScopedStore = _ScopedStore;
|
|
16078
|
+
function createScopedStore(data) {
|
|
16079
|
+
return new ScopedStore(data);
|
|
16080
|
+
}
|
|
16081
|
+
function createLazyCreatorState(state) {
|
|
16082
|
+
let _uniforms = null;
|
|
16083
|
+
let _nodes = null;
|
|
16084
|
+
let _buffers = null;
|
|
16085
|
+
let _gpuStorage = null;
|
|
16086
|
+
return Object.create(state, {
|
|
16087
|
+
uniforms: {
|
|
16088
|
+
get() {
|
|
16089
|
+
return _uniforms ?? (_uniforms = createScopedStore(state.uniforms));
|
|
16090
|
+
}
|
|
16091
|
+
},
|
|
16092
|
+
nodes: {
|
|
16093
|
+
get() {
|
|
16094
|
+
return _nodes ?? (_nodes = createScopedStore(state.nodes));
|
|
16095
|
+
}
|
|
16096
|
+
},
|
|
16097
|
+
buffers: {
|
|
16098
|
+
get() {
|
|
16099
|
+
return _buffers ?? (_buffers = createScopedStore(state.buffers));
|
|
16100
|
+
}
|
|
16101
|
+
},
|
|
16102
|
+
gpuStorage: {
|
|
16103
|
+
get() {
|
|
16104
|
+
return _gpuStorage ?? (_gpuStorage = createScopedStore(state.gpuStorage));
|
|
16105
|
+
}
|
|
16106
|
+
}
|
|
16107
|
+
});
|
|
16108
|
+
}
|
|
16109
|
+
|
|
15128
16110
|
function addTexture(set, key, value) {
|
|
15129
16111
|
set((state) => {
|
|
15130
16112
|
const newMap = new Map(state.textures);
|
|
@@ -15164,6 +16146,27 @@ function createTextureOperations(set) {
|
|
|
15164
16146
|
removeMultiple: (keys) => removeTextures(set, keys)
|
|
15165
16147
|
};
|
|
15166
16148
|
}
|
|
16149
|
+
function extractTSLValue(value) {
|
|
16150
|
+
if (value === null || value === void 0) return value;
|
|
16151
|
+
if (typeof value !== "object") return value;
|
|
16152
|
+
const node = value;
|
|
16153
|
+
if (!node.isNode) return value;
|
|
16154
|
+
if (node.isConstNode) {
|
|
16155
|
+
return node.value;
|
|
16156
|
+
}
|
|
16157
|
+
if ("value" in node) {
|
|
16158
|
+
let extractedValue = node.value;
|
|
16159
|
+
if (typeof node.traverse === "function") {
|
|
16160
|
+
node.traverse((n) => {
|
|
16161
|
+
if (n.isConstNode) {
|
|
16162
|
+
extractedValue = n.value;
|
|
16163
|
+
}
|
|
16164
|
+
});
|
|
16165
|
+
}
|
|
16166
|
+
return extractedValue;
|
|
16167
|
+
}
|
|
16168
|
+
return value;
|
|
16169
|
+
}
|
|
15167
16170
|
function vectorize(inObject) {
|
|
15168
16171
|
if (inObject === null || inObject === void 0) return inObject;
|
|
15169
16172
|
if (typeof inObject === "string") {
|
|
@@ -15176,9 +16179,16 @@ function vectorize(inObject) {
|
|
|
15176
16179
|
}
|
|
15177
16180
|
if (typeof inObject !== "object") return inObject;
|
|
15178
16181
|
const obj = inObject;
|
|
16182
|
+
if (obj.isNode) {
|
|
16183
|
+
return extractTSLValue(inObject);
|
|
16184
|
+
}
|
|
15179
16185
|
if (obj.isVector2 || obj.isVector3 || obj.isVector4) return inObject;
|
|
15180
16186
|
if (obj.isMatrix3 || obj.isMatrix4) return inObject;
|
|
15181
16187
|
if (obj.isColor || obj.isEuler || obj.isQuaternion || obj.isSpherical) return inObject;
|
|
16188
|
+
if ("r" in obj && "g" in obj && "b" in obj && typeof obj.r === "number" && typeof obj.g === "number" && typeof obj.b === "number") {
|
|
16189
|
+
const scale = obj.r > 1 || obj.g > 1 || obj.b > 1 ? 1 / 255 : 1;
|
|
16190
|
+
return new Color(obj.r * scale, obj.g * scale, obj.b * scale);
|
|
16191
|
+
}
|
|
15182
16192
|
if ("x" in obj && "y" in obj && typeof obj.x === "number" && typeof obj.y === "number") {
|
|
15183
16193
|
if ("w" in obj && typeof obj.w === "number" && "z" in obj && typeof obj.z === "number") {
|
|
15184
16194
|
return new Vector4(obj.x, obj.y, obj.z, obj.w);
|
|
@@ -15238,21 +16248,55 @@ function useUniforms(creatorOrScope, scope) {
|
|
|
15238
16248
|
},
|
|
15239
16249
|
[store]
|
|
15240
16250
|
);
|
|
16251
|
+
const rebuildUniforms = useCallback(
|
|
16252
|
+
(targetScope) => {
|
|
16253
|
+
store.setState((state) => {
|
|
16254
|
+
let newUniforms = {};
|
|
16255
|
+
if (targetScope && targetScope !== "root") {
|
|
16256
|
+
const { [targetScope]: _, ...rest } = state.uniforms;
|
|
16257
|
+
newUniforms = rest;
|
|
16258
|
+
} else if (targetScope === "root") {
|
|
16259
|
+
for (const [key, value] of Object.entries(state.uniforms)) {
|
|
16260
|
+
if (!isUniformNode$1(value)) newUniforms[key] = value;
|
|
16261
|
+
}
|
|
16262
|
+
}
|
|
16263
|
+
return { uniforms: newUniforms, _hmrVersion: state._hmrVersion + 1 };
|
|
16264
|
+
});
|
|
16265
|
+
},
|
|
16266
|
+
[store]
|
|
16267
|
+
);
|
|
15241
16268
|
const inputForMemoization = useMemo(() => {
|
|
15242
|
-
|
|
16269
|
+
let raw = creatorOrScope;
|
|
16270
|
+
if (is.fun(creatorOrScope)) {
|
|
16271
|
+
const wrappedState = createLazyCreatorState(store.getState());
|
|
16272
|
+
raw = creatorOrScope(wrappedState);
|
|
16273
|
+
}
|
|
16274
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
16275
|
+
const normalized = {};
|
|
16276
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
16277
|
+
normalized[key] = vectorize(value);
|
|
16278
|
+
}
|
|
16279
|
+
return normalized;
|
|
16280
|
+
}
|
|
16281
|
+
return raw;
|
|
15243
16282
|
}, [creatorOrScope, store]);
|
|
15244
16283
|
const memoizedInput = useCompareMemoize(inputForMemoization);
|
|
16284
|
+
const isReader = memoizedInput === void 0 || typeof memoizedInput === "string";
|
|
16285
|
+
const storeUniforms = useThree((s) => s.uniforms);
|
|
16286
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
16287
|
+
const readerDep = isReader ? storeUniforms : null;
|
|
16288
|
+
const creatorDep = isReader ? null : hmrVersion;
|
|
15245
16289
|
const uniforms = useMemo(() => {
|
|
15246
|
-
const state = store.getState();
|
|
15247
|
-
const set = store.setState;
|
|
15248
16290
|
if (memoizedInput === void 0) {
|
|
15249
|
-
return
|
|
16291
|
+
return storeUniforms;
|
|
15250
16292
|
}
|
|
15251
16293
|
if (typeof memoizedInput === "string") {
|
|
15252
|
-
const scopeData =
|
|
16294
|
+
const scopeData = storeUniforms[memoizedInput];
|
|
15253
16295
|
if (scopeData && !isUniformNode$1(scopeData)) return scopeData;
|
|
15254
16296
|
return {};
|
|
15255
16297
|
}
|
|
16298
|
+
const state = store.getState();
|
|
16299
|
+
const set = store.setState;
|
|
15256
16300
|
if (typeof memoizedInput !== "object" || memoizedInput === null) {
|
|
15257
16301
|
throw new Error("Invalid uniform input");
|
|
15258
16302
|
}
|
|
@@ -15296,8 +16340,22 @@ function useUniforms(creatorOrScope, scope) {
|
|
|
15296
16340
|
}
|
|
15297
16341
|
}
|
|
15298
16342
|
return result;
|
|
15299
|
-
}, [store, memoizedInput, scope]);
|
|
15300
|
-
return { ...uniforms, removeUniforms: removeUniforms2, clearUniforms };
|
|
16343
|
+
}, [store, memoizedInput, scope, readerDep, creatorDep]);
|
|
16344
|
+
return { ...uniforms, removeUniforms: removeUniforms2, clearUniforms, rebuildUniforms };
|
|
16345
|
+
}
|
|
16346
|
+
function rebuildAllUniforms(store, scope) {
|
|
16347
|
+
store.setState((state) => {
|
|
16348
|
+
let newUniforms = {};
|
|
16349
|
+
if (scope && scope !== "root") {
|
|
16350
|
+
const { [scope]: _, ...rest } = state.uniforms;
|
|
16351
|
+
newUniforms = rest;
|
|
16352
|
+
} else if (scope === "root") {
|
|
16353
|
+
for (const [key, value] of Object.entries(state.uniforms)) {
|
|
16354
|
+
if (!isUniformNode$1(value)) newUniforms[key] = value;
|
|
16355
|
+
}
|
|
16356
|
+
}
|
|
16357
|
+
return { uniforms: newUniforms, _hmrVersion: state._hmrVersion + 1 };
|
|
16358
|
+
});
|
|
15301
16359
|
}
|
|
15302
16360
|
function removeUniforms(set, names, scope) {
|
|
15303
16361
|
set((state) => {
|
|
@@ -15362,15 +16420,17 @@ function isSameThreeType(a, b) {
|
|
|
15362
16420
|
}
|
|
15363
16421
|
|
|
15364
16422
|
const isUniformNode = (value) => value !== null && typeof value === "object" && "value" in value && "uuid" in value;
|
|
16423
|
+
const isTSLNode$1 = (value) => value !== null && typeof value === "object" && "uuid" in value && "nodeType" in value;
|
|
15365
16424
|
function useUniform(name, value) {
|
|
15366
16425
|
const store = useStore();
|
|
16426
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
15367
16427
|
return useMemo(() => {
|
|
15368
16428
|
const state = store.getState();
|
|
15369
16429
|
const set = store.setState;
|
|
15370
16430
|
const existing = state.uniforms[name];
|
|
15371
16431
|
if (existing && isUniformNode(existing)) {
|
|
15372
|
-
if (value !== void 0) {
|
|
15373
|
-
existing.value = value;
|
|
16432
|
+
if (value !== void 0 && !isTSLNode$1(value) && !isUniformNode(value)) {
|
|
16433
|
+
existing.value = typeof value === "string" ? new Color(value) : value;
|
|
15374
16434
|
}
|
|
15375
16435
|
return existing;
|
|
15376
16436
|
}
|
|
@@ -15379,7 +16439,24 @@ function useUniform(name, value) {
|
|
|
15379
16439
|
`[useUniform] Uniform "${name}" not found. Create it first with: useUniform('${name}', initialValue)`
|
|
15380
16440
|
);
|
|
15381
16441
|
}
|
|
15382
|
-
|
|
16442
|
+
if (isUniformNode(value)) {
|
|
16443
|
+
const node2 = value;
|
|
16444
|
+
if (typeof node2.setName === "function") {
|
|
16445
|
+
node2.setName(name);
|
|
16446
|
+
}
|
|
16447
|
+
set((s) => ({
|
|
16448
|
+
uniforms: { ...s.uniforms, [name]: node2 }
|
|
16449
|
+
}));
|
|
16450
|
+
return node2;
|
|
16451
|
+
}
|
|
16452
|
+
let node;
|
|
16453
|
+
if (isTSLNode$1(value)) {
|
|
16454
|
+
node = uniform(value);
|
|
16455
|
+
} else if (typeof value === "string") {
|
|
16456
|
+
node = uniform(new Color(value));
|
|
16457
|
+
} else {
|
|
16458
|
+
node = uniform(value);
|
|
16459
|
+
}
|
|
15383
16460
|
if (typeof node.setName === "function") {
|
|
15384
16461
|
node.setName(name);
|
|
15385
16462
|
}
|
|
@@ -15390,7 +16467,7 @@ function useUniform(name, value) {
|
|
|
15390
16467
|
}
|
|
15391
16468
|
}));
|
|
15392
16469
|
return node;
|
|
15393
|
-
}, [store, name]);
|
|
16470
|
+
}, [store, name, hmrVersion]);
|
|
15394
16471
|
}
|
|
15395
16472
|
|
|
15396
16473
|
const isTSLNode = (value) => value !== null && typeof value === "object" && ("uuid" in value || "nodeType" in value);
|
|
@@ -15431,19 +16508,46 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15431
16508
|
},
|
|
15432
16509
|
[store]
|
|
15433
16510
|
);
|
|
16511
|
+
const rebuildNodes = useCallback(
|
|
16512
|
+
(targetScope) => {
|
|
16513
|
+
store.setState((state) => {
|
|
16514
|
+
let newNodes = state.nodes;
|
|
16515
|
+
if (targetScope && targetScope !== "root") {
|
|
16516
|
+
const { [targetScope]: _, ...rest } = state.nodes;
|
|
16517
|
+
newNodes = rest;
|
|
16518
|
+
} else if (targetScope === "root") {
|
|
16519
|
+
newNodes = {};
|
|
16520
|
+
for (const [key, value] of Object.entries(state.nodes)) {
|
|
16521
|
+
if (!isTSLNode(value)) newNodes[key] = value;
|
|
16522
|
+
}
|
|
16523
|
+
} else {
|
|
16524
|
+
newNodes = {};
|
|
16525
|
+
}
|
|
16526
|
+
return { nodes: newNodes, _hmrVersion: state._hmrVersion + 1 };
|
|
16527
|
+
});
|
|
16528
|
+
},
|
|
16529
|
+
[store]
|
|
16530
|
+
);
|
|
16531
|
+
const isReader = creatorOrScope === void 0 || typeof creatorOrScope === "string";
|
|
16532
|
+
const storeNodes = useThree((s) => s.nodes);
|
|
16533
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
16534
|
+
const scopeDep = typeof creatorOrScope === "string" ? creatorOrScope : scope;
|
|
16535
|
+
const readerDep = isReader ? storeNodes : null;
|
|
16536
|
+
const creatorDep = isReader ? null : hmrVersion;
|
|
15434
16537
|
const nodes = useMemo(() => {
|
|
15435
|
-
const state = store.getState();
|
|
15436
|
-
const set = store.setState;
|
|
15437
16538
|
if (creatorOrScope === void 0) {
|
|
15438
|
-
return
|
|
16539
|
+
return storeNodes;
|
|
15439
16540
|
}
|
|
15440
16541
|
if (typeof creatorOrScope === "string") {
|
|
15441
|
-
const scopeData =
|
|
16542
|
+
const scopeData = storeNodes[creatorOrScope];
|
|
15442
16543
|
if (scopeData && !isTSLNode(scopeData)) return scopeData;
|
|
15443
16544
|
return {};
|
|
15444
16545
|
}
|
|
16546
|
+
const state = store.getState();
|
|
16547
|
+
const set = store.setState;
|
|
15445
16548
|
const creator = creatorOrScope;
|
|
15446
|
-
const
|
|
16549
|
+
const wrappedState = createLazyCreatorState(state);
|
|
16550
|
+
const created = creator(wrappedState);
|
|
15447
16551
|
const result = {};
|
|
15448
16552
|
let hasNewNodes = false;
|
|
15449
16553
|
if (scope) {
|
|
@@ -15452,7 +16556,7 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15452
16556
|
if (currentScope[name]) {
|
|
15453
16557
|
result[name] = currentScope[name];
|
|
15454
16558
|
} else {
|
|
15455
|
-
|
|
16559
|
+
node.setName?.(`${scope}.${name}`);
|
|
15456
16560
|
result[name] = node;
|
|
15457
16561
|
hasNewNodes = true;
|
|
15458
16562
|
}
|
|
@@ -15472,7 +16576,7 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15472
16576
|
if (existing && isTSLNode(existing)) {
|
|
15473
16577
|
result[name] = existing;
|
|
15474
16578
|
} else {
|
|
15475
|
-
|
|
16579
|
+
node.setName?.(name);
|
|
15476
16580
|
result[name] = node;
|
|
15477
16581
|
hasNewNodes = true;
|
|
15478
16582
|
}
|
|
@@ -15481,8 +16585,25 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15481
16585
|
set((s) => ({ nodes: { ...s.nodes, ...result } }));
|
|
15482
16586
|
}
|
|
15483
16587
|
return result;
|
|
15484
|
-
}, [store,
|
|
15485
|
-
return { ...nodes, removeNodes: removeNodes2, clearNodes };
|
|
16588
|
+
}, [store, scopeDep, readerDep, creatorDep]);
|
|
16589
|
+
return { ...nodes, removeNodes: removeNodes2, clearNodes, rebuildNodes };
|
|
16590
|
+
}
|
|
16591
|
+
function rebuildAllNodes(store, scope) {
|
|
16592
|
+
store.setState((state) => {
|
|
16593
|
+
let newNodes = state.nodes;
|
|
16594
|
+
if (scope && scope !== "root") {
|
|
16595
|
+
const { [scope]: _, ...rest } = state.nodes;
|
|
16596
|
+
newNodes = rest;
|
|
16597
|
+
} else if (scope === "root") {
|
|
16598
|
+
newNodes = {};
|
|
16599
|
+
for (const [key, value] of Object.entries(state.nodes)) {
|
|
16600
|
+
if (!isTSLNode(value)) newNodes[key] = value;
|
|
16601
|
+
}
|
|
16602
|
+
} else {
|
|
16603
|
+
newNodes = {};
|
|
16604
|
+
}
|
|
16605
|
+
return { nodes: newNodes, _hmrVersion: state._hmrVersion + 1 };
|
|
16606
|
+
});
|
|
15486
16607
|
}
|
|
15487
16608
|
function removeNodes(set, names, scope) {
|
|
15488
16609
|
set((state) => {
|
|
@@ -15516,13 +16637,358 @@ function useLocalNodes(creator) {
|
|
|
15516
16637
|
const uniforms = useThree((s) => s.uniforms);
|
|
15517
16638
|
const nodes = useThree((s) => s.nodes);
|
|
15518
16639
|
const textures = useThree((s) => s.textures);
|
|
16640
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
15519
16641
|
return useMemo(() => {
|
|
16642
|
+
const wrappedState = createLazyCreatorState(store.getState());
|
|
16643
|
+
return creator(wrappedState);
|
|
16644
|
+
}, [store, creator, uniforms, nodes, textures, hmrVersion]);
|
|
16645
|
+
}
|
|
16646
|
+
|
|
16647
|
+
const isBufferLike = (value) => {
|
|
16648
|
+
if (value === null || typeof value !== "object") return false;
|
|
16649
|
+
if (ArrayBuffer.isView(value)) return true;
|
|
16650
|
+
if ("isBufferAttribute" in value) return true;
|
|
16651
|
+
if ("uuid" in value || "nodeType" in value) return true;
|
|
16652
|
+
return false;
|
|
16653
|
+
};
|
|
16654
|
+
const disposeBuffer = (buffer) => {
|
|
16655
|
+
if (buffer === null || typeof buffer !== "object") return;
|
|
16656
|
+
if ("dispose" in buffer && typeof buffer.dispose === "function") {
|
|
16657
|
+
buffer.dispose();
|
|
16658
|
+
}
|
|
16659
|
+
};
|
|
16660
|
+
function useBuffers(creatorOrScope, scope) {
|
|
16661
|
+
const store = useStore();
|
|
16662
|
+
const removeBuffers = useCallback(
|
|
16663
|
+
(names, targetScope) => {
|
|
16664
|
+
const nameArray = Array.isArray(names) ? names : [names];
|
|
16665
|
+
store.setState((state) => {
|
|
16666
|
+
if (targetScope) {
|
|
16667
|
+
const currentScope = { ...state.buffers[targetScope] };
|
|
16668
|
+
for (const name of nameArray) delete currentScope[name];
|
|
16669
|
+
return { buffers: { ...state.buffers, [targetScope]: currentScope } };
|
|
16670
|
+
}
|
|
16671
|
+
const buffers2 = { ...state.buffers };
|
|
16672
|
+
for (const name of nameArray) if (isBufferLike(buffers2[name])) delete buffers2[name];
|
|
16673
|
+
return { buffers: buffers2 };
|
|
16674
|
+
});
|
|
16675
|
+
},
|
|
16676
|
+
[store]
|
|
16677
|
+
);
|
|
16678
|
+
const clearBuffers = useCallback(
|
|
16679
|
+
(targetScope) => {
|
|
16680
|
+
store.setState((state) => {
|
|
16681
|
+
if (targetScope && targetScope !== "root") {
|
|
16682
|
+
const { [targetScope]: _, ...rest } = state.buffers;
|
|
16683
|
+
return { buffers: rest };
|
|
16684
|
+
}
|
|
16685
|
+
if (targetScope === "root") {
|
|
16686
|
+
const buffers2 = {};
|
|
16687
|
+
for (const [key, value] of Object.entries(state.buffers)) {
|
|
16688
|
+
if (!isBufferLike(value)) buffers2[key] = value;
|
|
16689
|
+
}
|
|
16690
|
+
return { buffers: buffers2 };
|
|
16691
|
+
}
|
|
16692
|
+
return { buffers: {} };
|
|
16693
|
+
});
|
|
16694
|
+
},
|
|
16695
|
+
[store]
|
|
16696
|
+
);
|
|
16697
|
+
const rebuildBuffers = useCallback(
|
|
16698
|
+
(targetScope) => {
|
|
16699
|
+
store.setState((state) => {
|
|
16700
|
+
let newBuffers = state.buffers;
|
|
16701
|
+
if (targetScope && targetScope !== "root") {
|
|
16702
|
+
const { [targetScope]: _, ...rest } = state.buffers;
|
|
16703
|
+
newBuffers = rest;
|
|
16704
|
+
} else if (targetScope === "root") {
|
|
16705
|
+
newBuffers = {};
|
|
16706
|
+
for (const [key, value] of Object.entries(state.buffers)) {
|
|
16707
|
+
if (!isBufferLike(value)) newBuffers[key] = value;
|
|
16708
|
+
}
|
|
16709
|
+
} else {
|
|
16710
|
+
newBuffers = {};
|
|
16711
|
+
}
|
|
16712
|
+
return { buffers: newBuffers, _hmrVersion: state._hmrVersion + 1 };
|
|
16713
|
+
});
|
|
16714
|
+
},
|
|
16715
|
+
[store]
|
|
16716
|
+
);
|
|
16717
|
+
const disposeBuffers = useCallback(
|
|
16718
|
+
(names, targetScope) => {
|
|
16719
|
+
const nameArray = Array.isArray(names) ? names : [names];
|
|
16720
|
+
const state = store.getState();
|
|
16721
|
+
for (const name of nameArray) {
|
|
16722
|
+
const buffer = targetScope ? state.buffers[targetScope]?.[name] : state.buffers[name];
|
|
16723
|
+
if (buffer && isBufferLike(buffer)) {
|
|
16724
|
+
disposeBuffer(buffer);
|
|
16725
|
+
}
|
|
16726
|
+
}
|
|
16727
|
+
removeBuffers(names, targetScope);
|
|
16728
|
+
},
|
|
16729
|
+
[store, removeBuffers]
|
|
16730
|
+
);
|
|
16731
|
+
const isReader = creatorOrScope === void 0 || typeof creatorOrScope === "string";
|
|
16732
|
+
const storeBuffers = useThree((s) => s.buffers);
|
|
16733
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
16734
|
+
const scopeDep = typeof creatorOrScope === "string" ? creatorOrScope : scope;
|
|
16735
|
+
const readerDep = isReader ? storeBuffers : null;
|
|
16736
|
+
const creatorDep = isReader ? null : hmrVersion;
|
|
16737
|
+
const buffers = useMemo(() => {
|
|
16738
|
+
if (creatorOrScope === void 0) {
|
|
16739
|
+
return storeBuffers;
|
|
16740
|
+
}
|
|
16741
|
+
if (typeof creatorOrScope === "string") {
|
|
16742
|
+
const scopeData = storeBuffers[creatorOrScope];
|
|
16743
|
+
if (scopeData && !isBufferLike(scopeData)) return scopeData;
|
|
16744
|
+
return {};
|
|
16745
|
+
}
|
|
16746
|
+
const state = store.getState();
|
|
16747
|
+
const set = store.setState;
|
|
16748
|
+
const creator = creatorOrScope;
|
|
16749
|
+
const wrappedState = createLazyCreatorState(state);
|
|
16750
|
+
const created = creator(wrappedState);
|
|
16751
|
+
const result = {};
|
|
16752
|
+
let hasNewBuffers = false;
|
|
16753
|
+
if (scope) {
|
|
16754
|
+
const currentScope = state.buffers[scope] ?? {};
|
|
16755
|
+
for (const [name, buffer] of Object.entries(created)) {
|
|
16756
|
+
if (currentScope[name]) {
|
|
16757
|
+
result[name] = currentScope[name];
|
|
16758
|
+
} else {
|
|
16759
|
+
if ("setName" in buffer && typeof buffer.setName === "function") {
|
|
16760
|
+
buffer.setName(`${scope}.${name}`);
|
|
16761
|
+
}
|
|
16762
|
+
result[name] = buffer;
|
|
16763
|
+
hasNewBuffers = true;
|
|
16764
|
+
}
|
|
16765
|
+
}
|
|
16766
|
+
if (hasNewBuffers) {
|
|
16767
|
+
set((s) => ({
|
|
16768
|
+
buffers: {
|
|
16769
|
+
...s.buffers,
|
|
16770
|
+
[scope]: { ...s.buffers[scope], ...result }
|
|
16771
|
+
}
|
|
16772
|
+
}));
|
|
16773
|
+
}
|
|
16774
|
+
return result;
|
|
16775
|
+
}
|
|
16776
|
+
for (const [name, buffer] of Object.entries(created)) {
|
|
16777
|
+
const existing = state.buffers[name];
|
|
16778
|
+
if (existing && isBufferLike(existing)) {
|
|
16779
|
+
result[name] = existing;
|
|
16780
|
+
} else {
|
|
16781
|
+
if ("setName" in buffer && typeof buffer.setName === "function") {
|
|
16782
|
+
buffer.setName(name);
|
|
16783
|
+
}
|
|
16784
|
+
result[name] = buffer;
|
|
16785
|
+
hasNewBuffers = true;
|
|
16786
|
+
}
|
|
16787
|
+
}
|
|
16788
|
+
if (hasNewBuffers) {
|
|
16789
|
+
set((s) => ({ buffers: { ...s.buffers, ...result } }));
|
|
16790
|
+
}
|
|
16791
|
+
return result;
|
|
16792
|
+
}, [store, scopeDep, readerDep, creatorDep]);
|
|
16793
|
+
return { ...buffers, removeBuffers, clearBuffers, rebuildBuffers, disposeBuffers };
|
|
16794
|
+
}
|
|
16795
|
+
function rebuildAllBuffers(store, scope) {
|
|
16796
|
+
store.setState((state) => {
|
|
16797
|
+
let newBuffers = state.buffers;
|
|
16798
|
+
if (scope && scope !== "root") {
|
|
16799
|
+
const { [scope]: _, ...rest } = state.buffers;
|
|
16800
|
+
newBuffers = rest;
|
|
16801
|
+
} else if (scope === "root") {
|
|
16802
|
+
newBuffers = {};
|
|
16803
|
+
for (const [key, value] of Object.entries(state.buffers)) {
|
|
16804
|
+
if (!isBufferLike(value)) newBuffers[key] = value;
|
|
16805
|
+
}
|
|
16806
|
+
} else {
|
|
16807
|
+
newBuffers = {};
|
|
16808
|
+
}
|
|
16809
|
+
return { buffers: newBuffers, _hmrVersion: state._hmrVersion + 1 };
|
|
16810
|
+
});
|
|
16811
|
+
}
|
|
16812
|
+
|
|
16813
|
+
const isStorageLike = (value) => {
|
|
16814
|
+
if (value === null || typeof value !== "object") return false;
|
|
16815
|
+
if ("isTexture" in value) return true;
|
|
16816
|
+
if ("isData3DTexture" in value) return true;
|
|
16817
|
+
if ("uuid" in value || "nodeType" in value) return true;
|
|
16818
|
+
return false;
|
|
16819
|
+
};
|
|
16820
|
+
const disposeStorage = (storage) => {
|
|
16821
|
+
if (storage === null || typeof storage !== "object") return;
|
|
16822
|
+
if ("dispose" in storage && typeof storage.dispose === "function") {
|
|
16823
|
+
storage.dispose();
|
|
16824
|
+
}
|
|
16825
|
+
};
|
|
16826
|
+
function useGPUStorage(creatorOrScope, scope) {
|
|
16827
|
+
const store = useStore();
|
|
16828
|
+
const removeStorage = useCallback(
|
|
16829
|
+
(names, targetScope) => {
|
|
16830
|
+
const nameArray = Array.isArray(names) ? names : [names];
|
|
16831
|
+
store.setState((state) => {
|
|
16832
|
+
if (targetScope) {
|
|
16833
|
+
const currentScope = { ...state.gpuStorage[targetScope] };
|
|
16834
|
+
for (const name of nameArray) delete currentScope[name];
|
|
16835
|
+
return { gpuStorage: { ...state.gpuStorage, [targetScope]: currentScope } };
|
|
16836
|
+
}
|
|
16837
|
+
const gpuStorage2 = { ...state.gpuStorage };
|
|
16838
|
+
for (const name of nameArray) if (isStorageLike(gpuStorage2[name])) delete gpuStorage2[name];
|
|
16839
|
+
return { gpuStorage: gpuStorage2 };
|
|
16840
|
+
});
|
|
16841
|
+
},
|
|
16842
|
+
[store]
|
|
16843
|
+
);
|
|
16844
|
+
const clearStorage = useCallback(
|
|
16845
|
+
(targetScope) => {
|
|
16846
|
+
store.setState((state) => {
|
|
16847
|
+
if (targetScope && targetScope !== "root") {
|
|
16848
|
+
const { [targetScope]: _, ...rest } = state.gpuStorage;
|
|
16849
|
+
return { gpuStorage: rest };
|
|
16850
|
+
}
|
|
16851
|
+
if (targetScope === "root") {
|
|
16852
|
+
const gpuStorage2 = {};
|
|
16853
|
+
for (const [key, value] of Object.entries(state.gpuStorage)) {
|
|
16854
|
+
if (!isStorageLike(value)) gpuStorage2[key] = value;
|
|
16855
|
+
}
|
|
16856
|
+
return { gpuStorage: gpuStorage2 };
|
|
16857
|
+
}
|
|
16858
|
+
return { gpuStorage: {} };
|
|
16859
|
+
});
|
|
16860
|
+
},
|
|
16861
|
+
[store]
|
|
16862
|
+
);
|
|
16863
|
+
const rebuildStorage = useCallback(
|
|
16864
|
+
(targetScope) => {
|
|
16865
|
+
store.setState((state) => {
|
|
16866
|
+
let newStorage = state.gpuStorage;
|
|
16867
|
+
if (targetScope && targetScope !== "root") {
|
|
16868
|
+
const { [targetScope]: _, ...rest } = state.gpuStorage;
|
|
16869
|
+
newStorage = rest;
|
|
16870
|
+
} else if (targetScope === "root") {
|
|
16871
|
+
newStorage = {};
|
|
16872
|
+
for (const [key, value] of Object.entries(state.gpuStorage)) {
|
|
16873
|
+
if (!isStorageLike(value)) newStorage[key] = value;
|
|
16874
|
+
}
|
|
16875
|
+
} else {
|
|
16876
|
+
newStorage = {};
|
|
16877
|
+
}
|
|
16878
|
+
return { gpuStorage: newStorage, _hmrVersion: state._hmrVersion + 1 };
|
|
16879
|
+
});
|
|
16880
|
+
},
|
|
16881
|
+
[store]
|
|
16882
|
+
);
|
|
16883
|
+
const disposeStorageFn = useCallback(
|
|
16884
|
+
(names, targetScope) => {
|
|
16885
|
+
const nameArray = Array.isArray(names) ? names : [names];
|
|
16886
|
+
const state = store.getState();
|
|
16887
|
+
for (const name of nameArray) {
|
|
16888
|
+
const storage = targetScope ? state.gpuStorage[targetScope]?.[name] : state.gpuStorage[name];
|
|
16889
|
+
if (storage && isStorageLike(storage)) {
|
|
16890
|
+
disposeStorage(storage);
|
|
16891
|
+
}
|
|
16892
|
+
}
|
|
16893
|
+
removeStorage(names, targetScope);
|
|
16894
|
+
},
|
|
16895
|
+
[store, removeStorage]
|
|
16896
|
+
);
|
|
16897
|
+
const isReader = creatorOrScope === void 0 || typeof creatorOrScope === "string";
|
|
16898
|
+
const storeStorage = useThree((s) => s.gpuStorage);
|
|
16899
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
16900
|
+
const scopeDep = typeof creatorOrScope === "string" ? creatorOrScope : scope;
|
|
16901
|
+
const readerDep = isReader ? storeStorage : null;
|
|
16902
|
+
const creatorDep = isReader ? null : hmrVersion;
|
|
16903
|
+
const gpuStorage = useMemo(() => {
|
|
16904
|
+
if (creatorOrScope === void 0) {
|
|
16905
|
+
return storeStorage;
|
|
16906
|
+
}
|
|
16907
|
+
if (typeof creatorOrScope === "string") {
|
|
16908
|
+
const scopeData = storeStorage[creatorOrScope];
|
|
16909
|
+
if (scopeData && !isStorageLike(scopeData)) return scopeData;
|
|
16910
|
+
return {};
|
|
16911
|
+
}
|
|
15520
16912
|
const state = store.getState();
|
|
15521
|
-
|
|
15522
|
-
|
|
16913
|
+
const set = store.setState;
|
|
16914
|
+
const creator = creatorOrScope;
|
|
16915
|
+
const wrappedState = createLazyCreatorState(state);
|
|
16916
|
+
const created = creator(wrappedState);
|
|
16917
|
+
const result = {};
|
|
16918
|
+
let hasNewStorage = false;
|
|
16919
|
+
if (scope) {
|
|
16920
|
+
const currentScope = state.gpuStorage[scope] ?? {};
|
|
16921
|
+
for (const [name, storage] of Object.entries(created)) {
|
|
16922
|
+
if (currentScope[name]) {
|
|
16923
|
+
result[name] = currentScope[name];
|
|
16924
|
+
} else {
|
|
16925
|
+
if ("setName" in storage && typeof storage.setName === "function") {
|
|
16926
|
+
storage.setName(`${scope}.${name}`);
|
|
16927
|
+
}
|
|
16928
|
+
if ("name" in storage && typeof storage.name === "string") {
|
|
16929
|
+
storage.name = `${scope}.${name}`;
|
|
16930
|
+
}
|
|
16931
|
+
result[name] = storage;
|
|
16932
|
+
hasNewStorage = true;
|
|
16933
|
+
}
|
|
16934
|
+
}
|
|
16935
|
+
if (hasNewStorage) {
|
|
16936
|
+
set((s) => ({
|
|
16937
|
+
gpuStorage: {
|
|
16938
|
+
...s.gpuStorage,
|
|
16939
|
+
[scope]: { ...s.gpuStorage[scope], ...result }
|
|
16940
|
+
}
|
|
16941
|
+
}));
|
|
16942
|
+
}
|
|
16943
|
+
return result;
|
|
16944
|
+
}
|
|
16945
|
+
for (const [name, storage] of Object.entries(created)) {
|
|
16946
|
+
const existing = state.gpuStorage[name];
|
|
16947
|
+
if (existing && isStorageLike(existing)) {
|
|
16948
|
+
result[name] = existing;
|
|
16949
|
+
} else {
|
|
16950
|
+
if ("setName" in storage && typeof storage.setName === "function") {
|
|
16951
|
+
storage.setName(name);
|
|
16952
|
+
}
|
|
16953
|
+
if ("name" in storage && typeof storage.name === "string") {
|
|
16954
|
+
storage.name = name;
|
|
16955
|
+
}
|
|
16956
|
+
result[name] = storage;
|
|
16957
|
+
hasNewStorage = true;
|
|
16958
|
+
}
|
|
16959
|
+
}
|
|
16960
|
+
if (hasNewStorage) {
|
|
16961
|
+
set((s) => ({ gpuStorage: { ...s.gpuStorage, ...result } }));
|
|
16962
|
+
}
|
|
16963
|
+
return result;
|
|
16964
|
+
}, [store, scopeDep, readerDep, creatorDep]);
|
|
16965
|
+
return {
|
|
16966
|
+
...gpuStorage,
|
|
16967
|
+
removeStorage,
|
|
16968
|
+
clearStorage,
|
|
16969
|
+
rebuildStorage,
|
|
16970
|
+
disposeStorage: disposeStorageFn
|
|
16971
|
+
};
|
|
16972
|
+
}
|
|
16973
|
+
function rebuildAllStorage(store, scope) {
|
|
16974
|
+
store.setState((state) => {
|
|
16975
|
+
let newStorage = state.gpuStorage;
|
|
16976
|
+
if (scope && scope !== "root") {
|
|
16977
|
+
const { [scope]: _, ...rest } = state.gpuStorage;
|
|
16978
|
+
newStorage = rest;
|
|
16979
|
+
} else if (scope === "root") {
|
|
16980
|
+
newStorage = {};
|
|
16981
|
+
for (const [key, value] of Object.entries(state.gpuStorage)) {
|
|
16982
|
+
if (!isStorageLike(value)) newStorage[key] = value;
|
|
16983
|
+
}
|
|
16984
|
+
} else {
|
|
16985
|
+
newStorage = {};
|
|
16986
|
+
}
|
|
16987
|
+
return { gpuStorage: newStorage, _hmrVersion: state._hmrVersion + 1 };
|
|
16988
|
+
});
|
|
15523
16989
|
}
|
|
15524
16990
|
|
|
15525
|
-
function
|
|
16991
|
+
function useRenderPipeline(mainCB, setupCB) {
|
|
15526
16992
|
const store = useStore();
|
|
15527
16993
|
const { scene, camera, renderer, isLegacy } = useThree();
|
|
15528
16994
|
const callbacksRanRef = useRef(false);
|
|
@@ -15532,12 +16998,16 @@ function usePostProcessing(mainCB, setupCB) {
|
|
|
15532
16998
|
mainCBRef.current = mainCB;
|
|
15533
16999
|
setupCBRef.current = setupCB;
|
|
15534
17000
|
const [rebuildVersion, setRebuildVersion] = useState(0);
|
|
17001
|
+
useEffect(() => {
|
|
17002
|
+
callbacksRanRef.current = false;
|
|
17003
|
+
scenePassCacheRef.current = null;
|
|
17004
|
+
}, []);
|
|
15535
17005
|
const clearPasses = useCallback(() => {
|
|
15536
17006
|
store.setState({ passes: {} });
|
|
15537
17007
|
}, [store]);
|
|
15538
17008
|
const reset = useCallback(() => {
|
|
15539
17009
|
store.setState({
|
|
15540
|
-
|
|
17010
|
+
renderPipeline: null,
|
|
15541
17011
|
passes: {}
|
|
15542
17012
|
});
|
|
15543
17013
|
callbacksRanRef.current = false;
|
|
@@ -15550,13 +17020,13 @@ function usePostProcessing(mainCB, setupCB) {
|
|
|
15550
17020
|
}, []);
|
|
15551
17021
|
useLayoutEffect(() => {
|
|
15552
17022
|
if (isLegacy) {
|
|
15553
|
-
throw new Error("
|
|
17023
|
+
throw new Error("useRenderPipeline is only available with WebGPU renderer. Set renderer prop on Canvas.");
|
|
15554
17024
|
}
|
|
15555
17025
|
if (!renderer || !scene || !camera) return;
|
|
15556
17026
|
const state = store.getState();
|
|
15557
17027
|
const set = store.setState;
|
|
15558
17028
|
try {
|
|
15559
|
-
let pp = state.
|
|
17029
|
+
let pp = state.renderPipeline;
|
|
15560
17030
|
let currentPasses = { ...state.passes };
|
|
15561
17031
|
let justCreatedPP = false;
|
|
15562
17032
|
if (!pp) {
|
|
@@ -15573,7 +17043,7 @@ function usePostProcessing(mainCB, setupCB) {
|
|
|
15573
17043
|
}
|
|
15574
17044
|
currentPasses.scenePass = scenePass;
|
|
15575
17045
|
if (!pp.outputNode || justCreatedPP) pp.outputNode = scenePass;
|
|
15576
|
-
set({
|
|
17046
|
+
set({ renderPipeline: pp, passes: currentPasses });
|
|
15577
17047
|
const shouldRunCallbacks = justCreatedPP || !callbacksRanRef.current || !cacheValid;
|
|
15578
17048
|
if (shouldRunCallbacks) {
|
|
15579
17049
|
if (setupCBRef.current) {
|
|
@@ -15595,22 +17065,22 @@ function usePostProcessing(mainCB, setupCB) {
|
|
|
15595
17065
|
callbacksRanRef.current = true;
|
|
15596
17066
|
}
|
|
15597
17067
|
} catch (error) {
|
|
15598
|
-
console.error("[
|
|
17068
|
+
console.error("[useRenderPipeline] Setup error:", error);
|
|
15599
17069
|
}
|
|
15600
17070
|
}, [store, renderer, scene, camera, isLegacy, rebuildVersion]);
|
|
15601
17071
|
const passes = useThree((s) => s.passes);
|
|
15602
|
-
const
|
|
17072
|
+
const renderPipeline = useThree((s) => s.renderPipeline);
|
|
15603
17073
|
return {
|
|
15604
17074
|
passes,
|
|
15605
|
-
|
|
17075
|
+
renderPipeline,
|
|
15606
17076
|
clearPasses,
|
|
15607
17077
|
reset,
|
|
15608
17078
|
rebuild,
|
|
15609
|
-
// isReady indicates if
|
|
15610
|
-
isReady:
|
|
17079
|
+
// isReady indicates if RenderPipeline is configured and ready for rendering
|
|
17080
|
+
isReady: renderPipeline !== null
|
|
15611
17081
|
};
|
|
15612
17082
|
}
|
|
15613
17083
|
|
|
15614
17084
|
extend(THREE);
|
|
15615
17085
|
|
|
15616
|
-
export { Block, Canvas, ErrorBoundary, IsObject, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, Scheduler, Texture, _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, clearNodeScope, clearRootNodes, clearRootUniforms, clearScope, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, createTextureOperations, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, getInstanceProps, getRootState, getScheduler, getUuidPrefix, hasConstructor, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isObject3D, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, prepare, reconciler, removeInteractivity, removeNodes, removeUniforms, resolve, unmountComponentAtNode, updateCamera, updateFrustum, useBridge, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes,
|
|
17086
|
+
export { Block, Canvas, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, ErrorBoundary, FROM_REF, IsObject, ONCE, Portal, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, Scheduler, Texture, _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, clearNodeScope, clearRootNodes, clearRootUniforms, clearScope, context, createEvents, createPointerEvents, createPortal, createRoot, createScopedStore, createStore, createTextureOperations, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, fromRef, getInstanceProps, getPrimary, getPrimaryIds, getRootState, getScheduler, getUuidPrefix, hasConstructor, hasPrimary, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isFromRef, isObject3D, isOnce, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, once, prepare, presetsObj, rebuildAllBuffers, rebuildAllNodes, rebuildAllStorage, rebuildAllUniforms, reconciler, registerPrimary, removeInteractivity, removeNodes, removeUniforms, resolve, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useBuffers, useEnvironment, useFrame, useGPUStorage, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes, useRenderPipeline, useRenderTarget, useStore, useTexture, useTextures, useThree, useUniform, useUniforms, waitForPrimary };
|