@react-three/fiber 10.0.0-alpha.2 → 10.0.0-canary.b0fafc8
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 +1122 -558
- package/dist/index.d.cts +2001 -1285
- package/dist/index.d.mts +2001 -1285
- package/dist/index.d.ts +2001 -1285
- package/dist/index.mjs +1107 -562
- package/dist/legacy.cjs +1093 -547
- package/dist/legacy.d.cts +2002 -1286
- package/dist/legacy.d.mts +2002 -1286
- package/dist/legacy.d.ts +2002 -1286
- package/dist/legacy.mjs +1078 -551
- package/dist/webgpu/index.cjs +1176 -548
- package/dist/webgpu/index.d.cts +2097 -1300
- package/dist/webgpu/index.d.mts +2097 -1300
- package/dist/webgpu/index.d.ts +2097 -1300
- package/dist/webgpu/index.mjs +1161 -552
- package/package.json +3 -1
- package/readme.md +244 -318
package/dist/legacy.cjs
CHANGED
|
@@ -5,6 +5,12 @@ 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');
|
|
@@ -66,6 +72,374 @@ const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
|
66
72
|
WebGPURenderer: WebGPURenderer
|
|
67
73
|
}, [three__namespace]);
|
|
68
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
|
+
|
|
69
443
|
var __defProp$2 = Object.defineProperty;
|
|
70
444
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
71
445
|
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -245,7 +619,8 @@ function prepare(target, root, type, props) {
|
|
|
245
619
|
object,
|
|
246
620
|
eventCount: 0,
|
|
247
621
|
handlers: {},
|
|
248
|
-
isHidden: false
|
|
622
|
+
isHidden: false,
|
|
623
|
+
deferredRefs: []
|
|
249
624
|
};
|
|
250
625
|
if (object) object.__r3f = instance;
|
|
251
626
|
}
|
|
@@ -294,7 +669,7 @@ function createOcclusionObserverNode(store, uniform) {
|
|
|
294
669
|
let occlusionSetupPromise = null;
|
|
295
670
|
function enableOcclusion(store) {
|
|
296
671
|
const state = store.getState();
|
|
297
|
-
const { internal, renderer
|
|
672
|
+
const { internal, renderer } = state;
|
|
298
673
|
if (internal.occlusionEnabled || occlusionSetupPromise) return;
|
|
299
674
|
const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
|
|
300
675
|
if (!hasOcclusionSupport) {
|
|
@@ -457,6 +832,22 @@ function hasVisibilityHandlers(handlers) {
|
|
|
457
832
|
return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
|
|
458
833
|
}
|
|
459
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
|
+
|
|
460
851
|
const RESERVED_PROPS = [
|
|
461
852
|
"children",
|
|
462
853
|
"key",
|
|
@@ -527,7 +918,7 @@ function getMemoizedPrototype(root) {
|
|
|
527
918
|
ctor = new root.constructor();
|
|
528
919
|
MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
|
|
529
920
|
}
|
|
530
|
-
} catch
|
|
921
|
+
} catch {
|
|
531
922
|
}
|
|
532
923
|
return ctor;
|
|
533
924
|
}
|
|
@@ -573,6 +964,25 @@ function applyProps(object, props) {
|
|
|
573
964
|
continue;
|
|
574
965
|
}
|
|
575
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
|
+
}
|
|
576
986
|
let { root, key, target } = resolve(object, prop);
|
|
577
987
|
if (target === void 0 && (typeof root !== "object" || root === null)) {
|
|
578
988
|
throw Error(`R3F: Cannot set "${prop}". Ensure it is an object before setting "${key}".`);
|
|
@@ -595,7 +1005,7 @@ function applyProps(object, props) {
|
|
|
595
1005
|
else target.set(value);
|
|
596
1006
|
} else {
|
|
597
1007
|
root[key] = value;
|
|
598
|
-
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
|
|
599
1009
|
root[key].format === three.RGBAFormat && root[key].type === three.UnsignedByteType) {
|
|
600
1010
|
root[key].colorSpace = rootState.textureColorSpace;
|
|
601
1011
|
}
|
|
@@ -952,7 +1362,7 @@ function createPointerEvents(store) {
|
|
|
952
1362
|
return {
|
|
953
1363
|
priority: 1,
|
|
954
1364
|
enabled: true,
|
|
955
|
-
compute(event, state
|
|
1365
|
+
compute(event, state) {
|
|
956
1366
|
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
957
1367
|
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
958
1368
|
},
|
|
@@ -1050,331 +1460,26 @@ function notifyAlpha({ message, link }) {
|
|
|
1050
1460
|
}
|
|
1051
1461
|
}
|
|
1052
1462
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
let performanceTimeout = void 0;
|
|
1076
|
-
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
1077
|
-
const pointer = new three.Vector2();
|
|
1078
|
-
const rootState = {
|
|
1079
|
-
set,
|
|
1080
|
-
get,
|
|
1081
|
-
// Mock objects that have to be configured
|
|
1082
|
-
gl: null,
|
|
1083
|
-
renderer: null,
|
|
1084
|
-
camera: null,
|
|
1085
|
-
frustum: new three.Frustum(),
|
|
1086
|
-
autoUpdateFrustum: true,
|
|
1087
|
-
raycaster: null,
|
|
1088
|
-
events: { priority: 1, enabled: true, connected: false },
|
|
1089
|
-
scene: null,
|
|
1090
|
-
rootScene: null,
|
|
1091
|
-
xr: null,
|
|
1092
|
-
inspector: null,
|
|
1093
|
-
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
1094
|
-
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1095
|
-
legacy: false,
|
|
1096
|
-
linear: false,
|
|
1097
|
-
flat: false,
|
|
1098
|
-
textureColorSpace: "srgb",
|
|
1099
|
-
isLegacy: false,
|
|
1100
|
-
webGPUSupported: false,
|
|
1101
|
-
isNative: false,
|
|
1102
|
-
controls: null,
|
|
1103
|
-
pointer,
|
|
1104
|
-
mouse: pointer,
|
|
1105
|
-
frameloop: "always",
|
|
1106
|
-
onPointerMissed: void 0,
|
|
1107
|
-
onDragOverMissed: void 0,
|
|
1108
|
-
onDropMissed: void 0,
|
|
1109
|
-
performance: {
|
|
1110
|
-
current: 1,
|
|
1111
|
-
min: 0.5,
|
|
1112
|
-
max: 1,
|
|
1113
|
-
debounce: 200,
|
|
1114
|
-
regress: () => {
|
|
1115
|
-
const state2 = get();
|
|
1116
|
-
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
1117
|
-
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
1118
|
-
performanceTimeout = setTimeout(
|
|
1119
|
-
() => setPerformanceCurrent(get().performance.max),
|
|
1120
|
-
state2.performance.debounce
|
|
1121
|
-
);
|
|
1122
|
-
}
|
|
1123
|
-
},
|
|
1124
|
-
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
1125
|
-
viewport: {
|
|
1126
|
-
initialDpr: 0,
|
|
1127
|
-
dpr: 0,
|
|
1128
|
-
width: 0,
|
|
1129
|
-
height: 0,
|
|
1130
|
-
top: 0,
|
|
1131
|
-
left: 0,
|
|
1132
|
-
aspect: 0,
|
|
1133
|
-
distance: 0,
|
|
1134
|
-
factor: 0,
|
|
1135
|
-
getCurrentViewport
|
|
1136
|
-
},
|
|
1137
|
-
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
1138
|
-
setSize: (width, height, top, left) => {
|
|
1139
|
-
const state2 = get();
|
|
1140
|
-
if (width === void 0) {
|
|
1141
|
-
set({ _sizeImperative: false });
|
|
1142
|
-
if (state2._sizeProps) {
|
|
1143
|
-
const { width: propW, height: propH } = state2._sizeProps;
|
|
1144
|
-
if (propW !== void 0 || propH !== void 0) {
|
|
1145
|
-
const currentSize = state2.size;
|
|
1146
|
-
const newSize = {
|
|
1147
|
-
width: propW ?? currentSize.width,
|
|
1148
|
-
height: propH ?? currentSize.height,
|
|
1149
|
-
top: currentSize.top,
|
|
1150
|
-
left: currentSize.left
|
|
1151
|
-
};
|
|
1152
|
-
set((s) => ({
|
|
1153
|
-
size: newSize,
|
|
1154
|
-
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
1155
|
-
}));
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
return;
|
|
1159
|
-
}
|
|
1160
|
-
const w = width;
|
|
1161
|
-
const h = height ?? width;
|
|
1162
|
-
const t = top ?? state2.size.top;
|
|
1163
|
-
const l = left ?? state2.size.left;
|
|
1164
|
-
const size = { width: w, height: h, top: t, left: l };
|
|
1165
|
-
set((s) => ({
|
|
1166
|
-
size,
|
|
1167
|
-
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
1168
|
-
_sizeImperative: true
|
|
1169
|
-
}));
|
|
1170
|
-
},
|
|
1171
|
-
setDpr: (dpr) => set((state2) => {
|
|
1172
|
-
const resolved = calculateDpr(dpr);
|
|
1173
|
-
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
1174
|
-
}),
|
|
1175
|
-
setFrameloop: (frameloop = "always") => {
|
|
1176
|
-
set(() => ({ frameloop }));
|
|
1177
|
-
},
|
|
1178
|
-
setError: (error) => set(() => ({ error })),
|
|
1179
|
-
error: null,
|
|
1180
|
-
//* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
|
|
1181
|
-
uniforms: {},
|
|
1182
|
-
nodes: {},
|
|
1183
|
-
textures: /* @__PURE__ */ new Map(),
|
|
1184
|
-
postProcessing: null,
|
|
1185
|
-
passes: {},
|
|
1186
|
-
_hmrVersion: 0,
|
|
1187
|
-
_sizeImperative: false,
|
|
1188
|
-
_sizeProps: null,
|
|
1189
|
-
previousRoot: void 0,
|
|
1190
|
-
internal: {
|
|
1191
|
-
// Events
|
|
1192
|
-
interaction: [],
|
|
1193
|
-
hovered: /* @__PURE__ */ new Map(),
|
|
1194
|
-
subscribers: [],
|
|
1195
|
-
initialClick: [0, 0],
|
|
1196
|
-
initialHits: [],
|
|
1197
|
-
capturedMap: /* @__PURE__ */ new Map(),
|
|
1198
|
-
lastEvent: React__namespace.createRef(),
|
|
1199
|
-
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
1200
|
-
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
1201
|
-
// Occlusion system (WebGPU only)
|
|
1202
|
-
occlusionEnabled: false,
|
|
1203
|
-
occlusionObserver: null,
|
|
1204
|
-
occlusionCache: /* @__PURE__ */ new Map(),
|
|
1205
|
-
helperGroup: null,
|
|
1206
|
-
// Updates
|
|
1207
|
-
active: false,
|
|
1208
|
-
frames: 0,
|
|
1209
|
-
priority: 0,
|
|
1210
|
-
subscribe: (ref, priority, store) => {
|
|
1211
|
-
const internal = get().internal;
|
|
1212
|
-
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
1213
|
-
internal.subscribers.push({ ref, priority, store });
|
|
1214
|
-
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
1215
|
-
return () => {
|
|
1216
|
-
const internal2 = get().internal;
|
|
1217
|
-
if (internal2?.subscribers) {
|
|
1218
|
-
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
1219
|
-
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
1220
|
-
}
|
|
1221
|
-
};
|
|
1222
|
-
},
|
|
1223
|
-
// Renderer Storage (single source of truth)
|
|
1224
|
-
actualRenderer: null,
|
|
1225
|
-
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
1226
|
-
scheduler: null
|
|
1227
|
-
}
|
|
1228
|
-
};
|
|
1229
|
-
return rootState;
|
|
1230
|
-
});
|
|
1231
|
-
const state = rootStore.getState();
|
|
1232
|
-
Object.defineProperty(state, "gl", {
|
|
1233
|
-
get() {
|
|
1234
|
-
const currentState = rootStore.getState();
|
|
1235
|
-
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1236
|
-
const stack = new Error().stack || "";
|
|
1237
|
-
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
1238
|
-
if (!isInternalAccess) {
|
|
1239
|
-
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1240
|
-
notifyDepreciated({
|
|
1241
|
-
heading: "Accessing state.gl in WebGPU mode",
|
|
1242
|
-
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
|
|
1243
|
-
});
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
return currentState.internal.actualRenderer;
|
|
1247
|
-
},
|
|
1248
|
-
set(value) {
|
|
1249
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1250
|
-
},
|
|
1251
|
-
enumerable: true,
|
|
1252
|
-
configurable: true
|
|
1253
|
-
});
|
|
1254
|
-
Object.defineProperty(state, "renderer", {
|
|
1255
|
-
get() {
|
|
1256
|
-
return rootStore.getState().internal.actualRenderer;
|
|
1257
|
-
},
|
|
1258
|
-
set(value) {
|
|
1259
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1260
|
-
},
|
|
1261
|
-
enumerable: true,
|
|
1262
|
-
configurable: true
|
|
1263
|
-
});
|
|
1264
|
-
let oldScene = state.scene;
|
|
1265
|
-
rootStore.subscribe(() => {
|
|
1266
|
-
const currentState = rootStore.getState();
|
|
1267
|
-
const { scene, rootScene, set } = currentState;
|
|
1268
|
-
if (scene !== oldScene) {
|
|
1269
|
-
oldScene = scene;
|
|
1270
|
-
if (scene?.isScene && scene !== rootScene) {
|
|
1271
|
-
set({ rootScene: scene });
|
|
1272
|
-
}
|
|
1273
|
-
}
|
|
1274
|
-
});
|
|
1275
|
-
let oldSize = state.size;
|
|
1276
|
-
let oldDpr = state.viewport.dpr;
|
|
1277
|
-
let oldCamera = state.camera;
|
|
1278
|
-
rootStore.subscribe(() => {
|
|
1279
|
-
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
1280
|
-
const actualRenderer = internal.actualRenderer;
|
|
1281
|
-
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
1282
|
-
oldSize = size;
|
|
1283
|
-
oldDpr = viewport.dpr;
|
|
1284
|
-
updateCamera(camera, size);
|
|
1285
|
-
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1286
|
-
const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
|
|
1287
|
-
actualRenderer.setSize(size.width, size.height, updateStyle);
|
|
1288
|
-
}
|
|
1289
|
-
if (camera !== oldCamera) {
|
|
1290
|
-
oldCamera = camera;
|
|
1291
|
-
const { rootScene } = rootStore.getState();
|
|
1292
|
-
if (camera && rootScene && !camera.parent) {
|
|
1293
|
-
rootScene.add(camera);
|
|
1294
|
-
}
|
|
1295
|
-
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
1296
|
-
const currentState = rootStore.getState();
|
|
1297
|
-
if (currentState.autoUpdateFrustum && camera) {
|
|
1298
|
-
updateFrustum(camera, currentState.frustum);
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
});
|
|
1302
|
-
rootStore.subscribe((state2) => invalidate(state2));
|
|
1303
|
-
return rootStore;
|
|
1304
|
-
};
|
|
1305
|
-
|
|
1306
|
-
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
1307
|
-
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
1308
|
-
function getLoader(Proto) {
|
|
1309
|
-
if (isConstructor$1(Proto)) {
|
|
1310
|
-
let loader = memoizedLoaders.get(Proto);
|
|
1311
|
-
if (!loader) {
|
|
1312
|
-
loader = new Proto();
|
|
1313
|
-
memoizedLoaders.set(Proto, loader);
|
|
1314
|
-
}
|
|
1315
|
-
return loader;
|
|
1316
|
-
}
|
|
1317
|
-
return Proto;
|
|
1318
|
-
}
|
|
1319
|
-
function loadingFn(extensions, onProgress) {
|
|
1320
|
-
return function(Proto, input) {
|
|
1321
|
-
const loader = getLoader(Proto);
|
|
1322
|
-
if (extensions) extensions(loader);
|
|
1323
|
-
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
1324
|
-
return loader.loadAsync(input, onProgress).then((data) => {
|
|
1325
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1326
|
-
return data;
|
|
1327
|
-
});
|
|
1328
|
-
}
|
|
1329
|
-
return new Promise(
|
|
1330
|
-
(res, reject) => loader.load(
|
|
1331
|
-
input,
|
|
1332
|
-
(data) => {
|
|
1333
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1334
|
-
res(data);
|
|
1335
|
-
},
|
|
1336
|
-
onProgress,
|
|
1337
|
-
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
1338
|
-
)
|
|
1339
|
-
);
|
|
1340
|
-
};
|
|
1341
|
-
}
|
|
1342
|
-
function useLoader(loader, input, extensions, onProgress) {
|
|
1343
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1344
|
-
const fn = loadingFn(extensions, onProgress);
|
|
1345
|
-
const results = keys.map((key) => suspendReact.suspend(fn, [loader, key], { equal: is.equ }));
|
|
1346
|
-
return Array.isArray(input) ? results : results[0];
|
|
1347
|
-
}
|
|
1348
|
-
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
1349
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1350
|
-
keys.forEach((key) => suspendReact.preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
1351
|
-
};
|
|
1352
|
-
useLoader.clear = function(loader, input) {
|
|
1353
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1354
|
-
keys.forEach((key) => suspendReact.clear([loader, key]));
|
|
1355
|
-
};
|
|
1356
|
-
useLoader.loader = getLoader;
|
|
1357
|
-
|
|
1358
|
-
var __defProp$1 = Object.defineProperty;
|
|
1359
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1360
|
-
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1361
|
-
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1362
|
-
class PhaseGraph {
|
|
1363
|
-
constructor() {
|
|
1364
|
-
/** Ordered list of phase nodes */
|
|
1365
|
-
__publicField$1(this, "phases", []);
|
|
1366
|
-
/** Quick lookup by name */
|
|
1367
|
-
__publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1368
|
-
/** Cached ordered names (invalidated on changes) */
|
|
1369
|
-
__publicField$1(this, "orderedNamesCache", null);
|
|
1370
|
-
this.initializeDefaultPhases();
|
|
1371
|
-
}
|
|
1372
|
-
//* Initialization --------------------------------
|
|
1373
|
-
initializeDefaultPhases() {
|
|
1374
|
-
for (const name of DEFAULT_PHASES) {
|
|
1375
|
-
const node = { name, isAutoGenerated: false };
|
|
1376
|
-
this.phases.push(node);
|
|
1377
|
-
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);
|
|
1378
1483
|
}
|
|
1379
1484
|
this.invalidateCache();
|
|
1380
1485
|
}
|
|
@@ -2260,132 +2365,445 @@ const _Scheduler = class _Scheduler {
|
|
|
2260
2365
|
console.error(`[Scheduler] Error in global job "${job.id}":`, error);
|
|
2261
2366
|
}
|
|
2262
2367
|
}
|
|
2263
|
-
}
|
|
2264
|
-
/**
|
|
2265
|
-
* Execute all jobs for a single root in sorted order.
|
|
2266
|
-
* Rebuilds sorted job list if needed, then dispatches each job.
|
|
2267
|
-
* Errors are caught and propagated via triggerError.
|
|
2268
|
-
* @param {RootEntry} root - The root entry to tick
|
|
2269
|
-
* @param {number} timestamp - RAF timestamp in milliseconds
|
|
2270
|
-
* @param {number} delta - Time since last frame in seconds
|
|
2271
|
-
* @returns {void}
|
|
2272
|
-
* @private
|
|
2273
|
-
*/
|
|
2274
|
-
tickRoot(root, timestamp, delta) {
|
|
2275
|
-
if (root.needsRebuild) {
|
|
2276
|
-
root.sortedJobs = rebuildSortedJobs(root.jobs, this.phaseGraph);
|
|
2277
|
-
root.needsRebuild = false;
|
|
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
|
+
}
|
|
2278
2738
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
if (!shouldRun(job, timestamp)) continue;
|
|
2290
|
-
try {
|
|
2291
|
-
job.callback(frameState, delta);
|
|
2292
|
-
} catch (error) {
|
|
2293
|
-
console.error(`[Scheduler] Error in job "${job.id}":`, error);
|
|
2294
|
-
this.triggerError(error instanceof Error ? error : new Error(String(error)));
|
|
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);
|
|
2295
2749
|
}
|
|
2296
2750
|
}
|
|
2297
|
-
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
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);
|
|
2308
2764
|
}
|
|
2309
|
-
return
|
|
2765
|
+
return loader;
|
|
2310
2766
|
}
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
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
|
+
});
|
|
2320
2778
|
}
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
*/
|
|
2340
|
-
hasUserJobsInPhase(phase, rootId) {
|
|
2341
|
-
const rootsToCheck = rootId ? [this.roots.get(rootId)].filter(Boolean) : Array.from(this.roots.values());
|
|
2342
|
-
return rootsToCheck.some((root) => {
|
|
2343
|
-
if (!root) return false;
|
|
2344
|
-
for (const job of root.jobs.values()) {
|
|
2345
|
-
if (job.phase === phase && !job.system && job.enabled) return true;
|
|
2346
|
-
}
|
|
2347
|
-
return false;
|
|
2348
|
-
});
|
|
2349
|
-
}
|
|
2350
|
-
//* Utility Methods ================================
|
|
2351
|
-
/**
|
|
2352
|
-
* Generate a unique root ID for automatic root registration.
|
|
2353
|
-
* @returns {string} A unique root ID in the format 'root_N'
|
|
2354
|
-
*/
|
|
2355
|
-
generateRootId() {
|
|
2356
|
-
return `root_${this.nextRootIndex++}`;
|
|
2357
|
-
}
|
|
2358
|
-
/**
|
|
2359
|
-
* Generate a unique job ID.
|
|
2360
|
-
* @returns {string} A unique job ID in the format 'job_N'
|
|
2361
|
-
* @private
|
|
2362
|
-
*/
|
|
2363
|
-
generateJobId() {
|
|
2364
|
-
return `job_${this.nextJobIndex}`;
|
|
2365
|
-
}
|
|
2366
|
-
/**
|
|
2367
|
-
* Normalize before/after constraints to a Set.
|
|
2368
|
-
* Handles undefined, single string, or array inputs.
|
|
2369
|
-
* @param {string | string[] | undefined} value - The constraint value(s)
|
|
2370
|
-
* @returns {Set<string>} Normalized Set of constraint strings
|
|
2371
|
-
* @private
|
|
2372
|
-
*/
|
|
2373
|
-
normalizeConstraints(value) {
|
|
2374
|
-
if (!value) return /* @__PURE__ */ new Set();
|
|
2375
|
-
if (Array.isArray(value)) return new Set(value);
|
|
2376
|
-
return /* @__PURE__ */ new Set([value]);
|
|
2377
|
-
}
|
|
2378
|
-
};
|
|
2379
|
-
//* Static State & Methods (Singleton Usage) ================================
|
|
2380
|
-
//* Cross-Bundle Singleton Key ==============================
|
|
2381
|
-
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2382
|
-
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2383
|
-
__publicField(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2384
|
-
let Scheduler = _Scheduler;
|
|
2385
|
-
const getScheduler = () => Scheduler.get();
|
|
2386
|
-
if (hmrData) {
|
|
2387
|
-
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];
|
|
2388
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;
|
|
2389
2807
|
|
|
2390
2808
|
function useFrame(callback, priorityOrOptions) {
|
|
2391
2809
|
const store = React__namespace.useContext(context);
|
|
@@ -2566,6 +2984,9 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2566
2984
|
const textureCache = useThree((state) => state.textures);
|
|
2567
2985
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
2568
2986
|
const { onLoad, cache = false } = options;
|
|
2987
|
+
const onLoadRef = React.useRef(onLoad);
|
|
2988
|
+
onLoadRef.current = onLoad;
|
|
2989
|
+
const onLoadCalledForRef = React.useRef(null);
|
|
2569
2990
|
const urls = React.useMemo(() => getUrls(input), [input]);
|
|
2570
2991
|
const cachedResult = React.useMemo(() => {
|
|
2571
2992
|
if (!cache) return null;
|
|
@@ -2576,9 +2997,13 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2576
2997
|
three.TextureLoader,
|
|
2577
2998
|
IsObject(input) ? Object.values(input) : input
|
|
2578
2999
|
);
|
|
3000
|
+
const inputKey = urls.join("\0");
|
|
2579
3001
|
React.useLayoutEffect(() => {
|
|
2580
|
-
if (
|
|
2581
|
-
|
|
3002
|
+
if (cachedResult) return;
|
|
3003
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
3004
|
+
onLoadCalledForRef.current = inputKey;
|
|
3005
|
+
onLoadRef.current?.(loadedTextures);
|
|
3006
|
+
}, [cachedResult, loadedTextures, inputKey]);
|
|
2582
3007
|
React.useEffect(() => {
|
|
2583
3008
|
if (cachedResult) return;
|
|
2584
3009
|
if ("initTexture" in renderer) {
|
|
@@ -2745,14 +3170,31 @@ function useTextures() {
|
|
|
2745
3170
|
}, [store]);
|
|
2746
3171
|
}
|
|
2747
3172
|
|
|
2748
|
-
function useRenderTarget(
|
|
3173
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
2749
3174
|
const isLegacy = useThree((s) => s.isLegacy);
|
|
2750
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
|
+
}
|
|
2751
3193
|
return React.useMemo(() => {
|
|
2752
3194
|
const w = width ?? size.width;
|
|
2753
3195
|
const h = height ?? size.height;
|
|
2754
|
-
return new three.WebGLRenderTarget(w, h,
|
|
2755
|
-
}, [width, height, size.width, size.height,
|
|
3196
|
+
return new three.WebGLRenderTarget(w, h, opts);
|
|
3197
|
+
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
2756
3198
|
}
|
|
2757
3199
|
|
|
2758
3200
|
function useStore() {
|
|
@@ -2802,7 +3244,7 @@ function addTail(callback) {
|
|
|
2802
3244
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
2803
3245
|
getScheduler().invalidate(frames, stackFrames);
|
|
2804
3246
|
}
|
|
2805
|
-
function advance(timestamp
|
|
3247
|
+
function advance(timestamp) {
|
|
2806
3248
|
getScheduler().step(timestamp);
|
|
2807
3249
|
}
|
|
2808
3250
|
|
|
@@ -14256,6 +14698,7 @@ function swapInstances() {
|
|
|
14256
14698
|
instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
|
|
14257
14699
|
instance.object.__r3f = instance;
|
|
14258
14700
|
setFiberRef(fiber, instance.object);
|
|
14701
|
+
delete instance.appliedOnce;
|
|
14259
14702
|
applyProps(instance.object, instance.props);
|
|
14260
14703
|
if (instance.props.attach) {
|
|
14261
14704
|
attach(parent, instance);
|
|
@@ -14329,8 +14772,22 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14329
14772
|
const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
|
|
14330
14773
|
if (isTailSibling) swapInstances();
|
|
14331
14774
|
},
|
|
14332
|
-
finalizeInitialChildren: () =>
|
|
14333
|
-
|
|
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);
|
|
14334
14791
|
},
|
|
14335
14792
|
getPublicInstance: (instance) => instance?.object,
|
|
14336
14793
|
prepareForCommit: () => null,
|
|
@@ -14551,6 +15008,9 @@ function createRoot(canvas) {
|
|
|
14551
15008
|
let resolve;
|
|
14552
15009
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14553
15010
|
const {
|
|
15011
|
+
id: canvasId,
|
|
15012
|
+
primaryCanvas,
|
|
15013
|
+
scheduler: schedulerConfig,
|
|
14554
15014
|
gl: glConfig,
|
|
14555
15015
|
renderer: rendererConfig,
|
|
14556
15016
|
size: propsSize,
|
|
@@ -14558,10 +15018,7 @@ function createRoot(canvas) {
|
|
|
14558
15018
|
events,
|
|
14559
15019
|
onCreated: onCreatedCallback,
|
|
14560
15020
|
shadows = false,
|
|
14561
|
-
linear = false,
|
|
14562
|
-
flat = false,
|
|
14563
15021
|
textureColorSpace = three.SRGBColorSpace,
|
|
14564
|
-
legacy = false,
|
|
14565
15022
|
orthographic = false,
|
|
14566
15023
|
frameloop = "always",
|
|
14567
15024
|
dpr = [1, 2],
|
|
@@ -14573,7 +15030,8 @@ function createRoot(canvas) {
|
|
|
14573
15030
|
onDropMissed,
|
|
14574
15031
|
autoUpdateFrustum = true,
|
|
14575
15032
|
occlusion = false,
|
|
14576
|
-
_sizeProps
|
|
15033
|
+
_sizeProps,
|
|
15034
|
+
forceEven
|
|
14577
15035
|
} = props;
|
|
14578
15036
|
const state = store.getState();
|
|
14579
15037
|
const defaultGLProps = {
|
|
@@ -14587,15 +15045,25 @@ function createRoot(canvas) {
|
|
|
14587
15045
|
"WebGPURenderer (renderer prop) is not available in this build. Use @react-three/fiber or @react-three/fiber/webgpu instead."
|
|
14588
15046
|
);
|
|
14589
15047
|
}
|
|
14590
|
-
(state.isLegacy || glConfig || !R3F_BUILD_WEBGPU);
|
|
15048
|
+
const wantsGL = (state.isLegacy || glConfig || !R3F_BUILD_WEBGPU);
|
|
14591
15049
|
if (glConfig && rendererConfig) {
|
|
14592
15050
|
throw new Error("Cannot use both gl and renderer props at the same time");
|
|
14593
15051
|
}
|
|
14594
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
|
+
}
|
|
14595
15063
|
if (!state.internal.actualRenderer) {
|
|
14596
15064
|
renderer = await resolveRenderer(glConfig, defaultGLProps, three.WebGLRenderer);
|
|
14597
15065
|
state.internal.actualRenderer = renderer;
|
|
14598
|
-
state.set({ isLegacy: true, gl: renderer, renderer });
|
|
15066
|
+
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
14599
15067
|
}
|
|
14600
15068
|
let raycaster = state.raycaster;
|
|
14601
15069
|
if (!raycaster) state.set({ raycaster: raycaster = new three.Raycaster() });
|
|
@@ -14604,6 +15072,7 @@ function createRoot(canvas) {
|
|
|
14604
15072
|
if (!is.equ(params, raycaster.params, shallowLoose)) {
|
|
14605
15073
|
applyProps(raycaster, { params: { ...raycaster.params, ...params } });
|
|
14606
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) {
|
|
@@ -14657,6 +15127,9 @@ function createRoot(canvas) {
|
|
|
14657
15127
|
if (_sizeProps !== void 0) {
|
|
14658
15128
|
state.set({ _sizeProps });
|
|
14659
15129
|
}
|
|
15130
|
+
if (forceEven !== void 0 && state.internal.forceEven !== forceEven) {
|
|
15131
|
+
state.set((prev) => ({ internal: { ...prev.internal, forceEven } }));
|
|
15132
|
+
}
|
|
14660
15133
|
const size = computeInitialSize(canvas, propsSize);
|
|
14661
15134
|
if (!state._sizeImperative && !is.equ(size, state.size, shallowLoose)) {
|
|
14662
15135
|
const wasImperative = state._sizeImperative;
|
|
@@ -14686,7 +15159,7 @@ function createRoot(canvas) {
|
|
|
14686
15159
|
const handleXRFrame = (timestamp, frame) => {
|
|
14687
15160
|
const state2 = store.getState();
|
|
14688
15161
|
if (state2.frameloop === "never") return;
|
|
14689
|
-
advance(timestamp
|
|
15162
|
+
advance(timestamp);
|
|
14690
15163
|
};
|
|
14691
15164
|
const actualRenderer = state.internal.actualRenderer;
|
|
14692
15165
|
const handleSessionChange = () => {
|
|
@@ -14698,16 +15171,16 @@ function createRoot(canvas) {
|
|
|
14698
15171
|
};
|
|
14699
15172
|
const xr = {
|
|
14700
15173
|
connect() {
|
|
14701
|
-
const { gl, renderer: renderer2
|
|
14702
|
-
const
|
|
14703
|
-
|
|
14704
|
-
|
|
15174
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15175
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15176
|
+
xrManager.addEventListener("sessionstart", handleSessionChange);
|
|
15177
|
+
xrManager.addEventListener("sessionend", handleSessionChange);
|
|
14705
15178
|
},
|
|
14706
15179
|
disconnect() {
|
|
14707
|
-
const { gl, renderer: renderer2
|
|
14708
|
-
const
|
|
14709
|
-
|
|
14710
|
-
|
|
15180
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15181
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15182
|
+
xrManager.removeEventListener("sessionstart", handleSessionChange);
|
|
15183
|
+
xrManager.removeEventListener("sessionend", handleSessionChange);
|
|
14711
15184
|
}
|
|
14712
15185
|
};
|
|
14713
15186
|
if (typeof renderer.xr?.addEventListener === "function") xr.connect();
|
|
@@ -14735,25 +15208,9 @@ function createRoot(canvas) {
|
|
|
14735
15208
|
renderer.shadowMap.needsUpdate = true;
|
|
14736
15209
|
}
|
|
14737
15210
|
}
|
|
14738
|
-
{
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
const flatChanged = flat !== lastConfiguredProps.flat;
|
|
14742
|
-
if (legacyChanged) {
|
|
14743
|
-
three.ColorManagement.enabled = !legacy;
|
|
14744
|
-
lastConfiguredProps.legacy = legacy;
|
|
14745
|
-
}
|
|
14746
|
-
if (!configured || linearChanged) {
|
|
14747
|
-
renderer.outputColorSpace = linear ? three.LinearSRGBColorSpace : three.SRGBColorSpace;
|
|
14748
|
-
lastConfiguredProps.linear = linear;
|
|
14749
|
-
}
|
|
14750
|
-
if (!configured || flatChanged) {
|
|
14751
|
-
renderer.toneMapping = flat ? three.NoToneMapping : three.ACESFilmicToneMapping;
|
|
14752
|
-
lastConfiguredProps.flat = flat;
|
|
14753
|
-
}
|
|
14754
|
-
if (legacyChanged && state.legacy !== legacy) state.set(() => ({ legacy }));
|
|
14755
|
-
if (linearChanged && state.linear !== linear) state.set(() => ({ linear }));
|
|
14756
|
-
if (flatChanged && state.flat !== flat) state.set(() => ({ flat }));
|
|
15211
|
+
if (!configured) {
|
|
15212
|
+
renderer.outputColorSpace = three.SRGBColorSpace;
|
|
15213
|
+
renderer.toneMapping = three.ACESFilmicToneMapping;
|
|
14757
15214
|
}
|
|
14758
15215
|
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
14759
15216
|
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
@@ -14771,11 +15228,26 @@ function createRoot(canvas) {
|
|
|
14771
15228
|
const scheduler = getScheduler();
|
|
14772
15229
|
const rootId = state.internal.rootId;
|
|
14773
15230
|
if (!rootId) {
|
|
14774
|
-
const newRootId = scheduler.generateRootId();
|
|
15231
|
+
const newRootId = canvasId || scheduler.generateRootId();
|
|
14775
15232
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14776
15233
|
getState: () => store.getState(),
|
|
14777
15234
|
onError: (err) => store.getState().setError(err)
|
|
14778
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
|
+
);
|
|
14779
15251
|
const unregisterFrustum = scheduler.register(
|
|
14780
15252
|
() => {
|
|
14781
15253
|
const state2 = store.getState();
|
|
@@ -14817,11 +15289,15 @@ function createRoot(canvas) {
|
|
|
14817
15289
|
}
|
|
14818
15290
|
},
|
|
14819
15291
|
{
|
|
14820
|
-
|
|
15292
|
+
// Use canvas ID directly as job ID if available, otherwise use generated rootId
|
|
15293
|
+
id: canvasId || `${newRootId}_render`,
|
|
14821
15294
|
rootId: newRootId,
|
|
14822
15295
|
phase: "render",
|
|
14823
|
-
system: true
|
|
15296
|
+
system: true,
|
|
14824
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 }
|
|
14825
15301
|
}
|
|
14826
15302
|
);
|
|
14827
15303
|
state.set((state2) => ({
|
|
@@ -14830,6 +15306,7 @@ function createRoot(canvas) {
|
|
|
14830
15306
|
rootId: newRootId,
|
|
14831
15307
|
unregisterRoot: () => {
|
|
14832
15308
|
unregisterRoot();
|
|
15309
|
+
unregisterCanvasTarget();
|
|
14833
15310
|
unregisterFrustum();
|
|
14834
15311
|
unregisterVisibility();
|
|
14835
15312
|
unregisterRender();
|
|
@@ -14888,15 +15365,24 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14888
15365
|
const renderer = state.internal.actualRenderer;
|
|
14889
15366
|
const unregisterRoot = state.internal.unregisterRoot;
|
|
14890
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();
|
|
14891
15372
|
state.events.disconnect?.();
|
|
14892
15373
|
cleanupHelperGroup(root.store);
|
|
14893
|
-
renderer
|
|
14894
|
-
|
|
14895
|
-
|
|
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
|
+
}
|
|
14896
15382
|
dispose(state.scene);
|
|
14897
15383
|
_roots.delete(canvas);
|
|
14898
15384
|
if (callback) callback(canvas);
|
|
14899
|
-
} catch
|
|
15385
|
+
} catch {
|
|
14900
15386
|
}
|
|
14901
15387
|
}, 500);
|
|
14902
15388
|
}
|
|
@@ -14904,36 +15390,34 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14904
15390
|
}
|
|
14905
15391
|
}
|
|
14906
15392
|
function createPortal(children, container, state) {
|
|
14907
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15393
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Portal, { children, container, state });
|
|
14908
15394
|
}
|
|
14909
|
-
function
|
|
15395
|
+
function Portal({ children, container, state }) {
|
|
14910
15396
|
const isRef = React.useCallback((obj) => obj && "current" in obj, []);
|
|
14911
|
-
const [resolvedContainer,
|
|
15397
|
+
const [resolvedContainer, _setResolvedContainer] = React.useState(() => {
|
|
14912
15398
|
if (isRef(container)) return container.current ?? null;
|
|
14913
15399
|
return container;
|
|
14914
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
|
+
);
|
|
14915
15408
|
React.useMemo(() => {
|
|
14916
|
-
if (isRef(container)) {
|
|
14917
|
-
|
|
14918
|
-
|
|
14919
|
-
|
|
14920
|
-
const updated = container.current;
|
|
14921
|
-
if (updated && updated !== resolvedContainer) {
|
|
14922
|
-
setResolvedContainer(updated);
|
|
14923
|
-
}
|
|
14924
|
-
});
|
|
14925
|
-
} else if (current !== resolvedContainer) {
|
|
14926
|
-
setResolvedContainer(current);
|
|
14927
|
-
}
|
|
14928
|
-
} else if (container !== resolvedContainer) {
|
|
14929
|
-
setResolvedContainer(container);
|
|
15409
|
+
if (isRef(container) && !container.current) {
|
|
15410
|
+
return queueMicrotask(() => {
|
|
15411
|
+
setResolvedContainer(container.current);
|
|
15412
|
+
});
|
|
14930
15413
|
}
|
|
14931
|
-
|
|
15414
|
+
setResolvedContainer(container);
|
|
15415
|
+
}, [container, isRef, setResolvedContainer]);
|
|
14932
15416
|
if (!resolvedContainer) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
14933
15417
|
const portalKey = resolvedContainer.uuid ?? `portal-${resolvedContainer.id ?? "unknown"}`;
|
|
14934
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15418
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PortalInner, { children, container: resolvedContainer, state }, portalKey);
|
|
14935
15419
|
}
|
|
14936
|
-
function
|
|
15420
|
+
function PortalInner({ state = {}, children, container }) {
|
|
14937
15421
|
const { events, size, injectScene = true, ...rest } = state;
|
|
14938
15422
|
const previousRoot = useStore();
|
|
14939
15423
|
const [raycaster] = React.useState(() => new three.Raycaster());
|
|
@@ -14954,11 +15438,12 @@ function Portal({ state = {}, children, container }) {
|
|
|
14954
15438
|
};
|
|
14955
15439
|
}, [portalScene, container, injectScene]);
|
|
14956
15440
|
const inject = useMutableCallback((rootState, injectState) => {
|
|
15441
|
+
const resolvedSize = { ...rootState.size, ...injectState.size, ...size };
|
|
14957
15442
|
let viewport = void 0;
|
|
14958
|
-
if (injectState.camera && size) {
|
|
15443
|
+
if (injectState.camera && (size || injectState.size)) {
|
|
14959
15444
|
const camera = injectState.camera;
|
|
14960
|
-
viewport = rootState.viewport.getCurrentViewport(camera, new three.Vector3(),
|
|
14961
|
-
if (camera !== rootState.camera) updateCamera(camera,
|
|
15445
|
+
viewport = rootState.viewport.getCurrentViewport(camera, new three.Vector3(), resolvedSize);
|
|
15446
|
+
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14962
15447
|
}
|
|
14963
15448
|
return {
|
|
14964
15449
|
// The intersect consists of the previous root state
|
|
@@ -14975,7 +15460,7 @@ function Portal({ state = {}, children, container }) {
|
|
|
14975
15460
|
previousRoot,
|
|
14976
15461
|
// Events, size and viewport can be overridden by the inject layer
|
|
14977
15462
|
events: { ...rootState.events, ...injectState.events, ...events },
|
|
14978
|
-
size:
|
|
15463
|
+
size: resolvedSize,
|
|
14979
15464
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14980
15465
|
// Layers are allowed to override events
|
|
14981
15466
|
setEvents: (events2) => injectState.set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
@@ -15009,15 +15494,13 @@ function CanvasImpl({
|
|
|
15009
15494
|
fallback,
|
|
15010
15495
|
resize,
|
|
15011
15496
|
style,
|
|
15497
|
+
id,
|
|
15012
15498
|
gl,
|
|
15013
|
-
renderer,
|
|
15499
|
+
renderer: rendererProp,
|
|
15014
15500
|
events = createPointerEvents,
|
|
15015
15501
|
eventSource,
|
|
15016
15502
|
eventPrefix,
|
|
15017
15503
|
shadows,
|
|
15018
|
-
linear,
|
|
15019
|
-
flat,
|
|
15020
|
-
legacy,
|
|
15021
15504
|
orthographic,
|
|
15022
15505
|
frameloop,
|
|
15023
15506
|
dpr,
|
|
@@ -15032,10 +15515,43 @@ function CanvasImpl({
|
|
|
15032
15515
|
hmr,
|
|
15033
15516
|
width,
|
|
15034
15517
|
height,
|
|
15518
|
+
background,
|
|
15519
|
+
forceEven,
|
|
15035
15520
|
...props
|
|
15036
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;
|
|
15037
15524
|
React__namespace.useMemo(() => extend(THREE), []);
|
|
15038
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]);
|
|
15039
15555
|
const hasInitialSizeRef = React__namespace.useRef(false);
|
|
15040
15556
|
const measureConfig = React__namespace.useMemo(() => {
|
|
15041
15557
|
if (!hasInitialSizeRef.current) {
|
|
@@ -15052,15 +15568,20 @@ function CanvasImpl({
|
|
|
15052
15568
|
};
|
|
15053
15569
|
}, [resize, hasInitialSizeRef.current]);
|
|
15054
15570
|
const [containerRef, containerRect] = useMeasure__default(measureConfig);
|
|
15055
|
-
const effectiveSize = React__namespace.useMemo(
|
|
15056
|
-
|
|
15057
|
-
|
|
15058
|
-
|
|
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,
|
|
15059
15581
|
top: containerRect.top,
|
|
15060
15582
|
left: containerRect.left
|
|
15061
|
-
}
|
|
15062
|
-
|
|
15063
|
-
);
|
|
15583
|
+
};
|
|
15584
|
+
}, [width, height, containerRect, forceEven]);
|
|
15064
15585
|
if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
|
|
15065
15586
|
hasInitialSizeRef.current = true;
|
|
15066
15587
|
}
|
|
@@ -15100,14 +15621,14 @@ function CanvasImpl({
|
|
|
15100
15621
|
async function run() {
|
|
15101
15622
|
if (!effectActiveRef.current || !root.current) return;
|
|
15102
15623
|
await root.current.configure({
|
|
15624
|
+
id,
|
|
15625
|
+
primaryCanvas,
|
|
15626
|
+
scheduler,
|
|
15103
15627
|
gl,
|
|
15104
15628
|
renderer,
|
|
15105
15629
|
scene,
|
|
15106
15630
|
events,
|
|
15107
15631
|
shadows,
|
|
15108
|
-
linear,
|
|
15109
|
-
flat,
|
|
15110
|
-
legacy,
|
|
15111
15632
|
orthographic,
|
|
15112
15633
|
frameloop,
|
|
15113
15634
|
dpr,
|
|
@@ -15117,6 +15638,7 @@ function CanvasImpl({
|
|
|
15117
15638
|
size: effectiveSize,
|
|
15118
15639
|
// Store size props for reset functionality
|
|
15119
15640
|
_sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
|
|
15641
|
+
forceEven,
|
|
15120
15642
|
// Pass mutable reference to onPointerMissed so it's free to update
|
|
15121
15643
|
onPointerMissed: (...args) => handlePointerMissed.current?.(...args),
|
|
15122
15644
|
onDragOverMissed: (...args) => handleDragOverMissed.current?.(...args),
|
|
@@ -15140,7 +15662,10 @@ function CanvasImpl({
|
|
|
15140
15662
|
});
|
|
15141
15663
|
if (!effectActiveRef.current || !root.current) return;
|
|
15142
15664
|
root.current.render(
|
|
15143
|
-
/* @__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
|
+
] }) }) })
|
|
15144
15669
|
);
|
|
15145
15670
|
}
|
|
15146
15671
|
run();
|
|
@@ -15167,14 +15692,16 @@ function CanvasImpl({
|
|
|
15167
15692
|
const canvas = canvasRef.current;
|
|
15168
15693
|
if (!canvas) return;
|
|
15169
15694
|
const handleHMR = () => {
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
rootEntry
|
|
15173
|
-
|
|
15174
|
-
|
|
15175
|
-
|
|
15176
|
-
|
|
15177
|
-
|
|
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
|
+
});
|
|
15178
15705
|
};
|
|
15179
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) {
|
|
15180
15707
|
const hot = undefined;
|
|
@@ -15203,7 +15730,7 @@ function CanvasImpl({
|
|
|
15203
15730
|
...style
|
|
15204
15731
|
},
|
|
15205
15732
|
...props,
|
|
15206
|
-
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 }) })
|
|
15207
15734
|
}
|
|
15208
15735
|
);
|
|
15209
15736
|
}
|
|
@@ -15215,8 +15742,15 @@ extend(THREE);
|
|
|
15215
15742
|
|
|
15216
15743
|
exports.Block = Block;
|
|
15217
15744
|
exports.Canvas = Canvas;
|
|
15745
|
+
exports.Environment = Environment;
|
|
15746
|
+
exports.EnvironmentCube = EnvironmentCube;
|
|
15747
|
+
exports.EnvironmentMap = EnvironmentMap;
|
|
15748
|
+
exports.EnvironmentPortal = EnvironmentPortal;
|
|
15218
15749
|
exports.ErrorBoundary = ErrorBoundary;
|
|
15750
|
+
exports.FROM_REF = FROM_REF;
|
|
15219
15751
|
exports.IsObject = IsObject;
|
|
15752
|
+
exports.ONCE = ONCE;
|
|
15753
|
+
exports.Portal = Portal;
|
|
15220
15754
|
exports.R3F_BUILD_LEGACY = R3F_BUILD_LEGACY;
|
|
15221
15755
|
exports.R3F_BUILD_WEBGPU = R3F_BUILD_WEBGPU;
|
|
15222
15756
|
exports.REACT_INTERNAL_PROPS = REACT_INTERNAL_PROPS;
|
|
@@ -15246,30 +15780,41 @@ exports.events = createPointerEvents;
|
|
|
15246
15780
|
exports.extend = extend;
|
|
15247
15781
|
exports.findInitialRoot = findInitialRoot;
|
|
15248
15782
|
exports.flushSync = flushSync;
|
|
15783
|
+
exports.fromRef = fromRef;
|
|
15249
15784
|
exports.getInstanceProps = getInstanceProps;
|
|
15785
|
+
exports.getPrimary = getPrimary;
|
|
15786
|
+
exports.getPrimaryIds = getPrimaryIds;
|
|
15250
15787
|
exports.getRootState = getRootState;
|
|
15251
15788
|
exports.getScheduler = getScheduler;
|
|
15252
15789
|
exports.getUuidPrefix = getUuidPrefix;
|
|
15253
15790
|
exports.hasConstructor = hasConstructor;
|
|
15791
|
+
exports.hasPrimary = hasPrimary;
|
|
15254
15792
|
exports.invalidate = invalidate;
|
|
15255
15793
|
exports.invalidateInstance = invalidateInstance;
|
|
15256
15794
|
exports.is = is;
|
|
15257
15795
|
exports.isColorRepresentation = isColorRepresentation;
|
|
15258
15796
|
exports.isCopyable = isCopyable;
|
|
15797
|
+
exports.isFromRef = isFromRef;
|
|
15259
15798
|
exports.isObject3D = isObject3D;
|
|
15799
|
+
exports.isOnce = isOnce;
|
|
15260
15800
|
exports.isOrthographicCamera = isOrthographicCamera;
|
|
15261
15801
|
exports.isRef = isRef;
|
|
15262
15802
|
exports.isRenderer = isRenderer;
|
|
15263
15803
|
exports.isTexture = isTexture;
|
|
15264
15804
|
exports.isVectorLike = isVectorLike;
|
|
15805
|
+
exports.once = once;
|
|
15265
15806
|
exports.prepare = prepare;
|
|
15807
|
+
exports.presetsObj = presetsObj;
|
|
15266
15808
|
exports.reconciler = reconciler;
|
|
15809
|
+
exports.registerPrimary = registerPrimary;
|
|
15267
15810
|
exports.removeInteractivity = removeInteractivity;
|
|
15268
15811
|
exports.resolve = resolve;
|
|
15269
15812
|
exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
15813
|
+
exports.unregisterPrimary = unregisterPrimary;
|
|
15270
15814
|
exports.updateCamera = updateCamera;
|
|
15271
15815
|
exports.updateFrustum = updateFrustum;
|
|
15272
15816
|
exports.useBridge = useBridge;
|
|
15817
|
+
exports.useEnvironment = useEnvironment;
|
|
15273
15818
|
exports.useFrame = useFrame;
|
|
15274
15819
|
exports.useGraph = useGraph;
|
|
15275
15820
|
exports.useInstanceHandle = useInstanceHandle;
|
|
@@ -15281,3 +15826,4 @@ exports.useStore = useStore;
|
|
|
15281
15826
|
exports.useTexture = useTexture;
|
|
15282
15827
|
exports.useTextures = useTextures;
|
|
15283
15828
|
exports.useThree = useThree;
|
|
15829
|
+
exports.waitForPrimary = waitForPrimary;
|