@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/legacy.cjs
CHANGED
|
@@ -5,10 +5,17 @@ const jsxRuntime = require('react/jsx-runtime');
|
|
|
5
5
|
const React = require('react');
|
|
6
6
|
const useMeasure = require('react-use-measure');
|
|
7
7
|
const itsFine = require('its-fine');
|
|
8
|
+
const fiber = require('@react-three/fiber');
|
|
9
|
+
const GroundedSkybox_js = require('three/examples/jsm/objects/GroundedSkybox.js');
|
|
10
|
+
const HDRLoader_js = require('three/examples/jsm/loaders/HDRLoader.js');
|
|
11
|
+
const EXRLoader_js = require('three/examples/jsm/loaders/EXRLoader.js');
|
|
12
|
+
const UltraHDRLoader_js = require('three/examples/jsm/loaders/UltraHDRLoader.js');
|
|
13
|
+
const gainmapJs = require('@monogrid/gainmap-js');
|
|
8
14
|
const Tb = require('scheduler');
|
|
9
15
|
const traditional = require('zustand/traditional');
|
|
10
16
|
const suspendReact = require('suspend-react');
|
|
11
17
|
|
|
18
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
12
19
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
13
20
|
|
|
14
21
|
function _interopNamespaceCompat(e) {
|
|
@@ -65,6 +72,374 @@ const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
|
65
72
|
WebGPURenderer: WebGPURenderer
|
|
66
73
|
}, [three__namespace]);
|
|
67
74
|
|
|
75
|
+
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
76
|
+
const pendingSubscribers = /* @__PURE__ */ new Map();
|
|
77
|
+
function registerPrimary(id, renderer, store) {
|
|
78
|
+
if (primaryRegistry.has(id)) {
|
|
79
|
+
console.warn(`Canvas with id="${id}" already registered. Overwriting.`);
|
|
80
|
+
}
|
|
81
|
+
const entry = { renderer, store };
|
|
82
|
+
primaryRegistry.set(id, entry);
|
|
83
|
+
const subscribers = pendingSubscribers.get(id);
|
|
84
|
+
if (subscribers) {
|
|
85
|
+
subscribers.forEach((callback) => callback(entry));
|
|
86
|
+
pendingSubscribers.delete(id);
|
|
87
|
+
}
|
|
88
|
+
return () => {
|
|
89
|
+
const currentEntry = primaryRegistry.get(id);
|
|
90
|
+
if (currentEntry?.renderer === renderer) {
|
|
91
|
+
primaryRegistry.delete(id);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function getPrimary(id) {
|
|
96
|
+
return primaryRegistry.get(id);
|
|
97
|
+
}
|
|
98
|
+
function waitForPrimary(id, timeout = 5e3) {
|
|
99
|
+
const existing = primaryRegistry.get(id);
|
|
100
|
+
if (existing) {
|
|
101
|
+
return Promise.resolve(existing);
|
|
102
|
+
}
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const timeoutId = setTimeout(() => {
|
|
105
|
+
const subscribers = pendingSubscribers.get(id);
|
|
106
|
+
if (subscribers) {
|
|
107
|
+
const index = subscribers.indexOf(callback);
|
|
108
|
+
if (index !== -1) subscribers.splice(index, 1);
|
|
109
|
+
if (subscribers.length === 0) pendingSubscribers.delete(id);
|
|
110
|
+
}
|
|
111
|
+
reject(new Error(`Timeout waiting for canvas with id="${id}". Make sure a <Canvas id="${id}"> is mounted.`));
|
|
112
|
+
}, timeout);
|
|
113
|
+
const callback = (entry) => {
|
|
114
|
+
clearTimeout(timeoutId);
|
|
115
|
+
resolve(entry);
|
|
116
|
+
};
|
|
117
|
+
if (!pendingSubscribers.has(id)) {
|
|
118
|
+
pendingSubscribers.set(id, []);
|
|
119
|
+
}
|
|
120
|
+
pendingSubscribers.get(id).push(callback);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function hasPrimary(id) {
|
|
124
|
+
return primaryRegistry.has(id);
|
|
125
|
+
}
|
|
126
|
+
function unregisterPrimary(id) {
|
|
127
|
+
primaryRegistry.delete(id);
|
|
128
|
+
}
|
|
129
|
+
function getPrimaryIds() {
|
|
130
|
+
return Array.from(primaryRegistry.keys());
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const presetsObj = {
|
|
134
|
+
apartment: "lebombo_1k.hdr",
|
|
135
|
+
city: "potsdamer_platz_1k.hdr",
|
|
136
|
+
dawn: "kiara_1_dawn_1k.hdr",
|
|
137
|
+
forest: "forest_slope_1k.hdr",
|
|
138
|
+
lobby: "st_fagans_interior_1k.hdr",
|
|
139
|
+
night: "dikhololo_night_1k.hdr",
|
|
140
|
+
park: "rooitou_park_1k.hdr",
|
|
141
|
+
studio: "studio_small_03_1k.hdr",
|
|
142
|
+
sunset: "venice_sunset_1k.hdr",
|
|
143
|
+
warehouse: "empty_warehouse_01_1k.hdr"
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
|
|
147
|
+
const isArray = (arr) => Array.isArray(arr);
|
|
148
|
+
const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
|
|
149
|
+
function useEnvironment({
|
|
150
|
+
files = defaultFiles,
|
|
151
|
+
path = "",
|
|
152
|
+
preset = void 0,
|
|
153
|
+
colorSpace = void 0,
|
|
154
|
+
extensions
|
|
155
|
+
} = {}) {
|
|
156
|
+
if (preset) {
|
|
157
|
+
validatePreset(preset);
|
|
158
|
+
files = presetsObj[preset];
|
|
159
|
+
path = CUBEMAP_ROOT;
|
|
160
|
+
}
|
|
161
|
+
const multiFile = isArray(files);
|
|
162
|
+
const { extension, isCubemap } = getExtension(files);
|
|
163
|
+
const loader = getLoader$1(extension);
|
|
164
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
165
|
+
const renderer = fiber.useThree((state) => state.renderer);
|
|
166
|
+
React.useLayoutEffect(() => {
|
|
167
|
+
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
168
|
+
function clearGainmapTexture() {
|
|
169
|
+
fiber.useLoader.clear(loader, multiFile ? [files] : files);
|
|
170
|
+
}
|
|
171
|
+
renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
|
|
172
|
+
}, [files, renderer.domElement]);
|
|
173
|
+
const loaderResult = fiber.useLoader(
|
|
174
|
+
loader,
|
|
175
|
+
multiFile ? [files] : files,
|
|
176
|
+
(loader2) => {
|
|
177
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
178
|
+
loader2.setRenderer?.(renderer);
|
|
179
|
+
}
|
|
180
|
+
loader2.setPath?.(path);
|
|
181
|
+
if (extensions) extensions(loader2);
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
let texture = multiFile ? (
|
|
185
|
+
// @ts-ignore
|
|
186
|
+
loaderResult[0]
|
|
187
|
+
) : loaderResult;
|
|
188
|
+
if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
|
|
189
|
+
texture = texture.renderTarget?.texture;
|
|
190
|
+
}
|
|
191
|
+
texture.mapping = isCubemap ? three.CubeReflectionMapping : three.EquirectangularReflectionMapping;
|
|
192
|
+
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
193
|
+
return texture;
|
|
194
|
+
}
|
|
195
|
+
const preloadDefaultOptions = {
|
|
196
|
+
files: defaultFiles,
|
|
197
|
+
path: "",
|
|
198
|
+
preset: void 0,
|
|
199
|
+
extensions: void 0
|
|
200
|
+
};
|
|
201
|
+
useEnvironment.preload = (preloadOptions) => {
|
|
202
|
+
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
203
|
+
let { files, path = "" } = options;
|
|
204
|
+
const { preset, extensions } = options;
|
|
205
|
+
if (preset) {
|
|
206
|
+
validatePreset(preset);
|
|
207
|
+
files = presetsObj[preset];
|
|
208
|
+
path = CUBEMAP_ROOT;
|
|
209
|
+
}
|
|
210
|
+
const { extension } = getExtension(files);
|
|
211
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
212
|
+
throw new Error("useEnvironment: Preloading gainmaps is not supported");
|
|
213
|
+
}
|
|
214
|
+
const loader = getLoader$1(extension);
|
|
215
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
216
|
+
fiber.useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
|
|
217
|
+
loader2.setPath?.(path);
|
|
218
|
+
if (extensions) extensions(loader2);
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
const clearDefaultOptins = {
|
|
222
|
+
files: defaultFiles,
|
|
223
|
+
preset: void 0
|
|
224
|
+
};
|
|
225
|
+
useEnvironment.clear = (clearOptions) => {
|
|
226
|
+
const options = { ...clearDefaultOptins, ...clearOptions };
|
|
227
|
+
let { files } = options;
|
|
228
|
+
const { preset } = options;
|
|
229
|
+
if (preset) {
|
|
230
|
+
validatePreset(preset);
|
|
231
|
+
files = presetsObj[preset];
|
|
232
|
+
}
|
|
233
|
+
const { extension } = getExtension(files);
|
|
234
|
+
const loader = getLoader$1(extension);
|
|
235
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
236
|
+
fiber.useLoader.clear(loader, isArray(files) ? [files] : files);
|
|
237
|
+
};
|
|
238
|
+
function validatePreset(preset) {
|
|
239
|
+
if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
|
|
240
|
+
}
|
|
241
|
+
function getExtension(files) {
|
|
242
|
+
const isCubemap = isArray(files) && files.length === 6;
|
|
243
|
+
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
244
|
+
const firstEntry = isArray(files) ? files[0] : files;
|
|
245
|
+
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();
|
|
246
|
+
return { extension, isCubemap, isGainmap };
|
|
247
|
+
}
|
|
248
|
+
function getLoader$1(extension) {
|
|
249
|
+
const loader = extension === "cube" ? three.CubeTextureLoader : extension === "hdr" ? HDRLoader_js.HDRLoader : extension === "exr" ? EXRLoader_js.EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader_js.UltraHDRLoader : extension === "webp" ? gainmapJs.GainMapLoader : null;
|
|
250
|
+
return loader;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const isRef$1 = (obj) => obj.current && obj.current.isScene;
|
|
254
|
+
const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
|
|
255
|
+
function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
|
|
256
|
+
sceneProps = {
|
|
257
|
+
backgroundBlurriness: 0,
|
|
258
|
+
backgroundIntensity: 1,
|
|
259
|
+
backgroundRotation: [0, 0, 0],
|
|
260
|
+
environmentIntensity: 1,
|
|
261
|
+
environmentRotation: [0, 0, 0],
|
|
262
|
+
...sceneProps
|
|
263
|
+
};
|
|
264
|
+
const target = resolveScene(scene || defaultScene);
|
|
265
|
+
const oldbg = target.background;
|
|
266
|
+
const oldenv = target.environment;
|
|
267
|
+
const oldSceneProps = {
|
|
268
|
+
// @ts-ignore
|
|
269
|
+
backgroundBlurriness: target.backgroundBlurriness,
|
|
270
|
+
// @ts-ignore
|
|
271
|
+
backgroundIntensity: target.backgroundIntensity,
|
|
272
|
+
// @ts-ignore
|
|
273
|
+
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
274
|
+
// @ts-ignore
|
|
275
|
+
environmentIntensity: target.environmentIntensity,
|
|
276
|
+
// @ts-ignore
|
|
277
|
+
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
278
|
+
};
|
|
279
|
+
if (background !== "only") target.environment = texture;
|
|
280
|
+
if (background) target.background = texture;
|
|
281
|
+
fiber.applyProps(target, sceneProps);
|
|
282
|
+
return () => {
|
|
283
|
+
if (background !== "only") target.environment = oldenv;
|
|
284
|
+
if (background) target.background = oldbg;
|
|
285
|
+
fiber.applyProps(target, oldSceneProps);
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function EnvironmentMap({ scene, background = false, map, ...config }) {
|
|
289
|
+
const defaultScene = fiber.useThree((state) => state.scene);
|
|
290
|
+
React__namespace.useLayoutEffect(() => {
|
|
291
|
+
if (map) return setEnvProps(background, scene, defaultScene, map, config);
|
|
292
|
+
});
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
function EnvironmentCube({
|
|
296
|
+
background = false,
|
|
297
|
+
scene,
|
|
298
|
+
blur,
|
|
299
|
+
backgroundBlurriness,
|
|
300
|
+
backgroundIntensity,
|
|
301
|
+
backgroundRotation,
|
|
302
|
+
environmentIntensity,
|
|
303
|
+
environmentRotation,
|
|
304
|
+
...rest
|
|
305
|
+
}) {
|
|
306
|
+
const texture = useEnvironment(rest);
|
|
307
|
+
const defaultScene = fiber.useThree((state) => state.scene);
|
|
308
|
+
React__namespace.useLayoutEffect(() => {
|
|
309
|
+
return setEnvProps(background, scene, defaultScene, texture, {
|
|
310
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
311
|
+
backgroundIntensity,
|
|
312
|
+
backgroundRotation,
|
|
313
|
+
environmentIntensity,
|
|
314
|
+
environmentRotation
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
React__namespace.useEffect(() => {
|
|
318
|
+
return () => {
|
|
319
|
+
texture.dispose();
|
|
320
|
+
};
|
|
321
|
+
}, [texture]);
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
function EnvironmentPortal({
|
|
325
|
+
children,
|
|
326
|
+
near = 0.1,
|
|
327
|
+
far = 1e3,
|
|
328
|
+
resolution = 256,
|
|
329
|
+
frames = 1,
|
|
330
|
+
map,
|
|
331
|
+
background = false,
|
|
332
|
+
blur,
|
|
333
|
+
backgroundBlurriness,
|
|
334
|
+
backgroundIntensity,
|
|
335
|
+
backgroundRotation,
|
|
336
|
+
environmentIntensity,
|
|
337
|
+
environmentRotation,
|
|
338
|
+
scene,
|
|
339
|
+
files,
|
|
340
|
+
path,
|
|
341
|
+
preset = void 0,
|
|
342
|
+
extensions
|
|
343
|
+
}) {
|
|
344
|
+
const gl = fiber.useThree((state) => state.gl);
|
|
345
|
+
const defaultScene = fiber.useThree((state) => state.scene);
|
|
346
|
+
const camera = React__namespace.useRef(null);
|
|
347
|
+
const [virtualScene] = React__namespace.useState(() => new three.Scene());
|
|
348
|
+
const fbo = React__namespace.useMemo(() => {
|
|
349
|
+
const fbo2 = new three.WebGLCubeRenderTarget(resolution);
|
|
350
|
+
fbo2.texture.type = three.HalfFloatType;
|
|
351
|
+
return fbo2;
|
|
352
|
+
}, [resolution]);
|
|
353
|
+
React__namespace.useEffect(() => {
|
|
354
|
+
return () => {
|
|
355
|
+
fbo.dispose();
|
|
356
|
+
};
|
|
357
|
+
}, [fbo]);
|
|
358
|
+
React__namespace.useLayoutEffect(() => {
|
|
359
|
+
if (frames === 1) {
|
|
360
|
+
const autoClear = gl.autoClear;
|
|
361
|
+
gl.autoClear = true;
|
|
362
|
+
camera.current.update(gl, virtualScene);
|
|
363
|
+
gl.autoClear = autoClear;
|
|
364
|
+
}
|
|
365
|
+
return setEnvProps(background, scene, defaultScene, fbo.texture, {
|
|
366
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
367
|
+
backgroundIntensity,
|
|
368
|
+
backgroundRotation,
|
|
369
|
+
environmentIntensity,
|
|
370
|
+
environmentRotation
|
|
371
|
+
});
|
|
372
|
+
}, [children, virtualScene, fbo.texture, scene, defaultScene, background, frames, gl]);
|
|
373
|
+
let count = 1;
|
|
374
|
+
fiber.useFrame(() => {
|
|
375
|
+
if (frames === Infinity || count < frames) {
|
|
376
|
+
const autoClear = gl.autoClear;
|
|
377
|
+
gl.autoClear = true;
|
|
378
|
+
camera.current.update(gl, virtualScene);
|
|
379
|
+
gl.autoClear = autoClear;
|
|
380
|
+
count++;
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fiber.createPortal(
|
|
384
|
+
/* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
385
|
+
children,
|
|
386
|
+
/* @__PURE__ */ jsxRuntime.jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
|
|
387
|
+
files || preset ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { background: true, map, extensions }) : null
|
|
388
|
+
] }),
|
|
389
|
+
virtualScene
|
|
390
|
+
) });
|
|
391
|
+
}
|
|
392
|
+
function EnvironmentGround(props) {
|
|
393
|
+
const textureDefault = useEnvironment(props);
|
|
394
|
+
const texture = props.map || textureDefault;
|
|
395
|
+
React__namespace.useMemo(() => fiber.extend({ GroundProjectedEnvImpl: GroundedSkybox_js.GroundedSkybox }), []);
|
|
396
|
+
React__namespace.useEffect(() => {
|
|
397
|
+
return () => {
|
|
398
|
+
textureDefault.dispose();
|
|
399
|
+
};
|
|
400
|
+
}, [textureDefault]);
|
|
401
|
+
const height = props.ground?.height ?? 15;
|
|
402
|
+
const radius = props.ground?.radius ?? 60;
|
|
403
|
+
const scale = props.ground?.scale ?? 1e3;
|
|
404
|
+
const args = React__namespace.useMemo(
|
|
405
|
+
() => [texture, height, radius],
|
|
406
|
+
[texture, height, radius]
|
|
407
|
+
);
|
|
408
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
409
|
+
/* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props, map: texture }),
|
|
410
|
+
/* @__PURE__ */ jsxRuntime.jsx("groundProjectedEnvImpl", { args, scale })
|
|
411
|
+
] });
|
|
412
|
+
}
|
|
413
|
+
function EnvironmentColor({ color, scene }) {
|
|
414
|
+
const defaultScene = fiber.useThree((state) => state.scene);
|
|
415
|
+
React__namespace.useLayoutEffect(() => {
|
|
416
|
+
if (color === void 0) return;
|
|
417
|
+
const target = resolveScene(scene || defaultScene);
|
|
418
|
+
const oldBg = target.background;
|
|
419
|
+
target.background = new three.Color(color);
|
|
420
|
+
return () => {
|
|
421
|
+
target.background = oldBg;
|
|
422
|
+
};
|
|
423
|
+
});
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
function EnvironmentDualSource(props) {
|
|
427
|
+
const { backgroundFiles, ...envProps } = props;
|
|
428
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
429
|
+
/* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
430
|
+
/* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
|
|
431
|
+
] });
|
|
432
|
+
}
|
|
433
|
+
function Environment(props) {
|
|
434
|
+
if (props.color && !props.files && !props.preset && !props.map) {
|
|
435
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentColor, { ...props });
|
|
436
|
+
}
|
|
437
|
+
if (props.backgroundFiles && props.backgroundFiles !== props.files) {
|
|
438
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentDualSource, { ...props });
|
|
439
|
+
}
|
|
440
|
+
return props.ground ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props });
|
|
441
|
+
}
|
|
442
|
+
|
|
68
443
|
var __defProp$2 = Object.defineProperty;
|
|
69
444
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
70
445
|
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -244,7 +619,8 @@ function prepare(target, root, type, props) {
|
|
|
244
619
|
object,
|
|
245
620
|
eventCount: 0,
|
|
246
621
|
handlers: {},
|
|
247
|
-
isHidden: false
|
|
622
|
+
isHidden: false,
|
|
623
|
+
deferredRefs: []
|
|
248
624
|
};
|
|
249
625
|
if (object) object.__r3f = instance;
|
|
250
626
|
}
|
|
@@ -293,7 +669,7 @@ function createOcclusionObserverNode(store, uniform) {
|
|
|
293
669
|
let occlusionSetupPromise = null;
|
|
294
670
|
function enableOcclusion(store) {
|
|
295
671
|
const state = store.getState();
|
|
296
|
-
const { internal, renderer
|
|
672
|
+
const { internal, renderer } = state;
|
|
297
673
|
if (internal.occlusionEnabled || occlusionSetupPromise) return;
|
|
298
674
|
const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
|
|
299
675
|
if (!hasOcclusionSupport) {
|
|
@@ -456,6 +832,22 @@ function hasVisibilityHandlers(handlers) {
|
|
|
456
832
|
return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
|
|
457
833
|
}
|
|
458
834
|
|
|
835
|
+
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
836
|
+
function fromRef(ref) {
|
|
837
|
+
return { [FROM_REF]: ref };
|
|
838
|
+
}
|
|
839
|
+
function isFromRef(value) {
|
|
840
|
+
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
const ONCE = Symbol.for("@react-three/fiber.once");
|
|
844
|
+
function once(...args) {
|
|
845
|
+
return { [ONCE]: args.length ? args : true };
|
|
846
|
+
}
|
|
847
|
+
function isOnce(value) {
|
|
848
|
+
return value !== null && typeof value === "object" && ONCE in value;
|
|
849
|
+
}
|
|
850
|
+
|
|
459
851
|
const RESERVED_PROPS = [
|
|
460
852
|
"children",
|
|
461
853
|
"key",
|
|
@@ -526,7 +918,7 @@ function getMemoizedPrototype(root) {
|
|
|
526
918
|
ctor = new root.constructor();
|
|
527
919
|
MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
|
|
528
920
|
}
|
|
529
|
-
} catch
|
|
921
|
+
} catch {
|
|
530
922
|
}
|
|
531
923
|
return ctor;
|
|
532
924
|
}
|
|
@@ -557,7 +949,7 @@ function applyProps(object, props) {
|
|
|
557
949
|
const rootState = instance && findInitialRoot(instance).getState();
|
|
558
950
|
const prevHandlers = instance?.eventCount;
|
|
559
951
|
for (const prop in props) {
|
|
560
|
-
|
|
952
|
+
const value = props[prop];
|
|
561
953
|
if (RESERVED_PROPS.includes(prop)) continue;
|
|
562
954
|
if (instance && EVENT_REGEX.test(prop)) {
|
|
563
955
|
if (typeof value === "function") instance.handlers[prop] = value;
|
|
@@ -572,6 +964,25 @@ function applyProps(object, props) {
|
|
|
572
964
|
continue;
|
|
573
965
|
}
|
|
574
966
|
if (value === void 0) continue;
|
|
967
|
+
if (isFromRef(value)) {
|
|
968
|
+
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
969
|
+
continue;
|
|
970
|
+
}
|
|
971
|
+
if (isOnce(value)) {
|
|
972
|
+
if (instance?.appliedOnce?.has(prop)) continue;
|
|
973
|
+
if (instance) {
|
|
974
|
+
instance.appliedOnce ?? (instance.appliedOnce = /* @__PURE__ */ new Set());
|
|
975
|
+
instance.appliedOnce.add(prop);
|
|
976
|
+
}
|
|
977
|
+
const { root: targetRoot, key: targetKey } = resolve(object, prop);
|
|
978
|
+
const args = value[ONCE];
|
|
979
|
+
if (typeof targetRoot[targetKey] === "function") {
|
|
980
|
+
targetRoot[targetKey](...args === true ? [] : args);
|
|
981
|
+
} else if (args !== true && args.length > 0) {
|
|
982
|
+
targetRoot[targetKey] = args[0];
|
|
983
|
+
}
|
|
984
|
+
continue;
|
|
985
|
+
}
|
|
575
986
|
let { root, key, target } = resolve(object, prop);
|
|
576
987
|
if (target === void 0 && (typeof root !== "object" || root === null)) {
|
|
577
988
|
throw Error(`R3F: Cannot set "${prop}". Ensure it is an object before setting "${key}".`);
|
|
@@ -594,7 +1005,7 @@ function applyProps(object, props) {
|
|
|
594
1005
|
else target.set(value);
|
|
595
1006
|
} else {
|
|
596
1007
|
root[key] = value;
|
|
597
|
-
if (rootState &&
|
|
1008
|
+
if (rootState && rootState.renderer?.outputColorSpace === three.SRGBColorSpace && colorMaps.includes(key) && isTexture(value) && root[key]?.isTexture && // sRGB textures must be RGBA8 since r137 https://github.com/mrdoob/three.js/pull/23129
|
|
598
1009
|
root[key].format === three.RGBAFormat && root[key].type === three.UnsignedByteType) {
|
|
599
1010
|
root[key].colorSpace = rootState.textureColorSpace;
|
|
600
1011
|
}
|
|
@@ -709,13 +1120,14 @@ function createEvents(store) {
|
|
|
709
1120
|
for (const hit of hits) {
|
|
710
1121
|
let eventObject = hit.object;
|
|
711
1122
|
while (eventObject) {
|
|
712
|
-
if (eventObject.__r3f?.eventCount)
|
|
1123
|
+
if (eventObject.__r3f?.eventCount) {
|
|
713
1124
|
intersections.push({ ...hit, eventObject });
|
|
1125
|
+
}
|
|
714
1126
|
eventObject = eventObject.parent;
|
|
715
1127
|
}
|
|
716
1128
|
}
|
|
717
1129
|
if ("pointerId" in event && state.internal.capturedMap.has(event.pointerId)) {
|
|
718
|
-
for (
|
|
1130
|
+
for (const captureData of state.internal.capturedMap.get(event.pointerId).values()) {
|
|
719
1131
|
if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
|
|
720
1132
|
}
|
|
721
1133
|
}
|
|
@@ -745,12 +1157,12 @@ function createEvents(store) {
|
|
|
745
1157
|
releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
|
|
746
1158
|
}
|
|
747
1159
|
};
|
|
748
|
-
|
|
749
|
-
for (
|
|
750
|
-
|
|
1160
|
+
const extractEventProps = {};
|
|
1161
|
+
for (const prop in event) {
|
|
1162
|
+
const property = event[prop];
|
|
751
1163
|
if (typeof property !== "function") extractEventProps[prop] = property;
|
|
752
1164
|
}
|
|
753
|
-
|
|
1165
|
+
const raycastEvent = {
|
|
754
1166
|
...hit,
|
|
755
1167
|
...extractEventProps,
|
|
756
1168
|
pointer,
|
|
@@ -950,7 +1362,7 @@ function createPointerEvents(store) {
|
|
|
950
1362
|
return {
|
|
951
1363
|
priority: 1,
|
|
952
1364
|
enabled: true,
|
|
953
|
-
compute(event, state
|
|
1365
|
+
compute(event, state) {
|
|
954
1366
|
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
955
1367
|
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
956
1368
|
},
|
|
@@ -1048,300 +1460,26 @@ function notifyAlpha({ message, link }) {
|
|
|
1048
1460
|
}
|
|
1049
1461
|
}
|
|
1050
1462
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
let performanceTimeout = void 0;
|
|
1074
|
-
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
1075
|
-
const pointer = new three.Vector2();
|
|
1076
|
-
const rootState = {
|
|
1077
|
-
set,
|
|
1078
|
-
get,
|
|
1079
|
-
// Mock objects that have to be configured
|
|
1080
|
-
gl: null,
|
|
1081
|
-
renderer: null,
|
|
1082
|
-
camera: null,
|
|
1083
|
-
frustum: new three.Frustum(),
|
|
1084
|
-
autoUpdateFrustum: true,
|
|
1085
|
-
raycaster: null,
|
|
1086
|
-
events: { priority: 1, enabled: true, connected: false },
|
|
1087
|
-
scene: null,
|
|
1088
|
-
rootScene: null,
|
|
1089
|
-
xr: null,
|
|
1090
|
-
inspector: null,
|
|
1091
|
-
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
1092
|
-
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1093
|
-
legacy: false,
|
|
1094
|
-
linear: false,
|
|
1095
|
-
flat: false,
|
|
1096
|
-
textureColorSpace: "srgb",
|
|
1097
|
-
isLegacy: false,
|
|
1098
|
-
webGPUSupported: false,
|
|
1099
|
-
isNative: false,
|
|
1100
|
-
controls: null,
|
|
1101
|
-
pointer,
|
|
1102
|
-
mouse: pointer,
|
|
1103
|
-
frameloop: "always",
|
|
1104
|
-
onPointerMissed: void 0,
|
|
1105
|
-
onDragOverMissed: void 0,
|
|
1106
|
-
onDropMissed: void 0,
|
|
1107
|
-
performance: {
|
|
1108
|
-
current: 1,
|
|
1109
|
-
min: 0.5,
|
|
1110
|
-
max: 1,
|
|
1111
|
-
debounce: 200,
|
|
1112
|
-
regress: () => {
|
|
1113
|
-
const state2 = get();
|
|
1114
|
-
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
1115
|
-
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
1116
|
-
performanceTimeout = setTimeout(
|
|
1117
|
-
() => setPerformanceCurrent(get().performance.max),
|
|
1118
|
-
state2.performance.debounce
|
|
1119
|
-
);
|
|
1120
|
-
}
|
|
1121
|
-
},
|
|
1122
|
-
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
1123
|
-
viewport: {
|
|
1124
|
-
initialDpr: 0,
|
|
1125
|
-
dpr: 0,
|
|
1126
|
-
width: 0,
|
|
1127
|
-
height: 0,
|
|
1128
|
-
top: 0,
|
|
1129
|
-
left: 0,
|
|
1130
|
-
aspect: 0,
|
|
1131
|
-
distance: 0,
|
|
1132
|
-
factor: 0,
|
|
1133
|
-
getCurrentViewport
|
|
1134
|
-
},
|
|
1135
|
-
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
1136
|
-
setSize: (width, height, top = 0, left = 0) => {
|
|
1137
|
-
const camera = get().camera;
|
|
1138
|
-
const size = { width, height, top, left };
|
|
1139
|
-
set((state2) => ({ size, viewport: { ...state2.viewport, ...getCurrentViewport(camera, defaultTarget, size) } }));
|
|
1140
|
-
},
|
|
1141
|
-
setDpr: (dpr) => set((state2) => {
|
|
1142
|
-
const resolved = calculateDpr(dpr);
|
|
1143
|
-
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
1144
|
-
}),
|
|
1145
|
-
setFrameloop: (frameloop = "always") => {
|
|
1146
|
-
set(() => ({ frameloop }));
|
|
1147
|
-
},
|
|
1148
|
-
setError: (error) => set(() => ({ error })),
|
|
1149
|
-
error: null,
|
|
1150
|
-
//* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
|
|
1151
|
-
uniforms: {},
|
|
1152
|
-
nodes: {},
|
|
1153
|
-
textures: /* @__PURE__ */ new Map(),
|
|
1154
|
-
postProcessing: null,
|
|
1155
|
-
passes: {},
|
|
1156
|
-
previousRoot: void 0,
|
|
1157
|
-
internal: {
|
|
1158
|
-
// Events
|
|
1159
|
-
interaction: [],
|
|
1160
|
-
hovered: /* @__PURE__ */ new Map(),
|
|
1161
|
-
subscribers: [],
|
|
1162
|
-
initialClick: [0, 0],
|
|
1163
|
-
initialHits: [],
|
|
1164
|
-
capturedMap: /* @__PURE__ */ new Map(),
|
|
1165
|
-
lastEvent: React__namespace.createRef(),
|
|
1166
|
-
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
1167
|
-
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
1168
|
-
// Occlusion system (WebGPU only)
|
|
1169
|
-
occlusionEnabled: false,
|
|
1170
|
-
occlusionObserver: null,
|
|
1171
|
-
occlusionCache: /* @__PURE__ */ new Map(),
|
|
1172
|
-
helperGroup: null,
|
|
1173
|
-
// Updates
|
|
1174
|
-
active: false,
|
|
1175
|
-
frames: 0,
|
|
1176
|
-
priority: 0,
|
|
1177
|
-
subscribe: (ref, priority, store) => {
|
|
1178
|
-
const internal = get().internal;
|
|
1179
|
-
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
1180
|
-
internal.subscribers.push({ ref, priority, store });
|
|
1181
|
-
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
1182
|
-
return () => {
|
|
1183
|
-
const internal2 = get().internal;
|
|
1184
|
-
if (internal2?.subscribers) {
|
|
1185
|
-
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
1186
|
-
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
1187
|
-
}
|
|
1188
|
-
};
|
|
1189
|
-
},
|
|
1190
|
-
// Renderer Storage (single source of truth)
|
|
1191
|
-
actualRenderer: null,
|
|
1192
|
-
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
1193
|
-
scheduler: null
|
|
1194
|
-
}
|
|
1195
|
-
};
|
|
1196
|
-
return rootState;
|
|
1197
|
-
});
|
|
1198
|
-
const state = rootStore.getState();
|
|
1199
|
-
Object.defineProperty(state, "gl", {
|
|
1200
|
-
get() {
|
|
1201
|
-
const currentState = rootStore.getState();
|
|
1202
|
-
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1203
|
-
const stack = new Error().stack || "";
|
|
1204
|
-
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
1205
|
-
if (!isInternalAccess) {
|
|
1206
|
-
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1207
|
-
notifyDepreciated({
|
|
1208
|
-
heading: "Accessing state.gl in WebGPU mode",
|
|
1209
|
-
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
|
|
1210
|
-
});
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
return currentState.internal.actualRenderer;
|
|
1214
|
-
},
|
|
1215
|
-
set(value) {
|
|
1216
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1217
|
-
},
|
|
1218
|
-
enumerable: true,
|
|
1219
|
-
configurable: true
|
|
1220
|
-
});
|
|
1221
|
-
Object.defineProperty(state, "renderer", {
|
|
1222
|
-
get() {
|
|
1223
|
-
return rootStore.getState().internal.actualRenderer;
|
|
1224
|
-
},
|
|
1225
|
-
set(value) {
|
|
1226
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1227
|
-
},
|
|
1228
|
-
enumerable: true,
|
|
1229
|
-
configurable: true
|
|
1230
|
-
});
|
|
1231
|
-
let oldScene = state.scene;
|
|
1232
|
-
rootStore.subscribe(() => {
|
|
1233
|
-
const currentState = rootStore.getState();
|
|
1234
|
-
const { scene, rootScene, set } = currentState;
|
|
1235
|
-
if (scene !== oldScene) {
|
|
1236
|
-
oldScene = scene;
|
|
1237
|
-
if (scene?.isScene && scene !== rootScene) {
|
|
1238
|
-
set({ rootScene: scene });
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
});
|
|
1242
|
-
let oldSize = state.size;
|
|
1243
|
-
let oldDpr = state.viewport.dpr;
|
|
1244
|
-
let oldCamera = state.camera;
|
|
1245
|
-
rootStore.subscribe(() => {
|
|
1246
|
-
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
1247
|
-
const actualRenderer = internal.actualRenderer;
|
|
1248
|
-
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
1249
|
-
oldSize = size;
|
|
1250
|
-
oldDpr = viewport.dpr;
|
|
1251
|
-
updateCamera(camera, size);
|
|
1252
|
-
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1253
|
-
const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
|
|
1254
|
-
actualRenderer.setSize(size.width, size.height, updateStyle);
|
|
1255
|
-
}
|
|
1256
|
-
if (camera !== oldCamera) {
|
|
1257
|
-
oldCamera = camera;
|
|
1258
|
-
const { rootScene } = rootStore.getState();
|
|
1259
|
-
if (camera && rootScene && !camera.parent) {
|
|
1260
|
-
rootScene.add(camera);
|
|
1261
|
-
}
|
|
1262
|
-
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
1263
|
-
const currentState = rootStore.getState();
|
|
1264
|
-
if (currentState.autoUpdateFrustum && camera) {
|
|
1265
|
-
updateFrustum(camera, currentState.frustum);
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
});
|
|
1269
|
-
rootStore.subscribe((state2) => invalidate(state2));
|
|
1270
|
-
return rootStore;
|
|
1271
|
-
};
|
|
1272
|
-
|
|
1273
|
-
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
1274
|
-
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
1275
|
-
function getLoader(Proto) {
|
|
1276
|
-
if (isConstructor$1(Proto)) {
|
|
1277
|
-
let loader = memoizedLoaders.get(Proto);
|
|
1278
|
-
if (!loader) {
|
|
1279
|
-
loader = new Proto();
|
|
1280
|
-
memoizedLoaders.set(Proto, loader);
|
|
1281
|
-
}
|
|
1282
|
-
return loader;
|
|
1283
|
-
}
|
|
1284
|
-
return Proto;
|
|
1285
|
-
}
|
|
1286
|
-
function loadingFn(extensions, onProgress) {
|
|
1287
|
-
return function(Proto, input) {
|
|
1288
|
-
const loader = getLoader(Proto);
|
|
1289
|
-
if (extensions) extensions(loader);
|
|
1290
|
-
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
1291
|
-
return loader.loadAsync(input, onProgress).then((data) => {
|
|
1292
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1293
|
-
return data;
|
|
1294
|
-
});
|
|
1295
|
-
}
|
|
1296
|
-
return new Promise(
|
|
1297
|
-
(res, reject) => loader.load(
|
|
1298
|
-
input,
|
|
1299
|
-
(data) => {
|
|
1300
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1301
|
-
res(data);
|
|
1302
|
-
},
|
|
1303
|
-
onProgress,
|
|
1304
|
-
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
1305
|
-
)
|
|
1306
|
-
);
|
|
1307
|
-
};
|
|
1308
|
-
}
|
|
1309
|
-
function useLoader(loader, input, extensions, onProgress) {
|
|
1310
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1311
|
-
const fn = loadingFn(extensions, onProgress);
|
|
1312
|
-
const results = keys.map((key) => suspendReact.suspend(fn, [loader, key], { equal: is.equ }));
|
|
1313
|
-
return Array.isArray(input) ? results : results[0];
|
|
1314
|
-
}
|
|
1315
|
-
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
1316
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1317
|
-
keys.forEach((key) => suspendReact.preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
1318
|
-
};
|
|
1319
|
-
useLoader.clear = function(loader, input) {
|
|
1320
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1321
|
-
keys.forEach((key) => suspendReact.clear([loader, key]));
|
|
1322
|
-
};
|
|
1323
|
-
useLoader.loader = getLoader;
|
|
1324
|
-
|
|
1325
|
-
var __defProp$1 = Object.defineProperty;
|
|
1326
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1327
|
-
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1328
|
-
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1329
|
-
class PhaseGraph {
|
|
1330
|
-
constructor() {
|
|
1331
|
-
/** Ordered list of phase nodes */
|
|
1332
|
-
__publicField$1(this, "phases", []);
|
|
1333
|
-
/** Quick lookup by name */
|
|
1334
|
-
__publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1335
|
-
/** Cached ordered names (invalidated on changes) */
|
|
1336
|
-
__publicField$1(this, "orderedNamesCache", null);
|
|
1337
|
-
this.initializeDefaultPhases();
|
|
1338
|
-
}
|
|
1339
|
-
//* Initialization --------------------------------
|
|
1340
|
-
initializeDefaultPhases() {
|
|
1341
|
-
for (const name of DEFAULT_PHASES) {
|
|
1342
|
-
const node = { name, isAutoGenerated: false };
|
|
1343
|
-
this.phases.push(node);
|
|
1344
|
-
this.phaseMap.set(name, node);
|
|
1463
|
+
var __defProp$1 = Object.defineProperty;
|
|
1464
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1465
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1466
|
+
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1467
|
+
class PhaseGraph {
|
|
1468
|
+
constructor() {
|
|
1469
|
+
/** Ordered list of phase nodes */
|
|
1470
|
+
__publicField$1(this, "phases", []);
|
|
1471
|
+
/** Quick lookup by name */
|
|
1472
|
+
__publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1473
|
+
/** Cached ordered names (invalidated on changes) */
|
|
1474
|
+
__publicField$1(this, "orderedNamesCache", null);
|
|
1475
|
+
this.initializeDefaultPhases();
|
|
1476
|
+
}
|
|
1477
|
+
//* Initialization --------------------------------
|
|
1478
|
+
initializeDefaultPhases() {
|
|
1479
|
+
for (const name of DEFAULT_PHASES) {
|
|
1480
|
+
const node = { name, isAutoGenerated: false };
|
|
1481
|
+
this.phases.push(node);
|
|
1482
|
+
this.phaseMap.set(name, node);
|
|
1345
1483
|
}
|
|
1346
1484
|
this.invalidateCache();
|
|
1347
1485
|
}
|
|
@@ -1360,8 +1498,9 @@ class PhaseGraph {
|
|
|
1360
1498
|
const node = { name, isAutoGenerated: false };
|
|
1361
1499
|
let insertIndex = this.phases.length;
|
|
1362
1500
|
const targetIndex = this.getPhaseIndex(before ?? after);
|
|
1363
|
-
if (targetIndex !== -1)
|
|
1364
|
-
|
|
1501
|
+
if (targetIndex !== -1) {
|
|
1502
|
+
insertIndex = before ? targetIndex : targetIndex + 1;
|
|
1503
|
+
} else {
|
|
1365
1504
|
const constraintType = before ? "before" : "after";
|
|
1366
1505
|
console.warn(`[useFrame] Phase "${before ?? after}" not found for '${constraintType}' constraint`);
|
|
1367
1506
|
}
|
|
@@ -2226,132 +2365,445 @@ const _Scheduler = class _Scheduler {
|
|
|
2226
2365
|
console.error(`[Scheduler] Error in global job "${job.id}":`, error);
|
|
2227
2366
|
}
|
|
2228
2367
|
}
|
|
2229
|
-
}
|
|
2230
|
-
/**
|
|
2231
|
-
* Execute all jobs for a single root in sorted order.
|
|
2232
|
-
* Rebuilds sorted job list if needed, then dispatches each job.
|
|
2233
|
-
* Errors are caught and propagated via triggerError.
|
|
2234
|
-
* @param {RootEntry} root - The root entry to tick
|
|
2235
|
-
* @param {number} timestamp - RAF timestamp in milliseconds
|
|
2236
|
-
* @param {number} delta - Time since last frame in seconds
|
|
2237
|
-
* @returns {void}
|
|
2238
|
-
* @private
|
|
2239
|
-
*/
|
|
2240
|
-
tickRoot(root, timestamp, delta) {
|
|
2241
|
-
if (root.needsRebuild) {
|
|
2242
|
-
root.sortedJobs = rebuildSortedJobs(root.jobs, this.phaseGraph);
|
|
2243
|
-
root.needsRebuild = false;
|
|
2244
|
-
}
|
|
2245
|
-
const providedState = root.getState?.() ?? {};
|
|
2246
|
-
const frameState = {
|
|
2247
|
-
...providedState,
|
|
2248
|
-
time: timestamp,
|
|
2249
|
-
delta,
|
|
2250
|
-
elapsed: this.loopState.elapsedTime / 1e3,
|
|
2251
|
-
// Convert ms to seconds
|
|
2252
|
-
frame: this.loopState.frameCount
|
|
2253
|
-
};
|
|
2254
|
-
for (const job of root.sortedJobs) {
|
|
2255
|
-
if (!shouldRun(job, timestamp)) continue;
|
|
2256
|
-
try {
|
|
2257
|
-
job.callback(frameState, delta);
|
|
2258
|
-
} catch (error) {
|
|
2259
|
-
console.error(`[Scheduler] Error in job "${job.id}":`, error);
|
|
2260
|
-
this.triggerError(error instanceof Error ? error : new Error(String(error)));
|
|
2368
|
+
}
|
|
2369
|
+
/**
|
|
2370
|
+
* Execute all jobs for a single root in sorted order.
|
|
2371
|
+
* Rebuilds sorted job list if needed, then dispatches each job.
|
|
2372
|
+
* Errors are caught and propagated via triggerError.
|
|
2373
|
+
* @param {RootEntry} root - The root entry to tick
|
|
2374
|
+
* @param {number} timestamp - RAF timestamp in milliseconds
|
|
2375
|
+
* @param {number} delta - Time since last frame in seconds
|
|
2376
|
+
* @returns {void}
|
|
2377
|
+
* @private
|
|
2378
|
+
*/
|
|
2379
|
+
tickRoot(root, timestamp, delta) {
|
|
2380
|
+
if (root.needsRebuild) {
|
|
2381
|
+
root.sortedJobs = rebuildSortedJobs(root.jobs, this.phaseGraph);
|
|
2382
|
+
root.needsRebuild = false;
|
|
2383
|
+
}
|
|
2384
|
+
const providedState = root.getState?.() ?? {};
|
|
2385
|
+
const frameState = {
|
|
2386
|
+
...providedState,
|
|
2387
|
+
time: timestamp,
|
|
2388
|
+
delta,
|
|
2389
|
+
elapsed: this.loopState.elapsedTime / 1e3,
|
|
2390
|
+
// Convert ms to seconds
|
|
2391
|
+
frame: this.loopState.frameCount
|
|
2392
|
+
};
|
|
2393
|
+
for (const job of root.sortedJobs) {
|
|
2394
|
+
if (!shouldRun(job, timestamp)) continue;
|
|
2395
|
+
try {
|
|
2396
|
+
job.callback(frameState, delta);
|
|
2397
|
+
} catch (error) {
|
|
2398
|
+
console.error(`[Scheduler] Error in job "${job.id}":`, error);
|
|
2399
|
+
this.triggerError(error instanceof Error ? error : new Error(String(error)));
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
//* Debug & Inspection Methods ================================
|
|
2404
|
+
/**
|
|
2405
|
+
* Get the total number of registered jobs across all roots.
|
|
2406
|
+
* Includes both per-root jobs and global before/after jobs.
|
|
2407
|
+
* @returns {number} Total job count
|
|
2408
|
+
*/
|
|
2409
|
+
getJobCount() {
|
|
2410
|
+
let count = 0;
|
|
2411
|
+
for (const root of this.roots.values()) {
|
|
2412
|
+
count += root.jobs.size;
|
|
2413
|
+
}
|
|
2414
|
+
return count + this.globalBeforeJobs.size + this.globalAfterJobs.size;
|
|
2415
|
+
}
|
|
2416
|
+
/**
|
|
2417
|
+
* Get all registered job IDs across all roots.
|
|
2418
|
+
* Includes both per-root jobs and global before/after jobs.
|
|
2419
|
+
* @returns {string[]} Array of all job IDs
|
|
2420
|
+
*/
|
|
2421
|
+
getJobIds() {
|
|
2422
|
+
const ids = [];
|
|
2423
|
+
for (const root of this.roots.values()) {
|
|
2424
|
+
ids.push(...root.jobs.keys());
|
|
2425
|
+
}
|
|
2426
|
+
ids.push(...this.globalBeforeJobs.keys());
|
|
2427
|
+
ids.push(...this.globalAfterJobs.keys());
|
|
2428
|
+
return ids;
|
|
2429
|
+
}
|
|
2430
|
+
/**
|
|
2431
|
+
* Get the number of registered roots (Canvas instances).
|
|
2432
|
+
* @returns {number} Number of registered roots
|
|
2433
|
+
*/
|
|
2434
|
+
getRootCount() {
|
|
2435
|
+
return this.roots.size;
|
|
2436
|
+
}
|
|
2437
|
+
/**
|
|
2438
|
+
* Check if any user (non-system) jobs are registered in a specific phase.
|
|
2439
|
+
* Used by the default render job to know if a user has taken over rendering.
|
|
2440
|
+
*
|
|
2441
|
+
* @param phase The phase to check
|
|
2442
|
+
* @param rootId Optional root ID to check (checks all roots if not provided)
|
|
2443
|
+
* @returns true if any user jobs exist in the phase
|
|
2444
|
+
*/
|
|
2445
|
+
hasUserJobsInPhase(phase, rootId) {
|
|
2446
|
+
const rootsToCheck = rootId ? [this.roots.get(rootId)].filter(Boolean) : Array.from(this.roots.values());
|
|
2447
|
+
return rootsToCheck.some((root) => {
|
|
2448
|
+
if (!root) return false;
|
|
2449
|
+
for (const job of root.jobs.values()) {
|
|
2450
|
+
if (job.phase === phase && !job.system && job.enabled) return true;
|
|
2451
|
+
}
|
|
2452
|
+
return false;
|
|
2453
|
+
});
|
|
2454
|
+
}
|
|
2455
|
+
//* Utility Methods ================================
|
|
2456
|
+
/**
|
|
2457
|
+
* Generate a unique root ID for automatic root registration.
|
|
2458
|
+
* @returns {string} A unique root ID in the format 'root_N'
|
|
2459
|
+
*/
|
|
2460
|
+
generateRootId() {
|
|
2461
|
+
return `root_${this.nextRootIndex++}`;
|
|
2462
|
+
}
|
|
2463
|
+
/**
|
|
2464
|
+
* Generate a unique job ID.
|
|
2465
|
+
* @returns {string} A unique job ID in the format 'job_N'
|
|
2466
|
+
* @private
|
|
2467
|
+
*/
|
|
2468
|
+
generateJobId() {
|
|
2469
|
+
return `job_${this.nextJobIndex}`;
|
|
2470
|
+
}
|
|
2471
|
+
/**
|
|
2472
|
+
* Normalize before/after constraints to a Set.
|
|
2473
|
+
* Handles undefined, single string, or array inputs.
|
|
2474
|
+
* @param {string | string[] | undefined} value - The constraint value(s)
|
|
2475
|
+
* @returns {Set<string>} Normalized Set of constraint strings
|
|
2476
|
+
* @private
|
|
2477
|
+
*/
|
|
2478
|
+
normalizeConstraints(value) {
|
|
2479
|
+
if (!value) return /* @__PURE__ */ new Set();
|
|
2480
|
+
if (Array.isArray(value)) return new Set(value);
|
|
2481
|
+
return /* @__PURE__ */ new Set([value]);
|
|
2482
|
+
}
|
|
2483
|
+
};
|
|
2484
|
+
//* Static State & Methods (Singleton Usage) ================================
|
|
2485
|
+
//* Cross-Bundle Singleton Key ==============================
|
|
2486
|
+
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2487
|
+
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2488
|
+
__publicField(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2489
|
+
let Scheduler = _Scheduler;
|
|
2490
|
+
const getScheduler = () => Scheduler.get();
|
|
2491
|
+
if (hmrData) {
|
|
2492
|
+
hmrData.accept?.();
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2495
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
2496
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React__namespace.createContext(null));
|
|
2497
|
+
const createStore = (invalidate, advance) => {
|
|
2498
|
+
const rootStore = traditional.createWithEqualityFn((set, get) => {
|
|
2499
|
+
const position = new three.Vector3();
|
|
2500
|
+
const defaultTarget = new three.Vector3();
|
|
2501
|
+
const tempTarget = new three.Vector3();
|
|
2502
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
2503
|
+
const { width, height, top, left } = size;
|
|
2504
|
+
const aspect = width / height;
|
|
2505
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
2506
|
+
else tempTarget.set(...target);
|
|
2507
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
2508
|
+
if (isOrthographicCamera(camera)) {
|
|
2509
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
2510
|
+
} else {
|
|
2511
|
+
const fov = camera.fov * Math.PI / 180;
|
|
2512
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
2513
|
+
const w = h * (width / height);
|
|
2514
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
let performanceTimeout = void 0;
|
|
2518
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
2519
|
+
const pointer = new three.Vector2();
|
|
2520
|
+
const rootState = {
|
|
2521
|
+
set,
|
|
2522
|
+
get,
|
|
2523
|
+
// Mock objects that have to be configured
|
|
2524
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
2525
|
+
primaryStore: null,
|
|
2526
|
+
gl: null,
|
|
2527
|
+
renderer: null,
|
|
2528
|
+
camera: null,
|
|
2529
|
+
frustum: new three.Frustum(),
|
|
2530
|
+
autoUpdateFrustum: true,
|
|
2531
|
+
raycaster: null,
|
|
2532
|
+
events: { priority: 1, enabled: true, connected: false },
|
|
2533
|
+
scene: null,
|
|
2534
|
+
rootScene: null,
|
|
2535
|
+
xr: null,
|
|
2536
|
+
inspector: null,
|
|
2537
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
2538
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
2539
|
+
textureColorSpace: three.SRGBColorSpace,
|
|
2540
|
+
isLegacy: false,
|
|
2541
|
+
webGPUSupported: false,
|
|
2542
|
+
isNative: false,
|
|
2543
|
+
controls: null,
|
|
2544
|
+
pointer,
|
|
2545
|
+
mouse: pointer,
|
|
2546
|
+
frameloop: "always",
|
|
2547
|
+
onPointerMissed: void 0,
|
|
2548
|
+
onDragOverMissed: void 0,
|
|
2549
|
+
onDropMissed: void 0,
|
|
2550
|
+
performance: {
|
|
2551
|
+
current: 1,
|
|
2552
|
+
min: 0.5,
|
|
2553
|
+
max: 1,
|
|
2554
|
+
debounce: 200,
|
|
2555
|
+
regress: () => {
|
|
2556
|
+
const state2 = get();
|
|
2557
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
2558
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
2559
|
+
performanceTimeout = setTimeout(
|
|
2560
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
2561
|
+
state2.performance.debounce
|
|
2562
|
+
);
|
|
2563
|
+
}
|
|
2564
|
+
},
|
|
2565
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
2566
|
+
viewport: {
|
|
2567
|
+
initialDpr: 0,
|
|
2568
|
+
dpr: 0,
|
|
2569
|
+
width: 0,
|
|
2570
|
+
height: 0,
|
|
2571
|
+
top: 0,
|
|
2572
|
+
left: 0,
|
|
2573
|
+
aspect: 0,
|
|
2574
|
+
distance: 0,
|
|
2575
|
+
factor: 0,
|
|
2576
|
+
getCurrentViewport
|
|
2577
|
+
},
|
|
2578
|
+
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
2579
|
+
setSize: (width, height, top, left) => {
|
|
2580
|
+
const state2 = get();
|
|
2581
|
+
if (width === void 0) {
|
|
2582
|
+
set({ _sizeImperative: false });
|
|
2583
|
+
if (state2._sizeProps) {
|
|
2584
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
2585
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
2586
|
+
const currentSize = state2.size;
|
|
2587
|
+
const newSize = {
|
|
2588
|
+
width: propW ?? currentSize.width,
|
|
2589
|
+
height: propH ?? currentSize.height,
|
|
2590
|
+
top: currentSize.top,
|
|
2591
|
+
left: currentSize.left
|
|
2592
|
+
};
|
|
2593
|
+
set((s) => ({
|
|
2594
|
+
size: newSize,
|
|
2595
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
2596
|
+
}));
|
|
2597
|
+
getScheduler().invalidate();
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
return;
|
|
2601
|
+
}
|
|
2602
|
+
const w = width;
|
|
2603
|
+
const h = height ?? width;
|
|
2604
|
+
const t = top ?? state2.size.top;
|
|
2605
|
+
const l = left ?? state2.size.left;
|
|
2606
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
2607
|
+
set((s) => ({
|
|
2608
|
+
size,
|
|
2609
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
2610
|
+
_sizeImperative: true
|
|
2611
|
+
}));
|
|
2612
|
+
getScheduler().invalidate();
|
|
2613
|
+
},
|
|
2614
|
+
setDpr: (dpr) => set((state2) => {
|
|
2615
|
+
const resolved = calculateDpr(dpr);
|
|
2616
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
2617
|
+
}),
|
|
2618
|
+
setFrameloop: (frameloop = "always") => {
|
|
2619
|
+
set(() => ({ frameloop }));
|
|
2620
|
+
},
|
|
2621
|
+
setError: (error) => set(() => ({ error })),
|
|
2622
|
+
error: null,
|
|
2623
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
|
|
2624
|
+
uniforms: {},
|
|
2625
|
+
nodes: {},
|
|
2626
|
+
textures: /* @__PURE__ */ new Map(),
|
|
2627
|
+
postProcessing: null,
|
|
2628
|
+
passes: {},
|
|
2629
|
+
_hmrVersion: 0,
|
|
2630
|
+
_sizeImperative: false,
|
|
2631
|
+
_sizeProps: null,
|
|
2632
|
+
previousRoot: void 0,
|
|
2633
|
+
internal: {
|
|
2634
|
+
// Events
|
|
2635
|
+
interaction: [],
|
|
2636
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
2637
|
+
subscribers: [],
|
|
2638
|
+
initialClick: [0, 0],
|
|
2639
|
+
initialHits: [],
|
|
2640
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
2641
|
+
lastEvent: React__namespace.createRef(),
|
|
2642
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
2643
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
2644
|
+
// Occlusion system (WebGPU only)
|
|
2645
|
+
occlusionEnabled: false,
|
|
2646
|
+
occlusionObserver: null,
|
|
2647
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
2648
|
+
helperGroup: null,
|
|
2649
|
+
// Updates
|
|
2650
|
+
active: false,
|
|
2651
|
+
frames: 0,
|
|
2652
|
+
priority: 0,
|
|
2653
|
+
subscribe: (ref, priority, store) => {
|
|
2654
|
+
const internal = get().internal;
|
|
2655
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
2656
|
+
internal.subscribers.push({ ref, priority, store });
|
|
2657
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
2658
|
+
return () => {
|
|
2659
|
+
const internal2 = get().internal;
|
|
2660
|
+
if (internal2?.subscribers) {
|
|
2661
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
2662
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
2663
|
+
}
|
|
2664
|
+
};
|
|
2665
|
+
},
|
|
2666
|
+
// Renderer Storage (single source of truth)
|
|
2667
|
+
actualRenderer: null,
|
|
2668
|
+
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
2669
|
+
scheduler: null
|
|
2670
|
+
}
|
|
2671
|
+
};
|
|
2672
|
+
return rootState;
|
|
2673
|
+
});
|
|
2674
|
+
const state = rootStore.getState();
|
|
2675
|
+
Object.defineProperty(state, "gl", {
|
|
2676
|
+
get() {
|
|
2677
|
+
const currentState = rootStore.getState();
|
|
2678
|
+
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
2679
|
+
const stack = new Error().stack || "";
|
|
2680
|
+
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
2681
|
+
if (!isInternalAccess) {
|
|
2682
|
+
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
2683
|
+
notifyDepreciated({
|
|
2684
|
+
heading: "Accessing state.gl in WebGPU mode",
|
|
2685
|
+
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
|
|
2686
|
+
});
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
return currentState.internal.actualRenderer;
|
|
2690
|
+
},
|
|
2691
|
+
set(value) {
|
|
2692
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2693
|
+
},
|
|
2694
|
+
enumerable: true,
|
|
2695
|
+
configurable: true
|
|
2696
|
+
});
|
|
2697
|
+
Object.defineProperty(state, "renderer", {
|
|
2698
|
+
get() {
|
|
2699
|
+
return rootStore.getState().internal.actualRenderer;
|
|
2700
|
+
},
|
|
2701
|
+
set(value) {
|
|
2702
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2703
|
+
},
|
|
2704
|
+
enumerable: true,
|
|
2705
|
+
configurable: true
|
|
2706
|
+
});
|
|
2707
|
+
let oldScene = state.scene;
|
|
2708
|
+
rootStore.subscribe(() => {
|
|
2709
|
+
const currentState = rootStore.getState();
|
|
2710
|
+
const { scene, rootScene, set } = currentState;
|
|
2711
|
+
if (scene !== oldScene) {
|
|
2712
|
+
oldScene = scene;
|
|
2713
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
2714
|
+
set({ rootScene: scene });
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
});
|
|
2718
|
+
let oldSize = state.size;
|
|
2719
|
+
let oldDpr = state.viewport.dpr;
|
|
2720
|
+
let oldCamera = state.camera;
|
|
2721
|
+
rootStore.subscribe(() => {
|
|
2722
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
2723
|
+
const actualRenderer = internal.actualRenderer;
|
|
2724
|
+
const canvasTarget = internal.canvasTarget;
|
|
2725
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
2726
|
+
oldSize = size;
|
|
2727
|
+
oldDpr = viewport.dpr;
|
|
2728
|
+
updateCamera(camera, size);
|
|
2729
|
+
if (canvasTarget) {
|
|
2730
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2731
|
+
const updateStyle = typeof HTMLCanvasElement !== "undefined" && canvasTarget.domElement instanceof HTMLCanvasElement;
|
|
2732
|
+
canvasTarget.setSize(size.width, size.height, updateStyle);
|
|
2733
|
+
} else {
|
|
2734
|
+
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
2735
|
+
const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
|
|
2736
|
+
actualRenderer.setSize(size.width, size.height, updateStyle);
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
if (camera !== oldCamera) {
|
|
2740
|
+
oldCamera = camera;
|
|
2741
|
+
const { rootScene } = rootStore.getState();
|
|
2742
|
+
if (camera && rootScene && !camera.parent) {
|
|
2743
|
+
rootScene.add(camera);
|
|
2744
|
+
}
|
|
2745
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
2746
|
+
const currentState = rootStore.getState();
|
|
2747
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
2748
|
+
updateFrustum(camera, currentState.frustum);
|
|
2261
2749
|
}
|
|
2262
2750
|
}
|
|
2263
|
-
}
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2751
|
+
});
|
|
2752
|
+
rootStore.subscribe((state2) => invalidate(state2));
|
|
2753
|
+
return rootStore;
|
|
2754
|
+
};
|
|
2755
|
+
|
|
2756
|
+
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
2757
|
+
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
2758
|
+
function getLoader(Proto) {
|
|
2759
|
+
if (isConstructor$1(Proto)) {
|
|
2760
|
+
let loader = memoizedLoaders.get(Proto);
|
|
2761
|
+
if (!loader) {
|
|
2762
|
+
loader = new Proto();
|
|
2763
|
+
memoizedLoaders.set(Proto, loader);
|
|
2274
2764
|
}
|
|
2275
|
-
return
|
|
2765
|
+
return loader;
|
|
2276
2766
|
}
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2767
|
+
return Proto;
|
|
2768
|
+
}
|
|
2769
|
+
function loadingFn(extensions, onProgress) {
|
|
2770
|
+
return function(Proto, input) {
|
|
2771
|
+
const loader = getLoader(Proto);
|
|
2772
|
+
if (extensions) extensions(loader);
|
|
2773
|
+
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
2774
|
+
return loader.loadAsync(input, onProgress).then((data) => {
|
|
2775
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2776
|
+
return data;
|
|
2777
|
+
});
|
|
2286
2778
|
}
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
*/
|
|
2306
|
-
hasUserJobsInPhase(phase, rootId) {
|
|
2307
|
-
const rootsToCheck = rootId ? [this.roots.get(rootId)].filter(Boolean) : Array.from(this.roots.values());
|
|
2308
|
-
return rootsToCheck.some((root) => {
|
|
2309
|
-
if (!root) return false;
|
|
2310
|
-
for (const job of root.jobs.values()) {
|
|
2311
|
-
if (job.phase === phase && !job.system && job.enabled) return true;
|
|
2312
|
-
}
|
|
2313
|
-
return false;
|
|
2314
|
-
});
|
|
2315
|
-
}
|
|
2316
|
-
//* Utility Methods ================================
|
|
2317
|
-
/**
|
|
2318
|
-
* Generate a unique root ID for automatic root registration.
|
|
2319
|
-
* @returns {string} A unique root ID in the format 'root_N'
|
|
2320
|
-
*/
|
|
2321
|
-
generateRootId() {
|
|
2322
|
-
return `root_${this.nextRootIndex++}`;
|
|
2323
|
-
}
|
|
2324
|
-
/**
|
|
2325
|
-
* Generate a unique job ID.
|
|
2326
|
-
* @returns {string} A unique job ID in the format 'job_N'
|
|
2327
|
-
* @private
|
|
2328
|
-
*/
|
|
2329
|
-
generateJobId() {
|
|
2330
|
-
return `job_${this.nextJobIndex}`;
|
|
2331
|
-
}
|
|
2332
|
-
/**
|
|
2333
|
-
* Normalize before/after constraints to a Set.
|
|
2334
|
-
* Handles undefined, single string, or array inputs.
|
|
2335
|
-
* @param {string | string[] | undefined} value - The constraint value(s)
|
|
2336
|
-
* @returns {Set<string>} Normalized Set of constraint strings
|
|
2337
|
-
* @private
|
|
2338
|
-
*/
|
|
2339
|
-
normalizeConstraints(value) {
|
|
2340
|
-
if (!value) return /* @__PURE__ */ new Set();
|
|
2341
|
-
if (Array.isArray(value)) return new Set(value);
|
|
2342
|
-
return /* @__PURE__ */ new Set([value]);
|
|
2343
|
-
}
|
|
2344
|
-
};
|
|
2345
|
-
//* Static State & Methods (Singleton Usage) ================================
|
|
2346
|
-
//* Cross-Bundle Singleton Key ==============================
|
|
2347
|
-
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2348
|
-
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2349
|
-
__publicField(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2350
|
-
let Scheduler = _Scheduler;
|
|
2351
|
-
const getScheduler = () => Scheduler.get();
|
|
2352
|
-
if (hmrData) {
|
|
2353
|
-
hmrData.accept?.();
|
|
2779
|
+
return new Promise(
|
|
2780
|
+
(res, reject) => loader.load(
|
|
2781
|
+
input,
|
|
2782
|
+
(data) => {
|
|
2783
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2784
|
+
res(data);
|
|
2785
|
+
},
|
|
2786
|
+
onProgress,
|
|
2787
|
+
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
2788
|
+
)
|
|
2789
|
+
);
|
|
2790
|
+
};
|
|
2791
|
+
}
|
|
2792
|
+
function useLoader(loader, input, extensions, onProgress) {
|
|
2793
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2794
|
+
const fn = loadingFn(extensions, onProgress);
|
|
2795
|
+
const results = keys.map((key) => suspendReact.suspend(fn, [loader, key], { equal: is.equ }));
|
|
2796
|
+
return Array.isArray(input) ? results : results[0];
|
|
2354
2797
|
}
|
|
2798
|
+
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
2799
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2800
|
+
keys.forEach((key) => suspendReact.preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
2801
|
+
};
|
|
2802
|
+
useLoader.clear = function(loader, input) {
|
|
2803
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2804
|
+
keys.forEach((key) => suspendReact.clear([loader, key]));
|
|
2805
|
+
};
|
|
2806
|
+
useLoader.loader = getLoader;
|
|
2355
2807
|
|
|
2356
2808
|
function useFrame(callback, priorityOrOptions) {
|
|
2357
2809
|
const store = React__namespace.useContext(context);
|
|
@@ -2532,6 +2984,9 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2532
2984
|
const textureCache = useThree((state) => state.textures);
|
|
2533
2985
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
2534
2986
|
const { onLoad, cache = false } = options;
|
|
2987
|
+
const onLoadRef = React.useRef(onLoad);
|
|
2988
|
+
onLoadRef.current = onLoad;
|
|
2989
|
+
const onLoadCalledForRef = React.useRef(null);
|
|
2535
2990
|
const urls = React.useMemo(() => getUrls(input), [input]);
|
|
2536
2991
|
const cachedResult = React.useMemo(() => {
|
|
2537
2992
|
if (!cache) return null;
|
|
@@ -2542,9 +2997,13 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2542
2997
|
three.TextureLoader,
|
|
2543
2998
|
IsObject(input) ? Object.values(input) : input
|
|
2544
2999
|
);
|
|
3000
|
+
const inputKey = urls.join("\0");
|
|
2545
3001
|
React.useLayoutEffect(() => {
|
|
2546
|
-
if (
|
|
2547
|
-
|
|
3002
|
+
if (cachedResult) return;
|
|
3003
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
3004
|
+
onLoadCalledForRef.current = inputKey;
|
|
3005
|
+
onLoadRef.current?.(loadedTextures);
|
|
3006
|
+
}, [cachedResult, loadedTextures, inputKey]);
|
|
2548
3007
|
React.useEffect(() => {
|
|
2549
3008
|
if (cachedResult) return;
|
|
2550
3009
|
if ("initTexture" in renderer) {
|
|
@@ -2711,14 +3170,31 @@ function useTextures() {
|
|
|
2711
3170
|
}, [store]);
|
|
2712
3171
|
}
|
|
2713
3172
|
|
|
2714
|
-
function useRenderTarget(
|
|
3173
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
2715
3174
|
const isLegacy = useThree((s) => s.isLegacy);
|
|
2716
3175
|
const size = useThree((s) => s.size);
|
|
3176
|
+
let width;
|
|
3177
|
+
let height;
|
|
3178
|
+
let opts;
|
|
3179
|
+
if (typeof widthOrOptions === "object") {
|
|
3180
|
+
opts = widthOrOptions;
|
|
3181
|
+
} else if (typeof widthOrOptions === "number") {
|
|
3182
|
+
width = widthOrOptions;
|
|
3183
|
+
if (typeof heightOrOptions === "object") {
|
|
3184
|
+
height = widthOrOptions;
|
|
3185
|
+
opts = heightOrOptions;
|
|
3186
|
+
} else if (typeof heightOrOptions === "number") {
|
|
3187
|
+
height = heightOrOptions;
|
|
3188
|
+
opts = options;
|
|
3189
|
+
} else {
|
|
3190
|
+
height = widthOrOptions;
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
2717
3193
|
return React.useMemo(() => {
|
|
2718
3194
|
const w = width ?? size.width;
|
|
2719
3195
|
const h = height ?? size.height;
|
|
2720
|
-
return new three.WebGLRenderTarget(w, h,
|
|
2721
|
-
}, [width, height, size.width, size.height,
|
|
3196
|
+
return new three.WebGLRenderTarget(w, h, opts);
|
|
3197
|
+
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
2722
3198
|
}
|
|
2723
3199
|
|
|
2724
3200
|
function useStore() {
|
|
@@ -2768,28 +3244,18 @@ function addTail(callback) {
|
|
|
2768
3244
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
2769
3245
|
getScheduler().invalidate(frames, stackFrames);
|
|
2770
3246
|
}
|
|
2771
|
-
function advance(timestamp
|
|
3247
|
+
function advance(timestamp) {
|
|
2772
3248
|
getScheduler().step(timestamp);
|
|
2773
3249
|
}
|
|
2774
3250
|
|
|
2775
|
-
const version = "10.0.0-alpha.
|
|
3251
|
+
const version = "10.0.0-alpha.2";
|
|
2776
3252
|
const packageData = {
|
|
2777
3253
|
version: version};
|
|
2778
3254
|
|
|
2779
3255
|
function Xb(Tt) {
|
|
2780
3256
|
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
2781
3257
|
}
|
|
2782
|
-
var Rm = { exports: {} }, Og = { exports: {} };
|
|
2783
|
-
/**
|
|
2784
|
-
* @license React
|
|
2785
|
-
* react-reconciler.production.js
|
|
2786
|
-
*
|
|
2787
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2788
|
-
*
|
|
2789
|
-
* This source code is licensed under the MIT license found in the
|
|
2790
|
-
* LICENSE file in the root directory of this source tree.
|
|
2791
|
-
*/
|
|
2792
|
-
var _b;
|
|
3258
|
+
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
2793
3259
|
function Kb() {
|
|
2794
3260
|
return _b || (_b = 1, (function(Tt) {
|
|
2795
3261
|
Tt.exports = function(m) {
|
|
@@ -3861,7 +4327,6 @@ Error generating stack: ` + l.message + `
|
|
|
3861
4327
|
if (J === cl || J === jc) throw J;
|
|
3862
4328
|
var Ge = Yn(29, J, null, P.mode);
|
|
3863
4329
|
return Ge.lanes = H, Ge.return = P, Ge;
|
|
3864
|
-
} finally {
|
|
3865
4330
|
}
|
|
3866
4331
|
};
|
|
3867
4332
|
}
|
|
@@ -4515,7 +4980,6 @@ Error generating stack: ` + l.message + `
|
|
|
4515
4980
|
var h = r.lastRenderedState, y = d(h, a);
|
|
4516
4981
|
if (c.hasEagerState = true, c.eagerState = y, jn(y, h)) return go(t, r, c, 0), Ne === null && Bn(), false;
|
|
4517
4982
|
} catch {
|
|
4518
|
-
} finally {
|
|
4519
4983
|
}
|
|
4520
4984
|
if (a = yo(t, r, c, l), a !== null) return nt(a, t, l), ns(a, r, l), true;
|
|
4521
4985
|
}
|
|
@@ -6936,10 +7400,7 @@ Error generating stack: ` + l.message + `
|
|
|
6936
7400
|
function vr(t, r) {
|
|
6937
7401
|
Sf(t, r), (t = t.alternate) && Sf(t, r);
|
|
6938
7402
|
}
|
|
6939
|
-
var ie = {}, Fm = React__default, tt = Tb__default, 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");
|
|
6940
|
-
var gc = Symbol.for("react.activity");
|
|
6941
|
-
var $r = Symbol.for("react.memo_cache_sentinel");
|
|
6942
|
-
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;
|
|
7403
|
+
var ie = {}, Fm = React__default, tt = Tb__default, 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;
|
|
6943
7404
|
m.cloneMutableInstance;
|
|
6944
7405
|
var yc = m.appendInitialChild, Kp = m.finalizeInitialChildren, Rs = m.shouldSetTextContent, bc = m.createTextInstance;
|
|
6945
7406
|
m.cloneMutableTextInstance;
|
|
@@ -7308,17 +7769,7 @@ No matching component was found for:
|
|
|
7308
7769
|
}, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true });
|
|
7309
7770
|
})(Og)), Og.exports;
|
|
7310
7771
|
}
|
|
7311
|
-
var Mg = { exports: {} };
|
|
7312
|
-
/**
|
|
7313
|
-
* @license React
|
|
7314
|
-
* react-reconciler.development.js
|
|
7315
|
-
*
|
|
7316
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
7317
|
-
*
|
|
7318
|
-
* This source code is licensed under the MIT license found in the
|
|
7319
|
-
* LICENSE file in the root directory of this source tree.
|
|
7320
|
-
*/
|
|
7321
|
-
var Rb;
|
|
7772
|
+
var Mg = { exports: {} }, Rb;
|
|
7322
7773
|
function e0() {
|
|
7323
7774
|
return Rb || (Rb = 1, (function(Tt) {
|
|
7324
7775
|
process.env.NODE_ENV !== "production" && (Tt.exports = function(m) {
|
|
@@ -13085,10 +13536,7 @@ Check the render method of %s.`, G(di) || "Unknown")), i = zo(n), i.payload = {
|
|
|
13085
13536
|
function Ic() {
|
|
13086
13537
|
return di;
|
|
13087
13538
|
}
|
|
13088
|
-
var le = {}, qm = React__default, St = Tb__default, 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");
|
|
13089
|
-
var Ds = Symbol.for("react.activity");
|
|
13090
|
-
var Bh = Symbol.for("react.memo_cache_sentinel");
|
|
13091
|
-
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;
|
|
13539
|
+
var le = {}, qm = React__default, St = Tb__default, 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;
|
|
13092
13540
|
m.cloneMutableInstance;
|
|
13093
13541
|
var bn = m.appendInitialChild, Ue = m.finalizeInitialChildren, ue = m.shouldSetTextContent, Do = m.createTextInstance;
|
|
13094
13542
|
m.cloneMutableTextInstance;
|
|
@@ -14056,15 +14504,6 @@ function n0() {
|
|
|
14056
14504
|
var t0 = n0();
|
|
14057
14505
|
const r0 = Xb(t0);
|
|
14058
14506
|
|
|
14059
|
-
/**
|
|
14060
|
-
* @license React
|
|
14061
|
-
* react-reconciler-constants.production.js
|
|
14062
|
-
*
|
|
14063
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14064
|
-
*
|
|
14065
|
-
* This source code is licensed under the MIT license found in the
|
|
14066
|
-
* LICENSE file in the root directory of this source tree.
|
|
14067
|
-
*/
|
|
14068
14507
|
const t = 1, o = 8, r = 32, e = 2;
|
|
14069
14508
|
|
|
14070
14509
|
function createReconciler(config) {
|
|
@@ -14091,10 +14530,11 @@ function extend(objects) {
|
|
|
14091
14530
|
function validateInstance(type, props) {
|
|
14092
14531
|
const name = toPascalCase(type);
|
|
14093
14532
|
const target = catalogue[name];
|
|
14094
|
-
if (type !== "primitive" && !target)
|
|
14533
|
+
if (type !== "primitive" && !target) {
|
|
14095
14534
|
throw new Error(
|
|
14096
14535
|
`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`
|
|
14097
14536
|
);
|
|
14537
|
+
}
|
|
14098
14538
|
if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
|
|
14099
14539
|
if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
|
|
14100
14540
|
}
|
|
@@ -14258,6 +14698,7 @@ function swapInstances() {
|
|
|
14258
14698
|
instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
|
|
14259
14699
|
instance.object.__r3f = instance;
|
|
14260
14700
|
setFiberRef(fiber, instance.object);
|
|
14701
|
+
delete instance.appliedOnce;
|
|
14261
14702
|
applyProps(instance.object, instance.props);
|
|
14262
14703
|
if (instance.props.attach) {
|
|
14263
14704
|
attach(parent, instance);
|
|
@@ -14331,8 +14772,22 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14331
14772
|
const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
|
|
14332
14773
|
if (isTailSibling) swapInstances();
|
|
14333
14774
|
},
|
|
14334
|
-
finalizeInitialChildren: () =>
|
|
14335
|
-
|
|
14775
|
+
finalizeInitialChildren: (instance) => {
|
|
14776
|
+
for (const prop in instance.props) {
|
|
14777
|
+
if (isFromRef(instance.props[prop])) return true;
|
|
14778
|
+
}
|
|
14779
|
+
return false;
|
|
14780
|
+
},
|
|
14781
|
+
commitMount(instance) {
|
|
14782
|
+
const resolved = {};
|
|
14783
|
+
for (const prop in instance.props) {
|
|
14784
|
+
const value = instance.props[prop];
|
|
14785
|
+
if (isFromRef(value)) {
|
|
14786
|
+
const ref = value[FROM_REF];
|
|
14787
|
+
if (ref.current != null) resolved[prop] = ref.current;
|
|
14788
|
+
}
|
|
14789
|
+
}
|
|
14790
|
+
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
14336
14791
|
},
|
|
14337
14792
|
getPublicInstance: (instance) => instance?.object,
|
|
14338
14793
|
prepareForCommit: () => null,
|
|
@@ -14545,14 +15000,17 @@ function createRoot(canvas) {
|
|
|
14545
15000
|
if (!prevRoot) _roots.set(canvas, { fiber, store });
|
|
14546
15001
|
let onCreated;
|
|
14547
15002
|
let lastCamera;
|
|
14548
|
-
|
|
15003
|
+
const lastConfiguredProps = {};
|
|
14549
15004
|
let configured = false;
|
|
14550
15005
|
let pending = null;
|
|
14551
15006
|
return {
|
|
14552
15007
|
async configure(props = {}) {
|
|
14553
15008
|
let resolve;
|
|
14554
15009
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14555
|
-
|
|
15010
|
+
const {
|
|
15011
|
+
id: canvasId,
|
|
15012
|
+
primaryCanvas,
|
|
15013
|
+
scheduler: schedulerConfig,
|
|
14556
15014
|
gl: glConfig,
|
|
14557
15015
|
renderer: rendererConfig,
|
|
14558
15016
|
size: propsSize,
|
|
@@ -14560,10 +15018,7 @@ function createRoot(canvas) {
|
|
|
14560
15018
|
events,
|
|
14561
15019
|
onCreated: onCreatedCallback,
|
|
14562
15020
|
shadows = false,
|
|
14563
|
-
linear = false,
|
|
14564
|
-
flat = false,
|
|
14565
15021
|
textureColorSpace = three.SRGBColorSpace,
|
|
14566
|
-
legacy = false,
|
|
14567
15022
|
orthographic = false,
|
|
14568
15023
|
frameloop = "always",
|
|
14569
15024
|
dpr = [1, 2],
|
|
@@ -14574,9 +15029,11 @@ function createRoot(canvas) {
|
|
|
14574
15029
|
onDragOverMissed,
|
|
14575
15030
|
onDropMissed,
|
|
14576
15031
|
autoUpdateFrustum = true,
|
|
14577
|
-
occlusion = false
|
|
15032
|
+
occlusion = false,
|
|
15033
|
+
_sizeProps,
|
|
15034
|
+
forceEven
|
|
14578
15035
|
} = props;
|
|
14579
|
-
|
|
15036
|
+
const state = store.getState();
|
|
14580
15037
|
const defaultGLProps = {
|
|
14581
15038
|
canvas,
|
|
14582
15039
|
powerPreference: "high-performance",
|
|
@@ -14588,22 +15045,34 @@ function createRoot(canvas) {
|
|
|
14588
15045
|
"WebGPURenderer (renderer prop) is not available in this build. Use @react-three/fiber or @react-three/fiber/webgpu instead."
|
|
14589
15046
|
);
|
|
14590
15047
|
}
|
|
14591
|
-
(state.isLegacy || glConfig || !R3F_BUILD_WEBGPU);
|
|
15048
|
+
const wantsGL = (state.isLegacy || glConfig || !R3F_BUILD_WEBGPU);
|
|
14592
15049
|
if (glConfig && rendererConfig) {
|
|
14593
15050
|
throw new Error("Cannot use both gl and renderer props at the same time");
|
|
14594
15051
|
}
|
|
14595
15052
|
let renderer = state.internal.actualRenderer;
|
|
15053
|
+
if (primaryCanvas && !R3F_BUILD_WEBGPU) {
|
|
15054
|
+
throw new Error(
|
|
15055
|
+
"The `primaryCanvas` prop for multi-canvas rendering is only available with WebGPU. Use @react-three/fiber/webgpu instead."
|
|
15056
|
+
);
|
|
15057
|
+
}
|
|
15058
|
+
if (primaryCanvas && wantsGL) {
|
|
15059
|
+
throw new Error(
|
|
15060
|
+
"The `primaryCanvas` prop for multi-canvas rendering cannot be used with WebGL. Remove the `gl` prop or use WebGPU."
|
|
15061
|
+
);
|
|
15062
|
+
}
|
|
14596
15063
|
if (!state.internal.actualRenderer) {
|
|
14597
15064
|
renderer = await resolveRenderer(glConfig, defaultGLProps, three.WebGLRenderer);
|
|
14598
15065
|
state.internal.actualRenderer = renderer;
|
|
14599
|
-
state.set({ isLegacy: true, gl: renderer, renderer });
|
|
15066
|
+
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
14600
15067
|
}
|
|
14601
15068
|
let raycaster = state.raycaster;
|
|
14602
15069
|
if (!raycaster) state.set({ raycaster: raycaster = new three.Raycaster() });
|
|
14603
15070
|
const { params, ...options } = raycastOptions || {};
|
|
14604
15071
|
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options });
|
|
14605
|
-
if (!is.equ(params, raycaster.params, shallowLoose))
|
|
15072
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) {
|
|
14606
15073
|
applyProps(raycaster, { params: { ...raycaster.params, ...params } });
|
|
15074
|
+
}
|
|
15075
|
+
let tempCamera = state.camera;
|
|
14607
15076
|
if (!state.camera || state.camera === lastCamera && !is.equ(lastCamera, cameraOptions, shallowLoose)) {
|
|
14608
15077
|
lastCamera = cameraOptions;
|
|
14609
15078
|
const isCamera = cameraOptions?.isCamera;
|
|
@@ -14623,6 +15092,7 @@ function createRoot(canvas) {
|
|
|
14623
15092
|
if (!state.camera && !cameraOptions?.rotation) camera.lookAt(0, 0, 0);
|
|
14624
15093
|
}
|
|
14625
15094
|
state.set({ camera });
|
|
15095
|
+
tempCamera = camera;
|
|
14626
15096
|
raycaster.camera = camera;
|
|
14627
15097
|
}
|
|
14628
15098
|
if (!state.scene) {
|
|
@@ -14640,7 +15110,7 @@ function createRoot(canvas) {
|
|
|
14640
15110
|
rootScene: scene,
|
|
14641
15111
|
internal: { ...prev.internal, container: scene }
|
|
14642
15112
|
}));
|
|
14643
|
-
const camera =
|
|
15113
|
+
const camera = tempCamera;
|
|
14644
15114
|
if (camera && !camera.parent) scene.add(camera);
|
|
14645
15115
|
}
|
|
14646
15116
|
if (events && !state.events.handlers) {
|
|
@@ -14654,9 +15124,17 @@ function createRoot(canvas) {
|
|
|
14654
15124
|
wasEnabled = enabled;
|
|
14655
15125
|
});
|
|
14656
15126
|
}
|
|
15127
|
+
if (_sizeProps !== void 0) {
|
|
15128
|
+
state.set({ _sizeProps });
|
|
15129
|
+
}
|
|
15130
|
+
if (forceEven !== void 0 && state.internal.forceEven !== forceEven) {
|
|
15131
|
+
state.set((prev) => ({ internal: { ...prev.internal, forceEven } }));
|
|
15132
|
+
}
|
|
14657
15133
|
const size = computeInitialSize(canvas, propsSize);
|
|
14658
|
-
if (!is.equ(size, state.size, shallowLoose)) {
|
|
15134
|
+
if (!state._sizeImperative && !is.equ(size, state.size, shallowLoose)) {
|
|
15135
|
+
const wasImperative = state._sizeImperative;
|
|
14659
15136
|
state.setSize(size.width, size.height, size.top, size.left);
|
|
15137
|
+
if (!wasImperative) state.set({ _sizeImperative: false });
|
|
14660
15138
|
}
|
|
14661
15139
|
if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
|
|
14662
15140
|
state.setDpr(dpr);
|
|
@@ -14681,7 +15159,7 @@ function createRoot(canvas) {
|
|
|
14681
15159
|
const handleXRFrame = (timestamp, frame) => {
|
|
14682
15160
|
const state2 = store.getState();
|
|
14683
15161
|
if (state2.frameloop === "never") return;
|
|
14684
|
-
advance(timestamp
|
|
15162
|
+
advance(timestamp);
|
|
14685
15163
|
};
|
|
14686
15164
|
const actualRenderer = state.internal.actualRenderer;
|
|
14687
15165
|
const handleSessionChange = () => {
|
|
@@ -14693,16 +15171,16 @@ function createRoot(canvas) {
|
|
|
14693
15171
|
};
|
|
14694
15172
|
const xr = {
|
|
14695
15173
|
connect() {
|
|
14696
|
-
const { gl, renderer: renderer2
|
|
14697
|
-
const
|
|
14698
|
-
|
|
14699
|
-
|
|
15174
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15175
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15176
|
+
xrManager.addEventListener("sessionstart", handleSessionChange);
|
|
15177
|
+
xrManager.addEventListener("sessionend", handleSessionChange);
|
|
14700
15178
|
},
|
|
14701
15179
|
disconnect() {
|
|
14702
|
-
const { gl, renderer: renderer2
|
|
14703
|
-
const
|
|
14704
|
-
|
|
14705
|
-
|
|
15180
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15181
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15182
|
+
xrManager.removeEventListener("sessionstart", handleSessionChange);
|
|
15183
|
+
xrManager.removeEventListener("sessionend", handleSessionChange);
|
|
14706
15184
|
}
|
|
14707
15185
|
};
|
|
14708
15186
|
if (typeof renderer.xr?.addEventListener === "function") xr.connect();
|
|
@@ -14726,35 +15204,21 @@ function createRoot(canvas) {
|
|
|
14726
15204
|
} else if (is.obj(shadows)) {
|
|
14727
15205
|
Object.assign(renderer.shadowMap, shadows);
|
|
14728
15206
|
}
|
|
14729
|
-
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type)
|
|
15207
|
+
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type) {
|
|
14730
15208
|
renderer.shadowMap.needsUpdate = true;
|
|
14731
|
-
}
|
|
14732
|
-
{
|
|
14733
|
-
const legacyChanged = legacy !== lastConfiguredProps.legacy;
|
|
14734
|
-
const linearChanged = linear !== lastConfiguredProps.linear;
|
|
14735
|
-
const flatChanged = flat !== lastConfiguredProps.flat;
|
|
14736
|
-
if (legacyChanged) {
|
|
14737
|
-
three.ColorManagement.enabled = !legacy;
|
|
14738
|
-
lastConfiguredProps.legacy = legacy;
|
|
14739
15209
|
}
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
if (!configured || flatChanged) {
|
|
14745
|
-
renderer.toneMapping = flat ? three.NoToneMapping : three.ACESFilmicToneMapping;
|
|
14746
|
-
lastConfiguredProps.flat = flat;
|
|
14747
|
-
}
|
|
14748
|
-
if (legacyChanged && state.legacy !== legacy) state.set(() => ({ legacy }));
|
|
14749
|
-
if (linearChanged && state.linear !== linear) state.set(() => ({ linear }));
|
|
14750
|
-
if (flatChanged && state.flat !== flat) state.set(() => ({ flat }));
|
|
15210
|
+
}
|
|
15211
|
+
if (!configured) {
|
|
15212
|
+
renderer.outputColorSpace = three.SRGBColorSpace;
|
|
15213
|
+
renderer.toneMapping = three.ACESFilmicToneMapping;
|
|
14751
15214
|
}
|
|
14752
15215
|
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
14753
15216
|
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
14754
15217
|
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
14755
15218
|
}
|
|
14756
|
-
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose))
|
|
15219
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
|
|
14757
15220
|
applyProps(renderer, glConfig);
|
|
15221
|
+
}
|
|
14758
15222
|
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
|
|
14759
15223
|
const currentRenderer = state.renderer;
|
|
14760
15224
|
if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
|
|
@@ -14764,11 +15228,26 @@ function createRoot(canvas) {
|
|
|
14764
15228
|
const scheduler = getScheduler();
|
|
14765
15229
|
const rootId = state.internal.rootId;
|
|
14766
15230
|
if (!rootId) {
|
|
14767
|
-
const newRootId = scheduler.generateRootId();
|
|
15231
|
+
const newRootId = canvasId || scheduler.generateRootId();
|
|
14768
15232
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14769
15233
|
getState: () => store.getState(),
|
|
14770
15234
|
onError: (err) => store.getState().setError(err)
|
|
14771
15235
|
});
|
|
15236
|
+
const unregisterCanvasTarget = scheduler.register(
|
|
15237
|
+
() => {
|
|
15238
|
+
const state2 = store.getState();
|
|
15239
|
+
if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
|
|
15240
|
+
const renderer2 = state2.internal.actualRenderer;
|
|
15241
|
+
renderer2.setCanvasTarget(state2.internal.canvasTarget);
|
|
15242
|
+
}
|
|
15243
|
+
},
|
|
15244
|
+
{
|
|
15245
|
+
id: `${newRootId}_canvasTarget`,
|
|
15246
|
+
rootId: newRootId,
|
|
15247
|
+
phase: "start",
|
|
15248
|
+
system: true
|
|
15249
|
+
}
|
|
15250
|
+
);
|
|
14772
15251
|
const unregisterFrustum = scheduler.register(
|
|
14773
15252
|
() => {
|
|
14774
15253
|
const state2 = store.getState();
|
|
@@ -14810,11 +15289,15 @@ function createRoot(canvas) {
|
|
|
14810
15289
|
}
|
|
14811
15290
|
},
|
|
14812
15291
|
{
|
|
14813
|
-
|
|
15292
|
+
// Use canvas ID directly as job ID if available, otherwise use generated rootId
|
|
15293
|
+
id: canvasId || `${newRootId}_render`,
|
|
14814
15294
|
rootId: newRootId,
|
|
14815
15295
|
phase: "render",
|
|
14816
|
-
system: true
|
|
15296
|
+
system: true,
|
|
14817
15297
|
// Internal flag: this is a system job, not user-controlled
|
|
15298
|
+
// Apply scheduler config for render ordering and rate limiting
|
|
15299
|
+
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
15300
|
+
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14818
15301
|
}
|
|
14819
15302
|
);
|
|
14820
15303
|
state.set((state2) => ({
|
|
@@ -14823,6 +15306,7 @@ function createRoot(canvas) {
|
|
|
14823
15306
|
rootId: newRootId,
|
|
14824
15307
|
unregisterRoot: () => {
|
|
14825
15308
|
unregisterRoot();
|
|
15309
|
+
unregisterCanvasTarget();
|
|
14826
15310
|
unregisterFrustum();
|
|
14827
15311
|
unregisterVisibility();
|
|
14828
15312
|
unregisterRender();
|
|
@@ -14881,15 +15365,24 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14881
15365
|
const renderer = state.internal.actualRenderer;
|
|
14882
15366
|
const unregisterRoot = state.internal.unregisterRoot;
|
|
14883
15367
|
if (unregisterRoot) unregisterRoot();
|
|
15368
|
+
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
15369
|
+
if (unregisterPrimary) unregisterPrimary();
|
|
15370
|
+
const canvasTarget = state.internal.canvasTarget;
|
|
15371
|
+
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14884
15372
|
state.events.disconnect?.();
|
|
14885
15373
|
cleanupHelperGroup(root.store);
|
|
14886
|
-
renderer
|
|
14887
|
-
|
|
14888
|
-
|
|
15374
|
+
if (state.isLegacy && renderer) {
|
|
15375
|
+
;
|
|
15376
|
+
renderer.renderLists?.dispose?.();
|
|
15377
|
+
renderer.forceContextLoss?.();
|
|
15378
|
+
}
|
|
15379
|
+
if (!state.internal.isSecondary) {
|
|
15380
|
+
if (renderer?.xr) state.xr.disconnect();
|
|
15381
|
+
}
|
|
14889
15382
|
dispose(state.scene);
|
|
14890
15383
|
_roots.delete(canvas);
|
|
14891
15384
|
if (callback) callback(canvas);
|
|
14892
|
-
} catch
|
|
15385
|
+
} catch {
|
|
14893
15386
|
}
|
|
14894
15387
|
}, 500);
|
|
14895
15388
|
}
|
|
@@ -14897,36 +15390,34 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14897
15390
|
}
|
|
14898
15391
|
}
|
|
14899
15392
|
function createPortal(children, container, state) {
|
|
14900
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15393
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Portal, { children, container, state });
|
|
14901
15394
|
}
|
|
14902
|
-
function
|
|
15395
|
+
function Portal({ children, container, state }) {
|
|
14903
15396
|
const isRef = React.useCallback((obj) => obj && "current" in obj, []);
|
|
14904
|
-
const [resolvedContainer,
|
|
15397
|
+
const [resolvedContainer, _setResolvedContainer] = React.useState(() => {
|
|
14905
15398
|
if (isRef(container)) return container.current ?? null;
|
|
14906
15399
|
return container;
|
|
14907
15400
|
});
|
|
15401
|
+
const setResolvedContainer = React.useCallback(
|
|
15402
|
+
(newContainer) => {
|
|
15403
|
+
if (!newContainer || newContainer === resolvedContainer) return;
|
|
15404
|
+
_setResolvedContainer(isRef(newContainer) ? newContainer.current : newContainer);
|
|
15405
|
+
},
|
|
15406
|
+
[resolvedContainer, _setResolvedContainer, isRef]
|
|
15407
|
+
);
|
|
14908
15408
|
React.useMemo(() => {
|
|
14909
|
-
if (isRef(container)) {
|
|
14910
|
-
|
|
14911
|
-
|
|
14912
|
-
|
|
14913
|
-
const updated = container.current;
|
|
14914
|
-
if (updated && updated !== resolvedContainer) {
|
|
14915
|
-
setResolvedContainer(updated);
|
|
14916
|
-
}
|
|
14917
|
-
});
|
|
14918
|
-
} else if (current !== resolvedContainer) {
|
|
14919
|
-
setResolvedContainer(current);
|
|
14920
|
-
}
|
|
14921
|
-
} else if (container !== resolvedContainer) {
|
|
14922
|
-
setResolvedContainer(container);
|
|
15409
|
+
if (isRef(container) && !container.current) {
|
|
15410
|
+
return queueMicrotask(() => {
|
|
15411
|
+
setResolvedContainer(container.current);
|
|
15412
|
+
});
|
|
14923
15413
|
}
|
|
14924
|
-
|
|
15414
|
+
setResolvedContainer(container);
|
|
15415
|
+
}, [container, isRef, setResolvedContainer]);
|
|
14925
15416
|
if (!resolvedContainer) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
14926
15417
|
const portalKey = resolvedContainer.uuid ?? `portal-${resolvedContainer.id ?? "unknown"}`;
|
|
14927
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15418
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PortalInner, { children, container: resolvedContainer, state }, portalKey);
|
|
14928
15419
|
}
|
|
14929
|
-
function
|
|
15420
|
+
function PortalInner({ state = {}, children, container }) {
|
|
14930
15421
|
const { events, size, injectScene = true, ...rest } = state;
|
|
14931
15422
|
const previousRoot = useStore();
|
|
14932
15423
|
const [raycaster] = React.useState(() => new three.Raycaster());
|
|
@@ -14947,11 +15438,12 @@ function Portal({ state = {}, children, container }) {
|
|
|
14947
15438
|
};
|
|
14948
15439
|
}, [portalScene, container, injectScene]);
|
|
14949
15440
|
const inject = useMutableCallback((rootState, injectState) => {
|
|
15441
|
+
const resolvedSize = { ...rootState.size, ...injectState.size, ...size };
|
|
14950
15442
|
let viewport = void 0;
|
|
14951
|
-
if (injectState.camera && size) {
|
|
15443
|
+
if (injectState.camera && (size || injectState.size)) {
|
|
14952
15444
|
const camera = injectState.camera;
|
|
14953
|
-
viewport = rootState.viewport.getCurrentViewport(camera, new three.Vector3(),
|
|
14954
|
-
if (camera !== rootState.camera) updateCamera(camera,
|
|
15445
|
+
viewport = rootState.viewport.getCurrentViewport(camera, new three.Vector3(), resolvedSize);
|
|
15446
|
+
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14955
15447
|
}
|
|
14956
15448
|
return {
|
|
14957
15449
|
// The intersect consists of the previous root state
|
|
@@ -14968,7 +15460,7 @@ function Portal({ state = {}, children, container }) {
|
|
|
14968
15460
|
previousRoot,
|
|
14969
15461
|
// Events, size and viewport can be overridden by the inject layer
|
|
14970
15462
|
events: { ...rootState.events, ...injectState.events, ...events },
|
|
14971
|
-
size:
|
|
15463
|
+
size: resolvedSize,
|
|
14972
15464
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14973
15465
|
// Layers are allowed to override events
|
|
14974
15466
|
setEvents: (events2) => injectState.set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
@@ -15002,15 +15494,13 @@ function CanvasImpl({
|
|
|
15002
15494
|
fallback,
|
|
15003
15495
|
resize,
|
|
15004
15496
|
style,
|
|
15497
|
+
id,
|
|
15005
15498
|
gl,
|
|
15006
|
-
renderer,
|
|
15499
|
+
renderer: rendererProp,
|
|
15007
15500
|
events = createPointerEvents,
|
|
15008
15501
|
eventSource,
|
|
15009
15502
|
eventPrefix,
|
|
15010
15503
|
shadows,
|
|
15011
|
-
linear,
|
|
15012
|
-
flat,
|
|
15013
|
-
legacy,
|
|
15014
15504
|
orthographic,
|
|
15015
15505
|
frameloop,
|
|
15016
15506
|
dpr,
|
|
@@ -15022,10 +15512,46 @@ function CanvasImpl({
|
|
|
15022
15512
|
onDragOverMissed,
|
|
15023
15513
|
onDropMissed,
|
|
15024
15514
|
onCreated,
|
|
15515
|
+
hmr,
|
|
15516
|
+
width,
|
|
15517
|
+
height,
|
|
15518
|
+
background,
|
|
15519
|
+
forceEven,
|
|
15025
15520
|
...props
|
|
15026
15521
|
}) {
|
|
15522
|
+
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 };
|
|
15523
|
+
const renderer = Object.keys(rendererConfig).length > 0 ? rendererConfig : rendererProp;
|
|
15027
15524
|
React__namespace.useMemo(() => extend(THREE), []);
|
|
15028
15525
|
const Bridge = useBridge();
|
|
15526
|
+
const backgroundProps = React__namespace.useMemo(() => {
|
|
15527
|
+
if (!background) return null;
|
|
15528
|
+
if (typeof background === "object" && !background.isColor) {
|
|
15529
|
+
const { backgroundMap, envMap, files, preset, ...rest } = background;
|
|
15530
|
+
return {
|
|
15531
|
+
...rest,
|
|
15532
|
+
preset,
|
|
15533
|
+
files: envMap || files,
|
|
15534
|
+
backgroundFiles: backgroundMap,
|
|
15535
|
+
background: true
|
|
15536
|
+
};
|
|
15537
|
+
}
|
|
15538
|
+
if (typeof background === "number") {
|
|
15539
|
+
return { color: background, background: true };
|
|
15540
|
+
}
|
|
15541
|
+
if (typeof background === "string") {
|
|
15542
|
+
if (background in presetsObj) {
|
|
15543
|
+
return { preset: background, background: true };
|
|
15544
|
+
}
|
|
15545
|
+
if (/^(https?:\/\/|\/|\.\/|\.\.\/)|\\.(hdr|exr|jpg|jpeg|png|webp|gif)$/i.test(background)) {
|
|
15546
|
+
return { files: background, background: true };
|
|
15547
|
+
}
|
|
15548
|
+
return { color: background, background: true };
|
|
15549
|
+
}
|
|
15550
|
+
if (background.isColor) {
|
|
15551
|
+
return { color: background, background: true };
|
|
15552
|
+
}
|
|
15553
|
+
return null;
|
|
15554
|
+
}, [background]);
|
|
15029
15555
|
const hasInitialSizeRef = React__namespace.useRef(false);
|
|
15030
15556
|
const measureConfig = React__namespace.useMemo(() => {
|
|
15031
15557
|
if (!hasInitialSizeRef.current) {
|
|
@@ -15042,7 +15568,21 @@ function CanvasImpl({
|
|
|
15042
15568
|
};
|
|
15043
15569
|
}, [resize, hasInitialSizeRef.current]);
|
|
15044
15570
|
const [containerRef, containerRect] = useMeasure__default(measureConfig);
|
|
15045
|
-
|
|
15571
|
+
const effectiveSize = React__namespace.useMemo(() => {
|
|
15572
|
+
let w = width ?? containerRect.width;
|
|
15573
|
+
let h = height ?? containerRect.height;
|
|
15574
|
+
if (forceEven) {
|
|
15575
|
+
w = Math.ceil(w / 2) * 2;
|
|
15576
|
+
h = Math.ceil(h / 2) * 2;
|
|
15577
|
+
}
|
|
15578
|
+
return {
|
|
15579
|
+
width: w,
|
|
15580
|
+
height: h,
|
|
15581
|
+
top: containerRect.top,
|
|
15582
|
+
left: containerRect.left
|
|
15583
|
+
};
|
|
15584
|
+
}, [width, height, containerRect, forceEven]);
|
|
15585
|
+
if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
|
|
15046
15586
|
hasInitialSizeRef.current = true;
|
|
15047
15587
|
}
|
|
15048
15588
|
const canvasRef = React__namespace.useRef(null);
|
|
@@ -15061,7 +15601,7 @@ function CanvasImpl({
|
|
|
15061
15601
|
useIsomorphicLayoutEffect(() => {
|
|
15062
15602
|
effectActiveRef.current = true;
|
|
15063
15603
|
const canvas = canvasRef.current;
|
|
15064
|
-
if (
|
|
15604
|
+
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
15065
15605
|
if (!root.current) {
|
|
15066
15606
|
root.current = createRoot(canvas);
|
|
15067
15607
|
notifyAlpha({
|
|
@@ -15081,21 +15621,24 @@ function CanvasImpl({
|
|
|
15081
15621
|
async function run() {
|
|
15082
15622
|
if (!effectActiveRef.current || !root.current) return;
|
|
15083
15623
|
await root.current.configure({
|
|
15624
|
+
id,
|
|
15625
|
+
primaryCanvas,
|
|
15626
|
+
scheduler,
|
|
15084
15627
|
gl,
|
|
15085
15628
|
renderer,
|
|
15086
15629
|
scene,
|
|
15087
15630
|
events,
|
|
15088
15631
|
shadows,
|
|
15089
|
-
linear,
|
|
15090
|
-
flat,
|
|
15091
|
-
legacy,
|
|
15092
15632
|
orthographic,
|
|
15093
15633
|
frameloop,
|
|
15094
15634
|
dpr,
|
|
15095
15635
|
performance,
|
|
15096
15636
|
raycaster,
|
|
15097
15637
|
camera,
|
|
15098
|
-
size:
|
|
15638
|
+
size: effectiveSize,
|
|
15639
|
+
// Store size props for reset functionality
|
|
15640
|
+
_sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
|
|
15641
|
+
forceEven,
|
|
15099
15642
|
// Pass mutable reference to onPointerMissed so it's free to update
|
|
15100
15643
|
onPointerMissed: (...args) => handlePointerMissed.current?.(...args),
|
|
15101
15644
|
onDragOverMissed: (...args) => handleDragOverMissed.current?.(...args),
|
|
@@ -15119,7 +15662,10 @@ function CanvasImpl({
|
|
|
15119
15662
|
});
|
|
15120
15663
|
if (!effectActiveRef.current || !root.current) return;
|
|
15121
15664
|
root.current.render(
|
|
15122
|
-
/* @__PURE__ */ jsxRuntime.jsx(Bridge, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxRuntime.
|
|
15665
|
+
/* @__PURE__ */ jsxRuntime.jsx(Bridge, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(Block, { set: setBlock }), children: [
|
|
15666
|
+
backgroundProps && /* @__PURE__ */ jsxRuntime.jsx(Environment, { ...backgroundProps }),
|
|
15667
|
+
children ?? null
|
|
15668
|
+
] }) }) })
|
|
15123
15669
|
);
|
|
15124
15670
|
}
|
|
15125
15671
|
run();
|
|
@@ -15141,6 +15687,35 @@ function CanvasImpl({
|
|
|
15141
15687
|
};
|
|
15142
15688
|
}
|
|
15143
15689
|
}, []);
|
|
15690
|
+
React__namespace.useEffect(() => {
|
|
15691
|
+
if (hmr === false) return;
|
|
15692
|
+
const canvas = canvasRef.current;
|
|
15693
|
+
if (!canvas) return;
|
|
15694
|
+
const handleHMR = () => {
|
|
15695
|
+
queueMicrotask(() => {
|
|
15696
|
+
const rootEntry = _roots.get(canvas);
|
|
15697
|
+
if (rootEntry?.store) {
|
|
15698
|
+
rootEntry.store.setState((state) => ({
|
|
15699
|
+
nodes: {},
|
|
15700
|
+
uniforms: {},
|
|
15701
|
+
_hmrVersion: state._hmrVersion + 1
|
|
15702
|
+
}));
|
|
15703
|
+
}
|
|
15704
|
+
});
|
|
15705
|
+
};
|
|
15706
|
+
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('legacy.cjs', document.baseURI).href)) }) !== "undefined" && undefined) {
|
|
15707
|
+
const hot = undefined;
|
|
15708
|
+
hot.on("vite:afterUpdate", handleHMR);
|
|
15709
|
+
return () => hot.dispose?.(() => {
|
|
15710
|
+
});
|
|
15711
|
+
}
|
|
15712
|
+
if (typeof module !== "undefined" && module.hot) {
|
|
15713
|
+
const hot = module.hot;
|
|
15714
|
+
hot.addStatusHandler((status) => {
|
|
15715
|
+
if (status === "idle") handleHMR();
|
|
15716
|
+
});
|
|
15717
|
+
}
|
|
15718
|
+
}, [hmr]);
|
|
15144
15719
|
const pointerEvents = eventSource ? "none" : "auto";
|
|
15145
15720
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15146
15721
|
"div",
|
|
@@ -15155,7 +15730,7 @@ function CanvasImpl({
|
|
|
15155
15730
|
...style
|
|
15156
15731
|
},
|
|
15157
15732
|
...props,
|
|
15158
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, className: "r3f-canvas", style: { display: "block" }, children: fallback }) })
|
|
15733
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, id, className: "r3f-canvas", style: { display: "block" }, children: fallback }) })
|
|
15159
15734
|
}
|
|
15160
15735
|
);
|
|
15161
15736
|
}
|
|
@@ -15167,8 +15742,15 @@ extend(THREE);
|
|
|
15167
15742
|
|
|
15168
15743
|
exports.Block = Block;
|
|
15169
15744
|
exports.Canvas = Canvas;
|
|
15745
|
+
exports.Environment = Environment;
|
|
15746
|
+
exports.EnvironmentCube = EnvironmentCube;
|
|
15747
|
+
exports.EnvironmentMap = EnvironmentMap;
|
|
15748
|
+
exports.EnvironmentPortal = EnvironmentPortal;
|
|
15170
15749
|
exports.ErrorBoundary = ErrorBoundary;
|
|
15750
|
+
exports.FROM_REF = FROM_REF;
|
|
15171
15751
|
exports.IsObject = IsObject;
|
|
15752
|
+
exports.ONCE = ONCE;
|
|
15753
|
+
exports.Portal = Portal;
|
|
15172
15754
|
exports.R3F_BUILD_LEGACY = R3F_BUILD_LEGACY;
|
|
15173
15755
|
exports.R3F_BUILD_WEBGPU = R3F_BUILD_WEBGPU;
|
|
15174
15756
|
exports.REACT_INTERNAL_PROPS = REACT_INTERNAL_PROPS;
|
|
@@ -15198,30 +15780,41 @@ exports.events = createPointerEvents;
|
|
|
15198
15780
|
exports.extend = extend;
|
|
15199
15781
|
exports.findInitialRoot = findInitialRoot;
|
|
15200
15782
|
exports.flushSync = flushSync;
|
|
15783
|
+
exports.fromRef = fromRef;
|
|
15201
15784
|
exports.getInstanceProps = getInstanceProps;
|
|
15785
|
+
exports.getPrimary = getPrimary;
|
|
15786
|
+
exports.getPrimaryIds = getPrimaryIds;
|
|
15202
15787
|
exports.getRootState = getRootState;
|
|
15203
15788
|
exports.getScheduler = getScheduler;
|
|
15204
15789
|
exports.getUuidPrefix = getUuidPrefix;
|
|
15205
15790
|
exports.hasConstructor = hasConstructor;
|
|
15791
|
+
exports.hasPrimary = hasPrimary;
|
|
15206
15792
|
exports.invalidate = invalidate;
|
|
15207
15793
|
exports.invalidateInstance = invalidateInstance;
|
|
15208
15794
|
exports.is = is;
|
|
15209
15795
|
exports.isColorRepresentation = isColorRepresentation;
|
|
15210
15796
|
exports.isCopyable = isCopyable;
|
|
15797
|
+
exports.isFromRef = isFromRef;
|
|
15211
15798
|
exports.isObject3D = isObject3D;
|
|
15799
|
+
exports.isOnce = isOnce;
|
|
15212
15800
|
exports.isOrthographicCamera = isOrthographicCamera;
|
|
15213
15801
|
exports.isRef = isRef;
|
|
15214
15802
|
exports.isRenderer = isRenderer;
|
|
15215
15803
|
exports.isTexture = isTexture;
|
|
15216
15804
|
exports.isVectorLike = isVectorLike;
|
|
15805
|
+
exports.once = once;
|
|
15217
15806
|
exports.prepare = prepare;
|
|
15807
|
+
exports.presetsObj = presetsObj;
|
|
15218
15808
|
exports.reconciler = reconciler;
|
|
15809
|
+
exports.registerPrimary = registerPrimary;
|
|
15219
15810
|
exports.removeInteractivity = removeInteractivity;
|
|
15220
15811
|
exports.resolve = resolve;
|
|
15221
15812
|
exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
15813
|
+
exports.unregisterPrimary = unregisterPrimary;
|
|
15222
15814
|
exports.updateCamera = updateCamera;
|
|
15223
15815
|
exports.updateFrustum = updateFrustum;
|
|
15224
15816
|
exports.useBridge = useBridge;
|
|
15817
|
+
exports.useEnvironment = useEnvironment;
|
|
15225
15818
|
exports.useFrame = useFrame;
|
|
15226
15819
|
exports.useGraph = useGraph;
|
|
15227
15820
|
exports.useInstanceHandle = useInstanceHandle;
|
|
@@ -15233,3 +15826,4 @@ exports.useStore = useStore;
|
|
|
15233
15826
|
exports.useTexture = useTexture;
|
|
15234
15827
|
exports.useTextures = useTextures;
|
|
15235
15828
|
exports.useThree = useThree;
|
|
15829
|
+
exports.waitForPrimary = waitForPrimary;
|