@react-three/fiber 10.0.0-alpha.1 → 10.0.0-canary.1b98c17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/dist/index.cjs +1499 -614
- package/dist/index.d.cts +2130 -1274
- package/dist/index.d.mts +2130 -1274
- package/dist/index.d.ts +2130 -1274
- package/dist/index.mjs +1483 -618
- package/dist/legacy.cjs +1481 -621
- package/dist/legacy.d.cts +2131 -1275
- package/dist/legacy.d.mts +2131 -1275
- package/dist/legacy.d.ts +2131 -1275
- package/dist/legacy.mjs +1465 -625
- package/dist/webgpu/index.cjs +2098 -601
- package/dist/webgpu/index.d.cts +2391 -1300
- package/dist/webgpu/index.d.mts +2391 -1300
- package/dist/webgpu/index.d.ts +2391 -1300
- package/dist/webgpu/index.mjs +2074 -604
- package/package.json +7 -5
- package/react-reconciler/constants.js +1 -9
- package/react-reconciler/index.js +4 -20
- package/readme.md +244 -318
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import * as webgpu from 'three/webgpu';
|
|
2
|
-
import { RenderTarget, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1,
|
|
2
|
+
import { RenderTarget, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, Scene, WebGLCubeRenderTarget, HalfFloatType, Color, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, SRGBColorSpace, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1, CanvasTarget, Raycaster, OrthographicCamera, PerspectiveCamera, PCFShadowMap, VSMShadowMap, BasicShadowMap, ACESFilmicToneMapping, WebGPURenderer } from 'three/webgpu';
|
|
3
3
|
import { WebGLRenderTarget, WebGLRenderer } from 'three';
|
|
4
4
|
import { Inspector } from 'three/addons/inspector/Inspector.js';
|
|
5
|
-
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
5
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
6
6
|
import * as React from 'react';
|
|
7
|
-
import React__default, {
|
|
7
|
+
import React__default, { useLayoutEffect, useRef, useMemo, useEffect, useContext, useImperativeHandle, useCallback, useState } from 'react';
|
|
8
8
|
import useMeasure from 'react-use-measure';
|
|
9
9
|
import { useFiber, useContextBridge, traverseFiber, FiberProvider } from 'its-fine';
|
|
10
|
+
import { useThree as useThree$1, useLoader as useLoader$1, useFrame as useFrame$1, createPortal as createPortal$1, applyProps as applyProps$1, extend as extend$1 } from '@react-three/fiber';
|
|
11
|
+
import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
|
|
12
|
+
import { HDRLoader } from 'three/examples/jsm/loaders/HDRLoader.js';
|
|
13
|
+
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
|
|
14
|
+
import { UltraHDRLoader } from 'three/examples/jsm/loaders/UltraHDRLoader.js';
|
|
15
|
+
import { GainMapLoader } from '@monogrid/gainmap-js';
|
|
10
16
|
import Tb, { unstable_scheduleCallback, unstable_IdlePriority } from 'scheduler';
|
|
11
17
|
import { createWithEqualityFn } from 'zustand/traditional';
|
|
12
18
|
import { suspend, preload, clear } from 'suspend-react';
|
|
@@ -36,6 +42,389 @@ const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
|
36
42
|
WebGLRenderer: WebGLRenderer
|
|
37
43
|
}, [webgpu]);
|
|
38
44
|
|
|
45
|
+
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
46
|
+
const pendingSubscribers = /* @__PURE__ */ new Map();
|
|
47
|
+
function registerPrimary(id, renderer, store) {
|
|
48
|
+
if (primaryRegistry.has(id)) {
|
|
49
|
+
console.warn(`Canvas with id="${id}" already registered. Overwriting.`);
|
|
50
|
+
}
|
|
51
|
+
const entry = { renderer, store };
|
|
52
|
+
primaryRegistry.set(id, entry);
|
|
53
|
+
const subscribers = pendingSubscribers.get(id);
|
|
54
|
+
if (subscribers) {
|
|
55
|
+
subscribers.forEach((callback) => callback(entry));
|
|
56
|
+
pendingSubscribers.delete(id);
|
|
57
|
+
}
|
|
58
|
+
return () => {
|
|
59
|
+
const currentEntry = primaryRegistry.get(id);
|
|
60
|
+
if (currentEntry?.renderer === renderer) {
|
|
61
|
+
primaryRegistry.delete(id);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function getPrimary(id) {
|
|
66
|
+
return primaryRegistry.get(id);
|
|
67
|
+
}
|
|
68
|
+
function waitForPrimary(id, timeout = 5e3) {
|
|
69
|
+
const existing = primaryRegistry.get(id);
|
|
70
|
+
if (existing) {
|
|
71
|
+
return Promise.resolve(existing);
|
|
72
|
+
}
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
const timeoutId = setTimeout(() => {
|
|
75
|
+
const subscribers = pendingSubscribers.get(id);
|
|
76
|
+
if (subscribers) {
|
|
77
|
+
const index = subscribers.indexOf(callback);
|
|
78
|
+
if (index !== -1) subscribers.splice(index, 1);
|
|
79
|
+
if (subscribers.length === 0) pendingSubscribers.delete(id);
|
|
80
|
+
}
|
|
81
|
+
reject(new Error(`Timeout waiting for canvas with id="${id}". Make sure a <Canvas id="${id}"> is mounted.`));
|
|
82
|
+
}, timeout);
|
|
83
|
+
const callback = (entry) => {
|
|
84
|
+
clearTimeout(timeoutId);
|
|
85
|
+
resolve(entry);
|
|
86
|
+
};
|
|
87
|
+
if (!pendingSubscribers.has(id)) {
|
|
88
|
+
pendingSubscribers.set(id, []);
|
|
89
|
+
}
|
|
90
|
+
pendingSubscribers.get(id).push(callback);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function hasPrimary(id) {
|
|
94
|
+
return primaryRegistry.has(id);
|
|
95
|
+
}
|
|
96
|
+
function unregisterPrimary(id) {
|
|
97
|
+
primaryRegistry.delete(id);
|
|
98
|
+
}
|
|
99
|
+
function getPrimaryIds() {
|
|
100
|
+
return Array.from(primaryRegistry.keys());
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const presetsObj = {
|
|
104
|
+
apartment: "lebombo_1k.hdr",
|
|
105
|
+
city: "potsdamer_platz_1k.hdr",
|
|
106
|
+
dawn: "kiara_1_dawn_1k.hdr",
|
|
107
|
+
forest: "forest_slope_1k.hdr",
|
|
108
|
+
lobby: "st_fagans_interior_1k.hdr",
|
|
109
|
+
night: "dikhololo_night_1k.hdr",
|
|
110
|
+
park: "rooitou_park_1k.hdr",
|
|
111
|
+
studio: "studio_small_03_1k.hdr",
|
|
112
|
+
sunset: "venice_sunset_1k.hdr",
|
|
113
|
+
warehouse: "empty_warehouse_01_1k.hdr"
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
|
|
117
|
+
const isArray = (arr) => Array.isArray(arr);
|
|
118
|
+
const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
|
|
119
|
+
function useEnvironment({
|
|
120
|
+
files = defaultFiles,
|
|
121
|
+
path = "",
|
|
122
|
+
preset = void 0,
|
|
123
|
+
colorSpace = void 0,
|
|
124
|
+
extensions
|
|
125
|
+
} = {}) {
|
|
126
|
+
if (preset) {
|
|
127
|
+
validatePreset(preset);
|
|
128
|
+
files = presetsObj[preset];
|
|
129
|
+
path = CUBEMAP_ROOT;
|
|
130
|
+
}
|
|
131
|
+
const multiFile = isArray(files);
|
|
132
|
+
const { extension, isCubemap } = getExtension(files);
|
|
133
|
+
const loader = getLoader$1(extension);
|
|
134
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
135
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
136
|
+
useLayoutEffect(() => {
|
|
137
|
+
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
138
|
+
function clearGainmapTexture() {
|
|
139
|
+
useLoader$1.clear(loader, multiFile ? [files] : files);
|
|
140
|
+
}
|
|
141
|
+
renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
|
|
142
|
+
}, [extension, files, loader, multiFile, renderer.domElement]);
|
|
143
|
+
const loaderResult = useLoader$1(
|
|
144
|
+
loader,
|
|
145
|
+
multiFile ? [files] : files,
|
|
146
|
+
(loader2) => {
|
|
147
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
148
|
+
loader2.setRenderer?.(renderer);
|
|
149
|
+
}
|
|
150
|
+
loader2.setPath?.(path);
|
|
151
|
+
if (extensions) extensions(loader2);
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
let texture = multiFile ? (
|
|
155
|
+
// @ts-ignore
|
|
156
|
+
loaderResult[0]
|
|
157
|
+
) : loaderResult;
|
|
158
|
+
if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
|
|
159
|
+
texture = texture.renderTarget?.texture;
|
|
160
|
+
}
|
|
161
|
+
texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
|
|
162
|
+
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
163
|
+
return texture;
|
|
164
|
+
}
|
|
165
|
+
const preloadDefaultOptions = {
|
|
166
|
+
files: defaultFiles,
|
|
167
|
+
path: "",
|
|
168
|
+
preset: void 0,
|
|
169
|
+
extensions: void 0
|
|
170
|
+
};
|
|
171
|
+
useEnvironment.preload = (preloadOptions) => {
|
|
172
|
+
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
173
|
+
let { files, path = "" } = options;
|
|
174
|
+
const { preset, extensions } = options;
|
|
175
|
+
if (preset) {
|
|
176
|
+
validatePreset(preset);
|
|
177
|
+
files = presetsObj[preset];
|
|
178
|
+
path = CUBEMAP_ROOT;
|
|
179
|
+
}
|
|
180
|
+
const { extension } = getExtension(files);
|
|
181
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
182
|
+
throw new Error("useEnvironment: Preloading gainmaps is not supported");
|
|
183
|
+
}
|
|
184
|
+
const loader = getLoader$1(extension);
|
|
185
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
186
|
+
useLoader$1.preload(loader, isArray(files) ? [files] : files, (loader2) => {
|
|
187
|
+
loader2.setPath?.(path);
|
|
188
|
+
if (extensions) extensions(loader2);
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
const clearDefaultOptins = {
|
|
192
|
+
files: defaultFiles,
|
|
193
|
+
preset: void 0
|
|
194
|
+
};
|
|
195
|
+
useEnvironment.clear = (clearOptions) => {
|
|
196
|
+
const options = { ...clearDefaultOptins, ...clearOptions };
|
|
197
|
+
let { files } = options;
|
|
198
|
+
const { preset } = options;
|
|
199
|
+
if (preset) {
|
|
200
|
+
validatePreset(preset);
|
|
201
|
+
files = presetsObj[preset];
|
|
202
|
+
}
|
|
203
|
+
const { extension } = getExtension(files);
|
|
204
|
+
const loader = getLoader$1(extension);
|
|
205
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
206
|
+
useLoader$1.clear(loader, isArray(files) ? [files] : files);
|
|
207
|
+
};
|
|
208
|
+
function validatePreset(preset) {
|
|
209
|
+
if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
|
|
210
|
+
}
|
|
211
|
+
function getExtension(files) {
|
|
212
|
+
const isCubemap = isArray(files) && files.length === 6;
|
|
213
|
+
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
214
|
+
const firstEntry = isArray(files) ? files[0] : files;
|
|
215
|
+
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();
|
|
216
|
+
return { extension, isCubemap, isGainmap };
|
|
217
|
+
}
|
|
218
|
+
function getLoader$1(extension) {
|
|
219
|
+
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
220
|
+
return loader;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const isRef$1 = (obj) => obj.current && obj.current.isScene;
|
|
224
|
+
const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
|
|
225
|
+
function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
|
|
226
|
+
sceneProps = {
|
|
227
|
+
backgroundBlurriness: 0,
|
|
228
|
+
backgroundIntensity: 1,
|
|
229
|
+
backgroundRotation: [0, 0, 0],
|
|
230
|
+
environmentIntensity: 1,
|
|
231
|
+
environmentRotation: [0, 0, 0],
|
|
232
|
+
...sceneProps
|
|
233
|
+
};
|
|
234
|
+
const target = resolveScene(scene || defaultScene);
|
|
235
|
+
const oldbg = target.background;
|
|
236
|
+
const oldenv = target.environment;
|
|
237
|
+
const oldSceneProps = {
|
|
238
|
+
// @ts-ignore
|
|
239
|
+
backgroundBlurriness: target.backgroundBlurriness,
|
|
240
|
+
// @ts-ignore
|
|
241
|
+
backgroundIntensity: target.backgroundIntensity,
|
|
242
|
+
// @ts-ignore
|
|
243
|
+
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
244
|
+
// @ts-ignore
|
|
245
|
+
environmentIntensity: target.environmentIntensity,
|
|
246
|
+
// @ts-ignore
|
|
247
|
+
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
248
|
+
};
|
|
249
|
+
if (background !== "only") target.environment = texture;
|
|
250
|
+
if (background) target.background = texture;
|
|
251
|
+
applyProps$1(target, sceneProps);
|
|
252
|
+
return () => {
|
|
253
|
+
if (background !== "only") target.environment = oldenv;
|
|
254
|
+
if (background) target.background = oldbg;
|
|
255
|
+
applyProps$1(target, oldSceneProps);
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
function EnvironmentMap({ scene, background = false, map, ...config }) {
|
|
259
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
260
|
+
React.useLayoutEffect(() => {
|
|
261
|
+
if (map) return setEnvProps(background, scene, defaultScene, map, config);
|
|
262
|
+
});
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
function EnvironmentCube({
|
|
266
|
+
background = false,
|
|
267
|
+
scene,
|
|
268
|
+
blur,
|
|
269
|
+
backgroundBlurriness,
|
|
270
|
+
backgroundIntensity,
|
|
271
|
+
backgroundRotation,
|
|
272
|
+
environmentIntensity,
|
|
273
|
+
environmentRotation,
|
|
274
|
+
...rest
|
|
275
|
+
}) {
|
|
276
|
+
const texture = useEnvironment(rest);
|
|
277
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
278
|
+
React.useLayoutEffect(() => {
|
|
279
|
+
return setEnvProps(background, scene, defaultScene, texture, {
|
|
280
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
281
|
+
backgroundIntensity,
|
|
282
|
+
backgroundRotation,
|
|
283
|
+
environmentIntensity,
|
|
284
|
+
environmentRotation
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
React.useEffect(() => {
|
|
288
|
+
return () => {
|
|
289
|
+
texture.dispose();
|
|
290
|
+
};
|
|
291
|
+
}, [texture]);
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
function EnvironmentPortal({
|
|
295
|
+
children,
|
|
296
|
+
near = 0.1,
|
|
297
|
+
far = 1e3,
|
|
298
|
+
resolution = 256,
|
|
299
|
+
frames = 1,
|
|
300
|
+
map,
|
|
301
|
+
background = false,
|
|
302
|
+
blur,
|
|
303
|
+
backgroundBlurriness,
|
|
304
|
+
backgroundIntensity,
|
|
305
|
+
backgroundRotation,
|
|
306
|
+
environmentIntensity,
|
|
307
|
+
environmentRotation,
|
|
308
|
+
scene,
|
|
309
|
+
files,
|
|
310
|
+
path,
|
|
311
|
+
preset = void 0,
|
|
312
|
+
extensions
|
|
313
|
+
}) {
|
|
314
|
+
const gl = useThree$1((state) => state.gl);
|
|
315
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
316
|
+
const camera = React.useRef(null);
|
|
317
|
+
const [virtualScene] = React.useState(() => new Scene());
|
|
318
|
+
const fbo = React.useMemo(() => {
|
|
319
|
+
const fbo2 = new WebGLCubeRenderTarget(resolution);
|
|
320
|
+
fbo2.texture.type = HalfFloatType;
|
|
321
|
+
return fbo2;
|
|
322
|
+
}, [resolution]);
|
|
323
|
+
React.useEffect(() => {
|
|
324
|
+
return () => {
|
|
325
|
+
fbo.dispose();
|
|
326
|
+
};
|
|
327
|
+
}, [fbo]);
|
|
328
|
+
React.useLayoutEffect(() => {
|
|
329
|
+
if (frames === 1) {
|
|
330
|
+
const autoClear = gl.autoClear;
|
|
331
|
+
gl.autoClear = true;
|
|
332
|
+
camera.current.update(gl, virtualScene);
|
|
333
|
+
gl.autoClear = autoClear;
|
|
334
|
+
}
|
|
335
|
+
return setEnvProps(background, scene, defaultScene, fbo.texture, {
|
|
336
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
337
|
+
backgroundIntensity,
|
|
338
|
+
backgroundRotation,
|
|
339
|
+
environmentIntensity,
|
|
340
|
+
environmentRotation
|
|
341
|
+
});
|
|
342
|
+
}, [
|
|
343
|
+
children,
|
|
344
|
+
virtualScene,
|
|
345
|
+
fbo.texture,
|
|
346
|
+
scene,
|
|
347
|
+
defaultScene,
|
|
348
|
+
background,
|
|
349
|
+
frames,
|
|
350
|
+
gl,
|
|
351
|
+
blur,
|
|
352
|
+
backgroundBlurriness,
|
|
353
|
+
backgroundIntensity,
|
|
354
|
+
backgroundRotation,
|
|
355
|
+
environmentIntensity,
|
|
356
|
+
environmentRotation
|
|
357
|
+
]);
|
|
358
|
+
let count = 1;
|
|
359
|
+
useFrame$1(() => {
|
|
360
|
+
if (frames === Infinity || count < frames) {
|
|
361
|
+
const autoClear = gl.autoClear;
|
|
362
|
+
gl.autoClear = true;
|
|
363
|
+
camera.current.update(gl, virtualScene);
|
|
364
|
+
gl.autoClear = autoClear;
|
|
365
|
+
count++;
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
return /* @__PURE__ */ jsx(Fragment, { children: createPortal$1(
|
|
369
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
370
|
+
children,
|
|
371
|
+
/* @__PURE__ */ jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
|
|
372
|
+
files || preset ? /* @__PURE__ */ jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsx(EnvironmentMap, { background: true, map, extensions }) : null
|
|
373
|
+
] }),
|
|
374
|
+
virtualScene
|
|
375
|
+
) });
|
|
376
|
+
}
|
|
377
|
+
function EnvironmentGround(props) {
|
|
378
|
+
const textureDefault = useEnvironment(props);
|
|
379
|
+
const texture = props.map || textureDefault;
|
|
380
|
+
React.useMemo(() => extend$1({ GroundProjectedEnvImpl: GroundedSkybox }), []);
|
|
381
|
+
React.useEffect(() => {
|
|
382
|
+
return () => {
|
|
383
|
+
textureDefault.dispose();
|
|
384
|
+
};
|
|
385
|
+
}, [textureDefault]);
|
|
386
|
+
const height = props.ground?.height ?? 15;
|
|
387
|
+
const radius = props.ground?.radius ?? 60;
|
|
388
|
+
const scale = props.ground?.scale ?? 1e3;
|
|
389
|
+
const args = React.useMemo(
|
|
390
|
+
() => [texture, height, radius],
|
|
391
|
+
[texture, height, radius]
|
|
392
|
+
);
|
|
393
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
394
|
+
/* @__PURE__ */ jsx(EnvironmentMap, { ...props, map: texture }),
|
|
395
|
+
/* @__PURE__ */ jsx("groundProjectedEnvImpl", { args, scale })
|
|
396
|
+
] });
|
|
397
|
+
}
|
|
398
|
+
function EnvironmentColor({ color, scene }) {
|
|
399
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
400
|
+
React.useLayoutEffect(() => {
|
|
401
|
+
if (color === void 0) return;
|
|
402
|
+
const target = resolveScene(scene || defaultScene);
|
|
403
|
+
const oldBg = target.background;
|
|
404
|
+
target.background = new Color(color);
|
|
405
|
+
return () => {
|
|
406
|
+
target.background = oldBg;
|
|
407
|
+
};
|
|
408
|
+
});
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
function EnvironmentDualSource(props) {
|
|
412
|
+
const { backgroundFiles, ...envProps } = props;
|
|
413
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
414
|
+
/* @__PURE__ */ jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
415
|
+
/* @__PURE__ */ jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
|
|
416
|
+
] });
|
|
417
|
+
}
|
|
418
|
+
function Environment(props) {
|
|
419
|
+
if (props.color && !props.files && !props.preset && !props.map) {
|
|
420
|
+
return /* @__PURE__ */ jsx(EnvironmentColor, { ...props });
|
|
421
|
+
}
|
|
422
|
+
if (props.backgroundFiles && props.backgroundFiles !== props.files) {
|
|
423
|
+
return /* @__PURE__ */ jsx(EnvironmentDualSource, { ...props });
|
|
424
|
+
}
|
|
425
|
+
return props.ground ? /* @__PURE__ */ jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsx(EnvironmentCube, { ...props });
|
|
426
|
+
}
|
|
427
|
+
|
|
39
428
|
var __defProp$2 = Object.defineProperty;
|
|
40
429
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
41
430
|
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -215,7 +604,8 @@ function prepare(target, root, type, props) {
|
|
|
215
604
|
object,
|
|
216
605
|
eventCount: 0,
|
|
217
606
|
handlers: {},
|
|
218
|
-
isHidden: false
|
|
607
|
+
isHidden: false,
|
|
608
|
+
deferredRefs: []
|
|
219
609
|
};
|
|
220
610
|
if (object) object.__r3f = instance;
|
|
221
611
|
}
|
|
@@ -264,7 +654,7 @@ function createOcclusionObserverNode(store, uniform) {
|
|
|
264
654
|
let occlusionSetupPromise = null;
|
|
265
655
|
function enableOcclusion(store) {
|
|
266
656
|
const state = store.getState();
|
|
267
|
-
const { internal, renderer
|
|
657
|
+
const { internal, renderer } = state;
|
|
268
658
|
if (internal.occlusionEnabled || occlusionSetupPromise) return;
|
|
269
659
|
const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
|
|
270
660
|
if (!hasOcclusionSupport) {
|
|
@@ -427,6 +817,22 @@ function hasVisibilityHandlers(handlers) {
|
|
|
427
817
|
return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
|
|
428
818
|
}
|
|
429
819
|
|
|
820
|
+
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
821
|
+
function fromRef(ref) {
|
|
822
|
+
return { [FROM_REF]: ref };
|
|
823
|
+
}
|
|
824
|
+
function isFromRef(value) {
|
|
825
|
+
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
const ONCE = Symbol.for("@react-three/fiber.once");
|
|
829
|
+
function once(...args) {
|
|
830
|
+
return { [ONCE]: args.length ? args : true };
|
|
831
|
+
}
|
|
832
|
+
function isOnce(value) {
|
|
833
|
+
return value !== null && typeof value === "object" && ONCE in value;
|
|
834
|
+
}
|
|
835
|
+
|
|
430
836
|
const RESERVED_PROPS = [
|
|
431
837
|
"children",
|
|
432
838
|
"key",
|
|
@@ -497,7 +903,7 @@ function getMemoizedPrototype(root) {
|
|
|
497
903
|
ctor = new root.constructor();
|
|
498
904
|
MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
|
|
499
905
|
}
|
|
500
|
-
} catch
|
|
906
|
+
} catch {
|
|
501
907
|
}
|
|
502
908
|
return ctor;
|
|
503
909
|
}
|
|
@@ -528,7 +934,7 @@ function applyProps(object, props) {
|
|
|
528
934
|
const rootState = instance && findInitialRoot(instance).getState();
|
|
529
935
|
const prevHandlers = instance?.eventCount;
|
|
530
936
|
for (const prop in props) {
|
|
531
|
-
|
|
937
|
+
const value = props[prop];
|
|
532
938
|
if (RESERVED_PROPS.includes(prop)) continue;
|
|
533
939
|
if (instance && EVENT_REGEX.test(prop)) {
|
|
534
940
|
if (typeof value === "function") instance.handlers[prop] = value;
|
|
@@ -543,6 +949,25 @@ function applyProps(object, props) {
|
|
|
543
949
|
continue;
|
|
544
950
|
}
|
|
545
951
|
if (value === void 0) continue;
|
|
952
|
+
if (isFromRef(value)) {
|
|
953
|
+
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
954
|
+
continue;
|
|
955
|
+
}
|
|
956
|
+
if (isOnce(value)) {
|
|
957
|
+
if (instance?.appliedOnce?.has(prop)) continue;
|
|
958
|
+
if (instance) {
|
|
959
|
+
instance.appliedOnce ?? (instance.appliedOnce = /* @__PURE__ */ new Set());
|
|
960
|
+
instance.appliedOnce.add(prop);
|
|
961
|
+
}
|
|
962
|
+
const { root: targetRoot, key: targetKey } = resolve(object, prop);
|
|
963
|
+
const args = value[ONCE];
|
|
964
|
+
if (typeof targetRoot[targetKey] === "function") {
|
|
965
|
+
targetRoot[targetKey](...args === true ? [] : args);
|
|
966
|
+
} else if (args !== true && args.length > 0) {
|
|
967
|
+
targetRoot[targetKey] = args[0];
|
|
968
|
+
}
|
|
969
|
+
continue;
|
|
970
|
+
}
|
|
546
971
|
let { root, key, target } = resolve(object, prop);
|
|
547
972
|
if (target === void 0 && (typeof root !== "object" || root === null)) {
|
|
548
973
|
throw Error(`R3F: Cannot set "${prop}". Ensure it is an object before setting "${key}".`);
|
|
@@ -565,7 +990,10 @@ function applyProps(object, props) {
|
|
|
565
990
|
else target.set(value);
|
|
566
991
|
} else {
|
|
567
992
|
root[key] = value;
|
|
568
|
-
if (
|
|
993
|
+
if (key.endsWith("Node") && root.isMaterial) {
|
|
994
|
+
root.needsUpdate = true;
|
|
995
|
+
}
|
|
996
|
+
if (rootState && rootState.renderer?.outputColorSpace === SRGBColorSpace && colorMaps.includes(key) && isTexture(value) && root[key]?.isTexture && // sRGB textures must be RGBA8 since r137 https://github.com/mrdoob/three.js/pull/23129
|
|
569
997
|
root[key].format === RGBAFormat && root[key].type === UnsignedByteType) {
|
|
570
998
|
root[key].colorSpace = rootState.textureColorSpace;
|
|
571
999
|
}
|
|
@@ -598,38 +1026,60 @@ function applyProps(object, props) {
|
|
|
598
1026
|
return object;
|
|
599
1027
|
}
|
|
600
1028
|
|
|
1029
|
+
const DEFAULT_POINTER_ID = 0;
|
|
1030
|
+
const XR_POINTER_ID_START = 1e3;
|
|
1031
|
+
function getPointerState(internal, pointerId) {
|
|
1032
|
+
let state = internal.pointerMap.get(pointerId);
|
|
1033
|
+
if (!state) {
|
|
1034
|
+
state = {
|
|
1035
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
1036
|
+
captured: /* @__PURE__ */ new Map(),
|
|
1037
|
+
initialClick: [0, 0],
|
|
1038
|
+
initialHits: []
|
|
1039
|
+
};
|
|
1040
|
+
internal.pointerMap.set(pointerId, state);
|
|
1041
|
+
}
|
|
1042
|
+
return state;
|
|
1043
|
+
}
|
|
1044
|
+
function getPointerId(event) {
|
|
1045
|
+
return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
|
|
1046
|
+
}
|
|
601
1047
|
function makeId(event) {
|
|
602
1048
|
return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
|
|
603
1049
|
}
|
|
604
|
-
function releaseInternalPointerCapture(
|
|
605
|
-
const
|
|
1050
|
+
function releaseInternalPointerCapture(internal, obj, pointerId) {
|
|
1051
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1052
|
+
if (!pointerState) return;
|
|
1053
|
+
const captureData = pointerState.captured.get(obj);
|
|
606
1054
|
if (captureData) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
capturedMap.delete(pointerId);
|
|
610
|
-
captureData.target.releasePointerCapture(pointerId);
|
|
611
|
-
}
|
|
1055
|
+
pointerState.captured.delete(obj);
|
|
1056
|
+
captureData.target.releasePointerCapture(pointerId);
|
|
612
1057
|
}
|
|
613
1058
|
}
|
|
614
1059
|
function removeInteractivity(store, object) {
|
|
615
1060
|
const { internal } = store.getState();
|
|
616
1061
|
internal.interaction = internal.interaction.filter((o) => o !== object);
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
1062
|
+
for (const [pointerId, pointerState] of internal.pointerMap) {
|
|
1063
|
+
pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
|
|
1064
|
+
pointerState.hovered.forEach((value, key) => {
|
|
1065
|
+
if (value.eventObject === object || value.object === object) {
|
|
1066
|
+
pointerState.hovered.delete(key);
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
if (pointerState.captured.has(object)) {
|
|
1070
|
+
releaseInternalPointerCapture(internal, object, pointerId);
|
|
621
1071
|
}
|
|
622
|
-
}
|
|
623
|
-
internal.capturedMap.forEach((captures, pointerId) => {
|
|
624
|
-
releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
|
|
625
|
-
});
|
|
1072
|
+
}
|
|
626
1073
|
unregisterVisibility(store, object);
|
|
627
1074
|
}
|
|
628
1075
|
function createEvents(store) {
|
|
629
|
-
function calculateDistance(event) {
|
|
1076
|
+
function calculateDistance(event, pointerId) {
|
|
630
1077
|
const { internal } = store.getState();
|
|
631
|
-
const
|
|
632
|
-
|
|
1078
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1079
|
+
if (!pointerState) return 0;
|
|
1080
|
+
const [initialX, initialY] = pointerState.initialClick;
|
|
1081
|
+
const dx = event.offsetX - initialX;
|
|
1082
|
+
const dy = event.offsetY - initialY;
|
|
633
1083
|
return Math.round(Math.sqrt(dx * dx + dy * dy));
|
|
634
1084
|
}
|
|
635
1085
|
function filterPointerEvents(objects) {
|
|
@@ -665,6 +1115,15 @@ function createEvents(store) {
|
|
|
665
1115
|
return state2.raycaster.camera ? state2.raycaster.intersectObject(obj, true) : [];
|
|
666
1116
|
}
|
|
667
1117
|
let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
|
|
1118
|
+
const aInteractivePriority = a.object.userData?.interactivePriority;
|
|
1119
|
+
const bInteractivePriority = b.object.userData?.interactivePriority;
|
|
1120
|
+
if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
|
|
1121
|
+
if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
|
|
1122
|
+
if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
|
|
1123
|
+
if (aInteractivePriority !== bInteractivePriority) {
|
|
1124
|
+
return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
668
1127
|
const aState = getRootState(a.object);
|
|
669
1128
|
const bState = getRootState(b.object);
|
|
670
1129
|
const aPriority = aState?.events?.priority ?? 1;
|
|
@@ -680,14 +1139,19 @@ function createEvents(store) {
|
|
|
680
1139
|
for (const hit of hits) {
|
|
681
1140
|
let eventObject = hit.object;
|
|
682
1141
|
while (eventObject) {
|
|
683
|
-
if (eventObject.__r3f?.eventCount)
|
|
1142
|
+
if (eventObject.__r3f?.eventCount) {
|
|
684
1143
|
intersections.push({ ...hit, eventObject });
|
|
1144
|
+
}
|
|
685
1145
|
eventObject = eventObject.parent;
|
|
686
1146
|
}
|
|
687
1147
|
}
|
|
688
|
-
if ("pointerId" in event
|
|
689
|
-
|
|
690
|
-
|
|
1148
|
+
if ("pointerId" in event) {
|
|
1149
|
+
const pointerId = event.pointerId;
|
|
1150
|
+
const pointerState = state.internal.pointerMap.get(pointerId);
|
|
1151
|
+
if (pointerState?.captured.size) {
|
|
1152
|
+
for (const captureData of pointerState.captured.values()) {
|
|
1153
|
+
if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
|
|
1154
|
+
}
|
|
691
1155
|
}
|
|
692
1156
|
}
|
|
693
1157
|
return intersections;
|
|
@@ -700,28 +1164,26 @@ function createEvents(store) {
|
|
|
700
1164
|
if (state) {
|
|
701
1165
|
const { raycaster, pointer, camera, internal } = state;
|
|
702
1166
|
const unprojectedPoint = new Vector3(pointer.x, pointer.y, 0).unproject(camera);
|
|
703
|
-
const hasPointerCapture = (id) =>
|
|
1167
|
+
const hasPointerCapture = (id) => {
|
|
1168
|
+
const pointerState = internal.pointerMap.get(id);
|
|
1169
|
+
return pointerState?.captured.has(hit.eventObject) ?? false;
|
|
1170
|
+
};
|
|
704
1171
|
const setPointerCapture = (id) => {
|
|
705
1172
|
const captureData = { intersection: hit, target: event.target };
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
} else {
|
|
709
|
-
internal.capturedMap.set(id, /* @__PURE__ */ new Map([[hit.eventObject, captureData]]));
|
|
710
|
-
}
|
|
1173
|
+
const pointerState = getPointerState(internal, id);
|
|
1174
|
+
pointerState.captured.set(hit.eventObject, captureData);
|
|
711
1175
|
event.target.setPointerCapture(id);
|
|
712
1176
|
};
|
|
713
1177
|
const releasePointerCapture = (id) => {
|
|
714
|
-
|
|
715
|
-
if (captures) {
|
|
716
|
-
releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
|
|
717
|
-
}
|
|
1178
|
+
releaseInternalPointerCapture(internal, hit.eventObject, id);
|
|
718
1179
|
};
|
|
719
|
-
|
|
720
|
-
for (
|
|
721
|
-
|
|
1180
|
+
const extractEventProps = {};
|
|
1181
|
+
for (const prop in event) {
|
|
1182
|
+
const property = event[prop];
|
|
722
1183
|
if (typeof property !== "function") extractEventProps[prop] = property;
|
|
723
1184
|
}
|
|
724
|
-
|
|
1185
|
+
const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
|
|
1186
|
+
const raycastEvent = {
|
|
725
1187
|
...hit,
|
|
726
1188
|
...extractEventProps,
|
|
727
1189
|
pointer,
|
|
@@ -731,18 +1193,19 @@ function createEvents(store) {
|
|
|
731
1193
|
unprojectedPoint,
|
|
732
1194
|
ray: raycaster.ray,
|
|
733
1195
|
camera,
|
|
1196
|
+
pointerId: eventPointerId,
|
|
734
1197
|
// Hijack stopPropagation, which just sets a flag
|
|
735
1198
|
stopPropagation() {
|
|
736
|
-
const
|
|
1199
|
+
const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
|
|
737
1200
|
if (
|
|
738
1201
|
// ...if this pointer hasn't been captured
|
|
739
|
-
!
|
|
740
|
-
|
|
1202
|
+
!pointerState?.captured.size || // ... or if the hit object is capturing the pointer
|
|
1203
|
+
pointerState.captured.has(hit.eventObject)
|
|
741
1204
|
) {
|
|
742
1205
|
raycastEvent.stopped = localState.stopped = true;
|
|
743
|
-
if (
|
|
1206
|
+
if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
|
|
744
1207
|
const higher = intersections.slice(0, intersections.indexOf(hit));
|
|
745
|
-
cancelPointer([...higher, hit]);
|
|
1208
|
+
cancelPointer([...higher, hit], eventPointerId);
|
|
746
1209
|
}
|
|
747
1210
|
}
|
|
748
1211
|
},
|
|
@@ -758,15 +1221,18 @@ function createEvents(store) {
|
|
|
758
1221
|
}
|
|
759
1222
|
return intersections;
|
|
760
1223
|
}
|
|
761
|
-
function cancelPointer(intersections) {
|
|
1224
|
+
function cancelPointer(intersections, pointerId) {
|
|
762
1225
|
const { internal } = store.getState();
|
|
763
|
-
|
|
1226
|
+
const pid = pointerId ?? DEFAULT_POINTER_ID;
|
|
1227
|
+
const pointerState = internal.pointerMap.get(pid);
|
|
1228
|
+
if (!pointerState) return;
|
|
1229
|
+
for (const [hoveredId, hoveredObj] of pointerState.hovered) {
|
|
764
1230
|
if (!intersections.length || !intersections.find(
|
|
765
1231
|
(hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
|
|
766
1232
|
)) {
|
|
767
1233
|
const eventObject = hoveredObj.eventObject;
|
|
768
1234
|
const instance = eventObject.__r3f;
|
|
769
|
-
|
|
1235
|
+
pointerState.hovered.delete(hoveredId);
|
|
770
1236
|
if (instance?.eventCount) {
|
|
771
1237
|
const handlers = instance.handlers;
|
|
772
1238
|
const data = { ...hoveredObj, intersections };
|
|
@@ -795,41 +1261,118 @@ function createEvents(store) {
|
|
|
795
1261
|
instance?.handlers.onDropMissed?.(event);
|
|
796
1262
|
}
|
|
797
1263
|
}
|
|
1264
|
+
function cleanupPointer(pointerId) {
|
|
1265
|
+
const { internal } = store.getState();
|
|
1266
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1267
|
+
if (pointerState) {
|
|
1268
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
1269
|
+
const eventObject = hoveredObj.eventObject;
|
|
1270
|
+
const instance = eventObject.__r3f;
|
|
1271
|
+
if (instance?.eventCount) {
|
|
1272
|
+
const handlers = instance.handlers;
|
|
1273
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
1274
|
+
handlers.onPointerOut?.(data);
|
|
1275
|
+
handlers.onPointerLeave?.(data);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
internal.pointerMap.delete(pointerId);
|
|
1279
|
+
}
|
|
1280
|
+
internal.pointerDirty.delete(pointerId);
|
|
1281
|
+
}
|
|
1282
|
+
function processDeferredPointer(event, pointerId) {
|
|
1283
|
+
const state = store.getState();
|
|
1284
|
+
const { internal } = state;
|
|
1285
|
+
if (!state.events.enabled) return;
|
|
1286
|
+
const filter = filterPointerEvents;
|
|
1287
|
+
const hits = intersect(event, filter);
|
|
1288
|
+
cancelPointer(hits, pointerId);
|
|
1289
|
+
function onIntersect(data) {
|
|
1290
|
+
const eventObject = data.eventObject;
|
|
1291
|
+
const instance = eventObject.__r3f;
|
|
1292
|
+
if (!instance?.eventCount) return;
|
|
1293
|
+
const handlers = instance.handlers;
|
|
1294
|
+
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
1295
|
+
const id = makeId(data);
|
|
1296
|
+
const pointerState = getPointerState(internal, pointerId);
|
|
1297
|
+
const hoveredItem = pointerState.hovered.get(id);
|
|
1298
|
+
if (!hoveredItem) {
|
|
1299
|
+
pointerState.hovered.set(id, data);
|
|
1300
|
+
handlers.onPointerOver?.(data);
|
|
1301
|
+
handlers.onPointerEnter?.(data);
|
|
1302
|
+
} else if (hoveredItem.stopped) {
|
|
1303
|
+
data.stopPropagation();
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
handlers.onPointerMove?.(data);
|
|
1307
|
+
}
|
|
1308
|
+
handleIntersects(hits, event, 0, onIntersect);
|
|
1309
|
+
}
|
|
798
1310
|
function handlePointer(name) {
|
|
799
1311
|
switch (name) {
|
|
800
1312
|
case "onPointerLeave":
|
|
801
|
-
case "onPointerCancel":
|
|
802
1313
|
case "onDragLeave":
|
|
803
1314
|
return () => cancelPointer([]);
|
|
1315
|
+
// Global cancel of these events
|
|
1316
|
+
case "onPointerCancel":
|
|
1317
|
+
return (event) => {
|
|
1318
|
+
const pointerId = getPointerId(event);
|
|
1319
|
+
cleanupPointer(pointerId);
|
|
1320
|
+
};
|
|
804
1321
|
case "onLostPointerCapture":
|
|
805
1322
|
return (event) => {
|
|
806
1323
|
const { internal } = store.getState();
|
|
807
|
-
|
|
1324
|
+
const pointerId = getPointerId(event);
|
|
1325
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1326
|
+
if (pointerState?.captured.size) {
|
|
808
1327
|
requestAnimationFrame(() => {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
1328
|
+
const pointerState2 = internal.pointerMap.get(pointerId);
|
|
1329
|
+
if (pointerState2?.captured.size) {
|
|
1330
|
+
pointerState2.captured.clear();
|
|
812
1331
|
}
|
|
1332
|
+
cancelPointer([], pointerId);
|
|
813
1333
|
});
|
|
814
1334
|
}
|
|
815
1335
|
};
|
|
816
1336
|
}
|
|
817
1337
|
return function handleEvent(event) {
|
|
818
1338
|
const state = store.getState();
|
|
819
|
-
const { onPointerMissed, onDragOverMissed, onDropMissed, internal } = state;
|
|
1339
|
+
const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
|
|
1340
|
+
const pointerId = getPointerId(event);
|
|
820
1341
|
internal.lastEvent.current = event;
|
|
821
|
-
if (!
|
|
1342
|
+
if (!events.enabled) return;
|
|
822
1343
|
const isPointerMove = name === "onPointerMove";
|
|
823
1344
|
const isDragOver = name === "onDragOver";
|
|
824
1345
|
const isDrop = name === "onDrop";
|
|
825
1346
|
const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
|
|
1347
|
+
const isPointerDown = name === "onPointerDown";
|
|
1348
|
+
const isPointerUp = name === "onPointerUp";
|
|
1349
|
+
const isWheel = name === "onWheel";
|
|
1350
|
+
const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
|
|
1351
|
+
if (isPointerMove && canDeferRaycasts) {
|
|
1352
|
+
events.compute?.(event, state);
|
|
1353
|
+
internal.pointerDirty.set(pointerId, event);
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
|
|
1357
|
+
events.compute?.(event, state);
|
|
1358
|
+
internal.pointerDirty.set(pointerId, event);
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
|
|
1362
|
+
const deferredEvent = internal.pointerDirty.get(pointerId);
|
|
1363
|
+
internal.pointerDirty.delete(pointerId);
|
|
1364
|
+
processDeferredPointer(deferredEvent, pointerId);
|
|
1365
|
+
}
|
|
826
1366
|
const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
|
|
827
1367
|
const hits = intersect(event, filter);
|
|
828
|
-
const delta = isClickEvent ? calculateDistance(event) : 0;
|
|
829
|
-
if (
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
1368
|
+
const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
|
|
1369
|
+
if (isPointerDown) {
|
|
1370
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1371
|
+
pointerState2.initialClick = [event.offsetX, event.offsetY];
|
|
1372
|
+
pointerState2.initialHits = hits.map((hit) => hit.eventObject);
|
|
1373
|
+
}
|
|
1374
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1375
|
+
const initialHits = pointerState?.initialHits ?? [];
|
|
833
1376
|
if (isClickEvent && !hits.length) {
|
|
834
1377
|
if (delta <= 2) {
|
|
835
1378
|
pointerMissed(event, internal.interaction);
|
|
@@ -844,7 +1387,9 @@ function createEvents(store) {
|
|
|
844
1387
|
dropMissed(event, internal.interaction);
|
|
845
1388
|
if (onDropMissed) onDropMissed(event);
|
|
846
1389
|
}
|
|
847
|
-
if (isPointerMove || isDragOver)
|
|
1390
|
+
if (isPointerMove || isDragOver) {
|
|
1391
|
+
cancelPointer(hits, pointerId);
|
|
1392
|
+
}
|
|
848
1393
|
function onIntersect(data) {
|
|
849
1394
|
const eventObject = data.eventObject;
|
|
850
1395
|
const instance = eventObject.__r3f;
|
|
@@ -853,9 +1398,10 @@ function createEvents(store) {
|
|
|
853
1398
|
if (isPointerMove) {
|
|
854
1399
|
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
855
1400
|
const id = makeId(data);
|
|
856
|
-
const
|
|
1401
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1402
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
857
1403
|
if (!hoveredItem) {
|
|
858
|
-
|
|
1404
|
+
pointerState2.hovered.set(id, data);
|
|
859
1405
|
handlers.onPointerOver?.(data);
|
|
860
1406
|
handlers.onPointerEnter?.(data);
|
|
861
1407
|
} else if (hoveredItem.stopped) {
|
|
@@ -865,9 +1411,10 @@ function createEvents(store) {
|
|
|
865
1411
|
handlers.onPointerMove?.(data);
|
|
866
1412
|
} else if (isDragOver) {
|
|
867
1413
|
const id = makeId(data);
|
|
868
|
-
const
|
|
1414
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1415
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
869
1416
|
if (!hoveredItem) {
|
|
870
|
-
|
|
1417
|
+
pointerState2.hovered.set(id, data);
|
|
871
1418
|
handlers.onDragOverEnter?.(data);
|
|
872
1419
|
} else if (hoveredItem.stopped) {
|
|
873
1420
|
data.stopPropagation();
|
|
@@ -878,18 +1425,18 @@ function createEvents(store) {
|
|
|
878
1425
|
} else {
|
|
879
1426
|
const handler = handlers[name];
|
|
880
1427
|
if (handler) {
|
|
881
|
-
if (!isClickEvent ||
|
|
1428
|
+
if (!isClickEvent || initialHits.includes(eventObject)) {
|
|
882
1429
|
pointerMissed(
|
|
883
1430
|
event,
|
|
884
|
-
internal.interaction.filter((object) => !
|
|
1431
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
885
1432
|
);
|
|
886
1433
|
handler(data);
|
|
887
1434
|
}
|
|
888
1435
|
} else {
|
|
889
|
-
if (isClickEvent &&
|
|
1436
|
+
if (isClickEvent && initialHits.includes(eventObject)) {
|
|
890
1437
|
pointerMissed(
|
|
891
1438
|
event,
|
|
892
|
-
internal.interaction.filter((object) => !
|
|
1439
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
893
1440
|
);
|
|
894
1441
|
}
|
|
895
1442
|
}
|
|
@@ -898,7 +1445,15 @@ function createEvents(store) {
|
|
|
898
1445
|
handleIntersects(hits, event, delta, onIntersect);
|
|
899
1446
|
};
|
|
900
1447
|
}
|
|
901
|
-
|
|
1448
|
+
function flushDeferredPointers() {
|
|
1449
|
+
const { internal, events } = store.getState();
|
|
1450
|
+
if (!events.frameTimedRaycasts) return;
|
|
1451
|
+
for (const [pointerId, event] of internal.pointerDirty) {
|
|
1452
|
+
processDeferredPointer(event, pointerId);
|
|
1453
|
+
}
|
|
1454
|
+
internal.pointerDirty.clear();
|
|
1455
|
+
}
|
|
1456
|
+
return { handlePointer, flushDeferredPointers, processDeferredPointer };
|
|
902
1457
|
}
|
|
903
1458
|
const DOM_EVENTS = {
|
|
904
1459
|
onClick: ["click", false],
|
|
@@ -917,11 +1472,16 @@ const DOM_EVENTS = {
|
|
|
917
1472
|
onLostPointerCapture: ["lostpointercapture", true]
|
|
918
1473
|
};
|
|
919
1474
|
function createPointerEvents(store) {
|
|
920
|
-
const { handlePointer } = createEvents(store);
|
|
1475
|
+
const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
|
|
1476
|
+
let nextXRPointerId = XR_POINTER_ID_START;
|
|
1477
|
+
const xrPointers = /* @__PURE__ */ new Map();
|
|
921
1478
|
return {
|
|
922
1479
|
priority: 1,
|
|
923
1480
|
enabled: true,
|
|
924
|
-
|
|
1481
|
+
frameTimedRaycasts: true,
|
|
1482
|
+
alwaysFireOnScroll: true,
|
|
1483
|
+
updateOnFrame: false,
|
|
1484
|
+
compute(event, state) {
|
|
925
1485
|
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
926
1486
|
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
927
1487
|
},
|
|
@@ -930,11 +1490,33 @@ function createPointerEvents(store) {
|
|
|
930
1490
|
(acc, key) => ({ ...acc, [key]: handlePointer(key) }),
|
|
931
1491
|
{}
|
|
932
1492
|
),
|
|
933
|
-
update: () => {
|
|
1493
|
+
update: (pointerId) => {
|
|
1494
|
+
const { events, internal } = store.getState();
|
|
1495
|
+
if (!events.handlers) return;
|
|
1496
|
+
if (pointerId !== void 0) {
|
|
1497
|
+
const event = internal.pointerDirty.get(pointerId);
|
|
1498
|
+
if (event) {
|
|
1499
|
+
internal.pointerDirty.delete(pointerId);
|
|
1500
|
+
processDeferredPointer(event, pointerId);
|
|
1501
|
+
} else if (internal.lastEvent?.current) {
|
|
1502
|
+
processDeferredPointer(internal.lastEvent.current, pointerId);
|
|
1503
|
+
}
|
|
1504
|
+
} else {
|
|
1505
|
+
flushDeferredPointers();
|
|
1506
|
+
if (internal.lastEvent?.current) {
|
|
1507
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
},
|
|
1511
|
+
flush: () => {
|
|
934
1512
|
const { events, internal } = store.getState();
|
|
935
|
-
|
|
1513
|
+
flushDeferredPointers();
|
|
1514
|
+
if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
|
|
1515
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1516
|
+
}
|
|
936
1517
|
},
|
|
937
1518
|
connect: (target) => {
|
|
1519
|
+
if (!target) return;
|
|
938
1520
|
const { set, events } = store.getState();
|
|
939
1521
|
events.disconnect?.();
|
|
940
1522
|
set((state) => ({ events: { ...state.events, connected: target } }));
|
|
@@ -958,6 +1540,32 @@ function createPointerEvents(store) {
|
|
|
958
1540
|
}
|
|
959
1541
|
set((state) => ({ events: { ...state.events, connected: void 0 } }));
|
|
960
1542
|
}
|
|
1543
|
+
},
|
|
1544
|
+
registerPointer: (config) => {
|
|
1545
|
+
const pointerId = nextXRPointerId++;
|
|
1546
|
+
xrPointers.set(pointerId, config);
|
|
1547
|
+
const { internal } = store.getState();
|
|
1548
|
+
getPointerState(internal, pointerId);
|
|
1549
|
+
return pointerId;
|
|
1550
|
+
},
|
|
1551
|
+
unregisterPointer: (pointerId) => {
|
|
1552
|
+
xrPointers.delete(pointerId);
|
|
1553
|
+
const { internal } = store.getState();
|
|
1554
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1555
|
+
if (pointerState) {
|
|
1556
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
1557
|
+
const eventObject = hoveredObj.eventObject;
|
|
1558
|
+
const instance = eventObject.__r3f;
|
|
1559
|
+
if (instance?.eventCount) {
|
|
1560
|
+
const handlers = instance.handlers;
|
|
1561
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
1562
|
+
handlers.onPointerOut?.(data);
|
|
1563
|
+
handlers.onPointerLeave?.(data);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
internal.pointerMap.delete(pointerId);
|
|
1567
|
+
}
|
|
1568
|
+
internal.pointerDirty.delete(pointerId);
|
|
961
1569
|
}
|
|
962
1570
|
};
|
|
963
1571
|
}
|
|
@@ -1019,300 +1627,26 @@ function notifyAlpha({ message, link }) {
|
|
|
1019
1627
|
}
|
|
1020
1628
|
}
|
|
1021
1629
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
let performanceTimeout = void 0;
|
|
1045
|
-
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
1046
|
-
const pointer = new Vector2();
|
|
1047
|
-
const rootState = {
|
|
1048
|
-
set,
|
|
1049
|
-
get,
|
|
1050
|
-
// Mock objects that have to be configured
|
|
1051
|
-
gl: null,
|
|
1052
|
-
renderer: null,
|
|
1053
|
-
camera: null,
|
|
1054
|
-
frustum: new Frustum(),
|
|
1055
|
-
autoUpdateFrustum: true,
|
|
1056
|
-
raycaster: null,
|
|
1057
|
-
events: { priority: 1, enabled: true, connected: false },
|
|
1058
|
-
scene: null,
|
|
1059
|
-
rootScene: null,
|
|
1060
|
-
xr: null,
|
|
1061
|
-
inspector: null,
|
|
1062
|
-
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
1063
|
-
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1064
|
-
legacy: false,
|
|
1065
|
-
linear: false,
|
|
1066
|
-
flat: false,
|
|
1067
|
-
textureColorSpace: "srgb",
|
|
1068
|
-
isLegacy: false,
|
|
1069
|
-
webGPUSupported: false,
|
|
1070
|
-
isNative: false,
|
|
1071
|
-
controls: null,
|
|
1072
|
-
pointer,
|
|
1073
|
-
mouse: pointer,
|
|
1074
|
-
frameloop: "always",
|
|
1075
|
-
onPointerMissed: void 0,
|
|
1076
|
-
onDragOverMissed: void 0,
|
|
1077
|
-
onDropMissed: void 0,
|
|
1078
|
-
performance: {
|
|
1079
|
-
current: 1,
|
|
1080
|
-
min: 0.5,
|
|
1081
|
-
max: 1,
|
|
1082
|
-
debounce: 200,
|
|
1083
|
-
regress: () => {
|
|
1084
|
-
const state2 = get();
|
|
1085
|
-
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
1086
|
-
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
1087
|
-
performanceTimeout = setTimeout(
|
|
1088
|
-
() => setPerformanceCurrent(get().performance.max),
|
|
1089
|
-
state2.performance.debounce
|
|
1090
|
-
);
|
|
1091
|
-
}
|
|
1092
|
-
},
|
|
1093
|
-
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
1094
|
-
viewport: {
|
|
1095
|
-
initialDpr: 0,
|
|
1096
|
-
dpr: 0,
|
|
1097
|
-
width: 0,
|
|
1098
|
-
height: 0,
|
|
1099
|
-
top: 0,
|
|
1100
|
-
left: 0,
|
|
1101
|
-
aspect: 0,
|
|
1102
|
-
distance: 0,
|
|
1103
|
-
factor: 0,
|
|
1104
|
-
getCurrentViewport
|
|
1105
|
-
},
|
|
1106
|
-
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
1107
|
-
setSize: (width, height, top = 0, left = 0) => {
|
|
1108
|
-
const camera = get().camera;
|
|
1109
|
-
const size = { width, height, top, left };
|
|
1110
|
-
set((state2) => ({ size, viewport: { ...state2.viewport, ...getCurrentViewport(camera, defaultTarget, size) } }));
|
|
1111
|
-
},
|
|
1112
|
-
setDpr: (dpr) => set((state2) => {
|
|
1113
|
-
const resolved = calculateDpr(dpr);
|
|
1114
|
-
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
1115
|
-
}),
|
|
1116
|
-
setFrameloop: (frameloop = "always") => {
|
|
1117
|
-
set(() => ({ frameloop }));
|
|
1118
|
-
},
|
|
1119
|
-
setError: (error) => set(() => ({ error })),
|
|
1120
|
-
error: null,
|
|
1121
|
-
//* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
|
|
1122
|
-
uniforms: {},
|
|
1123
|
-
nodes: {},
|
|
1124
|
-
textures: /* @__PURE__ */ new Map(),
|
|
1125
|
-
postProcessing: null,
|
|
1126
|
-
passes: {},
|
|
1127
|
-
previousRoot: void 0,
|
|
1128
|
-
internal: {
|
|
1129
|
-
// Events
|
|
1130
|
-
interaction: [],
|
|
1131
|
-
hovered: /* @__PURE__ */ new Map(),
|
|
1132
|
-
subscribers: [],
|
|
1133
|
-
initialClick: [0, 0],
|
|
1134
|
-
initialHits: [],
|
|
1135
|
-
capturedMap: /* @__PURE__ */ new Map(),
|
|
1136
|
-
lastEvent: React.createRef(),
|
|
1137
|
-
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
1138
|
-
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
1139
|
-
// Occlusion system (WebGPU only)
|
|
1140
|
-
occlusionEnabled: false,
|
|
1141
|
-
occlusionObserver: null,
|
|
1142
|
-
occlusionCache: /* @__PURE__ */ new Map(),
|
|
1143
|
-
helperGroup: null,
|
|
1144
|
-
// Updates
|
|
1145
|
-
active: false,
|
|
1146
|
-
frames: 0,
|
|
1147
|
-
priority: 0,
|
|
1148
|
-
subscribe: (ref, priority, store) => {
|
|
1149
|
-
const internal = get().internal;
|
|
1150
|
-
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
1151
|
-
internal.subscribers.push({ ref, priority, store });
|
|
1152
|
-
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
1153
|
-
return () => {
|
|
1154
|
-
const internal2 = get().internal;
|
|
1155
|
-
if (internal2?.subscribers) {
|
|
1156
|
-
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
1157
|
-
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
1158
|
-
}
|
|
1159
|
-
};
|
|
1160
|
-
},
|
|
1161
|
-
// Renderer Storage (single source of truth)
|
|
1162
|
-
actualRenderer: null,
|
|
1163
|
-
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
1164
|
-
scheduler: null
|
|
1165
|
-
}
|
|
1166
|
-
};
|
|
1167
|
-
return rootState;
|
|
1168
|
-
});
|
|
1169
|
-
const state = rootStore.getState();
|
|
1170
|
-
Object.defineProperty(state, "gl", {
|
|
1171
|
-
get() {
|
|
1172
|
-
const currentState = rootStore.getState();
|
|
1173
|
-
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1174
|
-
const stack = new Error().stack || "";
|
|
1175
|
-
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
1176
|
-
if (!isInternalAccess) {
|
|
1177
|
-
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1178
|
-
notifyDepreciated({
|
|
1179
|
-
heading: "Accessing state.gl in WebGPU mode",
|
|
1180
|
-
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
|
|
1181
|
-
});
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
return currentState.internal.actualRenderer;
|
|
1185
|
-
},
|
|
1186
|
-
set(value) {
|
|
1187
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1188
|
-
},
|
|
1189
|
-
enumerable: true,
|
|
1190
|
-
configurable: true
|
|
1191
|
-
});
|
|
1192
|
-
Object.defineProperty(state, "renderer", {
|
|
1193
|
-
get() {
|
|
1194
|
-
return rootStore.getState().internal.actualRenderer;
|
|
1195
|
-
},
|
|
1196
|
-
set(value) {
|
|
1197
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1198
|
-
},
|
|
1199
|
-
enumerable: true,
|
|
1200
|
-
configurable: true
|
|
1201
|
-
});
|
|
1202
|
-
let oldScene = state.scene;
|
|
1203
|
-
rootStore.subscribe(() => {
|
|
1204
|
-
const currentState = rootStore.getState();
|
|
1205
|
-
const { scene, rootScene, set } = currentState;
|
|
1206
|
-
if (scene !== oldScene) {
|
|
1207
|
-
oldScene = scene;
|
|
1208
|
-
if (scene?.isScene && scene !== rootScene) {
|
|
1209
|
-
set({ rootScene: scene });
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
});
|
|
1213
|
-
let oldSize = state.size;
|
|
1214
|
-
let oldDpr = state.viewport.dpr;
|
|
1215
|
-
let oldCamera = state.camera;
|
|
1216
|
-
rootStore.subscribe(() => {
|
|
1217
|
-
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
1218
|
-
const actualRenderer = internal.actualRenderer;
|
|
1219
|
-
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
1220
|
-
oldSize = size;
|
|
1221
|
-
oldDpr = viewport.dpr;
|
|
1222
|
-
updateCamera(camera, size);
|
|
1223
|
-
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1224
|
-
const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
|
|
1225
|
-
actualRenderer.setSize(size.width, size.height, updateStyle);
|
|
1226
|
-
}
|
|
1227
|
-
if (camera !== oldCamera) {
|
|
1228
|
-
oldCamera = camera;
|
|
1229
|
-
const { rootScene } = rootStore.getState();
|
|
1230
|
-
if (camera && rootScene && !camera.parent) {
|
|
1231
|
-
rootScene.add(camera);
|
|
1232
|
-
}
|
|
1233
|
-
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
1234
|
-
const currentState = rootStore.getState();
|
|
1235
|
-
if (currentState.autoUpdateFrustum && camera) {
|
|
1236
|
-
updateFrustum(camera, currentState.frustum);
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
});
|
|
1240
|
-
rootStore.subscribe((state2) => invalidate(state2));
|
|
1241
|
-
return rootStore;
|
|
1242
|
-
};
|
|
1243
|
-
|
|
1244
|
-
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
1245
|
-
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
1246
|
-
function getLoader(Proto) {
|
|
1247
|
-
if (isConstructor$1(Proto)) {
|
|
1248
|
-
let loader = memoizedLoaders.get(Proto);
|
|
1249
|
-
if (!loader) {
|
|
1250
|
-
loader = new Proto();
|
|
1251
|
-
memoizedLoaders.set(Proto, loader);
|
|
1252
|
-
}
|
|
1253
|
-
return loader;
|
|
1254
|
-
}
|
|
1255
|
-
return Proto;
|
|
1256
|
-
}
|
|
1257
|
-
function loadingFn(extensions, onProgress) {
|
|
1258
|
-
return function(Proto, input) {
|
|
1259
|
-
const loader = getLoader(Proto);
|
|
1260
|
-
if (extensions) extensions(loader);
|
|
1261
|
-
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
1262
|
-
return loader.loadAsync(input, onProgress).then((data) => {
|
|
1263
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1264
|
-
return data;
|
|
1265
|
-
});
|
|
1266
|
-
}
|
|
1267
|
-
return new Promise(
|
|
1268
|
-
(res, reject) => loader.load(
|
|
1269
|
-
input,
|
|
1270
|
-
(data) => {
|
|
1271
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1272
|
-
res(data);
|
|
1273
|
-
},
|
|
1274
|
-
onProgress,
|
|
1275
|
-
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
1276
|
-
)
|
|
1277
|
-
);
|
|
1278
|
-
};
|
|
1279
|
-
}
|
|
1280
|
-
function useLoader(loader, input, extensions, onProgress) {
|
|
1281
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1282
|
-
const fn = loadingFn(extensions, onProgress);
|
|
1283
|
-
const results = keys.map((key) => suspend(fn, [loader, key], { equal: is.equ }));
|
|
1284
|
-
return Array.isArray(input) ? results : results[0];
|
|
1285
|
-
}
|
|
1286
|
-
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
1287
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1288
|
-
keys.forEach((key) => preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
1289
|
-
};
|
|
1290
|
-
useLoader.clear = function(loader, input) {
|
|
1291
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1292
|
-
keys.forEach((key) => clear([loader, key]));
|
|
1293
|
-
};
|
|
1294
|
-
useLoader.loader = getLoader;
|
|
1295
|
-
|
|
1296
|
-
var __defProp$1 = Object.defineProperty;
|
|
1297
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1298
|
-
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1299
|
-
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1300
|
-
class PhaseGraph {
|
|
1301
|
-
constructor() {
|
|
1302
|
-
/** Ordered list of phase nodes */
|
|
1303
|
-
__publicField$1(this, "phases", []);
|
|
1304
|
-
/** Quick lookup by name */
|
|
1305
|
-
__publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1306
|
-
/** Cached ordered names (invalidated on changes) */
|
|
1307
|
-
__publicField$1(this, "orderedNamesCache", null);
|
|
1308
|
-
this.initializeDefaultPhases();
|
|
1309
|
-
}
|
|
1310
|
-
//* Initialization --------------------------------
|
|
1311
|
-
initializeDefaultPhases() {
|
|
1312
|
-
for (const name of DEFAULT_PHASES) {
|
|
1313
|
-
const node = { name, isAutoGenerated: false };
|
|
1314
|
-
this.phases.push(node);
|
|
1315
|
-
this.phaseMap.set(name, node);
|
|
1630
|
+
var __defProp$1 = Object.defineProperty;
|
|
1631
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1632
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1633
|
+
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1634
|
+
class PhaseGraph {
|
|
1635
|
+
constructor() {
|
|
1636
|
+
/** Ordered list of phase nodes */
|
|
1637
|
+
__publicField$1(this, "phases", []);
|
|
1638
|
+
/** Quick lookup by name */
|
|
1639
|
+
__publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1640
|
+
/** Cached ordered names (invalidated on changes) */
|
|
1641
|
+
__publicField$1(this, "orderedNamesCache", null);
|
|
1642
|
+
this.initializeDefaultPhases();
|
|
1643
|
+
}
|
|
1644
|
+
//* Initialization --------------------------------
|
|
1645
|
+
initializeDefaultPhases() {
|
|
1646
|
+
for (const name of DEFAULT_PHASES) {
|
|
1647
|
+
const node = { name, isAutoGenerated: false };
|
|
1648
|
+
this.phases.push(node);
|
|
1649
|
+
this.phaseMap.set(name, node);
|
|
1316
1650
|
}
|
|
1317
1651
|
this.invalidateCache();
|
|
1318
1652
|
}
|
|
@@ -1331,8 +1665,9 @@ class PhaseGraph {
|
|
|
1331
1665
|
const node = { name, isAutoGenerated: false };
|
|
1332
1666
|
let insertIndex = this.phases.length;
|
|
1333
1667
|
const targetIndex = this.getPhaseIndex(before ?? after);
|
|
1334
|
-
if (targetIndex !== -1)
|
|
1335
|
-
|
|
1668
|
+
if (targetIndex !== -1) {
|
|
1669
|
+
insertIndex = before ? targetIndex : targetIndex + 1;
|
|
1670
|
+
} else {
|
|
1336
1671
|
const constraintType = before ? "before" : "after";
|
|
1337
1672
|
console.warn(`[useFrame] Phase "${before ?? after}" not found for '${constraintType}' constraint`);
|
|
1338
1673
|
}
|
|
@@ -1544,7 +1879,7 @@ function shouldRun(job, now) {
|
|
|
1544
1879
|
const minInterval = 1e3 / job.fps;
|
|
1545
1880
|
const lastRun = job.lastRun ?? 0;
|
|
1546
1881
|
const elapsed = now - lastRun;
|
|
1547
|
-
if (elapsed < minInterval) return false;
|
|
1882
|
+
if (elapsed < minInterval - 1) return false;
|
|
1548
1883
|
if (job.drop) {
|
|
1549
1884
|
job.lastRun = now;
|
|
1550
1885
|
} else {
|
|
@@ -2231,98 +2566,426 @@ const _Scheduler = class _Scheduler {
|
|
|
2231
2566
|
this.triggerError(error instanceof Error ? error : new Error(String(error)));
|
|
2232
2567
|
}
|
|
2233
2568
|
}
|
|
2234
|
-
}
|
|
2235
|
-
//* Debug & Inspection Methods ================================
|
|
2236
|
-
/**
|
|
2237
|
-
* Get the total number of registered jobs across all roots.
|
|
2238
|
-
* Includes both per-root jobs and global before/after jobs.
|
|
2239
|
-
* @returns {number} Total job count
|
|
2240
|
-
*/
|
|
2241
|
-
getJobCount() {
|
|
2242
|
-
let count = 0;
|
|
2243
|
-
for (const root of this.roots.values()) {
|
|
2244
|
-
count += root.jobs.size;
|
|
2569
|
+
}
|
|
2570
|
+
//* Debug & Inspection Methods ================================
|
|
2571
|
+
/**
|
|
2572
|
+
* Get the total number of registered jobs across all roots.
|
|
2573
|
+
* Includes both per-root jobs and global before/after jobs.
|
|
2574
|
+
* @returns {number} Total job count
|
|
2575
|
+
*/
|
|
2576
|
+
getJobCount() {
|
|
2577
|
+
let count = 0;
|
|
2578
|
+
for (const root of this.roots.values()) {
|
|
2579
|
+
count += root.jobs.size;
|
|
2580
|
+
}
|
|
2581
|
+
return count + this.globalBeforeJobs.size + this.globalAfterJobs.size;
|
|
2582
|
+
}
|
|
2583
|
+
/**
|
|
2584
|
+
* Get all registered job IDs across all roots.
|
|
2585
|
+
* Includes both per-root jobs and global before/after jobs.
|
|
2586
|
+
* @returns {string[]} Array of all job IDs
|
|
2587
|
+
*/
|
|
2588
|
+
getJobIds() {
|
|
2589
|
+
const ids = [];
|
|
2590
|
+
for (const root of this.roots.values()) {
|
|
2591
|
+
ids.push(...root.jobs.keys());
|
|
2592
|
+
}
|
|
2593
|
+
ids.push(...this.globalBeforeJobs.keys());
|
|
2594
|
+
ids.push(...this.globalAfterJobs.keys());
|
|
2595
|
+
return ids;
|
|
2596
|
+
}
|
|
2597
|
+
/**
|
|
2598
|
+
* Get the number of registered roots (Canvas instances).
|
|
2599
|
+
* @returns {number} Number of registered roots
|
|
2600
|
+
*/
|
|
2601
|
+
getRootCount() {
|
|
2602
|
+
return this.roots.size;
|
|
2603
|
+
}
|
|
2604
|
+
/**
|
|
2605
|
+
* Check if any user (non-system) jobs are registered in a specific phase.
|
|
2606
|
+
* Used by the default render job to know if a user has taken over rendering.
|
|
2607
|
+
*
|
|
2608
|
+
* @param phase The phase to check
|
|
2609
|
+
* @param rootId Optional root ID to check (checks all roots if not provided)
|
|
2610
|
+
* @returns true if any user jobs exist in the phase
|
|
2611
|
+
*/
|
|
2612
|
+
hasUserJobsInPhase(phase, rootId) {
|
|
2613
|
+
const rootsToCheck = rootId ? [this.roots.get(rootId)].filter(Boolean) : Array.from(this.roots.values());
|
|
2614
|
+
return rootsToCheck.some((root) => {
|
|
2615
|
+
if (!root) return false;
|
|
2616
|
+
for (const job of root.jobs.values()) {
|
|
2617
|
+
if (job.phase === phase && !job.system && job.enabled) return true;
|
|
2618
|
+
}
|
|
2619
|
+
return false;
|
|
2620
|
+
});
|
|
2621
|
+
}
|
|
2622
|
+
//* Utility Methods ================================
|
|
2623
|
+
/**
|
|
2624
|
+
* Generate a unique root ID for automatic root registration.
|
|
2625
|
+
* @returns {string} A unique root ID in the format 'root_N'
|
|
2626
|
+
*/
|
|
2627
|
+
generateRootId() {
|
|
2628
|
+
return `root_${this.nextRootIndex++}`;
|
|
2629
|
+
}
|
|
2630
|
+
/**
|
|
2631
|
+
* Generate a unique job ID.
|
|
2632
|
+
* @returns {string} A unique job ID in the format 'job_N'
|
|
2633
|
+
* @private
|
|
2634
|
+
*/
|
|
2635
|
+
generateJobId() {
|
|
2636
|
+
return `job_${this.nextJobIndex}`;
|
|
2637
|
+
}
|
|
2638
|
+
/**
|
|
2639
|
+
* Normalize before/after constraints to a Set.
|
|
2640
|
+
* Handles undefined, single string, or array inputs.
|
|
2641
|
+
* @param {string | string[] | undefined} value - The constraint value(s)
|
|
2642
|
+
* @returns {Set<string>} Normalized Set of constraint strings
|
|
2643
|
+
* @private
|
|
2644
|
+
*/
|
|
2645
|
+
normalizeConstraints(value) {
|
|
2646
|
+
if (!value) return /* @__PURE__ */ new Set();
|
|
2647
|
+
if (Array.isArray(value)) return new Set(value);
|
|
2648
|
+
return /* @__PURE__ */ new Set([value]);
|
|
2649
|
+
}
|
|
2650
|
+
};
|
|
2651
|
+
//* Static State & Methods (Singleton Usage) ================================
|
|
2652
|
+
//* Cross-Bundle Singleton Key ==============================
|
|
2653
|
+
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2654
|
+
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2655
|
+
__publicField(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2656
|
+
let Scheduler = _Scheduler;
|
|
2657
|
+
const getScheduler = () => Scheduler.get();
|
|
2658
|
+
if (hmrData) {
|
|
2659
|
+
hmrData.accept?.();
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2662
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
2663
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React.createContext(null));
|
|
2664
|
+
const createStore = (invalidate, advance) => {
|
|
2665
|
+
const rootStore = createWithEqualityFn((set, get) => {
|
|
2666
|
+
const position = new Vector3();
|
|
2667
|
+
const defaultTarget = new Vector3();
|
|
2668
|
+
const tempTarget = new Vector3();
|
|
2669
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
2670
|
+
const { width, height, top, left } = size;
|
|
2671
|
+
const aspect = width / height;
|
|
2672
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
2673
|
+
else tempTarget.set(...target);
|
|
2674
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
2675
|
+
if (isOrthographicCamera(camera)) {
|
|
2676
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
2677
|
+
} else {
|
|
2678
|
+
const fov = camera.fov * Math.PI / 180;
|
|
2679
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
2680
|
+
const w = h * (width / height);
|
|
2681
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
let performanceTimeout = void 0;
|
|
2685
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
2686
|
+
const pointer = new Vector2();
|
|
2687
|
+
const rootState = {
|
|
2688
|
+
set,
|
|
2689
|
+
get,
|
|
2690
|
+
// Mock objects that have to be configured
|
|
2691
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
2692
|
+
primaryStore: null,
|
|
2693
|
+
gl: null,
|
|
2694
|
+
renderer: null,
|
|
2695
|
+
camera: null,
|
|
2696
|
+
frustum: new Frustum(),
|
|
2697
|
+
autoUpdateFrustum: true,
|
|
2698
|
+
raycaster: null,
|
|
2699
|
+
events: {
|
|
2700
|
+
priority: 1,
|
|
2701
|
+
enabled: true,
|
|
2702
|
+
connected: false,
|
|
2703
|
+
frameTimedRaycasts: true,
|
|
2704
|
+
alwaysFireOnScroll: true,
|
|
2705
|
+
updateOnFrame: false
|
|
2706
|
+
},
|
|
2707
|
+
scene: null,
|
|
2708
|
+
rootScene: null,
|
|
2709
|
+
xr: null,
|
|
2710
|
+
inspector: null,
|
|
2711
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
2712
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
2713
|
+
textureColorSpace: SRGBColorSpace,
|
|
2714
|
+
isLegacy: false,
|
|
2715
|
+
webGPUSupported: false,
|
|
2716
|
+
isNative: false,
|
|
2717
|
+
controls: null,
|
|
2718
|
+
pointer,
|
|
2719
|
+
mouse: pointer,
|
|
2720
|
+
frameloop: "always",
|
|
2721
|
+
onPointerMissed: void 0,
|
|
2722
|
+
onDragOverMissed: void 0,
|
|
2723
|
+
onDropMissed: void 0,
|
|
2724
|
+
performance: {
|
|
2725
|
+
current: 1,
|
|
2726
|
+
min: 0.5,
|
|
2727
|
+
max: 1,
|
|
2728
|
+
debounce: 200,
|
|
2729
|
+
regress: () => {
|
|
2730
|
+
const state2 = get();
|
|
2731
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
2732
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
2733
|
+
performanceTimeout = setTimeout(
|
|
2734
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
2735
|
+
state2.performance.debounce
|
|
2736
|
+
);
|
|
2737
|
+
}
|
|
2738
|
+
},
|
|
2739
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
2740
|
+
viewport: {
|
|
2741
|
+
initialDpr: 0,
|
|
2742
|
+
dpr: 0,
|
|
2743
|
+
width: 0,
|
|
2744
|
+
height: 0,
|
|
2745
|
+
top: 0,
|
|
2746
|
+
left: 0,
|
|
2747
|
+
aspect: 0,
|
|
2748
|
+
distance: 0,
|
|
2749
|
+
factor: 0,
|
|
2750
|
+
getCurrentViewport
|
|
2751
|
+
},
|
|
2752
|
+
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
2753
|
+
setSize: (width, height, top, left) => {
|
|
2754
|
+
const state2 = get();
|
|
2755
|
+
if (width === void 0) {
|
|
2756
|
+
set({ _sizeImperative: false });
|
|
2757
|
+
if (state2._sizeProps) {
|
|
2758
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
2759
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
2760
|
+
const currentSize = state2.size;
|
|
2761
|
+
const newSize = {
|
|
2762
|
+
width: propW ?? currentSize.width,
|
|
2763
|
+
height: propH ?? currentSize.height,
|
|
2764
|
+
top: currentSize.top,
|
|
2765
|
+
left: currentSize.left
|
|
2766
|
+
};
|
|
2767
|
+
set((s) => ({
|
|
2768
|
+
size: newSize,
|
|
2769
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
2770
|
+
}));
|
|
2771
|
+
getScheduler().invalidate();
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
return;
|
|
2775
|
+
}
|
|
2776
|
+
const w = width;
|
|
2777
|
+
const h = height ?? width;
|
|
2778
|
+
const t = top ?? state2.size.top;
|
|
2779
|
+
const l = left ?? state2.size.left;
|
|
2780
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
2781
|
+
set((s) => ({
|
|
2782
|
+
size,
|
|
2783
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
2784
|
+
_sizeImperative: true
|
|
2785
|
+
}));
|
|
2786
|
+
getScheduler().invalidate();
|
|
2787
|
+
},
|
|
2788
|
+
setDpr: (dpr) => set((state2) => {
|
|
2789
|
+
const resolved = calculateDpr(dpr);
|
|
2790
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
2791
|
+
}),
|
|
2792
|
+
setFrameloop: (frameloop = "always") => {
|
|
2793
|
+
set(() => ({ frameloop }));
|
|
2794
|
+
},
|
|
2795
|
+
setError: (error) => set(() => ({ error })),
|
|
2796
|
+
error: null,
|
|
2797
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useBuffers, useGPUStorage, useTextures, useRenderPipeline) ==============================
|
|
2798
|
+
uniforms: {},
|
|
2799
|
+
nodes: {},
|
|
2800
|
+
buffers: {},
|
|
2801
|
+
gpuStorage: {},
|
|
2802
|
+
textures: /* @__PURE__ */ new Map(),
|
|
2803
|
+
renderPipeline: null,
|
|
2804
|
+
passes: {},
|
|
2805
|
+
_hmrVersion: 0,
|
|
2806
|
+
_sizeImperative: false,
|
|
2807
|
+
_sizeProps: null,
|
|
2808
|
+
previousRoot: void 0,
|
|
2809
|
+
internal: {
|
|
2810
|
+
// Events
|
|
2811
|
+
interaction: [],
|
|
2812
|
+
subscribers: [],
|
|
2813
|
+
// Per-pointer state (new unified structure)
|
|
2814
|
+
pointerMap: /* @__PURE__ */ new Map(),
|
|
2815
|
+
pointerDirty: /* @__PURE__ */ new Map(),
|
|
2816
|
+
lastEvent: React.createRef(),
|
|
2817
|
+
// Deprecated but kept for backwards compatibility
|
|
2818
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
2819
|
+
initialClick: [0, 0],
|
|
2820
|
+
initialHits: [],
|
|
2821
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
2822
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
2823
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
2824
|
+
// Occlusion system (WebGPU only)
|
|
2825
|
+
occlusionEnabled: false,
|
|
2826
|
+
occlusionObserver: null,
|
|
2827
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
2828
|
+
helperGroup: null,
|
|
2829
|
+
// Updates
|
|
2830
|
+
active: false,
|
|
2831
|
+
frames: 0,
|
|
2832
|
+
priority: 0,
|
|
2833
|
+
subscribe: (ref, priority, store) => {
|
|
2834
|
+
const internal = get().internal;
|
|
2835
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
2836
|
+
internal.subscribers.push({ ref, priority, store });
|
|
2837
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
2838
|
+
return () => {
|
|
2839
|
+
const internal2 = get().internal;
|
|
2840
|
+
if (internal2?.subscribers) {
|
|
2841
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
2842
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
2843
|
+
}
|
|
2844
|
+
};
|
|
2845
|
+
},
|
|
2846
|
+
// Renderer Storage (single source of truth)
|
|
2847
|
+
actualRenderer: null,
|
|
2848
|
+
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
2849
|
+
scheduler: null
|
|
2850
|
+
}
|
|
2851
|
+
};
|
|
2852
|
+
return rootState;
|
|
2853
|
+
});
|
|
2854
|
+
const state = rootStore.getState();
|
|
2855
|
+
Object.defineProperty(state, "gl", {
|
|
2856
|
+
get() {
|
|
2857
|
+
const currentState = rootStore.getState();
|
|
2858
|
+
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
2859
|
+
const stack = new Error().stack || "";
|
|
2860
|
+
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
2861
|
+
if (!isInternalAccess) {
|
|
2862
|
+
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
2863
|
+
notifyDepreciated({
|
|
2864
|
+
heading: "Accessing state.gl in WebGPU mode",
|
|
2865
|
+
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
|
|
2866
|
+
});
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
return currentState.internal.actualRenderer;
|
|
2870
|
+
},
|
|
2871
|
+
set(value) {
|
|
2872
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2873
|
+
},
|
|
2874
|
+
enumerable: true,
|
|
2875
|
+
configurable: true
|
|
2876
|
+
});
|
|
2877
|
+
Object.defineProperty(state, "renderer", {
|
|
2878
|
+
get() {
|
|
2879
|
+
return rootStore.getState().internal.actualRenderer;
|
|
2880
|
+
},
|
|
2881
|
+
set(value) {
|
|
2882
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2883
|
+
},
|
|
2884
|
+
enumerable: true,
|
|
2885
|
+
configurable: true
|
|
2886
|
+
});
|
|
2887
|
+
let oldScene = state.scene;
|
|
2888
|
+
rootStore.subscribe(() => {
|
|
2889
|
+
const currentState = rootStore.getState();
|
|
2890
|
+
const { scene, rootScene, set } = currentState;
|
|
2891
|
+
if (scene !== oldScene) {
|
|
2892
|
+
oldScene = scene;
|
|
2893
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
2894
|
+
set({ rootScene: scene });
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
});
|
|
2898
|
+
let oldSize = state.size;
|
|
2899
|
+
let oldDpr = state.viewport.dpr;
|
|
2900
|
+
let oldCamera = state.camera;
|
|
2901
|
+
rootStore.subscribe(() => {
|
|
2902
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
2903
|
+
const actualRenderer = internal.actualRenderer;
|
|
2904
|
+
const canvasTarget = internal.canvasTarget;
|
|
2905
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
2906
|
+
oldSize = size;
|
|
2907
|
+
oldDpr = viewport.dpr;
|
|
2908
|
+
updateCamera(camera, size);
|
|
2909
|
+
if (internal.isSecondary && canvasTarget) {
|
|
2910
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2911
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
2912
|
+
} else {
|
|
2913
|
+
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
2914
|
+
actualRenderer.setSize(size.width, size.height, false);
|
|
2915
|
+
if (canvasTarget) {
|
|
2916
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2917
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
if (camera !== oldCamera) {
|
|
2922
|
+
oldCamera = camera;
|
|
2923
|
+
const { rootScene } = rootStore.getState();
|
|
2924
|
+
if (camera && rootScene && !camera.parent) {
|
|
2925
|
+
rootScene.add(camera);
|
|
2926
|
+
}
|
|
2927
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
2928
|
+
const currentState = rootStore.getState();
|
|
2929
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
2930
|
+
updateFrustum(camera, currentState.frustum);
|
|
2931
|
+
}
|
|
2245
2932
|
}
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2933
|
+
});
|
|
2934
|
+
rootStore.subscribe((state2) => invalidate(state2));
|
|
2935
|
+
return rootStore;
|
|
2936
|
+
};
|
|
2937
|
+
|
|
2938
|
+
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
2939
|
+
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
2940
|
+
function getLoader(Proto) {
|
|
2941
|
+
if (isConstructor$1(Proto)) {
|
|
2942
|
+
let loader = memoizedLoaders.get(Proto);
|
|
2943
|
+
if (!loader) {
|
|
2944
|
+
loader = new Proto();
|
|
2945
|
+
memoizedLoaders.set(Proto, loader);
|
|
2257
2946
|
}
|
|
2258
|
-
|
|
2259
|
-
ids.push(...this.globalAfterJobs.keys());
|
|
2260
|
-
return ids;
|
|
2261
|
-
}
|
|
2262
|
-
/**
|
|
2263
|
-
* Get the number of registered roots (Canvas instances).
|
|
2264
|
-
* @returns {number} Number of registered roots
|
|
2265
|
-
*/
|
|
2266
|
-
getRootCount() {
|
|
2267
|
-
return this.roots.size;
|
|
2268
|
-
}
|
|
2269
|
-
/**
|
|
2270
|
-
* Check if any user (non-system) jobs are registered in a specific phase.
|
|
2271
|
-
* Used by the default render job to know if a user has taken over rendering.
|
|
2272
|
-
*
|
|
2273
|
-
* @param phase The phase to check
|
|
2274
|
-
* @param rootId Optional root ID to check (checks all roots if not provided)
|
|
2275
|
-
* @returns true if any user jobs exist in the phase
|
|
2276
|
-
*/
|
|
2277
|
-
hasUserJobsInPhase(phase, rootId) {
|
|
2278
|
-
const rootsToCheck = rootId ? [this.roots.get(rootId)].filter(Boolean) : Array.from(this.roots.values());
|
|
2279
|
-
return rootsToCheck.some((root) => {
|
|
2280
|
-
if (!root) return false;
|
|
2281
|
-
for (const job of root.jobs.values()) {
|
|
2282
|
-
if (job.phase === phase && !job.system && job.enabled) return true;
|
|
2283
|
-
}
|
|
2284
|
-
return false;
|
|
2285
|
-
});
|
|
2286
|
-
}
|
|
2287
|
-
//* Utility Methods ================================
|
|
2288
|
-
/**
|
|
2289
|
-
* Generate a unique root ID for automatic root registration.
|
|
2290
|
-
* @returns {string} A unique root ID in the format 'root_N'
|
|
2291
|
-
*/
|
|
2292
|
-
generateRootId() {
|
|
2293
|
-
return `root_${this.nextRootIndex++}`;
|
|
2294
|
-
}
|
|
2295
|
-
/**
|
|
2296
|
-
* Generate a unique job ID.
|
|
2297
|
-
* @returns {string} A unique job ID in the format 'job_N'
|
|
2298
|
-
* @private
|
|
2299
|
-
*/
|
|
2300
|
-
generateJobId() {
|
|
2301
|
-
return `job_${this.nextJobIndex}`;
|
|
2302
|
-
}
|
|
2303
|
-
/**
|
|
2304
|
-
* Normalize before/after constraints to a Set.
|
|
2305
|
-
* Handles undefined, single string, or array inputs.
|
|
2306
|
-
* @param {string | string[] | undefined} value - The constraint value(s)
|
|
2307
|
-
* @returns {Set<string>} Normalized Set of constraint strings
|
|
2308
|
-
* @private
|
|
2309
|
-
*/
|
|
2310
|
-
normalizeConstraints(value) {
|
|
2311
|
-
if (!value) return /* @__PURE__ */ new Set();
|
|
2312
|
-
if (Array.isArray(value)) return new Set(value);
|
|
2313
|
-
return /* @__PURE__ */ new Set([value]);
|
|
2947
|
+
return loader;
|
|
2314
2948
|
}
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
if (
|
|
2324
|
-
|
|
2949
|
+
return Proto;
|
|
2950
|
+
}
|
|
2951
|
+
function loadingFn(extensions, onProgress) {
|
|
2952
|
+
return function(Proto, input) {
|
|
2953
|
+
const loader = getLoader(Proto);
|
|
2954
|
+
if (extensions) extensions(loader);
|
|
2955
|
+
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
2956
|
+
return loader.loadAsync(input, onProgress).then((data) => {
|
|
2957
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2958
|
+
return data;
|
|
2959
|
+
});
|
|
2960
|
+
}
|
|
2961
|
+
return new Promise(
|
|
2962
|
+
(res, reject) => loader.load(
|
|
2963
|
+
input,
|
|
2964
|
+
(data) => {
|
|
2965
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2966
|
+
res(data);
|
|
2967
|
+
},
|
|
2968
|
+
onProgress,
|
|
2969
|
+
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
2970
|
+
)
|
|
2971
|
+
);
|
|
2972
|
+
};
|
|
2325
2973
|
}
|
|
2974
|
+
function useLoader(loader, input, extensions, onProgress) {
|
|
2975
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2976
|
+
const fn = loadingFn(extensions, onProgress);
|
|
2977
|
+
const results = keys.map((key) => suspend(fn, [loader, key], { equal: is.equ }));
|
|
2978
|
+
return Array.isArray(input) ? results : results[0];
|
|
2979
|
+
}
|
|
2980
|
+
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
2981
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2982
|
+
keys.forEach((key) => preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
2983
|
+
};
|
|
2984
|
+
useLoader.clear = function(loader, input) {
|
|
2985
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2986
|
+
keys.forEach((key) => clear([loader, key]));
|
|
2987
|
+
};
|
|
2988
|
+
useLoader.loader = getLoader;
|
|
2326
2989
|
|
|
2327
2990
|
function useFrame(callback, priorityOrOptions) {
|
|
2328
2991
|
const store = React.useContext(context);
|
|
@@ -2503,6 +3166,9 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2503
3166
|
const textureCache = useThree((state) => state.textures);
|
|
2504
3167
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
2505
3168
|
const { onLoad, cache = false } = options;
|
|
3169
|
+
const onLoadRef = useRef(onLoad);
|
|
3170
|
+
onLoadRef.current = onLoad;
|
|
3171
|
+
const onLoadCalledForRef = useRef(null);
|
|
2506
3172
|
const urls = useMemo(() => getUrls(input), [input]);
|
|
2507
3173
|
const cachedResult = useMemo(() => {
|
|
2508
3174
|
if (!cache) return null;
|
|
@@ -2513,9 +3179,13 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2513
3179
|
TextureLoader,
|
|
2514
3180
|
IsObject(input) ? Object.values(input) : input
|
|
2515
3181
|
);
|
|
3182
|
+
const inputKey = urls.join("\0");
|
|
2516
3183
|
useLayoutEffect(() => {
|
|
2517
|
-
if (
|
|
2518
|
-
|
|
3184
|
+
if (cachedResult) return;
|
|
3185
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
3186
|
+
onLoadCalledForRef.current = inputKey;
|
|
3187
|
+
onLoadRef.current?.(loadedTextures);
|
|
3188
|
+
}, [cachedResult, loadedTextures, inputKey]);
|
|
2519
3189
|
useEffect(() => {
|
|
2520
3190
|
if (cachedResult) return;
|
|
2521
3191
|
if ("initTexture" in renderer) {
|
|
@@ -2682,16 +3352,33 @@ function useTextures() {
|
|
|
2682
3352
|
}, [store]);
|
|
2683
3353
|
}
|
|
2684
3354
|
|
|
2685
|
-
function useRenderTarget(
|
|
3355
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
2686
3356
|
const isLegacy = useThree((s) => s.isLegacy);
|
|
2687
3357
|
const size = useThree((s) => s.size);
|
|
3358
|
+
let width;
|
|
3359
|
+
let height;
|
|
3360
|
+
let opts;
|
|
3361
|
+
if (typeof widthOrOptions === "object") {
|
|
3362
|
+
opts = widthOrOptions;
|
|
3363
|
+
} else if (typeof widthOrOptions === "number") {
|
|
3364
|
+
width = widthOrOptions;
|
|
3365
|
+
if (typeof heightOrOptions === "object") {
|
|
3366
|
+
height = widthOrOptions;
|
|
3367
|
+
opts = heightOrOptions;
|
|
3368
|
+
} else if (typeof heightOrOptions === "number") {
|
|
3369
|
+
height = heightOrOptions;
|
|
3370
|
+
opts = options;
|
|
3371
|
+
} else {
|
|
3372
|
+
height = widthOrOptions;
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
2688
3375
|
return useMemo(() => {
|
|
2689
3376
|
const w = width ?? size.width;
|
|
2690
3377
|
const h = height ?? size.height;
|
|
2691
3378
|
{
|
|
2692
|
-
return isLegacy ? new WebGLRenderTarget(w, h,
|
|
3379
|
+
return isLegacy ? new WebGLRenderTarget(w, h, opts) : new RenderTarget(w, h, opts);
|
|
2693
3380
|
}
|
|
2694
|
-
}, [width, height, size.width, size.height,
|
|
3381
|
+
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
2695
3382
|
}
|
|
2696
3383
|
|
|
2697
3384
|
function useStore() {
|
|
@@ -2741,28 +3428,18 @@ function addTail(callback) {
|
|
|
2741
3428
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
2742
3429
|
getScheduler().invalidate(frames, stackFrames);
|
|
2743
3430
|
}
|
|
2744
|
-
function advance(timestamp
|
|
3431
|
+
function advance(timestamp) {
|
|
2745
3432
|
getScheduler().step(timestamp);
|
|
2746
3433
|
}
|
|
2747
3434
|
|
|
2748
|
-
const version = "10.0.0-alpha.
|
|
3435
|
+
const version = "10.0.0-alpha.2";
|
|
2749
3436
|
const packageData = {
|
|
2750
3437
|
version: version};
|
|
2751
3438
|
|
|
2752
3439
|
function Xb(Tt) {
|
|
2753
3440
|
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
2754
3441
|
}
|
|
2755
|
-
var Rm = { exports: {} }, Og = { exports: {} };
|
|
2756
|
-
/**
|
|
2757
|
-
* @license React
|
|
2758
|
-
* react-reconciler.production.js
|
|
2759
|
-
*
|
|
2760
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2761
|
-
*
|
|
2762
|
-
* This source code is licensed under the MIT license found in the
|
|
2763
|
-
* LICENSE file in the root directory of this source tree.
|
|
2764
|
-
*/
|
|
2765
|
-
var _b;
|
|
3442
|
+
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
2766
3443
|
function Kb() {
|
|
2767
3444
|
return _b || (_b = 1, (function(Tt) {
|
|
2768
3445
|
Tt.exports = function(m) {
|
|
@@ -3834,7 +4511,6 @@ Error generating stack: ` + l.message + `
|
|
|
3834
4511
|
if (J === cl || J === jc) throw J;
|
|
3835
4512
|
var Ge = Yn(29, J, null, P.mode);
|
|
3836
4513
|
return Ge.lanes = H, Ge.return = P, Ge;
|
|
3837
|
-
} finally {
|
|
3838
4514
|
}
|
|
3839
4515
|
};
|
|
3840
4516
|
}
|
|
@@ -4488,7 +5164,6 @@ Error generating stack: ` + l.message + `
|
|
|
4488
5164
|
var h = r.lastRenderedState, y = d(h, a);
|
|
4489
5165
|
if (c.hasEagerState = true, c.eagerState = y, jn(y, h)) return go(t, r, c, 0), Ne === null && Bn(), false;
|
|
4490
5166
|
} catch {
|
|
4491
|
-
} finally {
|
|
4492
5167
|
}
|
|
4493
5168
|
if (a = yo(t, r, c, l), a !== null) return nt(a, t, l), ns(a, r, l), true;
|
|
4494
5169
|
}
|
|
@@ -6909,10 +7584,7 @@ Error generating stack: ` + l.message + `
|
|
|
6909
7584
|
function vr(t, r) {
|
|
6910
7585
|
Sf(t, r), (t = t.alternate) && Sf(t, r);
|
|
6911
7586
|
}
|
|
6912
|
-
var ie = {}, Fm = React__default, tt = Tb, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy");
|
|
6913
|
-
var gc = Symbol.for("react.activity");
|
|
6914
|
-
var $r = Symbol.for("react.memo_cache_sentinel");
|
|
6915
|
-
var Pf = Symbol.iterator, xf = Symbol.for("react.client.reference"), ca = Array.isArray, M = Fm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Yp = m.rendererVersion, zf = m.rendererPackageName, Cf = m.extraDevToolsConfig, Ts = m.getPublicInstance, Hm = m.getRootHostContext, Xp = m.getChildHostContext, Am = m.prepareForCommit, _s = m.resetAfterCommit, Vr = m.createInstance;
|
|
7587
|
+
var ie = {}, Fm = React__default, tt = Tb, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy"), gc = Symbol.for("react.activity"), $r = Symbol.for("react.memo_cache_sentinel"), Pf = Symbol.iterator, xf = Symbol.for("react.client.reference"), ca = Array.isArray, M = Fm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Yp = m.rendererVersion, zf = m.rendererPackageName, Cf = m.extraDevToolsConfig, Ts = m.getPublicInstance, Hm = m.getRootHostContext, Xp = m.getChildHostContext, Am = m.prepareForCommit, _s = m.resetAfterCommit, Vr = m.createInstance;
|
|
6916
7588
|
m.cloneMutableInstance;
|
|
6917
7589
|
var yc = m.appendInitialChild, Kp = m.finalizeInitialChildren, Rs = m.shouldSetTextContent, bc = m.createTextInstance;
|
|
6918
7590
|
m.cloneMutableTextInstance;
|
|
@@ -7281,17 +7953,7 @@ No matching component was found for:
|
|
|
7281
7953
|
}, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true });
|
|
7282
7954
|
})(Og)), Og.exports;
|
|
7283
7955
|
}
|
|
7284
|
-
var Mg = { exports: {} };
|
|
7285
|
-
/**
|
|
7286
|
-
* @license React
|
|
7287
|
-
* react-reconciler.development.js
|
|
7288
|
-
*
|
|
7289
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
7290
|
-
*
|
|
7291
|
-
* This source code is licensed under the MIT license found in the
|
|
7292
|
-
* LICENSE file in the root directory of this source tree.
|
|
7293
|
-
*/
|
|
7294
|
-
var Rb;
|
|
7956
|
+
var Mg = { exports: {} }, Rb;
|
|
7295
7957
|
function e0() {
|
|
7296
7958
|
return Rb || (Rb = 1, (function(Tt) {
|
|
7297
7959
|
process.env.NODE_ENV !== "production" && (Tt.exports = function(m) {
|
|
@@ -13058,10 +13720,7 @@ Check the render method of %s.`, G(di) || "Unknown")), i = zo(n), i.payload = {
|
|
|
13058
13720
|
function Ic() {
|
|
13059
13721
|
return di;
|
|
13060
13722
|
}
|
|
13061
|
-
var le = {}, qm = React__default, St = Tb, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy");
|
|
13062
|
-
var Ds = Symbol.for("react.activity");
|
|
13063
|
-
var Bh = Symbol.for("react.memo_cache_sentinel");
|
|
13064
|
-
var ni = Symbol.iterator, il = Symbol.for("react.client.reference"), fn = Array.isArray, x = qm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Jt = m.rendererVersion, Zt = m.rendererPackageName, jo = m.extraDevToolsConfig, ot = m.getPublicInstance, Zr = m.getRootHostContext, Dn = m.getChildHostContext, Ws = m.prepareForCommit, pa = m.resetAfterCommit, Fc = m.createInstance;
|
|
13723
|
+
var le = {}, qm = React__default, St = Tb, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy"), Ds = Symbol.for("react.activity"), Bh = Symbol.for("react.memo_cache_sentinel"), ni = Symbol.iterator, il = Symbol.for("react.client.reference"), fn = Array.isArray, x = qm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Jt = m.rendererVersion, Zt = m.rendererPackageName, jo = m.extraDevToolsConfig, ot = m.getPublicInstance, Zr = m.getRootHostContext, Dn = m.getChildHostContext, Ws = m.prepareForCommit, pa = m.resetAfterCommit, Fc = m.createInstance;
|
|
13065
13724
|
m.cloneMutableInstance;
|
|
13066
13725
|
var bn = m.appendInitialChild, Ue = m.finalizeInitialChildren, ue = m.shouldSetTextContent, Do = m.createTextInstance;
|
|
13067
13726
|
m.cloneMutableTextInstance;
|
|
@@ -14029,15 +14688,6 @@ function n0() {
|
|
|
14029
14688
|
var t0 = n0();
|
|
14030
14689
|
const r0 = Xb(t0);
|
|
14031
14690
|
|
|
14032
|
-
/**
|
|
14033
|
-
* @license React
|
|
14034
|
-
* react-reconciler-constants.production.js
|
|
14035
|
-
*
|
|
14036
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14037
|
-
*
|
|
14038
|
-
* This source code is licensed under the MIT license found in the
|
|
14039
|
-
* LICENSE file in the root directory of this source tree.
|
|
14040
|
-
*/
|
|
14041
14691
|
const t = 1, o = 8, r = 32, e = 2;
|
|
14042
14692
|
|
|
14043
14693
|
function createReconciler(config) {
|
|
@@ -14064,10 +14714,11 @@ function extend(objects) {
|
|
|
14064
14714
|
function validateInstance(type, props) {
|
|
14065
14715
|
const name = toPascalCase(type);
|
|
14066
14716
|
const target = catalogue[name];
|
|
14067
|
-
if (type !== "primitive" && !target)
|
|
14717
|
+
if (type !== "primitive" && !target) {
|
|
14068
14718
|
throw new Error(
|
|
14069
14719
|
`R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`
|
|
14070
14720
|
);
|
|
14721
|
+
}
|
|
14071
14722
|
if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
|
|
14072
14723
|
if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
|
|
14073
14724
|
}
|
|
@@ -14231,6 +14882,7 @@ function swapInstances() {
|
|
|
14231
14882
|
instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
|
|
14232
14883
|
instance.object.__r3f = instance;
|
|
14233
14884
|
setFiberRef(fiber, instance.object);
|
|
14885
|
+
delete instance.appliedOnce;
|
|
14234
14886
|
applyProps(instance.object, instance.props);
|
|
14235
14887
|
if (instance.props.attach) {
|
|
14236
14888
|
attach(parent, instance);
|
|
@@ -14304,8 +14956,22 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14304
14956
|
const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
|
|
14305
14957
|
if (isTailSibling) swapInstances();
|
|
14306
14958
|
},
|
|
14307
|
-
finalizeInitialChildren: () =>
|
|
14308
|
-
|
|
14959
|
+
finalizeInitialChildren: (instance) => {
|
|
14960
|
+
for (const prop in instance.props) {
|
|
14961
|
+
if (isFromRef(instance.props[prop])) return true;
|
|
14962
|
+
}
|
|
14963
|
+
return false;
|
|
14964
|
+
},
|
|
14965
|
+
commitMount(instance) {
|
|
14966
|
+
const resolved = {};
|
|
14967
|
+
for (const prop in instance.props) {
|
|
14968
|
+
const value = instance.props[prop];
|
|
14969
|
+
if (isFromRef(value)) {
|
|
14970
|
+
const ref = value[FROM_REF];
|
|
14971
|
+
if (ref.current != null) resolved[prop] = ref.current;
|
|
14972
|
+
}
|
|
14973
|
+
}
|
|
14974
|
+
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
14309
14975
|
},
|
|
14310
14976
|
getPublicInstance: (instance) => instance?.object,
|
|
14311
14977
|
prepareForCommit: () => null,
|
|
@@ -14518,14 +15184,17 @@ function createRoot(canvas) {
|
|
|
14518
15184
|
if (!prevRoot) _roots.set(canvas, { fiber, store });
|
|
14519
15185
|
let onCreated;
|
|
14520
15186
|
let lastCamera;
|
|
14521
|
-
|
|
15187
|
+
const lastConfiguredProps = {};
|
|
14522
15188
|
let configured = false;
|
|
14523
15189
|
let pending = null;
|
|
14524
15190
|
return {
|
|
14525
15191
|
async configure(props = {}) {
|
|
14526
15192
|
let resolve;
|
|
14527
15193
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14528
|
-
|
|
15194
|
+
const {
|
|
15195
|
+
id: canvasId,
|
|
15196
|
+
primaryCanvas,
|
|
15197
|
+
scheduler: schedulerConfig,
|
|
14529
15198
|
gl: glConfig,
|
|
14530
15199
|
renderer: rendererConfig,
|
|
14531
15200
|
size: propsSize,
|
|
@@ -14533,10 +15202,6 @@ function createRoot(canvas) {
|
|
|
14533
15202
|
events,
|
|
14534
15203
|
onCreated: onCreatedCallback,
|
|
14535
15204
|
shadows = false,
|
|
14536
|
-
linear = false,
|
|
14537
|
-
flat = false,
|
|
14538
|
-
textureColorSpace = SRGBColorSpace,
|
|
14539
|
-
legacy = false,
|
|
14540
15205
|
orthographic = false,
|
|
14541
15206
|
frameloop = "always",
|
|
14542
15207
|
dpr = [1, 2],
|
|
@@ -14547,9 +15212,12 @@ function createRoot(canvas) {
|
|
|
14547
15212
|
onDragOverMissed,
|
|
14548
15213
|
onDropMissed,
|
|
14549
15214
|
autoUpdateFrustum = true,
|
|
14550
|
-
occlusion = false
|
|
15215
|
+
occlusion = false,
|
|
15216
|
+
_sizeProps,
|
|
15217
|
+
forceEven
|
|
14551
15218
|
} = props;
|
|
14552
|
-
|
|
15219
|
+
const textureColorSpace = is.obj(glConfig) && !is.fun(glConfig) && !isRenderer(glConfig) && glConfig.textureColorSpace || is.obj(rendererConfig) && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && rendererConfig.textureColorSpace || SRGBColorSpace;
|
|
15220
|
+
const state = store.getState();
|
|
14553
15221
|
const defaultGLProps = {
|
|
14554
15222
|
canvas,
|
|
14555
15223
|
powerPreference: "high-performance",
|
|
@@ -14557,7 +15225,8 @@ function createRoot(canvas) {
|
|
|
14557
15225
|
alpha: true
|
|
14558
15226
|
};
|
|
14559
15227
|
const defaultGPUProps = {
|
|
14560
|
-
canvas
|
|
15228
|
+
canvas,
|
|
15229
|
+
antialias: true
|
|
14561
15230
|
};
|
|
14562
15231
|
const wantsGL = (state.isLegacy || glConfig || !R3F_BUILD_WEBGPU || !rendererConfig);
|
|
14563
15232
|
if (glConfig && rendererConfig) {
|
|
@@ -14571,26 +15240,70 @@ function createRoot(canvas) {
|
|
|
14571
15240
|
});
|
|
14572
15241
|
}
|
|
14573
15242
|
let renderer = state.internal.actualRenderer;
|
|
15243
|
+
if (primaryCanvas && wantsGL) {
|
|
15244
|
+
throw new Error(
|
|
15245
|
+
"The `primaryCanvas` prop for multi-canvas rendering cannot be used with WebGL. Remove the `gl` prop or use WebGPU."
|
|
15246
|
+
);
|
|
15247
|
+
}
|
|
14574
15248
|
if (wantsGL && !state.internal.actualRenderer) {
|
|
14575
15249
|
renderer = await resolveRenderer(glConfig, defaultGLProps, WebGLRenderer);
|
|
14576
15250
|
state.internal.actualRenderer = renderer;
|
|
14577
|
-
state.set({ isLegacy: true, gl: renderer, renderer });
|
|
15251
|
+
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
15252
|
+
} else if (!wantsGL && primaryCanvas && !state.internal.actualRenderer) {
|
|
15253
|
+
const primary = await waitForPrimary(primaryCanvas);
|
|
15254
|
+
renderer = primary.renderer;
|
|
15255
|
+
state.internal.actualRenderer = renderer;
|
|
15256
|
+
const canvasTarget = new CanvasTarget(canvas);
|
|
15257
|
+
primary.store.setState((prev) => ({
|
|
15258
|
+
internal: { ...prev.internal, isMultiCanvas: true }
|
|
15259
|
+
}));
|
|
15260
|
+
state.set((prev) => ({
|
|
15261
|
+
webGPUSupported: primary.store.getState().webGPUSupported,
|
|
15262
|
+
renderer,
|
|
15263
|
+
primaryStore: primary.store,
|
|
15264
|
+
internal: {
|
|
15265
|
+
...prev.internal,
|
|
15266
|
+
canvasTarget,
|
|
15267
|
+
isMultiCanvas: true,
|
|
15268
|
+
isSecondary: true,
|
|
15269
|
+
targetId: primaryCanvas
|
|
15270
|
+
}
|
|
15271
|
+
}));
|
|
14578
15272
|
} else if (!wantsGL && !state.internal.actualRenderer) {
|
|
14579
15273
|
renderer = await resolveRenderer(rendererConfig, defaultGPUProps, WebGPURenderer);
|
|
14580
15274
|
if (!renderer.hasInitialized?.()) {
|
|
15275
|
+
const size2 = computeInitialSize(canvas, propsSize);
|
|
15276
|
+
if (size2.width > 0 && size2.height > 0) {
|
|
15277
|
+
const pixelRatio = calculateDpr(dpr);
|
|
15278
|
+
canvas.width = size2.width * pixelRatio;
|
|
15279
|
+
canvas.height = size2.height * pixelRatio;
|
|
15280
|
+
}
|
|
14581
15281
|
await renderer.init();
|
|
14582
15282
|
}
|
|
14583
15283
|
const backend = renderer.backend;
|
|
14584
15284
|
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
14585
15285
|
state.internal.actualRenderer = renderer;
|
|
14586
|
-
state.set({ webGPUSupported: isWebGPUBackend, renderer });
|
|
15286
|
+
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
15287
|
+
if (canvasId && !state.internal.isSecondary) {
|
|
15288
|
+
const canvasTarget = new CanvasTarget(canvas);
|
|
15289
|
+
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
15290
|
+
state.set((prev) => ({
|
|
15291
|
+
internal: {
|
|
15292
|
+
...prev.internal,
|
|
15293
|
+
canvasTarget,
|
|
15294
|
+
unregisterPrimary
|
|
15295
|
+
}
|
|
15296
|
+
}));
|
|
15297
|
+
}
|
|
14587
15298
|
}
|
|
14588
15299
|
let raycaster = state.raycaster;
|
|
14589
15300
|
if (!raycaster) state.set({ raycaster: raycaster = new Raycaster() });
|
|
14590
15301
|
const { params, ...options } = raycastOptions || {};
|
|
14591
15302
|
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options });
|
|
14592
|
-
if (!is.equ(params, raycaster.params, shallowLoose))
|
|
15303
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) {
|
|
14593
15304
|
applyProps(raycaster, { params: { ...raycaster.params, ...params } });
|
|
15305
|
+
}
|
|
15306
|
+
let tempCamera = state.camera;
|
|
14594
15307
|
if (!state.camera || state.camera === lastCamera && !is.equ(lastCamera, cameraOptions, shallowLoose)) {
|
|
14595
15308
|
lastCamera = cameraOptions;
|
|
14596
15309
|
const isCamera = cameraOptions?.isCamera;
|
|
@@ -14610,6 +15323,7 @@ function createRoot(canvas) {
|
|
|
14610
15323
|
if (!state.camera && !cameraOptions?.rotation) camera.lookAt(0, 0, 0);
|
|
14611
15324
|
}
|
|
14612
15325
|
state.set({ camera });
|
|
15326
|
+
tempCamera = camera;
|
|
14613
15327
|
raycaster.camera = camera;
|
|
14614
15328
|
}
|
|
14615
15329
|
if (!state.scene) {
|
|
@@ -14627,7 +15341,7 @@ function createRoot(canvas) {
|
|
|
14627
15341
|
rootScene: scene,
|
|
14628
15342
|
internal: { ...prev.internal, container: scene }
|
|
14629
15343
|
}));
|
|
14630
|
-
const camera =
|
|
15344
|
+
const camera = tempCamera;
|
|
14631
15345
|
if (camera && !camera.parent) scene.add(camera);
|
|
14632
15346
|
}
|
|
14633
15347
|
if (events && !state.events.handlers) {
|
|
@@ -14641,9 +15355,17 @@ function createRoot(canvas) {
|
|
|
14641
15355
|
wasEnabled = enabled;
|
|
14642
15356
|
});
|
|
14643
15357
|
}
|
|
15358
|
+
if (_sizeProps !== void 0) {
|
|
15359
|
+
state.set({ _sizeProps });
|
|
15360
|
+
}
|
|
15361
|
+
if (forceEven !== void 0 && state.internal.forceEven !== forceEven) {
|
|
15362
|
+
state.set((prev) => ({ internal: { ...prev.internal, forceEven } }));
|
|
15363
|
+
}
|
|
14644
15364
|
const size = computeInitialSize(canvas, propsSize);
|
|
14645
|
-
if (!is.equ(size, state.size, shallowLoose)) {
|
|
15365
|
+
if (!state._sizeImperative && !is.equ(size, state.size, shallowLoose)) {
|
|
15366
|
+
const wasImperative = state._sizeImperative;
|
|
14646
15367
|
state.setSize(size.width, size.height, size.top, size.left);
|
|
15368
|
+
if (!wasImperative) state.set({ _sizeImperative: false });
|
|
14647
15369
|
}
|
|
14648
15370
|
if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
|
|
14649
15371
|
state.setDpr(dpr);
|
|
@@ -14665,10 +15387,10 @@ function createRoot(canvas) {
|
|
|
14665
15387
|
lastConfiguredProps.performance = performance;
|
|
14666
15388
|
}
|
|
14667
15389
|
if (!state.xr) {
|
|
14668
|
-
const handleXRFrame = (timestamp,
|
|
15390
|
+
const handleXRFrame = (timestamp, _frame) => {
|
|
14669
15391
|
const state2 = store.getState();
|
|
14670
15392
|
if (state2.frameloop === "never") return;
|
|
14671
|
-
advance(timestamp
|
|
15393
|
+
advance(timestamp);
|
|
14672
15394
|
};
|
|
14673
15395
|
const actualRenderer = state.internal.actualRenderer;
|
|
14674
15396
|
const handleSessionChange = () => {
|
|
@@ -14680,16 +15402,16 @@ function createRoot(canvas) {
|
|
|
14680
15402
|
};
|
|
14681
15403
|
const xr = {
|
|
14682
15404
|
connect() {
|
|
14683
|
-
const { gl, renderer: renderer2
|
|
14684
|
-
const
|
|
14685
|
-
|
|
14686
|
-
|
|
15405
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15406
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15407
|
+
xrManager.addEventListener("sessionstart", handleSessionChange);
|
|
15408
|
+
xrManager.addEventListener("sessionend", handleSessionChange);
|
|
14687
15409
|
},
|
|
14688
15410
|
disconnect() {
|
|
14689
|
-
const { gl, renderer: renderer2
|
|
14690
|
-
const
|
|
14691
|
-
|
|
14692
|
-
|
|
15411
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15412
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15413
|
+
xrManager.removeEventListener("sessionstart", handleSessionChange);
|
|
15414
|
+
xrManager.removeEventListener("sessionend", handleSessionChange);
|
|
14693
15415
|
}
|
|
14694
15416
|
};
|
|
14695
15417
|
if (typeof renderer.xr?.addEventListener === "function") xr.connect();
|
|
@@ -14701,69 +15423,92 @@ function createRoot(canvas) {
|
|
|
14701
15423
|
const oldType = renderer.shadowMap.type;
|
|
14702
15424
|
renderer.shadowMap.enabled = !!shadows;
|
|
14703
15425
|
if (is.boo(shadows)) {
|
|
14704
|
-
renderer.shadowMap.type =
|
|
15426
|
+
renderer.shadowMap.type = PCFShadowMap;
|
|
14705
15427
|
} else if (is.str(shadows)) {
|
|
15428
|
+
if (shadows === "soft") {
|
|
15429
|
+
notifyDepreciated({
|
|
15430
|
+
heading: 'shadows="soft" is deprecated',
|
|
15431
|
+
body: "Three has depreciated soft and improved basic PCFShadows, we converted for you.",
|
|
15432
|
+
link: "https://github.com/mrdoob/three.js/wiki/Migration-Guide?utm_source=chatgpt.com#181--182"
|
|
15433
|
+
});
|
|
15434
|
+
}
|
|
14706
15435
|
const types = {
|
|
14707
15436
|
basic: BasicShadowMap,
|
|
14708
15437
|
percentage: PCFShadowMap,
|
|
14709
|
-
soft:
|
|
15438
|
+
soft: PCFShadowMap,
|
|
14710
15439
|
variance: VSMShadowMap
|
|
14711
15440
|
};
|
|
14712
|
-
renderer.shadowMap.type = types[shadows] ??
|
|
15441
|
+
renderer.shadowMap.type = types[shadows] ?? PCFShadowMap;
|
|
14713
15442
|
} else if (is.obj(shadows)) {
|
|
14714
15443
|
Object.assign(renderer.shadowMap, shadows);
|
|
14715
15444
|
}
|
|
14716
|
-
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type)
|
|
15445
|
+
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type) {
|
|
14717
15446
|
renderer.shadowMap.needsUpdate = true;
|
|
14718
|
-
}
|
|
14719
|
-
{
|
|
14720
|
-
const legacyChanged = legacy !== lastConfiguredProps.legacy;
|
|
14721
|
-
const linearChanged = linear !== lastConfiguredProps.linear;
|
|
14722
|
-
const flatChanged = flat !== lastConfiguredProps.flat;
|
|
14723
|
-
if (legacyChanged) {
|
|
14724
|
-
if (legacy)
|
|
14725
|
-
notifyDepreciated({
|
|
14726
|
-
heading: "Legacy Color Management",
|
|
14727
|
-
body: "Legacy color management is deprecated and will be removed in a future version.",
|
|
14728
|
-
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
14729
|
-
});
|
|
14730
|
-
}
|
|
14731
|
-
if (legacyChanged) {
|
|
14732
|
-
ColorManagement.enabled = !legacy;
|
|
14733
|
-
lastConfiguredProps.legacy = legacy;
|
|
14734
15447
|
}
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
if (!configured || flatChanged) {
|
|
14740
|
-
renderer.toneMapping = flat ? NoToneMapping : ACESFilmicToneMapping;
|
|
14741
|
-
lastConfiguredProps.flat = flat;
|
|
14742
|
-
}
|
|
14743
|
-
if (legacyChanged && state.legacy !== legacy) state.set(() => ({ legacy }));
|
|
14744
|
-
if (linearChanged && state.linear !== linear) state.set(() => ({ linear }));
|
|
14745
|
-
if (flatChanged && state.flat !== flat) state.set(() => ({ flat }));
|
|
15448
|
+
}
|
|
15449
|
+
if (!configured) {
|
|
15450
|
+
renderer.outputColorSpace = SRGBColorSpace;
|
|
15451
|
+
renderer.toneMapping = ACESFilmicToneMapping;
|
|
14746
15452
|
}
|
|
14747
15453
|
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
14748
15454
|
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
14749
15455
|
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
14750
15456
|
}
|
|
14751
|
-
|
|
14752
|
-
|
|
15457
|
+
const r3fProps = ["textureColorSpace"];
|
|
15458
|
+
const constructorOnlyProps = ["samples", "antialias", "alpha", "canvas", "powerPreference"];
|
|
15459
|
+
const nonApplyProps = [...r3fProps, ...constructorOnlyProps];
|
|
15460
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
|
|
15461
|
+
const glProps = {};
|
|
15462
|
+
for (const key in glConfig) {
|
|
15463
|
+
if (!nonApplyProps.includes(key)) glProps[key] = glConfig[key];
|
|
15464
|
+
}
|
|
15465
|
+
applyProps(renderer, glProps);
|
|
15466
|
+
}
|
|
14753
15467
|
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
|
|
14754
15468
|
const currentRenderer = state.renderer;
|
|
14755
15469
|
if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
|
|
14756
|
-
|
|
15470
|
+
const rendererProps = {};
|
|
15471
|
+
for (const key in rendererConfig) {
|
|
15472
|
+
if (!nonApplyProps.includes(key)) rendererProps[key] = rendererConfig[key];
|
|
15473
|
+
}
|
|
15474
|
+
applyProps(currentRenderer, rendererProps);
|
|
14757
15475
|
}
|
|
14758
15476
|
}
|
|
14759
15477
|
const scheduler = getScheduler();
|
|
14760
15478
|
const rootId = state.internal.rootId;
|
|
14761
15479
|
if (!rootId) {
|
|
14762
|
-
const newRootId = scheduler.generateRootId();
|
|
15480
|
+
const newRootId = canvasId || scheduler.generateRootId();
|
|
14763
15481
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14764
15482
|
getState: () => store.getState(),
|
|
14765
15483
|
onError: (err) => store.getState().setError(err)
|
|
14766
15484
|
});
|
|
15485
|
+
const unregisterCanvasTarget = scheduler.register(
|
|
15486
|
+
() => {
|
|
15487
|
+
const state2 = store.getState();
|
|
15488
|
+
if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
|
|
15489
|
+
const renderer2 = state2.internal.actualRenderer;
|
|
15490
|
+
renderer2.setCanvasTarget(state2.internal.canvasTarget);
|
|
15491
|
+
}
|
|
15492
|
+
},
|
|
15493
|
+
{
|
|
15494
|
+
id: `${newRootId}_canvasTarget`,
|
|
15495
|
+
rootId: newRootId,
|
|
15496
|
+
phase: "start",
|
|
15497
|
+
system: true
|
|
15498
|
+
}
|
|
15499
|
+
);
|
|
15500
|
+
const unregisterEventsFlush = scheduler.register(
|
|
15501
|
+
() => {
|
|
15502
|
+
const state2 = store.getState();
|
|
15503
|
+
state2.events.flush?.();
|
|
15504
|
+
},
|
|
15505
|
+
{
|
|
15506
|
+
id: `${newRootId}_events`,
|
|
15507
|
+
rootId: newRootId,
|
|
15508
|
+
phase: "input",
|
|
15509
|
+
system: true
|
|
15510
|
+
}
|
|
15511
|
+
);
|
|
14767
15512
|
const unregisterFrustum = scheduler.register(
|
|
14768
15513
|
() => {
|
|
14769
15514
|
const state2 = store.getState();
|
|
@@ -14798,18 +15543,22 @@ function createRoot(canvas) {
|
|
|
14798
15543
|
const userHandlesRender = scheduler.hasUserJobsInPhase("render", newRootId);
|
|
14799
15544
|
if (userHandlesRender || state2.internal.priority) return;
|
|
14800
15545
|
try {
|
|
14801
|
-
if (state2.
|
|
15546
|
+
if (state2.renderPipeline?.render) state2.renderPipeline.render();
|
|
14802
15547
|
else if (renderer2?.render) renderer2.render(state2.scene, state2.camera);
|
|
14803
15548
|
} catch (error) {
|
|
14804
15549
|
state2.setError(error instanceof Error ? error : new Error(String(error)));
|
|
14805
15550
|
}
|
|
14806
15551
|
},
|
|
14807
15552
|
{
|
|
14808
|
-
|
|
15553
|
+
// Use canvas ID directly as job ID if available, otherwise use generated rootId
|
|
15554
|
+
id: canvasId || `${newRootId}_render`,
|
|
14809
15555
|
rootId: newRootId,
|
|
14810
15556
|
phase: "render",
|
|
14811
|
-
system: true
|
|
15557
|
+
system: true,
|
|
14812
15558
|
// Internal flag: this is a system job, not user-controlled
|
|
15559
|
+
// Apply scheduler config for render ordering and rate limiting
|
|
15560
|
+
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
15561
|
+
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14813
15562
|
}
|
|
14814
15563
|
);
|
|
14815
15564
|
state.set((state2) => ({
|
|
@@ -14818,6 +15567,8 @@ function createRoot(canvas) {
|
|
|
14818
15567
|
rootId: newRootId,
|
|
14819
15568
|
unregisterRoot: () => {
|
|
14820
15569
|
unregisterRoot();
|
|
15570
|
+
unregisterCanvasTarget();
|
|
15571
|
+
unregisterEventsFlush();
|
|
14821
15572
|
unregisterFrustum();
|
|
14822
15573
|
unregisterVisibility();
|
|
14823
15574
|
unregisterRender();
|
|
@@ -14876,15 +15627,24 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14876
15627
|
const renderer = state.internal.actualRenderer;
|
|
14877
15628
|
const unregisterRoot = state.internal.unregisterRoot;
|
|
14878
15629
|
if (unregisterRoot) unregisterRoot();
|
|
15630
|
+
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
15631
|
+
if (unregisterPrimary) unregisterPrimary();
|
|
15632
|
+
const canvasTarget = state.internal.canvasTarget;
|
|
15633
|
+
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14879
15634
|
state.events.disconnect?.();
|
|
14880
15635
|
cleanupHelperGroup(root.store);
|
|
14881
|
-
renderer
|
|
14882
|
-
|
|
14883
|
-
|
|
15636
|
+
if (state.isLegacy && renderer) {
|
|
15637
|
+
;
|
|
15638
|
+
renderer.renderLists?.dispose?.();
|
|
15639
|
+
renderer.forceContextLoss?.();
|
|
15640
|
+
}
|
|
15641
|
+
if (!state.internal.isSecondary) {
|
|
15642
|
+
if (renderer?.xr) state.xr.disconnect();
|
|
15643
|
+
}
|
|
14884
15644
|
dispose(state.scene);
|
|
14885
15645
|
_roots.delete(canvas);
|
|
14886
15646
|
if (callback) callback(canvas);
|
|
14887
|
-
} catch
|
|
15647
|
+
} catch {
|
|
14888
15648
|
}
|
|
14889
15649
|
}, 500);
|
|
14890
15650
|
}
|
|
@@ -14892,36 +15652,34 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14892
15652
|
}
|
|
14893
15653
|
}
|
|
14894
15654
|
function createPortal(children, container, state) {
|
|
14895
|
-
return /* @__PURE__ */ jsx(
|
|
15655
|
+
return /* @__PURE__ */ jsx(Portal, { children, container, state });
|
|
14896
15656
|
}
|
|
14897
|
-
function
|
|
15657
|
+
function Portal({ children, container, state }) {
|
|
14898
15658
|
const isRef = useCallback((obj) => obj && "current" in obj, []);
|
|
14899
|
-
const [resolvedContainer,
|
|
15659
|
+
const [resolvedContainer, _setResolvedContainer] = useState(() => {
|
|
14900
15660
|
if (isRef(container)) return container.current ?? null;
|
|
14901
15661
|
return container;
|
|
14902
15662
|
});
|
|
15663
|
+
const setResolvedContainer = useCallback(
|
|
15664
|
+
(newContainer) => {
|
|
15665
|
+
if (!newContainer || newContainer === resolvedContainer) return;
|
|
15666
|
+
_setResolvedContainer(isRef(newContainer) ? newContainer.current : newContainer);
|
|
15667
|
+
},
|
|
15668
|
+
[resolvedContainer, _setResolvedContainer, isRef]
|
|
15669
|
+
);
|
|
14903
15670
|
useMemo(() => {
|
|
14904
|
-
if (isRef(container)) {
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
const updated = container.current;
|
|
14909
|
-
if (updated && updated !== resolvedContainer) {
|
|
14910
|
-
setResolvedContainer(updated);
|
|
14911
|
-
}
|
|
14912
|
-
});
|
|
14913
|
-
} else if (current !== resolvedContainer) {
|
|
14914
|
-
setResolvedContainer(current);
|
|
14915
|
-
}
|
|
14916
|
-
} else if (container !== resolvedContainer) {
|
|
14917
|
-
setResolvedContainer(container);
|
|
15671
|
+
if (isRef(container) && !container.current) {
|
|
15672
|
+
return queueMicrotask(() => {
|
|
15673
|
+
setResolvedContainer(container.current);
|
|
15674
|
+
});
|
|
14918
15675
|
}
|
|
14919
|
-
|
|
15676
|
+
setResolvedContainer(container);
|
|
15677
|
+
}, [container, isRef, setResolvedContainer]);
|
|
14920
15678
|
if (!resolvedContainer) return /* @__PURE__ */ jsx(Fragment, {});
|
|
14921
15679
|
const portalKey = resolvedContainer.uuid ?? `portal-${resolvedContainer.id ?? "unknown"}`;
|
|
14922
|
-
return /* @__PURE__ */ jsx(
|
|
15680
|
+
return /* @__PURE__ */ jsx(PortalInner, { children, container: resolvedContainer, state }, portalKey);
|
|
14923
15681
|
}
|
|
14924
|
-
function
|
|
15682
|
+
function PortalInner({ state = {}, children, container }) {
|
|
14925
15683
|
const { events, size, injectScene = true, ...rest } = state;
|
|
14926
15684
|
const previousRoot = useStore();
|
|
14927
15685
|
const [raycaster] = useState(() => new Raycaster());
|
|
@@ -14942,11 +15700,12 @@ function Portal({ state = {}, children, container }) {
|
|
|
14942
15700
|
};
|
|
14943
15701
|
}, [portalScene, container, injectScene]);
|
|
14944
15702
|
const inject = useMutableCallback((rootState, injectState) => {
|
|
15703
|
+
const resolvedSize = { ...rootState.size, ...injectState.size, ...size };
|
|
14945
15704
|
let viewport = void 0;
|
|
14946
|
-
if (injectState.camera && size) {
|
|
15705
|
+
if (injectState.camera && (size || injectState.size)) {
|
|
14947
15706
|
const camera = injectState.camera;
|
|
14948
|
-
viewport = rootState.viewport.getCurrentViewport(camera, new Vector3(),
|
|
14949
|
-
if (camera !== rootState.camera) updateCamera(camera,
|
|
15707
|
+
viewport = rootState.viewport.getCurrentViewport(camera, new Vector3(), resolvedSize);
|
|
15708
|
+
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14950
15709
|
}
|
|
14951
15710
|
return {
|
|
14952
15711
|
// The intersect consists of the previous root state
|
|
@@ -14963,7 +15722,7 @@ function Portal({ state = {}, children, container }) {
|
|
|
14963
15722
|
previousRoot,
|
|
14964
15723
|
// Events, size and viewport can be overridden by the inject layer
|
|
14965
15724
|
events: { ...rootState.events, ...injectState.events, ...events },
|
|
14966
|
-
size:
|
|
15725
|
+
size: resolvedSize,
|
|
14967
15726
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14968
15727
|
// Layers are allowed to override events
|
|
14969
15728
|
setEvents: (events2) => injectState.set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
@@ -14975,9 +15734,13 @@ function Portal({ state = {}, children, container }) {
|
|
|
14975
15734
|
const store = createWithEqualityFn((set, get) => ({ ...rest, set, get }));
|
|
14976
15735
|
const onMutate = (prev) => store.setState((state2) => inject.current(prev, state2));
|
|
14977
15736
|
onMutate(previousRoot.getState());
|
|
14978
|
-
previousRoot.subscribe(onMutate);
|
|
14979
15737
|
return store;
|
|
14980
15738
|
}, [previousRoot, container]);
|
|
15739
|
+
useIsomorphicLayoutEffect(() => {
|
|
15740
|
+
const onMutate = (prev) => usePortalStore.setState((state2) => inject.current(prev, state2));
|
|
15741
|
+
const unsubscribe = previousRoot.subscribe(onMutate);
|
|
15742
|
+
return unsubscribe;
|
|
15743
|
+
}, [previousRoot, usePortalStore]);
|
|
14981
15744
|
return (
|
|
14982
15745
|
// @ts-ignore, reconciler types are not maintained
|
|
14983
15746
|
/* @__PURE__ */ jsx(Fragment, { children: reconciler.createPortal(
|
|
@@ -14997,15 +15760,13 @@ function CanvasImpl({
|
|
|
14997
15760
|
fallback,
|
|
14998
15761
|
resize,
|
|
14999
15762
|
style,
|
|
15763
|
+
id,
|
|
15000
15764
|
gl,
|
|
15001
|
-
renderer,
|
|
15765
|
+
renderer: rendererProp,
|
|
15002
15766
|
events = createPointerEvents,
|
|
15003
15767
|
eventSource,
|
|
15004
15768
|
eventPrefix,
|
|
15005
15769
|
shadows,
|
|
15006
|
-
linear,
|
|
15007
|
-
flat,
|
|
15008
|
-
legacy,
|
|
15009
15770
|
orthographic,
|
|
15010
15771
|
frameloop,
|
|
15011
15772
|
dpr,
|
|
@@ -15017,10 +15778,56 @@ function CanvasImpl({
|
|
|
15017
15778
|
onDragOverMissed,
|
|
15018
15779
|
onDropMissed,
|
|
15019
15780
|
onCreated,
|
|
15781
|
+
hmr,
|
|
15782
|
+
width,
|
|
15783
|
+
height,
|
|
15784
|
+
background,
|
|
15785
|
+
forceEven,
|
|
15020
15786
|
...props
|
|
15021
15787
|
}) {
|
|
15788
|
+
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
15789
|
+
let primaryCanvas;
|
|
15790
|
+
let scheduler;
|
|
15791
|
+
let renderer;
|
|
15792
|
+
if (isRendererConfig) {
|
|
15793
|
+
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
15794
|
+
primaryCanvas = pc;
|
|
15795
|
+
scheduler = sc;
|
|
15796
|
+
renderer = Object.keys(rest).length > 0 ? rest : rendererProp;
|
|
15797
|
+
} else {
|
|
15798
|
+
renderer = rendererProp;
|
|
15799
|
+
}
|
|
15022
15800
|
React.useMemo(() => extend(THREE), []);
|
|
15023
15801
|
const Bridge = useBridge();
|
|
15802
|
+
const backgroundProps = React.useMemo(() => {
|
|
15803
|
+
if (!background) return null;
|
|
15804
|
+
if (typeof background === "object" && !background.isColor) {
|
|
15805
|
+
const { backgroundMap, envMap, files, preset, ...rest } = background;
|
|
15806
|
+
return {
|
|
15807
|
+
...rest,
|
|
15808
|
+
preset,
|
|
15809
|
+
files: envMap || files,
|
|
15810
|
+
backgroundFiles: backgroundMap,
|
|
15811
|
+
background: true
|
|
15812
|
+
};
|
|
15813
|
+
}
|
|
15814
|
+
if (typeof background === "number") {
|
|
15815
|
+
return { color: background, background: true };
|
|
15816
|
+
}
|
|
15817
|
+
if (typeof background === "string") {
|
|
15818
|
+
if (background in presetsObj) {
|
|
15819
|
+
return { preset: background, background: true };
|
|
15820
|
+
}
|
|
15821
|
+
if (/^(https?:\/\/|\/|\.\/|\.\.\/)|\\.(hdr|exr|jpg|jpeg|png|webp|gif)$/i.test(background)) {
|
|
15822
|
+
return { files: background, background: true };
|
|
15823
|
+
}
|
|
15824
|
+
return { color: background, background: true };
|
|
15825
|
+
}
|
|
15826
|
+
if (background.isColor) {
|
|
15827
|
+
return { color: background, background: true };
|
|
15828
|
+
}
|
|
15829
|
+
return null;
|
|
15830
|
+
}, [background]);
|
|
15024
15831
|
const hasInitialSizeRef = React.useRef(false);
|
|
15025
15832
|
const measureConfig = React.useMemo(() => {
|
|
15026
15833
|
if (!hasInitialSizeRef.current) {
|
|
@@ -15037,7 +15844,21 @@ function CanvasImpl({
|
|
|
15037
15844
|
};
|
|
15038
15845
|
}, [resize, hasInitialSizeRef.current]);
|
|
15039
15846
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
15040
|
-
|
|
15847
|
+
const effectiveSize = React.useMemo(() => {
|
|
15848
|
+
let w = width ?? containerRect.width;
|
|
15849
|
+
let h = height ?? containerRect.height;
|
|
15850
|
+
if (forceEven) {
|
|
15851
|
+
w = Math.ceil(w / 2) * 2;
|
|
15852
|
+
h = Math.ceil(h / 2) * 2;
|
|
15853
|
+
}
|
|
15854
|
+
return {
|
|
15855
|
+
width: w,
|
|
15856
|
+
height: h,
|
|
15857
|
+
top: containerRect.top,
|
|
15858
|
+
left: containerRect.left
|
|
15859
|
+
};
|
|
15860
|
+
}, [width, height, containerRect, forceEven]);
|
|
15861
|
+
if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
|
|
15041
15862
|
hasInitialSizeRef.current = true;
|
|
15042
15863
|
}
|
|
15043
15864
|
const canvasRef = React.useRef(null);
|
|
@@ -15056,7 +15877,7 @@ function CanvasImpl({
|
|
|
15056
15877
|
useIsomorphicLayoutEffect(() => {
|
|
15057
15878
|
effectActiveRef.current = true;
|
|
15058
15879
|
const canvas = canvasRef.current;
|
|
15059
|
-
if (
|
|
15880
|
+
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
15060
15881
|
if (!root.current) {
|
|
15061
15882
|
root.current = createRoot(canvas);
|
|
15062
15883
|
notifyAlpha({
|
|
@@ -15076,21 +15897,24 @@ function CanvasImpl({
|
|
|
15076
15897
|
async function run() {
|
|
15077
15898
|
if (!effectActiveRef.current || !root.current) return;
|
|
15078
15899
|
await root.current.configure({
|
|
15900
|
+
id,
|
|
15901
|
+
primaryCanvas,
|
|
15902
|
+
scheduler,
|
|
15079
15903
|
gl,
|
|
15080
15904
|
renderer,
|
|
15081
15905
|
scene,
|
|
15082
15906
|
events,
|
|
15083
15907
|
shadows,
|
|
15084
|
-
linear,
|
|
15085
|
-
flat,
|
|
15086
|
-
legacy,
|
|
15087
15908
|
orthographic,
|
|
15088
15909
|
frameloop,
|
|
15089
15910
|
dpr,
|
|
15090
15911
|
performance,
|
|
15091
15912
|
raycaster,
|
|
15092
15913
|
camera,
|
|
15093
|
-
size:
|
|
15914
|
+
size: effectiveSize,
|
|
15915
|
+
// Store size props for reset functionality
|
|
15916
|
+
_sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
|
|
15917
|
+
forceEven,
|
|
15094
15918
|
// Pass mutable reference to onPointerMissed so it's free to update
|
|
15095
15919
|
onPointerMissed: (...args) => handlePointerMissed.current?.(...args),
|
|
15096
15920
|
onDragOverMissed: (...args) => handleDragOverMissed.current?.(...args),
|
|
@@ -15114,7 +15938,10 @@ function CanvasImpl({
|
|
|
15114
15938
|
});
|
|
15115
15939
|
if (!effectActiveRef.current || !root.current) return;
|
|
15116
15940
|
root.current.render(
|
|
15117
|
-
/* @__PURE__ */ jsx(Bridge, { children: /* @__PURE__ */ jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */
|
|
15941
|
+
/* @__PURE__ */ jsx(Bridge, { children: /* @__PURE__ */ jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxs(React.Suspense, { fallback: /* @__PURE__ */ jsx(Block, { set: setBlock }), children: [
|
|
15942
|
+
backgroundProps && /* @__PURE__ */ jsx(Environment, { ...backgroundProps }),
|
|
15943
|
+
children ?? null
|
|
15944
|
+
] }) }) })
|
|
15118
15945
|
);
|
|
15119
15946
|
}
|
|
15120
15947
|
run();
|
|
@@ -15136,6 +15963,35 @@ function CanvasImpl({
|
|
|
15136
15963
|
};
|
|
15137
15964
|
}
|
|
15138
15965
|
}, []);
|
|
15966
|
+
React.useEffect(() => {
|
|
15967
|
+
if (hmr === false) return;
|
|
15968
|
+
const canvas = canvasRef.current;
|
|
15969
|
+
if (!canvas) return;
|
|
15970
|
+
const handleHMR = () => {
|
|
15971
|
+
queueMicrotask(() => {
|
|
15972
|
+
const rootEntry = _roots.get(canvas);
|
|
15973
|
+
if (rootEntry?.store) {
|
|
15974
|
+
console.log("[R3F] HMR detected \u2014 rebuilding nodes/uniforms");
|
|
15975
|
+
rootEntry.store.setState((state) => ({
|
|
15976
|
+
nodes: {},
|
|
15977
|
+
uniforms: {},
|
|
15978
|
+
_hmrVersion: state._hmrVersion + 1
|
|
15979
|
+
}));
|
|
15980
|
+
}
|
|
15981
|
+
});
|
|
15982
|
+
};
|
|
15983
|
+
if (typeof import.meta !== "undefined" && import.meta.hot) {
|
|
15984
|
+
const hot = import.meta.hot;
|
|
15985
|
+
hot.on("vite:afterUpdate", handleHMR);
|
|
15986
|
+
return () => hot.off?.("vite:afterUpdate", handleHMR);
|
|
15987
|
+
}
|
|
15988
|
+
if (typeof module !== "undefined" && module.hot) {
|
|
15989
|
+
const hot = module.hot;
|
|
15990
|
+
hot.addStatusHandler((status) => {
|
|
15991
|
+
if (status === "idle") handleHMR();
|
|
15992
|
+
});
|
|
15993
|
+
}
|
|
15994
|
+
}, [hmr]);
|
|
15139
15995
|
const pointerEvents = eventSource ? "none" : "auto";
|
|
15140
15996
|
return /* @__PURE__ */ jsx(
|
|
15141
15997
|
"div",
|
|
@@ -15150,7 +16006,16 @@ function CanvasImpl({
|
|
|
15150
16006
|
...style
|
|
15151
16007
|
},
|
|
15152
16008
|
...props,
|
|
15153
|
-
children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(
|
|
16009
|
+
children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(
|
|
16010
|
+
"canvas",
|
|
16011
|
+
{
|
|
16012
|
+
ref: canvasRef,
|
|
16013
|
+
id,
|
|
16014
|
+
className: "r3f-canvas",
|
|
16015
|
+
style: { display: "block", width: "100%", height: "100%" },
|
|
16016
|
+
children: fallback
|
|
16017
|
+
}
|
|
16018
|
+
) })
|
|
15154
16019
|
}
|
|
15155
16020
|
);
|
|
15156
16021
|
}
|
|
@@ -15160,4 +16025,4 @@ function Canvas(props) {
|
|
|
15160
16025
|
|
|
15161
16026
|
extend(THREE);
|
|
15162
16027
|
|
|
15163
|
-
export { Block, Canvas, ErrorBoundary, IsObject, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, Scheduler, Texture, _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, getInstanceProps, getRootState, getScheduler, getUuidPrefix, hasConstructor, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isObject3D, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, prepare, reconciler, removeInteractivity, resolve, unmountComponentAtNode, updateCamera, updateFrustum, useBridge, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useMutableCallback, useRenderTarget, useStore, useTexture, useTextures, useThree };
|
|
16028
|
+
export { Block, Canvas, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, ErrorBoundary, FROM_REF, IsObject, ONCE, Portal, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, Scheduler, Texture, _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, fromRef, getInstanceProps, getPrimary, getPrimaryIds, getRootState, getScheduler, getUuidPrefix, hasConstructor, hasPrimary, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isFromRef, isObject3D, isOnce, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, once, prepare, presetsObj, reconciler, registerPrimary, removeInteractivity, resolve, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useEnvironment, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useMutableCallback, useRenderTarget, useStore, useTexture, useTextures, useThree, waitForPrimary };
|