@react-three/fiber 10.0.0-alpha.1 → 10.0.0-canary.2b511a5
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 +1170 -557
- package/dist/index.d.cts +2001 -1274
- package/dist/index.d.mts +2001 -1274
- package/dist/index.d.ts +2001 -1274
- package/dist/index.mjs +1154 -561
- package/dist/legacy.cjs +1158 -564
- package/dist/legacy.d.cts +2002 -1275
- package/dist/legacy.d.mts +2002 -1275
- package/dist/legacy.d.ts +2002 -1275
- package/dist/legacy.mjs +1142 -568
- package/dist/webgpu/index.cjs +1365 -504
- package/dist/webgpu/index.d.cts +2180 -1290
- package/dist/webgpu/index.d.mts +2180 -1290
- package/dist/webgpu/index.d.ts +2180 -1290
- package/dist/webgpu/index.mjs +1346 -508
- 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, PCFSoftShadowMap, VSMShadowMap, PCFShadowMap, 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,377 @@ 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
|
+
}, [files, 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
|
+
}, [children, virtualScene, fbo.texture, scene, defaultScene, background, frames, gl]);
|
|
353
|
+
let count = 1;
|
|
354
|
+
useFrame$1(() => {
|
|
355
|
+
if (frames === Infinity || count < frames) {
|
|
356
|
+
const autoClear = gl.autoClear;
|
|
357
|
+
gl.autoClear = true;
|
|
358
|
+
camera.current.update(gl, virtualScene);
|
|
359
|
+
gl.autoClear = autoClear;
|
|
360
|
+
count++;
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
return /* @__PURE__ */ jsx(Fragment, { children: createPortal$1(
|
|
364
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
365
|
+
children,
|
|
366
|
+
/* @__PURE__ */ jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
|
|
367
|
+
files || preset ? /* @__PURE__ */ jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsx(EnvironmentMap, { background: true, map, extensions }) : null
|
|
368
|
+
] }),
|
|
369
|
+
virtualScene
|
|
370
|
+
) });
|
|
371
|
+
}
|
|
372
|
+
function EnvironmentGround(props) {
|
|
373
|
+
const textureDefault = useEnvironment(props);
|
|
374
|
+
const texture = props.map || textureDefault;
|
|
375
|
+
React.useMemo(() => extend$1({ GroundProjectedEnvImpl: GroundedSkybox }), []);
|
|
376
|
+
React.useEffect(() => {
|
|
377
|
+
return () => {
|
|
378
|
+
textureDefault.dispose();
|
|
379
|
+
};
|
|
380
|
+
}, [textureDefault]);
|
|
381
|
+
const height = props.ground?.height ?? 15;
|
|
382
|
+
const radius = props.ground?.radius ?? 60;
|
|
383
|
+
const scale = props.ground?.scale ?? 1e3;
|
|
384
|
+
const args = React.useMemo(
|
|
385
|
+
() => [texture, height, radius],
|
|
386
|
+
[texture, height, radius]
|
|
387
|
+
);
|
|
388
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
389
|
+
/* @__PURE__ */ jsx(EnvironmentMap, { ...props, map: texture }),
|
|
390
|
+
/* @__PURE__ */ jsx("groundProjectedEnvImpl", { args, scale })
|
|
391
|
+
] });
|
|
392
|
+
}
|
|
393
|
+
function EnvironmentColor({ color, scene }) {
|
|
394
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
395
|
+
React.useLayoutEffect(() => {
|
|
396
|
+
if (color === void 0) return;
|
|
397
|
+
const target = resolveScene(scene || defaultScene);
|
|
398
|
+
const oldBg = target.background;
|
|
399
|
+
target.background = new Color(color);
|
|
400
|
+
return () => {
|
|
401
|
+
target.background = oldBg;
|
|
402
|
+
};
|
|
403
|
+
});
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
function EnvironmentDualSource(props) {
|
|
407
|
+
const { backgroundFiles, ...envProps } = props;
|
|
408
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
409
|
+
/* @__PURE__ */ jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
410
|
+
/* @__PURE__ */ jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
|
|
411
|
+
] });
|
|
412
|
+
}
|
|
413
|
+
function Environment(props) {
|
|
414
|
+
if (props.color && !props.files && !props.preset && !props.map) {
|
|
415
|
+
return /* @__PURE__ */ jsx(EnvironmentColor, { ...props });
|
|
416
|
+
}
|
|
417
|
+
if (props.backgroundFiles && props.backgroundFiles !== props.files) {
|
|
418
|
+
return /* @__PURE__ */ jsx(EnvironmentDualSource, { ...props });
|
|
419
|
+
}
|
|
420
|
+
return props.ground ? /* @__PURE__ */ jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsx(EnvironmentCube, { ...props });
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
var __defProp$3 = Object.defineProperty;
|
|
424
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
425
|
+
var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
52
426
|
const act = React["act"];
|
|
53
427
|
const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React.useLayoutEffect : React.useEffect;
|
|
54
428
|
function useMutableCallback(fn) {
|
|
@@ -80,7 +454,7 @@ const ErrorBoundary = /* @__PURE__ */ (() => {
|
|
|
80
454
|
return _a = class extends React.Component {
|
|
81
455
|
constructor() {
|
|
82
456
|
super(...arguments);
|
|
83
|
-
__publicField$
|
|
457
|
+
__publicField$3(this, "state", { error: false });
|
|
84
458
|
}
|
|
85
459
|
componentDidCatch(err) {
|
|
86
460
|
this.props.set(err);
|
|
@@ -88,7 +462,7 @@ const ErrorBoundary = /* @__PURE__ */ (() => {
|
|
|
88
462
|
render() {
|
|
89
463
|
return this.state.error ? null : this.props.children;
|
|
90
464
|
}
|
|
91
|
-
}, __publicField$
|
|
465
|
+
}, __publicField$3(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
|
|
92
466
|
})();
|
|
93
467
|
|
|
94
468
|
const is = {
|
|
@@ -225,7 +599,8 @@ function prepare(target, root, type, props) {
|
|
|
225
599
|
object,
|
|
226
600
|
eventCount: 0,
|
|
227
601
|
handlers: {},
|
|
228
|
-
isHidden: false
|
|
602
|
+
isHidden: false,
|
|
603
|
+
deferredRefs: []
|
|
229
604
|
};
|
|
230
605
|
if (object) object.__r3f = instance;
|
|
231
606
|
}
|
|
@@ -274,7 +649,7 @@ function createOcclusionObserverNode(store, uniform) {
|
|
|
274
649
|
let occlusionSetupPromise = null;
|
|
275
650
|
function enableOcclusion(store) {
|
|
276
651
|
const state = store.getState();
|
|
277
|
-
const { internal, renderer
|
|
652
|
+
const { internal, renderer } = state;
|
|
278
653
|
if (internal.occlusionEnabled || occlusionSetupPromise) return;
|
|
279
654
|
const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
|
|
280
655
|
if (!hasOcclusionSupport) {
|
|
@@ -437,6 +812,22 @@ function hasVisibilityHandlers(handlers) {
|
|
|
437
812
|
return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
|
|
438
813
|
}
|
|
439
814
|
|
|
815
|
+
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
816
|
+
function fromRef(ref) {
|
|
817
|
+
return { [FROM_REF]: ref };
|
|
818
|
+
}
|
|
819
|
+
function isFromRef(value) {
|
|
820
|
+
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
const ONCE = Symbol.for("@react-three/fiber.once");
|
|
824
|
+
function once(...args) {
|
|
825
|
+
return { [ONCE]: args.length ? args : true };
|
|
826
|
+
}
|
|
827
|
+
function isOnce(value) {
|
|
828
|
+
return value !== null && typeof value === "object" && ONCE in value;
|
|
829
|
+
}
|
|
830
|
+
|
|
440
831
|
const RESERVED_PROPS = [
|
|
441
832
|
"children",
|
|
442
833
|
"key",
|
|
@@ -507,7 +898,7 @@ function getMemoizedPrototype(root) {
|
|
|
507
898
|
ctor = new root.constructor();
|
|
508
899
|
MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
|
|
509
900
|
}
|
|
510
|
-
} catch
|
|
901
|
+
} catch {
|
|
511
902
|
}
|
|
512
903
|
return ctor;
|
|
513
904
|
}
|
|
@@ -538,7 +929,7 @@ function applyProps(object, props) {
|
|
|
538
929
|
const rootState = instance && findInitialRoot(instance).getState();
|
|
539
930
|
const prevHandlers = instance?.eventCount;
|
|
540
931
|
for (const prop in props) {
|
|
541
|
-
|
|
932
|
+
const value = props[prop];
|
|
542
933
|
if (RESERVED_PROPS.includes(prop)) continue;
|
|
543
934
|
if (instance && EVENT_REGEX.test(prop)) {
|
|
544
935
|
if (typeof value === "function") instance.handlers[prop] = value;
|
|
@@ -553,6 +944,25 @@ function applyProps(object, props) {
|
|
|
553
944
|
continue;
|
|
554
945
|
}
|
|
555
946
|
if (value === void 0) continue;
|
|
947
|
+
if (isFromRef(value)) {
|
|
948
|
+
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
949
|
+
continue;
|
|
950
|
+
}
|
|
951
|
+
if (isOnce(value)) {
|
|
952
|
+
if (instance?.appliedOnce?.has(prop)) continue;
|
|
953
|
+
if (instance) {
|
|
954
|
+
instance.appliedOnce ?? (instance.appliedOnce = /* @__PURE__ */ new Set());
|
|
955
|
+
instance.appliedOnce.add(prop);
|
|
956
|
+
}
|
|
957
|
+
const { root: targetRoot, key: targetKey } = resolve(object, prop);
|
|
958
|
+
const args = value[ONCE];
|
|
959
|
+
if (typeof targetRoot[targetKey] === "function") {
|
|
960
|
+
targetRoot[targetKey](...args === true ? [] : args);
|
|
961
|
+
} else if (args !== true && args.length > 0) {
|
|
962
|
+
targetRoot[targetKey] = args[0];
|
|
963
|
+
}
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
556
966
|
let { root, key, target } = resolve(object, prop);
|
|
557
967
|
if (target === void 0 && (typeof root !== "object" || root === null)) {
|
|
558
968
|
throw Error(`R3F: Cannot set "${prop}". Ensure it is an object before setting "${key}".`);
|
|
@@ -575,7 +985,7 @@ function applyProps(object, props) {
|
|
|
575
985
|
else target.set(value);
|
|
576
986
|
} else {
|
|
577
987
|
root[key] = value;
|
|
578
|
-
if (rootState &&
|
|
988
|
+
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
989
|
root[key].format === RGBAFormat && root[key].type === UnsignedByteType) {
|
|
580
990
|
root[key].colorSpace = rootState.textureColorSpace;
|
|
581
991
|
}
|
|
@@ -690,13 +1100,14 @@ function createEvents(store) {
|
|
|
690
1100
|
for (const hit of hits) {
|
|
691
1101
|
let eventObject = hit.object;
|
|
692
1102
|
while (eventObject) {
|
|
693
|
-
if (eventObject.__r3f?.eventCount)
|
|
1103
|
+
if (eventObject.__r3f?.eventCount) {
|
|
694
1104
|
intersections.push({ ...hit, eventObject });
|
|
1105
|
+
}
|
|
695
1106
|
eventObject = eventObject.parent;
|
|
696
1107
|
}
|
|
697
1108
|
}
|
|
698
1109
|
if ("pointerId" in event && state.internal.capturedMap.has(event.pointerId)) {
|
|
699
|
-
for (
|
|
1110
|
+
for (const captureData of state.internal.capturedMap.get(event.pointerId).values()) {
|
|
700
1111
|
if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
|
|
701
1112
|
}
|
|
702
1113
|
}
|
|
@@ -726,12 +1137,12 @@ function createEvents(store) {
|
|
|
726
1137
|
releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
|
|
727
1138
|
}
|
|
728
1139
|
};
|
|
729
|
-
|
|
730
|
-
for (
|
|
731
|
-
|
|
1140
|
+
const extractEventProps = {};
|
|
1141
|
+
for (const prop in event) {
|
|
1142
|
+
const property = event[prop];
|
|
732
1143
|
if (typeof property !== "function") extractEventProps[prop] = property;
|
|
733
1144
|
}
|
|
734
|
-
|
|
1145
|
+
const raycastEvent = {
|
|
735
1146
|
...hit,
|
|
736
1147
|
...extractEventProps,
|
|
737
1148
|
pointer,
|
|
@@ -931,7 +1342,7 @@ function createPointerEvents(store) {
|
|
|
931
1342
|
return {
|
|
932
1343
|
priority: 1,
|
|
933
1344
|
enabled: true,
|
|
934
|
-
compute(event, state
|
|
1345
|
+
compute(event, state) {
|
|
935
1346
|
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
936
1347
|
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
937
1348
|
},
|
|
@@ -990,331 +1401,57 @@ function notifyDepreciated({ heading, body, link }) {
|
|
|
990
1401
|
if (body || link) {
|
|
991
1402
|
let message = "";
|
|
992
1403
|
if (body) message += body;
|
|
993
|
-
if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
|
|
994
|
-
console.warn(`%c${message}`, "font-weight: bold;");
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
function getCallerFrame(depth = 3) {
|
|
998
|
-
const stack = new Error().stack;
|
|
999
|
-
if (!stack) return null;
|
|
1000
|
-
const lines = stack.split("\n");
|
|
1001
|
-
const frame = lines[depth];
|
|
1002
|
-
if (!frame) return null;
|
|
1003
|
-
let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
|
|
1004
|
-
if (!match) {
|
|
1005
|
-
match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
|
|
1006
|
-
}
|
|
1007
|
-
if (!match) return null;
|
|
1008
|
-
const [, fn, url, line] = match;
|
|
1009
|
-
return {
|
|
1010
|
-
functionName: fn ?? "<anonymous>",
|
|
1011
|
-
location: formatLocation(url, Number(line))
|
|
1012
|
-
};
|
|
1013
|
-
}
|
|
1014
|
-
function formatLocation(url, line) {
|
|
1015
|
-
const clean = url.split("?")[0];
|
|
1016
|
-
const file = clean.split("/").pop() ?? clean;
|
|
1017
|
-
return `${file}:${line}`;
|
|
1018
|
-
}
|
|
1019
|
-
function notifyAlpha({ message, link }) {
|
|
1020
|
-
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
|
|
1021
|
-
return;
|
|
1022
|
-
}
|
|
1023
|
-
if (shownNotices.has(message)) return;
|
|
1024
|
-
shownNotices.add(message);
|
|
1025
|
-
const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
|
|
1026
|
-
console.log(`%c\u{1F52C} ${message}`, boxStyle);
|
|
1027
|
-
{
|
|
1028
|
-
console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
1033
|
-
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React.createContext(null));
|
|
1034
|
-
const createStore = (invalidate, advance) => {
|
|
1035
|
-
const rootStore = createWithEqualityFn((set, get) => {
|
|
1036
|
-
const position = new Vector3();
|
|
1037
|
-
const defaultTarget = new Vector3();
|
|
1038
|
-
const tempTarget = new Vector3();
|
|
1039
|
-
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
1040
|
-
const { width, height, top, left } = size;
|
|
1041
|
-
const aspect = width / height;
|
|
1042
|
-
if (target.isVector3) tempTarget.copy(target);
|
|
1043
|
-
else tempTarget.set(...target);
|
|
1044
|
-
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
1045
|
-
if (isOrthographicCamera(camera)) {
|
|
1046
|
-
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
1047
|
-
} else {
|
|
1048
|
-
const fov = camera.fov * Math.PI / 180;
|
|
1049
|
-
const h = 2 * Math.tan(fov / 2) * distance;
|
|
1050
|
-
const w = h * (width / height);
|
|
1051
|
-
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
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
|
-
);
|
|
1404
|
+
if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
|
|
1405
|
+
console.warn(`%c${message}`, "font-weight: bold;");
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
function getCallerFrame(depth = 3) {
|
|
1409
|
+
const stack = new Error().stack;
|
|
1410
|
+
if (!stack) return null;
|
|
1411
|
+
const lines = stack.split("\n");
|
|
1412
|
+
const frame = lines[depth];
|
|
1413
|
+
if (!frame) return null;
|
|
1414
|
+
let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
|
|
1415
|
+
if (!match) {
|
|
1416
|
+
match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
|
|
1417
|
+
}
|
|
1418
|
+
if (!match) return null;
|
|
1419
|
+
const [, fn, url, line] = match;
|
|
1420
|
+
return {
|
|
1421
|
+
functionName: fn ?? "<anonymous>",
|
|
1422
|
+
location: formatLocation(url, Number(line))
|
|
1288
1423
|
};
|
|
1289
1424
|
}
|
|
1290
|
-
function
|
|
1291
|
-
const
|
|
1292
|
-
const
|
|
1293
|
-
|
|
1294
|
-
|
|
1425
|
+
function formatLocation(url, line) {
|
|
1426
|
+
const clean = url.split("?")[0];
|
|
1427
|
+
const file = clean.split("/").pop() ?? clean;
|
|
1428
|
+
return `${file}:${line}`;
|
|
1429
|
+
}
|
|
1430
|
+
function notifyAlpha({ message, link }) {
|
|
1431
|
+
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
|
|
1432
|
+
return;
|
|
1433
|
+
}
|
|
1434
|
+
if (shownNotices.has(message)) return;
|
|
1435
|
+
shownNotices.add(message);
|
|
1436
|
+
const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
|
|
1437
|
+
console.log(`%c\u{1F52C} ${message}`, boxStyle);
|
|
1438
|
+
{
|
|
1439
|
+
console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
|
|
1440
|
+
}
|
|
1295
1441
|
}
|
|
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
1442
|
|
|
1306
|
-
var __defProp$
|
|
1307
|
-
var __defNormalProp$
|
|
1308
|
-
var __publicField$
|
|
1443
|
+
var __defProp$2 = Object.defineProperty;
|
|
1444
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1445
|
+
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1309
1446
|
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1310
1447
|
class PhaseGraph {
|
|
1311
1448
|
constructor() {
|
|
1312
1449
|
/** Ordered list of phase nodes */
|
|
1313
|
-
__publicField$
|
|
1450
|
+
__publicField$2(this, "phases", []);
|
|
1314
1451
|
/** Quick lookup by name */
|
|
1315
|
-
__publicField$
|
|
1452
|
+
__publicField$2(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1316
1453
|
/** Cached ordered names (invalidated on changes) */
|
|
1317
|
-
__publicField$
|
|
1454
|
+
__publicField$2(this, "orderedNamesCache", null);
|
|
1318
1455
|
this.initializeDefaultPhases();
|
|
1319
1456
|
}
|
|
1320
1457
|
//* Initialization --------------------------------
|
|
@@ -1341,8 +1478,9 @@ class PhaseGraph {
|
|
|
1341
1478
|
const node = { name, isAutoGenerated: false };
|
|
1342
1479
|
let insertIndex = this.phases.length;
|
|
1343
1480
|
const targetIndex = this.getPhaseIndex(before ?? after);
|
|
1344
|
-
if (targetIndex !== -1)
|
|
1345
|
-
|
|
1481
|
+
if (targetIndex !== -1) {
|
|
1482
|
+
insertIndex = before ? targetIndex : targetIndex + 1;
|
|
1483
|
+
} else {
|
|
1346
1484
|
const constraintType = before ? "before" : "after";
|
|
1347
1485
|
console.warn(`[useFrame] Phase "${before ?? after}" not found for '${constraintType}' constraint`);
|
|
1348
1486
|
}
|
|
@@ -1570,9 +1708,9 @@ function resetJobTiming(job) {
|
|
|
1570
1708
|
job.lastRun = void 0;
|
|
1571
1709
|
}
|
|
1572
1710
|
|
|
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);
|
|
1711
|
+
var __defProp$1 = Object.defineProperty;
|
|
1712
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1713
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1576
1714
|
const hmrData = (() => {
|
|
1577
1715
|
if (typeof process !== "undefined" && process.env.NODE_ENV === "test") return void 0;
|
|
1578
1716
|
if (typeof import_meta_hot !== "undefined") return import_meta_hot;
|
|
@@ -1586,9 +1724,9 @@ const _Scheduler = class _Scheduler {
|
|
|
1586
1724
|
//* Constructor ================================
|
|
1587
1725
|
constructor() {
|
|
1588
1726
|
//* Critical State ================================
|
|
1589
|
-
__publicField(this, "roots", /* @__PURE__ */ new Map());
|
|
1590
|
-
__publicField(this, "phaseGraph");
|
|
1591
|
-
__publicField(this, "loopState", {
|
|
1727
|
+
__publicField$1(this, "roots", /* @__PURE__ */ new Map());
|
|
1728
|
+
__publicField$1(this, "phaseGraph");
|
|
1729
|
+
__publicField$1(this, "loopState", {
|
|
1592
1730
|
running: false,
|
|
1593
1731
|
rafHandle: null,
|
|
1594
1732
|
lastTime: null,
|
|
@@ -1597,21 +1735,21 @@ const _Scheduler = class _Scheduler {
|
|
|
1597
1735
|
elapsedTime: 0,
|
|
1598
1736
|
createdAt: performance.now()
|
|
1599
1737
|
});
|
|
1600
|
-
__publicField(this, "stoppedTime", 0);
|
|
1738
|
+
__publicField$1(this, "stoppedTime", 0);
|
|
1601
1739
|
//* 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");
|
|
1740
|
+
__publicField$1(this, "nextRootIndex", 0);
|
|
1741
|
+
__publicField$1(this, "globalBeforeJobs", /* @__PURE__ */ new Map());
|
|
1742
|
+
__publicField$1(this, "globalAfterJobs", /* @__PURE__ */ new Map());
|
|
1743
|
+
__publicField$1(this, "nextGlobalIndex", 0);
|
|
1744
|
+
__publicField$1(this, "idleCallbacks", /* @__PURE__ */ new Set());
|
|
1745
|
+
__publicField$1(this, "nextJobIndex", 0);
|
|
1746
|
+
__publicField$1(this, "jobStateListeners", /* @__PURE__ */ new Map());
|
|
1747
|
+
__publicField$1(this, "pendingFrames", 0);
|
|
1748
|
+
__publicField$1(this, "_frameloop", "always");
|
|
1611
1749
|
//* Independent Mode & Error Handling State ================================
|
|
1612
|
-
__publicField(this, "_independent", false);
|
|
1613
|
-
__publicField(this, "errorHandler", null);
|
|
1614
|
-
__publicField(this, "rootReadyCallbacks", /* @__PURE__ */ new Set());
|
|
1750
|
+
__publicField$1(this, "_independent", false);
|
|
1751
|
+
__publicField$1(this, "errorHandler", null);
|
|
1752
|
+
__publicField$1(this, "rootReadyCallbacks", /* @__PURE__ */ new Set());
|
|
1615
1753
|
//* Core Loop Execution Methods ================================
|
|
1616
1754
|
/**
|
|
1617
1755
|
* Main RAF loop callback.
|
|
@@ -1620,7 +1758,7 @@ const _Scheduler = class _Scheduler {
|
|
|
1620
1758
|
* @returns {void}
|
|
1621
1759
|
* @private
|
|
1622
1760
|
*/
|
|
1623
|
-
__publicField(this, "loop", (timestamp) => {
|
|
1761
|
+
__publicField$1(this, "loop", (timestamp) => {
|
|
1624
1762
|
if (!this.loopState.running) return;
|
|
1625
1763
|
this.executeFrame(timestamp);
|
|
1626
1764
|
if (this._frameloop === "demand") {
|
|
@@ -2323,16 +2461,329 @@ const _Scheduler = class _Scheduler {
|
|
|
2323
2461
|
return /* @__PURE__ */ new Set([value]);
|
|
2324
2462
|
}
|
|
2325
2463
|
};
|
|
2326
|
-
//* Static State & Methods (Singleton Usage) ================================
|
|
2327
|
-
//* Cross-Bundle Singleton Key ==============================
|
|
2328
|
-
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2329
|
-
// 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"));
|
|
2331
|
-
let Scheduler = _Scheduler;
|
|
2332
|
-
const getScheduler = () => Scheduler.get();
|
|
2333
|
-
if (hmrData) {
|
|
2334
|
-
hmrData.accept?.();
|
|
2464
|
+
//* Static State & Methods (Singleton Usage) ================================
|
|
2465
|
+
//* Cross-Bundle Singleton Key ==============================
|
|
2466
|
+
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2467
|
+
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2468
|
+
__publicField$1(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2469
|
+
let Scheduler = _Scheduler;
|
|
2470
|
+
const getScheduler = () => Scheduler.get();
|
|
2471
|
+
if (hmrData) {
|
|
2472
|
+
hmrData.accept?.();
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
2476
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React.createContext(null));
|
|
2477
|
+
const createStore = (invalidate, advance) => {
|
|
2478
|
+
const rootStore = createWithEqualityFn((set, get) => {
|
|
2479
|
+
const position = new Vector3();
|
|
2480
|
+
const defaultTarget = new Vector3();
|
|
2481
|
+
const tempTarget = new Vector3();
|
|
2482
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
2483
|
+
const { width, height, top, left } = size;
|
|
2484
|
+
const aspect = width / height;
|
|
2485
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
2486
|
+
else tempTarget.set(...target);
|
|
2487
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
2488
|
+
if (isOrthographicCamera(camera)) {
|
|
2489
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
2490
|
+
} else {
|
|
2491
|
+
const fov = camera.fov * Math.PI / 180;
|
|
2492
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
2493
|
+
const w = h * (width / height);
|
|
2494
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
let performanceTimeout = void 0;
|
|
2498
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
2499
|
+
const pointer = new Vector2();
|
|
2500
|
+
const rootState = {
|
|
2501
|
+
set,
|
|
2502
|
+
get,
|
|
2503
|
+
// Mock objects that have to be configured
|
|
2504
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
2505
|
+
primaryStore: null,
|
|
2506
|
+
gl: null,
|
|
2507
|
+
renderer: null,
|
|
2508
|
+
camera: null,
|
|
2509
|
+
frustum: new Frustum(),
|
|
2510
|
+
autoUpdateFrustum: true,
|
|
2511
|
+
raycaster: null,
|
|
2512
|
+
events: { priority: 1, enabled: true, connected: false },
|
|
2513
|
+
scene: null,
|
|
2514
|
+
rootScene: null,
|
|
2515
|
+
xr: null,
|
|
2516
|
+
inspector: null,
|
|
2517
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
2518
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
2519
|
+
textureColorSpace: SRGBColorSpace,
|
|
2520
|
+
isLegacy: false,
|
|
2521
|
+
webGPUSupported: false,
|
|
2522
|
+
isNative: false,
|
|
2523
|
+
controls: null,
|
|
2524
|
+
pointer,
|
|
2525
|
+
mouse: pointer,
|
|
2526
|
+
frameloop: "always",
|
|
2527
|
+
onPointerMissed: void 0,
|
|
2528
|
+
onDragOverMissed: void 0,
|
|
2529
|
+
onDropMissed: void 0,
|
|
2530
|
+
performance: {
|
|
2531
|
+
current: 1,
|
|
2532
|
+
min: 0.5,
|
|
2533
|
+
max: 1,
|
|
2534
|
+
debounce: 200,
|
|
2535
|
+
regress: () => {
|
|
2536
|
+
const state2 = get();
|
|
2537
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
2538
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
2539
|
+
performanceTimeout = setTimeout(
|
|
2540
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
2541
|
+
state2.performance.debounce
|
|
2542
|
+
);
|
|
2543
|
+
}
|
|
2544
|
+
},
|
|
2545
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
2546
|
+
viewport: {
|
|
2547
|
+
initialDpr: 0,
|
|
2548
|
+
dpr: 0,
|
|
2549
|
+
width: 0,
|
|
2550
|
+
height: 0,
|
|
2551
|
+
top: 0,
|
|
2552
|
+
left: 0,
|
|
2553
|
+
aspect: 0,
|
|
2554
|
+
distance: 0,
|
|
2555
|
+
factor: 0,
|
|
2556
|
+
getCurrentViewport
|
|
2557
|
+
},
|
|
2558
|
+
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
2559
|
+
setSize: (width, height, top, left) => {
|
|
2560
|
+
const state2 = get();
|
|
2561
|
+
if (width === void 0) {
|
|
2562
|
+
set({ _sizeImperative: false });
|
|
2563
|
+
if (state2._sizeProps) {
|
|
2564
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
2565
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
2566
|
+
const currentSize = state2.size;
|
|
2567
|
+
const newSize = {
|
|
2568
|
+
width: propW ?? currentSize.width,
|
|
2569
|
+
height: propH ?? currentSize.height,
|
|
2570
|
+
top: currentSize.top,
|
|
2571
|
+
left: currentSize.left
|
|
2572
|
+
};
|
|
2573
|
+
set((s) => ({
|
|
2574
|
+
size: newSize,
|
|
2575
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
2576
|
+
}));
|
|
2577
|
+
getScheduler().invalidate();
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
return;
|
|
2581
|
+
}
|
|
2582
|
+
const w = width;
|
|
2583
|
+
const h = height ?? width;
|
|
2584
|
+
const t = top ?? state2.size.top;
|
|
2585
|
+
const l = left ?? state2.size.left;
|
|
2586
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
2587
|
+
set((s) => ({
|
|
2588
|
+
size,
|
|
2589
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
2590
|
+
_sizeImperative: true
|
|
2591
|
+
}));
|
|
2592
|
+
getScheduler().invalidate();
|
|
2593
|
+
},
|
|
2594
|
+
setDpr: (dpr) => set((state2) => {
|
|
2595
|
+
const resolved = calculateDpr(dpr);
|
|
2596
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
2597
|
+
}),
|
|
2598
|
+
setFrameloop: (frameloop = "always") => {
|
|
2599
|
+
set(() => ({ frameloop }));
|
|
2600
|
+
},
|
|
2601
|
+
setError: (error) => set(() => ({ error })),
|
|
2602
|
+
error: null,
|
|
2603
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
|
|
2604
|
+
uniforms: {},
|
|
2605
|
+
nodes: {},
|
|
2606
|
+
textures: /* @__PURE__ */ new Map(),
|
|
2607
|
+
postProcessing: null,
|
|
2608
|
+
passes: {},
|
|
2609
|
+
_hmrVersion: 0,
|
|
2610
|
+
_sizeImperative: false,
|
|
2611
|
+
_sizeProps: null,
|
|
2612
|
+
previousRoot: void 0,
|
|
2613
|
+
internal: {
|
|
2614
|
+
// Events
|
|
2615
|
+
interaction: [],
|
|
2616
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
2617
|
+
subscribers: [],
|
|
2618
|
+
initialClick: [0, 0],
|
|
2619
|
+
initialHits: [],
|
|
2620
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
2621
|
+
lastEvent: React.createRef(),
|
|
2622
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
2623
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
2624
|
+
// Occlusion system (WebGPU only)
|
|
2625
|
+
occlusionEnabled: false,
|
|
2626
|
+
occlusionObserver: null,
|
|
2627
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
2628
|
+
helperGroup: null,
|
|
2629
|
+
// Updates
|
|
2630
|
+
active: false,
|
|
2631
|
+
frames: 0,
|
|
2632
|
+
priority: 0,
|
|
2633
|
+
subscribe: (ref, priority, store) => {
|
|
2634
|
+
const internal = get().internal;
|
|
2635
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
2636
|
+
internal.subscribers.push({ ref, priority, store });
|
|
2637
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
2638
|
+
return () => {
|
|
2639
|
+
const internal2 = get().internal;
|
|
2640
|
+
if (internal2?.subscribers) {
|
|
2641
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
2642
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
2643
|
+
}
|
|
2644
|
+
};
|
|
2645
|
+
},
|
|
2646
|
+
// Renderer Storage (single source of truth)
|
|
2647
|
+
actualRenderer: null,
|
|
2648
|
+
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
2649
|
+
scheduler: null
|
|
2650
|
+
}
|
|
2651
|
+
};
|
|
2652
|
+
return rootState;
|
|
2653
|
+
});
|
|
2654
|
+
const state = rootStore.getState();
|
|
2655
|
+
Object.defineProperty(state, "gl", {
|
|
2656
|
+
get() {
|
|
2657
|
+
const currentState = rootStore.getState();
|
|
2658
|
+
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
2659
|
+
const stack = new Error().stack || "";
|
|
2660
|
+
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
2661
|
+
if (!isInternalAccess) {
|
|
2662
|
+
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
2663
|
+
notifyDepreciated({
|
|
2664
|
+
heading: "Accessing state.gl in WebGPU mode",
|
|
2665
|
+
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
|
|
2666
|
+
});
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
return currentState.internal.actualRenderer;
|
|
2670
|
+
},
|
|
2671
|
+
set(value) {
|
|
2672
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2673
|
+
},
|
|
2674
|
+
enumerable: true,
|
|
2675
|
+
configurable: true
|
|
2676
|
+
});
|
|
2677
|
+
Object.defineProperty(state, "renderer", {
|
|
2678
|
+
get() {
|
|
2679
|
+
return rootStore.getState().internal.actualRenderer;
|
|
2680
|
+
},
|
|
2681
|
+
set(value) {
|
|
2682
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2683
|
+
},
|
|
2684
|
+
enumerable: true,
|
|
2685
|
+
configurable: true
|
|
2686
|
+
});
|
|
2687
|
+
let oldScene = state.scene;
|
|
2688
|
+
rootStore.subscribe(() => {
|
|
2689
|
+
const currentState = rootStore.getState();
|
|
2690
|
+
const { scene, rootScene, set } = currentState;
|
|
2691
|
+
if (scene !== oldScene) {
|
|
2692
|
+
oldScene = scene;
|
|
2693
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
2694
|
+
set({ rootScene: scene });
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
});
|
|
2698
|
+
let oldSize = state.size;
|
|
2699
|
+
let oldDpr = state.viewport.dpr;
|
|
2700
|
+
let oldCamera = state.camera;
|
|
2701
|
+
rootStore.subscribe(() => {
|
|
2702
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
2703
|
+
const actualRenderer = internal.actualRenderer;
|
|
2704
|
+
const canvasTarget = internal.canvasTarget;
|
|
2705
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
2706
|
+
oldSize = size;
|
|
2707
|
+
oldDpr = viewport.dpr;
|
|
2708
|
+
updateCamera(camera, size);
|
|
2709
|
+
if (canvasTarget) {
|
|
2710
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2711
|
+
const updateStyle = typeof HTMLCanvasElement !== "undefined" && canvasTarget.domElement instanceof HTMLCanvasElement;
|
|
2712
|
+
canvasTarget.setSize(size.width, size.height, updateStyle);
|
|
2713
|
+
} else {
|
|
2714
|
+
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
2715
|
+
const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
|
|
2716
|
+
actualRenderer.setSize(size.width, size.height, updateStyle);
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
if (camera !== oldCamera) {
|
|
2720
|
+
oldCamera = camera;
|
|
2721
|
+
const { rootScene } = rootStore.getState();
|
|
2722
|
+
if (camera && rootScene && !camera.parent) {
|
|
2723
|
+
rootScene.add(camera);
|
|
2724
|
+
}
|
|
2725
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
2726
|
+
const currentState = rootStore.getState();
|
|
2727
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
2728
|
+
updateFrustum(camera, currentState.frustum);
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
});
|
|
2732
|
+
rootStore.subscribe((state2) => invalidate(state2));
|
|
2733
|
+
return rootStore;
|
|
2734
|
+
};
|
|
2735
|
+
|
|
2736
|
+
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
2737
|
+
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
2738
|
+
function getLoader(Proto) {
|
|
2739
|
+
if (isConstructor$1(Proto)) {
|
|
2740
|
+
let loader = memoizedLoaders.get(Proto);
|
|
2741
|
+
if (!loader) {
|
|
2742
|
+
loader = new Proto();
|
|
2743
|
+
memoizedLoaders.set(Proto, loader);
|
|
2744
|
+
}
|
|
2745
|
+
return loader;
|
|
2746
|
+
}
|
|
2747
|
+
return Proto;
|
|
2748
|
+
}
|
|
2749
|
+
function loadingFn(extensions, onProgress) {
|
|
2750
|
+
return function(Proto, input) {
|
|
2751
|
+
const loader = getLoader(Proto);
|
|
2752
|
+
if (extensions) extensions(loader);
|
|
2753
|
+
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
2754
|
+
return loader.loadAsync(input, onProgress).then((data) => {
|
|
2755
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2756
|
+
return data;
|
|
2757
|
+
});
|
|
2758
|
+
}
|
|
2759
|
+
return new Promise(
|
|
2760
|
+
(res, reject) => loader.load(
|
|
2761
|
+
input,
|
|
2762
|
+
(data) => {
|
|
2763
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2764
|
+
res(data);
|
|
2765
|
+
},
|
|
2766
|
+
onProgress,
|
|
2767
|
+
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
2768
|
+
)
|
|
2769
|
+
);
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2772
|
+
function useLoader(loader, input, extensions, onProgress) {
|
|
2773
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2774
|
+
const fn = loadingFn(extensions, onProgress);
|
|
2775
|
+
const results = keys.map((key) => suspend(fn, [loader, key], { equal: is.equ }));
|
|
2776
|
+
return Array.isArray(input) ? results : results[0];
|
|
2335
2777
|
}
|
|
2778
|
+
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
2779
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2780
|
+
keys.forEach((key) => preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
2781
|
+
};
|
|
2782
|
+
useLoader.clear = function(loader, input) {
|
|
2783
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2784
|
+
keys.forEach((key) => clear([loader, key]));
|
|
2785
|
+
};
|
|
2786
|
+
useLoader.loader = getLoader;
|
|
2336
2787
|
|
|
2337
2788
|
function useFrame(callback, priorityOrOptions) {
|
|
2338
2789
|
const store = React.useContext(context);
|
|
@@ -2513,6 +2964,9 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2513
2964
|
const textureCache = useThree((state) => state.textures);
|
|
2514
2965
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
2515
2966
|
const { onLoad, cache = false } = options;
|
|
2967
|
+
const onLoadRef = useRef(onLoad);
|
|
2968
|
+
onLoadRef.current = onLoad;
|
|
2969
|
+
const onLoadCalledForRef = useRef(null);
|
|
2516
2970
|
const urls = useMemo(() => getUrls(input), [input]);
|
|
2517
2971
|
const cachedResult = useMemo(() => {
|
|
2518
2972
|
if (!cache) return null;
|
|
@@ -2523,9 +2977,13 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2523
2977
|
TextureLoader,
|
|
2524
2978
|
IsObject(input) ? Object.values(input) : input
|
|
2525
2979
|
);
|
|
2980
|
+
const inputKey = urls.join("\0");
|
|
2526
2981
|
useLayoutEffect(() => {
|
|
2527
|
-
if (
|
|
2528
|
-
|
|
2982
|
+
if (cachedResult) return;
|
|
2983
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
2984
|
+
onLoadCalledForRef.current = inputKey;
|
|
2985
|
+
onLoadRef.current?.(loadedTextures);
|
|
2986
|
+
}, [cachedResult, loadedTextures, inputKey]);
|
|
2529
2987
|
useEffect(() => {
|
|
2530
2988
|
if (cachedResult) return;
|
|
2531
2989
|
if ("initTexture" in renderer) {
|
|
@@ -2692,14 +3150,31 @@ function useTextures() {
|
|
|
2692
3150
|
}, [store]);
|
|
2693
3151
|
}
|
|
2694
3152
|
|
|
2695
|
-
function useRenderTarget(
|
|
3153
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
2696
3154
|
const isLegacy = useThree((s) => s.isLegacy);
|
|
2697
3155
|
const size = useThree((s) => s.size);
|
|
3156
|
+
let width;
|
|
3157
|
+
let height;
|
|
3158
|
+
let opts;
|
|
3159
|
+
if (typeof widthOrOptions === "object") {
|
|
3160
|
+
opts = widthOrOptions;
|
|
3161
|
+
} else if (typeof widthOrOptions === "number") {
|
|
3162
|
+
width = widthOrOptions;
|
|
3163
|
+
if (typeof heightOrOptions === "object") {
|
|
3164
|
+
height = widthOrOptions;
|
|
3165
|
+
opts = heightOrOptions;
|
|
3166
|
+
} else if (typeof heightOrOptions === "number") {
|
|
3167
|
+
height = heightOrOptions;
|
|
3168
|
+
opts = options;
|
|
3169
|
+
} else {
|
|
3170
|
+
height = widthOrOptions;
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
2698
3173
|
return useMemo(() => {
|
|
2699
3174
|
const w = width ?? size.width;
|
|
2700
3175
|
const h = height ?? size.height;
|
|
2701
|
-
return new RenderTarget(w, h,
|
|
2702
|
-
}, [width, height, size.width, size.height,
|
|
3176
|
+
return new RenderTarget(w, h, opts);
|
|
3177
|
+
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
2703
3178
|
}
|
|
2704
3179
|
|
|
2705
3180
|
function useStore() {
|
|
@@ -2749,28 +3224,18 @@ function addTail(callback) {
|
|
|
2749
3224
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
2750
3225
|
getScheduler().invalidate(frames, stackFrames);
|
|
2751
3226
|
}
|
|
2752
|
-
function advance(timestamp
|
|
3227
|
+
function advance(timestamp) {
|
|
2753
3228
|
getScheduler().step(timestamp);
|
|
2754
3229
|
}
|
|
2755
3230
|
|
|
2756
|
-
const version = "10.0.0-alpha.
|
|
3231
|
+
const version = "10.0.0-alpha.2";
|
|
2757
3232
|
const packageData = {
|
|
2758
3233
|
version: version};
|
|
2759
3234
|
|
|
2760
3235
|
function Xb(Tt) {
|
|
2761
3236
|
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
2762
3237
|
}
|
|
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;
|
|
3238
|
+
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
2774
3239
|
function Kb() {
|
|
2775
3240
|
return _b || (_b = 1, (function(Tt) {
|
|
2776
3241
|
Tt.exports = function(m) {
|
|
@@ -3842,7 +4307,6 @@ Error generating stack: ` + l.message + `
|
|
|
3842
4307
|
if (J === cl || J === jc) throw J;
|
|
3843
4308
|
var Ge = Yn(29, J, null, P.mode);
|
|
3844
4309
|
return Ge.lanes = H, Ge.return = P, Ge;
|
|
3845
|
-
} finally {
|
|
3846
4310
|
}
|
|
3847
4311
|
};
|
|
3848
4312
|
}
|
|
@@ -4496,7 +4960,6 @@ Error generating stack: ` + l.message + `
|
|
|
4496
4960
|
var h = r.lastRenderedState, y = d(h, a);
|
|
4497
4961
|
if (c.hasEagerState = true, c.eagerState = y, jn(y, h)) return go(t, r, c, 0), Ne === null && Bn(), false;
|
|
4498
4962
|
} catch {
|
|
4499
|
-
} finally {
|
|
4500
4963
|
}
|
|
4501
4964
|
if (a = yo(t, r, c, l), a !== null) return nt(a, t, l), ns(a, r, l), true;
|
|
4502
4965
|
}
|
|
@@ -6917,10 +7380,7 @@ Error generating stack: ` + l.message + `
|
|
|
6917
7380
|
function vr(t, r) {
|
|
6918
7381
|
Sf(t, r), (t = t.alternate) && Sf(t, r);
|
|
6919
7382
|
}
|
|
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;
|
|
7383
|
+
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
7384
|
m.cloneMutableInstance;
|
|
6925
7385
|
var yc = m.appendInitialChild, Kp = m.finalizeInitialChildren, Rs = m.shouldSetTextContent, bc = m.createTextInstance;
|
|
6926
7386
|
m.cloneMutableTextInstance;
|
|
@@ -7289,17 +7749,7 @@ No matching component was found for:
|
|
|
7289
7749
|
}, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true });
|
|
7290
7750
|
})(Og)), Og.exports;
|
|
7291
7751
|
}
|
|
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;
|
|
7752
|
+
var Mg = { exports: {} }, Rb;
|
|
7303
7753
|
function e0() {
|
|
7304
7754
|
return Rb || (Rb = 1, (function(Tt) {
|
|
7305
7755
|
process.env.NODE_ENV !== "production" && (Tt.exports = function(m) {
|
|
@@ -13066,10 +13516,7 @@ Check the render method of %s.`, G(di) || "Unknown")), i = zo(n), i.payload = {
|
|
|
13066
13516
|
function Ic() {
|
|
13067
13517
|
return di;
|
|
13068
13518
|
}
|
|
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;
|
|
13519
|
+
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
13520
|
m.cloneMutableInstance;
|
|
13074
13521
|
var bn = m.appendInitialChild, Ue = m.finalizeInitialChildren, ue = m.shouldSetTextContent, Do = m.createTextInstance;
|
|
13075
13522
|
m.cloneMutableTextInstance;
|
|
@@ -14037,15 +14484,6 @@ function n0() {
|
|
|
14037
14484
|
var t0 = n0();
|
|
14038
14485
|
const r0 = Xb(t0);
|
|
14039
14486
|
|
|
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
14487
|
const t = 1, o = 8, r = 32, e = 2;
|
|
14050
14488
|
|
|
14051
14489
|
function createReconciler(config) {
|
|
@@ -14072,10 +14510,11 @@ function extend(objects) {
|
|
|
14072
14510
|
function validateInstance(type, props) {
|
|
14073
14511
|
const name = toPascalCase(type);
|
|
14074
14512
|
const target = catalogue[name];
|
|
14075
|
-
if (type !== "primitive" && !target)
|
|
14513
|
+
if (type !== "primitive" && !target) {
|
|
14076
14514
|
throw new Error(
|
|
14077
14515
|
`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
14516
|
);
|
|
14517
|
+
}
|
|
14079
14518
|
if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
|
|
14080
14519
|
if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
|
|
14081
14520
|
}
|
|
@@ -14239,6 +14678,7 @@ function swapInstances() {
|
|
|
14239
14678
|
instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
|
|
14240
14679
|
instance.object.__r3f = instance;
|
|
14241
14680
|
setFiberRef(fiber, instance.object);
|
|
14681
|
+
delete instance.appliedOnce;
|
|
14242
14682
|
applyProps(instance.object, instance.props);
|
|
14243
14683
|
if (instance.props.attach) {
|
|
14244
14684
|
attach(parent, instance);
|
|
@@ -14312,8 +14752,22 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14312
14752
|
const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
|
|
14313
14753
|
if (isTailSibling) swapInstances();
|
|
14314
14754
|
},
|
|
14315
|
-
finalizeInitialChildren: () =>
|
|
14316
|
-
|
|
14755
|
+
finalizeInitialChildren: (instance) => {
|
|
14756
|
+
for (const prop in instance.props) {
|
|
14757
|
+
if (isFromRef(instance.props[prop])) return true;
|
|
14758
|
+
}
|
|
14759
|
+
return false;
|
|
14760
|
+
},
|
|
14761
|
+
commitMount(instance) {
|
|
14762
|
+
const resolved = {};
|
|
14763
|
+
for (const prop in instance.props) {
|
|
14764
|
+
const value = instance.props[prop];
|
|
14765
|
+
if (isFromRef(value)) {
|
|
14766
|
+
const ref = value[FROM_REF];
|
|
14767
|
+
if (ref.current != null) resolved[prop] = ref.current;
|
|
14768
|
+
}
|
|
14769
|
+
}
|
|
14770
|
+
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
14317
14771
|
},
|
|
14318
14772
|
getPublicInstance: (instance) => instance?.object,
|
|
14319
14773
|
prepareForCommit: () => null,
|
|
@@ -14526,14 +14980,17 @@ function createRoot(canvas) {
|
|
|
14526
14980
|
if (!prevRoot) _roots.set(canvas, { fiber, store });
|
|
14527
14981
|
let onCreated;
|
|
14528
14982
|
let lastCamera;
|
|
14529
|
-
|
|
14983
|
+
const lastConfiguredProps = {};
|
|
14530
14984
|
let configured = false;
|
|
14531
14985
|
let pending = null;
|
|
14532
14986
|
return {
|
|
14533
14987
|
async configure(props = {}) {
|
|
14534
14988
|
let resolve;
|
|
14535
14989
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14536
|
-
|
|
14990
|
+
const {
|
|
14991
|
+
id: canvasId,
|
|
14992
|
+
primaryCanvas,
|
|
14993
|
+
scheduler: schedulerConfig,
|
|
14537
14994
|
gl: glConfig,
|
|
14538
14995
|
renderer: rendererConfig,
|
|
14539
14996
|
size: propsSize,
|
|
@@ -14541,10 +14998,7 @@ function createRoot(canvas) {
|
|
|
14541
14998
|
events,
|
|
14542
14999
|
onCreated: onCreatedCallback,
|
|
14543
15000
|
shadows = false,
|
|
14544
|
-
linear = false,
|
|
14545
|
-
flat = false,
|
|
14546
15001
|
textureColorSpace = SRGBColorSpace,
|
|
14547
|
-
legacy = false,
|
|
14548
15002
|
orthographic = false,
|
|
14549
15003
|
frameloop = "always",
|
|
14550
15004
|
dpr = [1, 2],
|
|
@@ -14555,11 +15009,14 @@ function createRoot(canvas) {
|
|
|
14555
15009
|
onDragOverMissed,
|
|
14556
15010
|
onDropMissed,
|
|
14557
15011
|
autoUpdateFrustum = true,
|
|
14558
|
-
occlusion = false
|
|
15012
|
+
occlusion = false,
|
|
15013
|
+
_sizeProps,
|
|
15014
|
+
forceEven
|
|
14559
15015
|
} = props;
|
|
14560
|
-
|
|
15016
|
+
const state = store.getState();
|
|
14561
15017
|
const defaultGPUProps = {
|
|
14562
|
-
canvas
|
|
15018
|
+
canvas,
|
|
15019
|
+
antialias: true
|
|
14563
15020
|
};
|
|
14564
15021
|
if (glConfig && !R3F_BUILD_LEGACY) {
|
|
14565
15022
|
throw new Error(
|
|
@@ -14570,7 +15027,27 @@ function createRoot(canvas) {
|
|
|
14570
15027
|
throw new Error("Cannot use both gl and renderer props at the same time");
|
|
14571
15028
|
}
|
|
14572
15029
|
let renderer = state.internal.actualRenderer;
|
|
14573
|
-
if (!state.internal.actualRenderer) {
|
|
15030
|
+
if (primaryCanvas && !state.internal.actualRenderer) {
|
|
15031
|
+
const primary = await waitForPrimary(primaryCanvas);
|
|
15032
|
+
renderer = primary.renderer;
|
|
15033
|
+
state.internal.actualRenderer = renderer;
|
|
15034
|
+
const canvasTarget = new CanvasTarget(canvas);
|
|
15035
|
+
primary.store.setState((prev) => ({
|
|
15036
|
+
internal: { ...prev.internal, isMultiCanvas: true }
|
|
15037
|
+
}));
|
|
15038
|
+
state.set((prev) => ({
|
|
15039
|
+
webGPUSupported: primary.store.getState().webGPUSupported,
|
|
15040
|
+
renderer,
|
|
15041
|
+
primaryStore: primary.store,
|
|
15042
|
+
internal: {
|
|
15043
|
+
...prev.internal,
|
|
15044
|
+
canvasTarget,
|
|
15045
|
+
isMultiCanvas: true,
|
|
15046
|
+
isSecondary: true,
|
|
15047
|
+
targetId: primaryCanvas
|
|
15048
|
+
}
|
|
15049
|
+
}));
|
|
15050
|
+
} else if (!state.internal.actualRenderer) {
|
|
14574
15051
|
renderer = await resolveRenderer(rendererConfig, defaultGPUProps, WebGPURenderer);
|
|
14575
15052
|
if (!renderer.hasInitialized?.()) {
|
|
14576
15053
|
await renderer.init();
|
|
@@ -14578,14 +15055,27 @@ function createRoot(canvas) {
|
|
|
14578
15055
|
const backend = renderer.backend;
|
|
14579
15056
|
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
14580
15057
|
state.internal.actualRenderer = renderer;
|
|
14581
|
-
state.set({ webGPUSupported: isWebGPUBackend, renderer });
|
|
15058
|
+
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
15059
|
+
if (canvasId && !state.internal.isSecondary) {
|
|
15060
|
+
const canvasTarget = new CanvasTarget(canvas);
|
|
15061
|
+
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
15062
|
+
state.set((prev) => ({
|
|
15063
|
+
internal: {
|
|
15064
|
+
...prev.internal,
|
|
15065
|
+
canvasTarget,
|
|
15066
|
+
unregisterPrimary
|
|
15067
|
+
}
|
|
15068
|
+
}));
|
|
15069
|
+
}
|
|
14582
15070
|
}
|
|
14583
15071
|
let raycaster = state.raycaster;
|
|
14584
15072
|
if (!raycaster) state.set({ raycaster: raycaster = new Raycaster() });
|
|
14585
15073
|
const { params, ...options } = raycastOptions || {};
|
|
14586
15074
|
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options });
|
|
14587
|
-
if (!is.equ(params, raycaster.params, shallowLoose))
|
|
15075
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) {
|
|
14588
15076
|
applyProps(raycaster, { params: { ...raycaster.params, ...params } });
|
|
15077
|
+
}
|
|
15078
|
+
let tempCamera = state.camera;
|
|
14589
15079
|
if (!state.camera || state.camera === lastCamera && !is.equ(lastCamera, cameraOptions, shallowLoose)) {
|
|
14590
15080
|
lastCamera = cameraOptions;
|
|
14591
15081
|
const isCamera = cameraOptions?.isCamera;
|
|
@@ -14605,6 +15095,7 @@ function createRoot(canvas) {
|
|
|
14605
15095
|
if (!state.camera && !cameraOptions?.rotation) camera.lookAt(0, 0, 0);
|
|
14606
15096
|
}
|
|
14607
15097
|
state.set({ camera });
|
|
15098
|
+
tempCamera = camera;
|
|
14608
15099
|
raycaster.camera = camera;
|
|
14609
15100
|
}
|
|
14610
15101
|
if (!state.scene) {
|
|
@@ -14622,7 +15113,7 @@ function createRoot(canvas) {
|
|
|
14622
15113
|
rootScene: scene,
|
|
14623
15114
|
internal: { ...prev.internal, container: scene }
|
|
14624
15115
|
}));
|
|
14625
|
-
const camera =
|
|
15116
|
+
const camera = tempCamera;
|
|
14626
15117
|
if (camera && !camera.parent) scene.add(camera);
|
|
14627
15118
|
}
|
|
14628
15119
|
if (events && !state.events.handlers) {
|
|
@@ -14636,9 +15127,17 @@ function createRoot(canvas) {
|
|
|
14636
15127
|
wasEnabled = enabled;
|
|
14637
15128
|
});
|
|
14638
15129
|
}
|
|
15130
|
+
if (_sizeProps !== void 0) {
|
|
15131
|
+
state.set({ _sizeProps });
|
|
15132
|
+
}
|
|
15133
|
+
if (forceEven !== void 0 && state.internal.forceEven !== forceEven) {
|
|
15134
|
+
state.set((prev) => ({ internal: { ...prev.internal, forceEven } }));
|
|
15135
|
+
}
|
|
14639
15136
|
const size = computeInitialSize(canvas, propsSize);
|
|
14640
|
-
if (!is.equ(size, state.size, shallowLoose)) {
|
|
15137
|
+
if (!state._sizeImperative && !is.equ(size, state.size, shallowLoose)) {
|
|
15138
|
+
const wasImperative = state._sizeImperative;
|
|
14641
15139
|
state.setSize(size.width, size.height, size.top, size.left);
|
|
15140
|
+
if (!wasImperative) state.set({ _sizeImperative: false });
|
|
14642
15141
|
}
|
|
14643
15142
|
if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
|
|
14644
15143
|
state.setDpr(dpr);
|
|
@@ -14663,7 +15162,7 @@ function createRoot(canvas) {
|
|
|
14663
15162
|
const handleXRFrame = (timestamp, frame) => {
|
|
14664
15163
|
const state2 = store.getState();
|
|
14665
15164
|
if (state2.frameloop === "never") return;
|
|
14666
|
-
advance(timestamp
|
|
15165
|
+
advance(timestamp);
|
|
14667
15166
|
};
|
|
14668
15167
|
const actualRenderer = state.internal.actualRenderer;
|
|
14669
15168
|
const handleSessionChange = () => {
|
|
@@ -14675,16 +15174,16 @@ function createRoot(canvas) {
|
|
|
14675
15174
|
};
|
|
14676
15175
|
const xr = {
|
|
14677
15176
|
connect() {
|
|
14678
|
-
const { gl, renderer: renderer2
|
|
14679
|
-
const
|
|
14680
|
-
|
|
14681
|
-
|
|
15177
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15178
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15179
|
+
xrManager.addEventListener("sessionstart", handleSessionChange);
|
|
15180
|
+
xrManager.addEventListener("sessionend", handleSessionChange);
|
|
14682
15181
|
},
|
|
14683
15182
|
disconnect() {
|
|
14684
|
-
const { gl, renderer: renderer2
|
|
14685
|
-
const
|
|
14686
|
-
|
|
14687
|
-
|
|
15183
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15184
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15185
|
+
xrManager.removeEventListener("sessionstart", handleSessionChange);
|
|
15186
|
+
xrManager.removeEventListener("sessionend", handleSessionChange);
|
|
14688
15187
|
}
|
|
14689
15188
|
};
|
|
14690
15189
|
if (typeof renderer.xr?.addEventListener === "function") xr.connect();
|
|
@@ -14708,15 +15207,21 @@ function createRoot(canvas) {
|
|
|
14708
15207
|
} else if (is.obj(shadows)) {
|
|
14709
15208
|
Object.assign(renderer.shadowMap, shadows);
|
|
14710
15209
|
}
|
|
14711
|
-
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type)
|
|
15210
|
+
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type) {
|
|
14712
15211
|
renderer.shadowMap.needsUpdate = true;
|
|
15212
|
+
}
|
|
15213
|
+
}
|
|
15214
|
+
if (!configured) {
|
|
15215
|
+
renderer.outputColorSpace = SRGBColorSpace;
|
|
15216
|
+
renderer.toneMapping = ACESFilmicToneMapping;
|
|
14713
15217
|
}
|
|
14714
15218
|
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
14715
15219
|
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
14716
15220
|
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
14717
15221
|
}
|
|
14718
|
-
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose))
|
|
15222
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
|
|
14719
15223
|
applyProps(renderer, glConfig);
|
|
15224
|
+
}
|
|
14720
15225
|
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
|
|
14721
15226
|
const currentRenderer = state.renderer;
|
|
14722
15227
|
if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
|
|
@@ -14726,11 +15231,26 @@ function createRoot(canvas) {
|
|
|
14726
15231
|
const scheduler = getScheduler();
|
|
14727
15232
|
const rootId = state.internal.rootId;
|
|
14728
15233
|
if (!rootId) {
|
|
14729
|
-
const newRootId = scheduler.generateRootId();
|
|
15234
|
+
const newRootId = canvasId || scheduler.generateRootId();
|
|
14730
15235
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14731
15236
|
getState: () => store.getState(),
|
|
14732
15237
|
onError: (err) => store.getState().setError(err)
|
|
14733
15238
|
});
|
|
15239
|
+
const unregisterCanvasTarget = scheduler.register(
|
|
15240
|
+
() => {
|
|
15241
|
+
const state2 = store.getState();
|
|
15242
|
+
if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
|
|
15243
|
+
const renderer2 = state2.internal.actualRenderer;
|
|
15244
|
+
renderer2.setCanvasTarget(state2.internal.canvasTarget);
|
|
15245
|
+
}
|
|
15246
|
+
},
|
|
15247
|
+
{
|
|
15248
|
+
id: `${newRootId}_canvasTarget`,
|
|
15249
|
+
rootId: newRootId,
|
|
15250
|
+
phase: "start",
|
|
15251
|
+
system: true
|
|
15252
|
+
}
|
|
15253
|
+
);
|
|
14734
15254
|
const unregisterFrustum = scheduler.register(
|
|
14735
15255
|
() => {
|
|
14736
15256
|
const state2 = store.getState();
|
|
@@ -14772,11 +15292,15 @@ function createRoot(canvas) {
|
|
|
14772
15292
|
}
|
|
14773
15293
|
},
|
|
14774
15294
|
{
|
|
14775
|
-
|
|
15295
|
+
// Use canvas ID directly as job ID if available, otherwise use generated rootId
|
|
15296
|
+
id: canvasId || `${newRootId}_render`,
|
|
14776
15297
|
rootId: newRootId,
|
|
14777
15298
|
phase: "render",
|
|
14778
|
-
system: true
|
|
15299
|
+
system: true,
|
|
14779
15300
|
// Internal flag: this is a system job, not user-controlled
|
|
15301
|
+
// Apply scheduler config for render ordering and rate limiting
|
|
15302
|
+
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
15303
|
+
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14780
15304
|
}
|
|
14781
15305
|
);
|
|
14782
15306
|
state.set((state2) => ({
|
|
@@ -14785,6 +15309,7 @@ function createRoot(canvas) {
|
|
|
14785
15309
|
rootId: newRootId,
|
|
14786
15310
|
unregisterRoot: () => {
|
|
14787
15311
|
unregisterRoot();
|
|
15312
|
+
unregisterCanvasTarget();
|
|
14788
15313
|
unregisterFrustum();
|
|
14789
15314
|
unregisterVisibility();
|
|
14790
15315
|
unregisterRender();
|
|
@@ -14843,15 +15368,24 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14843
15368
|
const renderer = state.internal.actualRenderer;
|
|
14844
15369
|
const unregisterRoot = state.internal.unregisterRoot;
|
|
14845
15370
|
if (unregisterRoot) unregisterRoot();
|
|
15371
|
+
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
15372
|
+
if (unregisterPrimary) unregisterPrimary();
|
|
15373
|
+
const canvasTarget = state.internal.canvasTarget;
|
|
15374
|
+
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14846
15375
|
state.events.disconnect?.();
|
|
14847
15376
|
cleanupHelperGroup(root.store);
|
|
14848
|
-
renderer
|
|
14849
|
-
|
|
14850
|
-
|
|
15377
|
+
if (state.isLegacy && renderer) {
|
|
15378
|
+
;
|
|
15379
|
+
renderer.renderLists?.dispose?.();
|
|
15380
|
+
renderer.forceContextLoss?.();
|
|
15381
|
+
}
|
|
15382
|
+
if (!state.internal.isSecondary) {
|
|
15383
|
+
if (renderer?.xr) state.xr.disconnect();
|
|
15384
|
+
}
|
|
14851
15385
|
dispose(state.scene);
|
|
14852
15386
|
_roots.delete(canvas);
|
|
14853
15387
|
if (callback) callback(canvas);
|
|
14854
|
-
} catch
|
|
15388
|
+
} catch {
|
|
14855
15389
|
}
|
|
14856
15390
|
}, 500);
|
|
14857
15391
|
}
|
|
@@ -14859,36 +15393,34 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14859
15393
|
}
|
|
14860
15394
|
}
|
|
14861
15395
|
function createPortal(children, container, state) {
|
|
14862
|
-
return /* @__PURE__ */ jsx(
|
|
15396
|
+
return /* @__PURE__ */ jsx(Portal, { children, container, state });
|
|
14863
15397
|
}
|
|
14864
|
-
function
|
|
15398
|
+
function Portal({ children, container, state }) {
|
|
14865
15399
|
const isRef = useCallback((obj) => obj && "current" in obj, []);
|
|
14866
|
-
const [resolvedContainer,
|
|
15400
|
+
const [resolvedContainer, _setResolvedContainer] = useState(() => {
|
|
14867
15401
|
if (isRef(container)) return container.current ?? null;
|
|
14868
15402
|
return container;
|
|
14869
15403
|
});
|
|
15404
|
+
const setResolvedContainer = useCallback(
|
|
15405
|
+
(newContainer) => {
|
|
15406
|
+
if (!newContainer || newContainer === resolvedContainer) return;
|
|
15407
|
+
_setResolvedContainer(isRef(newContainer) ? newContainer.current : newContainer);
|
|
15408
|
+
},
|
|
15409
|
+
[resolvedContainer, _setResolvedContainer, isRef]
|
|
15410
|
+
);
|
|
14870
15411
|
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);
|
|
15412
|
+
if (isRef(container) && !container.current) {
|
|
15413
|
+
return queueMicrotask(() => {
|
|
15414
|
+
setResolvedContainer(container.current);
|
|
15415
|
+
});
|
|
14885
15416
|
}
|
|
14886
|
-
|
|
15417
|
+
setResolvedContainer(container);
|
|
15418
|
+
}, [container, isRef, setResolvedContainer]);
|
|
14887
15419
|
if (!resolvedContainer) return /* @__PURE__ */ jsx(Fragment, {});
|
|
14888
15420
|
const portalKey = resolvedContainer.uuid ?? `portal-${resolvedContainer.id ?? "unknown"}`;
|
|
14889
|
-
return /* @__PURE__ */ jsx(
|
|
15421
|
+
return /* @__PURE__ */ jsx(PortalInner, { children, container: resolvedContainer, state }, portalKey);
|
|
14890
15422
|
}
|
|
14891
|
-
function
|
|
15423
|
+
function PortalInner({ state = {}, children, container }) {
|
|
14892
15424
|
const { events, size, injectScene = true, ...rest } = state;
|
|
14893
15425
|
const previousRoot = useStore();
|
|
14894
15426
|
const [raycaster] = useState(() => new Raycaster());
|
|
@@ -14909,11 +15441,12 @@ function Portal({ state = {}, children, container }) {
|
|
|
14909
15441
|
};
|
|
14910
15442
|
}, [portalScene, container, injectScene]);
|
|
14911
15443
|
const inject = useMutableCallback((rootState, injectState) => {
|
|
15444
|
+
const resolvedSize = { ...rootState.size, ...injectState.size, ...size };
|
|
14912
15445
|
let viewport = void 0;
|
|
14913
|
-
if (injectState.camera && size) {
|
|
15446
|
+
if (injectState.camera && (size || injectState.size)) {
|
|
14914
15447
|
const camera = injectState.camera;
|
|
14915
|
-
viewport = rootState.viewport.getCurrentViewport(camera, new Vector3(),
|
|
14916
|
-
if (camera !== rootState.camera) updateCamera(camera,
|
|
15448
|
+
viewport = rootState.viewport.getCurrentViewport(camera, new Vector3(), resolvedSize);
|
|
15449
|
+
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14917
15450
|
}
|
|
14918
15451
|
return {
|
|
14919
15452
|
// The intersect consists of the previous root state
|
|
@@ -14930,7 +15463,7 @@ function Portal({ state = {}, children, container }) {
|
|
|
14930
15463
|
previousRoot,
|
|
14931
15464
|
// Events, size and viewport can be overridden by the inject layer
|
|
14932
15465
|
events: { ...rootState.events, ...injectState.events, ...events },
|
|
14933
|
-
size:
|
|
15466
|
+
size: resolvedSize,
|
|
14934
15467
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14935
15468
|
// Layers are allowed to override events
|
|
14936
15469
|
setEvents: (events2) => injectState.set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
@@ -14964,15 +15497,13 @@ function CanvasImpl({
|
|
|
14964
15497
|
fallback,
|
|
14965
15498
|
resize,
|
|
14966
15499
|
style,
|
|
15500
|
+
id,
|
|
14967
15501
|
gl,
|
|
14968
|
-
renderer,
|
|
15502
|
+
renderer: rendererProp,
|
|
14969
15503
|
events = createPointerEvents,
|
|
14970
15504
|
eventSource,
|
|
14971
15505
|
eventPrefix,
|
|
14972
15506
|
shadows,
|
|
14973
|
-
linear,
|
|
14974
|
-
flat,
|
|
14975
|
-
legacy,
|
|
14976
15507
|
orthographic,
|
|
14977
15508
|
frameloop,
|
|
14978
15509
|
dpr,
|
|
@@ -14984,10 +15515,46 @@ function CanvasImpl({
|
|
|
14984
15515
|
onDragOverMissed,
|
|
14985
15516
|
onDropMissed,
|
|
14986
15517
|
onCreated,
|
|
15518
|
+
hmr,
|
|
15519
|
+
width,
|
|
15520
|
+
height,
|
|
15521
|
+
background,
|
|
15522
|
+
forceEven,
|
|
14987
15523
|
...props
|
|
14988
15524
|
}) {
|
|
15525
|
+
const { primaryCanvas, scheduler, ...rendererConfig } = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp) ? rendererProp : { primaryCanvas: void 0, scheduler: void 0 };
|
|
15526
|
+
const renderer = Object.keys(rendererConfig).length > 0 ? rendererConfig : rendererProp;
|
|
14989
15527
|
React.useMemo(() => extend(THREE), []);
|
|
14990
15528
|
const Bridge = useBridge();
|
|
15529
|
+
const backgroundProps = React.useMemo(() => {
|
|
15530
|
+
if (!background) return null;
|
|
15531
|
+
if (typeof background === "object" && !background.isColor) {
|
|
15532
|
+
const { backgroundMap, envMap, files, preset, ...rest } = background;
|
|
15533
|
+
return {
|
|
15534
|
+
...rest,
|
|
15535
|
+
preset,
|
|
15536
|
+
files: envMap || files,
|
|
15537
|
+
backgroundFiles: backgroundMap,
|
|
15538
|
+
background: true
|
|
15539
|
+
};
|
|
15540
|
+
}
|
|
15541
|
+
if (typeof background === "number") {
|
|
15542
|
+
return { color: background, background: true };
|
|
15543
|
+
}
|
|
15544
|
+
if (typeof background === "string") {
|
|
15545
|
+
if (background in presetsObj) {
|
|
15546
|
+
return { preset: background, background: true };
|
|
15547
|
+
}
|
|
15548
|
+
if (/^(https?:\/\/|\/|\.\/|\.\.\/)|\\.(hdr|exr|jpg|jpeg|png|webp|gif)$/i.test(background)) {
|
|
15549
|
+
return { files: background, background: true };
|
|
15550
|
+
}
|
|
15551
|
+
return { color: background, background: true };
|
|
15552
|
+
}
|
|
15553
|
+
if (background.isColor) {
|
|
15554
|
+
return { color: background, background: true };
|
|
15555
|
+
}
|
|
15556
|
+
return null;
|
|
15557
|
+
}, [background]);
|
|
14991
15558
|
const hasInitialSizeRef = React.useRef(false);
|
|
14992
15559
|
const measureConfig = React.useMemo(() => {
|
|
14993
15560
|
if (!hasInitialSizeRef.current) {
|
|
@@ -15004,7 +15571,21 @@ function CanvasImpl({
|
|
|
15004
15571
|
};
|
|
15005
15572
|
}, [resize, hasInitialSizeRef.current]);
|
|
15006
15573
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
15007
|
-
|
|
15574
|
+
const effectiveSize = React.useMemo(() => {
|
|
15575
|
+
let w = width ?? containerRect.width;
|
|
15576
|
+
let h = height ?? containerRect.height;
|
|
15577
|
+
if (forceEven) {
|
|
15578
|
+
w = Math.ceil(w / 2) * 2;
|
|
15579
|
+
h = Math.ceil(h / 2) * 2;
|
|
15580
|
+
}
|
|
15581
|
+
return {
|
|
15582
|
+
width: w,
|
|
15583
|
+
height: h,
|
|
15584
|
+
top: containerRect.top,
|
|
15585
|
+
left: containerRect.left
|
|
15586
|
+
};
|
|
15587
|
+
}, [width, height, containerRect, forceEven]);
|
|
15588
|
+
if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
|
|
15008
15589
|
hasInitialSizeRef.current = true;
|
|
15009
15590
|
}
|
|
15010
15591
|
const canvasRef = React.useRef(null);
|
|
@@ -15023,7 +15604,7 @@ function CanvasImpl({
|
|
|
15023
15604
|
useIsomorphicLayoutEffect(() => {
|
|
15024
15605
|
effectActiveRef.current = true;
|
|
15025
15606
|
const canvas = canvasRef.current;
|
|
15026
|
-
if (
|
|
15607
|
+
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
15027
15608
|
if (!root.current) {
|
|
15028
15609
|
root.current = createRoot(canvas);
|
|
15029
15610
|
notifyAlpha({
|
|
@@ -15043,21 +15624,24 @@ function CanvasImpl({
|
|
|
15043
15624
|
async function run() {
|
|
15044
15625
|
if (!effectActiveRef.current || !root.current) return;
|
|
15045
15626
|
await root.current.configure({
|
|
15627
|
+
id,
|
|
15628
|
+
primaryCanvas,
|
|
15629
|
+
scheduler,
|
|
15046
15630
|
gl,
|
|
15047
15631
|
renderer,
|
|
15048
15632
|
scene,
|
|
15049
15633
|
events,
|
|
15050
15634
|
shadows,
|
|
15051
|
-
linear,
|
|
15052
|
-
flat,
|
|
15053
|
-
legacy,
|
|
15054
15635
|
orthographic,
|
|
15055
15636
|
frameloop,
|
|
15056
15637
|
dpr,
|
|
15057
15638
|
performance,
|
|
15058
15639
|
raycaster,
|
|
15059
15640
|
camera,
|
|
15060
|
-
size:
|
|
15641
|
+
size: effectiveSize,
|
|
15642
|
+
// Store size props for reset functionality
|
|
15643
|
+
_sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
|
|
15644
|
+
forceEven,
|
|
15061
15645
|
// Pass mutable reference to onPointerMissed so it's free to update
|
|
15062
15646
|
onPointerMissed: (...args) => handlePointerMissed.current?.(...args),
|
|
15063
15647
|
onDragOverMissed: (...args) => handleDragOverMissed.current?.(...args),
|
|
@@ -15081,7 +15665,10 @@ function CanvasImpl({
|
|
|
15081
15665
|
});
|
|
15082
15666
|
if (!effectActiveRef.current || !root.current) return;
|
|
15083
15667
|
root.current.render(
|
|
15084
|
-
/* @__PURE__ */ jsx(Bridge, { children: /* @__PURE__ */ jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */
|
|
15668
|
+
/* @__PURE__ */ jsx(Bridge, { children: /* @__PURE__ */ jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxs(React.Suspense, { fallback: /* @__PURE__ */ jsx(Block, { set: setBlock }), children: [
|
|
15669
|
+
backgroundProps && /* @__PURE__ */ jsx(Environment, { ...backgroundProps }),
|
|
15670
|
+
children ?? null
|
|
15671
|
+
] }) }) })
|
|
15085
15672
|
);
|
|
15086
15673
|
}
|
|
15087
15674
|
run();
|
|
@@ -15103,6 +15690,35 @@ function CanvasImpl({
|
|
|
15103
15690
|
};
|
|
15104
15691
|
}
|
|
15105
15692
|
}, []);
|
|
15693
|
+
React.useEffect(() => {
|
|
15694
|
+
if (hmr === false) return;
|
|
15695
|
+
const canvas = canvasRef.current;
|
|
15696
|
+
if (!canvas) return;
|
|
15697
|
+
const handleHMR = () => {
|
|
15698
|
+
queueMicrotask(() => {
|
|
15699
|
+
const rootEntry = _roots.get(canvas);
|
|
15700
|
+
if (rootEntry?.store) {
|
|
15701
|
+
rootEntry.store.setState((state) => ({
|
|
15702
|
+
nodes: {},
|
|
15703
|
+
uniforms: {},
|
|
15704
|
+
_hmrVersion: state._hmrVersion + 1
|
|
15705
|
+
}));
|
|
15706
|
+
}
|
|
15707
|
+
});
|
|
15708
|
+
};
|
|
15709
|
+
if (typeof import.meta !== "undefined" && import.meta.hot) {
|
|
15710
|
+
const hot = import.meta.hot;
|
|
15711
|
+
hot.on("vite:afterUpdate", handleHMR);
|
|
15712
|
+
return () => hot.dispose?.(() => {
|
|
15713
|
+
});
|
|
15714
|
+
}
|
|
15715
|
+
if (typeof module !== "undefined" && module.hot) {
|
|
15716
|
+
const hot = module.hot;
|
|
15717
|
+
hot.addStatusHandler((status) => {
|
|
15718
|
+
if (status === "idle") handleHMR();
|
|
15719
|
+
});
|
|
15720
|
+
}
|
|
15721
|
+
}, [hmr]);
|
|
15106
15722
|
const pointerEvents = eventSource ? "none" : "auto";
|
|
15107
15723
|
return /* @__PURE__ */ jsx(
|
|
15108
15724
|
"div",
|
|
@@ -15117,7 +15733,7 @@ function CanvasImpl({
|
|
|
15117
15733
|
...style
|
|
15118
15734
|
},
|
|
15119
15735
|
...props,
|
|
15120
|
-
children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx("canvas", { ref: canvasRef, className: "r3f-canvas", style: { display: "block" }, children: fallback }) })
|
|
15736
|
+
children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx("canvas", { ref: canvasRef, id, className: "r3f-canvas", style: { display: "block" }, children: fallback }) })
|
|
15121
15737
|
}
|
|
15122
15738
|
);
|
|
15123
15739
|
}
|
|
@@ -15125,6 +15741,88 @@ function Canvas(props) {
|
|
|
15125
15741
|
return /* @__PURE__ */ jsx(FiberProvider, { children: /* @__PURE__ */ jsx(CanvasImpl, { ...props }) });
|
|
15126
15742
|
}
|
|
15127
15743
|
|
|
15744
|
+
var __defProp = Object.defineProperty;
|
|
15745
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
15746
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
15747
|
+
var _a;
|
|
15748
|
+
const INTERNAL_DATA = Symbol("ScopedStore.data");
|
|
15749
|
+
_a = INTERNAL_DATA;
|
|
15750
|
+
const _ScopedStore = class _ScopedStore {
|
|
15751
|
+
constructor(data) {
|
|
15752
|
+
__publicField(this, _a);
|
|
15753
|
+
this[INTERNAL_DATA] = data;
|
|
15754
|
+
return new Proxy(this, {
|
|
15755
|
+
get(target, prop, receiver) {
|
|
15756
|
+
if (typeof prop === "string") {
|
|
15757
|
+
if (prop === "scope" || prop === "has" || prop === "keys") {
|
|
15758
|
+
return Reflect.get(target, prop, receiver);
|
|
15759
|
+
}
|
|
15760
|
+
return target[INTERNAL_DATA][prop];
|
|
15761
|
+
}
|
|
15762
|
+
return Reflect.get(target, prop, receiver);
|
|
15763
|
+
},
|
|
15764
|
+
has(target, prop) {
|
|
15765
|
+
return typeof prop === "string" ? prop in target[INTERNAL_DATA] : Reflect.has(target, prop);
|
|
15766
|
+
},
|
|
15767
|
+
ownKeys(target) {
|
|
15768
|
+
return Reflect.ownKeys(target[INTERNAL_DATA]);
|
|
15769
|
+
},
|
|
15770
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
15771
|
+
if (typeof prop === "string" && prop in target[INTERNAL_DATA]) {
|
|
15772
|
+
return {
|
|
15773
|
+
configurable: true,
|
|
15774
|
+
enumerable: true,
|
|
15775
|
+
value: target[INTERNAL_DATA][prop]
|
|
15776
|
+
};
|
|
15777
|
+
}
|
|
15778
|
+
return void 0;
|
|
15779
|
+
}
|
|
15780
|
+
});
|
|
15781
|
+
}
|
|
15782
|
+
/**
|
|
15783
|
+
* Access a nested scope by key.
|
|
15784
|
+
* If the key doesn't exist or isn't a scope object, returns an empty ScopedStore.
|
|
15785
|
+
*/
|
|
15786
|
+
scope(key) {
|
|
15787
|
+
const data = this[INTERNAL_DATA][key];
|
|
15788
|
+
return new _ScopedStore(
|
|
15789
|
+
data && typeof data === "object" ? data : {}
|
|
15790
|
+
);
|
|
15791
|
+
}
|
|
15792
|
+
/**
|
|
15793
|
+
* Check if a key exists in the store.
|
|
15794
|
+
*/
|
|
15795
|
+
has(key) {
|
|
15796
|
+
return key in this[INTERNAL_DATA];
|
|
15797
|
+
}
|
|
15798
|
+
/**
|
|
15799
|
+
* Get all keys in the store.
|
|
15800
|
+
*/
|
|
15801
|
+
keys() {
|
|
15802
|
+
return Object.keys(this[INTERNAL_DATA]);
|
|
15803
|
+
}
|
|
15804
|
+
};
|
|
15805
|
+
let ScopedStore = _ScopedStore;
|
|
15806
|
+
function createScopedStore(data) {
|
|
15807
|
+
return new ScopedStore(data);
|
|
15808
|
+
}
|
|
15809
|
+
function createLazyCreatorState(state) {
|
|
15810
|
+
let _uniforms = null;
|
|
15811
|
+
let _nodes = null;
|
|
15812
|
+
return Object.create(state, {
|
|
15813
|
+
uniforms: {
|
|
15814
|
+
get() {
|
|
15815
|
+
return _uniforms ?? (_uniforms = createScopedStore(state.uniforms));
|
|
15816
|
+
}
|
|
15817
|
+
},
|
|
15818
|
+
nodes: {
|
|
15819
|
+
get() {
|
|
15820
|
+
return _nodes ?? (_nodes = createScopedStore(state.nodes));
|
|
15821
|
+
}
|
|
15822
|
+
}
|
|
15823
|
+
});
|
|
15824
|
+
}
|
|
15825
|
+
|
|
15128
15826
|
function addTexture(set, key, value) {
|
|
15129
15827
|
set((state) => {
|
|
15130
15828
|
const newMap = new Map(state.textures);
|
|
@@ -15164,6 +15862,27 @@ function createTextureOperations(set) {
|
|
|
15164
15862
|
removeMultiple: (keys) => removeTextures(set, keys)
|
|
15165
15863
|
};
|
|
15166
15864
|
}
|
|
15865
|
+
function extractTSLValue(value) {
|
|
15866
|
+
if (value === null || value === void 0) return value;
|
|
15867
|
+
if (typeof value !== "object") return value;
|
|
15868
|
+
const node = value;
|
|
15869
|
+
if (!node.isNode) return value;
|
|
15870
|
+
if (node.isConstNode) {
|
|
15871
|
+
return node.value;
|
|
15872
|
+
}
|
|
15873
|
+
if ("value" in node) {
|
|
15874
|
+
let extractedValue = node.value;
|
|
15875
|
+
if (typeof node.traverse === "function") {
|
|
15876
|
+
node.traverse((n) => {
|
|
15877
|
+
if (n.isConstNode) {
|
|
15878
|
+
extractedValue = n.value;
|
|
15879
|
+
}
|
|
15880
|
+
});
|
|
15881
|
+
}
|
|
15882
|
+
return extractedValue;
|
|
15883
|
+
}
|
|
15884
|
+
return value;
|
|
15885
|
+
}
|
|
15167
15886
|
function vectorize(inObject) {
|
|
15168
15887
|
if (inObject === null || inObject === void 0) return inObject;
|
|
15169
15888
|
if (typeof inObject === "string") {
|
|
@@ -15176,6 +15895,9 @@ function vectorize(inObject) {
|
|
|
15176
15895
|
}
|
|
15177
15896
|
if (typeof inObject !== "object") return inObject;
|
|
15178
15897
|
const obj = inObject;
|
|
15898
|
+
if (obj.isNode) {
|
|
15899
|
+
return extractTSLValue(inObject);
|
|
15900
|
+
}
|
|
15179
15901
|
if (obj.isVector2 || obj.isVector3 || obj.isVector4) return inObject;
|
|
15180
15902
|
if (obj.isMatrix3 || obj.isMatrix4) return inObject;
|
|
15181
15903
|
if (obj.isColor || obj.isEuler || obj.isQuaternion || obj.isSpherical) return inObject;
|
|
@@ -15238,21 +15960,55 @@ function useUniforms(creatorOrScope, scope) {
|
|
|
15238
15960
|
},
|
|
15239
15961
|
[store]
|
|
15240
15962
|
);
|
|
15963
|
+
const rebuildUniforms = useCallback(
|
|
15964
|
+
(targetScope) => {
|
|
15965
|
+
store.setState((state) => {
|
|
15966
|
+
let newUniforms = {};
|
|
15967
|
+
if (targetScope && targetScope !== "root") {
|
|
15968
|
+
const { [targetScope]: _, ...rest } = state.uniforms;
|
|
15969
|
+
newUniforms = rest;
|
|
15970
|
+
} else if (targetScope === "root") {
|
|
15971
|
+
for (const [key, value] of Object.entries(state.uniforms)) {
|
|
15972
|
+
if (!isUniformNode$1(value)) newUniforms[key] = value;
|
|
15973
|
+
}
|
|
15974
|
+
}
|
|
15975
|
+
return { uniforms: newUniforms, _hmrVersion: state._hmrVersion + 1 };
|
|
15976
|
+
});
|
|
15977
|
+
},
|
|
15978
|
+
[store]
|
|
15979
|
+
);
|
|
15241
15980
|
const inputForMemoization = useMemo(() => {
|
|
15242
|
-
|
|
15981
|
+
let raw = creatorOrScope;
|
|
15982
|
+
if (is.fun(creatorOrScope)) {
|
|
15983
|
+
const wrappedState = createLazyCreatorState(store.getState());
|
|
15984
|
+
raw = creatorOrScope(wrappedState);
|
|
15985
|
+
}
|
|
15986
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
15987
|
+
const normalized = {};
|
|
15988
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
15989
|
+
normalized[key] = vectorize(value);
|
|
15990
|
+
}
|
|
15991
|
+
return normalized;
|
|
15992
|
+
}
|
|
15993
|
+
return raw;
|
|
15243
15994
|
}, [creatorOrScope, store]);
|
|
15244
15995
|
const memoizedInput = useCompareMemoize(inputForMemoization);
|
|
15996
|
+
const isReader = memoizedInput === void 0 || typeof memoizedInput === "string";
|
|
15997
|
+
const storeUniforms = useThree((s) => s.uniforms);
|
|
15998
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
15999
|
+
const readerDep = isReader ? storeUniforms : null;
|
|
16000
|
+
const creatorDep = isReader ? null : hmrVersion;
|
|
15245
16001
|
const uniforms = useMemo(() => {
|
|
15246
|
-
const state = store.getState();
|
|
15247
|
-
const set = store.setState;
|
|
15248
16002
|
if (memoizedInput === void 0) {
|
|
15249
|
-
return
|
|
16003
|
+
return storeUniforms;
|
|
15250
16004
|
}
|
|
15251
16005
|
if (typeof memoizedInput === "string") {
|
|
15252
|
-
const scopeData =
|
|
16006
|
+
const scopeData = storeUniforms[memoizedInput];
|
|
15253
16007
|
if (scopeData && !isUniformNode$1(scopeData)) return scopeData;
|
|
15254
16008
|
return {};
|
|
15255
16009
|
}
|
|
16010
|
+
const state = store.getState();
|
|
16011
|
+
const set = store.setState;
|
|
15256
16012
|
if (typeof memoizedInput !== "object" || memoizedInput === null) {
|
|
15257
16013
|
throw new Error("Invalid uniform input");
|
|
15258
16014
|
}
|
|
@@ -15296,8 +16052,22 @@ function useUniforms(creatorOrScope, scope) {
|
|
|
15296
16052
|
}
|
|
15297
16053
|
}
|
|
15298
16054
|
return result;
|
|
15299
|
-
}, [store, memoizedInput, scope]);
|
|
15300
|
-
return { ...uniforms, removeUniforms: removeUniforms2, clearUniforms };
|
|
16055
|
+
}, [store, memoizedInput, scope, readerDep, creatorDep]);
|
|
16056
|
+
return { ...uniforms, removeUniforms: removeUniforms2, clearUniforms, rebuildUniforms };
|
|
16057
|
+
}
|
|
16058
|
+
function rebuildAllUniforms(store, scope) {
|
|
16059
|
+
store.setState((state) => {
|
|
16060
|
+
let newUniforms = {};
|
|
16061
|
+
if (scope && scope !== "root") {
|
|
16062
|
+
const { [scope]: _, ...rest } = state.uniforms;
|
|
16063
|
+
newUniforms = rest;
|
|
16064
|
+
} else if (scope === "root") {
|
|
16065
|
+
for (const [key, value] of Object.entries(state.uniforms)) {
|
|
16066
|
+
if (!isUniformNode$1(value)) newUniforms[key] = value;
|
|
16067
|
+
}
|
|
16068
|
+
}
|
|
16069
|
+
return { uniforms: newUniforms, _hmrVersion: state._hmrVersion + 1 };
|
|
16070
|
+
});
|
|
15301
16071
|
}
|
|
15302
16072
|
function removeUniforms(set, names, scope) {
|
|
15303
16073
|
set((state) => {
|
|
@@ -15362,15 +16132,17 @@ function isSameThreeType(a, b) {
|
|
|
15362
16132
|
}
|
|
15363
16133
|
|
|
15364
16134
|
const isUniformNode = (value) => value !== null && typeof value === "object" && "value" in value && "uuid" in value;
|
|
16135
|
+
const isTSLNode$1 = (value) => value !== null && typeof value === "object" && "uuid" in value && "nodeType" in value;
|
|
15365
16136
|
function useUniform(name, value) {
|
|
15366
16137
|
const store = useStore();
|
|
16138
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
15367
16139
|
return useMemo(() => {
|
|
15368
16140
|
const state = store.getState();
|
|
15369
16141
|
const set = store.setState;
|
|
15370
16142
|
const existing = state.uniforms[name];
|
|
15371
16143
|
if (existing && isUniformNode(existing)) {
|
|
15372
|
-
if (value !== void 0) {
|
|
15373
|
-
existing.value = value;
|
|
16144
|
+
if (value !== void 0 && !isTSLNode$1(value) && !isUniformNode(value)) {
|
|
16145
|
+
existing.value = typeof value === "string" ? new Color(value) : value;
|
|
15374
16146
|
}
|
|
15375
16147
|
return existing;
|
|
15376
16148
|
}
|
|
@@ -15379,7 +16151,24 @@ function useUniform(name, value) {
|
|
|
15379
16151
|
`[useUniform] Uniform "${name}" not found. Create it first with: useUniform('${name}', initialValue)`
|
|
15380
16152
|
);
|
|
15381
16153
|
}
|
|
15382
|
-
|
|
16154
|
+
if (isUniformNode(value)) {
|
|
16155
|
+
const node2 = value;
|
|
16156
|
+
if (typeof node2.setName === "function") {
|
|
16157
|
+
node2.setName(name);
|
|
16158
|
+
}
|
|
16159
|
+
set((s) => ({
|
|
16160
|
+
uniforms: { ...s.uniforms, [name]: node2 }
|
|
16161
|
+
}));
|
|
16162
|
+
return node2;
|
|
16163
|
+
}
|
|
16164
|
+
let node;
|
|
16165
|
+
if (isTSLNode$1(value)) {
|
|
16166
|
+
node = uniform(value);
|
|
16167
|
+
} else if (typeof value === "string") {
|
|
16168
|
+
node = uniform(new Color(value));
|
|
16169
|
+
} else {
|
|
16170
|
+
node = uniform(value);
|
|
16171
|
+
}
|
|
15383
16172
|
if (typeof node.setName === "function") {
|
|
15384
16173
|
node.setName(name);
|
|
15385
16174
|
}
|
|
@@ -15390,7 +16179,7 @@ function useUniform(name, value) {
|
|
|
15390
16179
|
}
|
|
15391
16180
|
}));
|
|
15392
16181
|
return node;
|
|
15393
|
-
}, [store, name]);
|
|
16182
|
+
}, [store, name, hmrVersion]);
|
|
15394
16183
|
}
|
|
15395
16184
|
|
|
15396
16185
|
const isTSLNode = (value) => value !== null && typeof value === "object" && ("uuid" in value || "nodeType" in value);
|
|
@@ -15431,19 +16220,46 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15431
16220
|
},
|
|
15432
16221
|
[store]
|
|
15433
16222
|
);
|
|
16223
|
+
const rebuildNodes = useCallback(
|
|
16224
|
+
(targetScope) => {
|
|
16225
|
+
store.setState((state) => {
|
|
16226
|
+
let newNodes = state.nodes;
|
|
16227
|
+
if (targetScope && targetScope !== "root") {
|
|
16228
|
+
const { [targetScope]: _, ...rest } = state.nodes;
|
|
16229
|
+
newNodes = rest;
|
|
16230
|
+
} else if (targetScope === "root") {
|
|
16231
|
+
newNodes = {};
|
|
16232
|
+
for (const [key, value] of Object.entries(state.nodes)) {
|
|
16233
|
+
if (!isTSLNode(value)) newNodes[key] = value;
|
|
16234
|
+
}
|
|
16235
|
+
} else {
|
|
16236
|
+
newNodes = {};
|
|
16237
|
+
}
|
|
16238
|
+
return { nodes: newNodes, _hmrVersion: state._hmrVersion + 1 };
|
|
16239
|
+
});
|
|
16240
|
+
},
|
|
16241
|
+
[store]
|
|
16242
|
+
);
|
|
16243
|
+
const isReader = creatorOrScope === void 0 || typeof creatorOrScope === "string";
|
|
16244
|
+
const storeNodes = useThree((s) => s.nodes);
|
|
16245
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
16246
|
+
const scopeDep = typeof creatorOrScope === "string" ? creatorOrScope : scope;
|
|
16247
|
+
const readerDep = isReader ? storeNodes : null;
|
|
16248
|
+
const creatorDep = isReader ? null : hmrVersion;
|
|
15434
16249
|
const nodes = useMemo(() => {
|
|
15435
|
-
const state = store.getState();
|
|
15436
|
-
const set = store.setState;
|
|
15437
16250
|
if (creatorOrScope === void 0) {
|
|
15438
|
-
return
|
|
16251
|
+
return storeNodes;
|
|
15439
16252
|
}
|
|
15440
16253
|
if (typeof creatorOrScope === "string") {
|
|
15441
|
-
const scopeData =
|
|
16254
|
+
const scopeData = storeNodes[creatorOrScope];
|
|
15442
16255
|
if (scopeData && !isTSLNode(scopeData)) return scopeData;
|
|
15443
16256
|
return {};
|
|
15444
16257
|
}
|
|
16258
|
+
const state = store.getState();
|
|
16259
|
+
const set = store.setState;
|
|
15445
16260
|
const creator = creatorOrScope;
|
|
15446
|
-
const
|
|
16261
|
+
const wrappedState = createLazyCreatorState(state);
|
|
16262
|
+
const created = creator(wrappedState);
|
|
15447
16263
|
const result = {};
|
|
15448
16264
|
let hasNewNodes = false;
|
|
15449
16265
|
if (scope) {
|
|
@@ -15452,7 +16268,7 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15452
16268
|
if (currentScope[name]) {
|
|
15453
16269
|
result[name] = currentScope[name];
|
|
15454
16270
|
} else {
|
|
15455
|
-
|
|
16271
|
+
node.setName?.(`${scope}.${name}`);
|
|
15456
16272
|
result[name] = node;
|
|
15457
16273
|
hasNewNodes = true;
|
|
15458
16274
|
}
|
|
@@ -15472,7 +16288,7 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15472
16288
|
if (existing && isTSLNode(existing)) {
|
|
15473
16289
|
result[name] = existing;
|
|
15474
16290
|
} else {
|
|
15475
|
-
|
|
16291
|
+
node.setName?.(name);
|
|
15476
16292
|
result[name] = node;
|
|
15477
16293
|
hasNewNodes = true;
|
|
15478
16294
|
}
|
|
@@ -15481,8 +16297,25 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15481
16297
|
set((s) => ({ nodes: { ...s.nodes, ...result } }));
|
|
15482
16298
|
}
|
|
15483
16299
|
return result;
|
|
15484
|
-
}, [store,
|
|
15485
|
-
return { ...nodes, removeNodes: removeNodes2, clearNodes };
|
|
16300
|
+
}, [store, scopeDep, readerDep, creatorDep]);
|
|
16301
|
+
return { ...nodes, removeNodes: removeNodes2, clearNodes, rebuildNodes };
|
|
16302
|
+
}
|
|
16303
|
+
function rebuildAllNodes(store, scope) {
|
|
16304
|
+
store.setState((state) => {
|
|
16305
|
+
let newNodes = state.nodes;
|
|
16306
|
+
if (scope && scope !== "root") {
|
|
16307
|
+
const { [scope]: _, ...rest } = state.nodes;
|
|
16308
|
+
newNodes = rest;
|
|
16309
|
+
} else if (scope === "root") {
|
|
16310
|
+
newNodes = {};
|
|
16311
|
+
for (const [key, value] of Object.entries(state.nodes)) {
|
|
16312
|
+
if (!isTSLNode(value)) newNodes[key] = value;
|
|
16313
|
+
}
|
|
16314
|
+
} else {
|
|
16315
|
+
newNodes = {};
|
|
16316
|
+
}
|
|
16317
|
+
return { nodes: newNodes, _hmrVersion: state._hmrVersion + 1 };
|
|
16318
|
+
});
|
|
15486
16319
|
}
|
|
15487
16320
|
function removeNodes(set, names, scope) {
|
|
15488
16321
|
set((state) => {
|
|
@@ -15516,10 +16349,11 @@ function useLocalNodes(creator) {
|
|
|
15516
16349
|
const uniforms = useThree((s) => s.uniforms);
|
|
15517
16350
|
const nodes = useThree((s) => s.nodes);
|
|
15518
16351
|
const textures = useThree((s) => s.textures);
|
|
16352
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
15519
16353
|
return useMemo(() => {
|
|
15520
|
-
const
|
|
15521
|
-
return creator(
|
|
15522
|
-
}, [store, creator, uniforms, nodes, textures]);
|
|
16354
|
+
const wrappedState = createLazyCreatorState(store.getState());
|
|
16355
|
+
return creator(wrappedState);
|
|
16356
|
+
}, [store, creator, uniforms, nodes, textures, hmrVersion]);
|
|
15523
16357
|
}
|
|
15524
16358
|
|
|
15525
16359
|
function usePostProcessing(mainCB, setupCB) {
|
|
@@ -15532,6 +16366,10 @@ function usePostProcessing(mainCB, setupCB) {
|
|
|
15532
16366
|
mainCBRef.current = mainCB;
|
|
15533
16367
|
setupCBRef.current = setupCB;
|
|
15534
16368
|
const [rebuildVersion, setRebuildVersion] = useState(0);
|
|
16369
|
+
useEffect(() => {
|
|
16370
|
+
callbacksRanRef.current = false;
|
|
16371
|
+
scenePassCacheRef.current = null;
|
|
16372
|
+
}, []);
|
|
15535
16373
|
const clearPasses = useCallback(() => {
|
|
15536
16374
|
store.setState({ passes: {} });
|
|
15537
16375
|
}, [store]);
|
|
@@ -15613,4 +16451,4 @@ function usePostProcessing(mainCB, setupCB) {
|
|
|
15613
16451
|
|
|
15614
16452
|
extend(THREE);
|
|
15615
16453
|
|
|
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, usePostProcessing, useRenderTarget, useStore, useTexture, useTextures, useThree, useUniform, useUniforms };
|
|
16454
|
+
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, rebuildAllNodes, rebuildAllUniforms, reconciler, registerPrimary, removeInteractivity, removeNodes, removeUniforms, resolve, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useEnvironment, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes, usePostProcessing, useRenderTarget, useStore, useTexture, useTextures, useThree, useUniform, useUniforms, waitForPrimary };
|