@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.cjs
CHANGED
|
@@ -7,10 +7,17 @@ const jsxRuntime = require('react/jsx-runtime');
|
|
|
7
7
|
const React = require('react');
|
|
8
8
|
const useMeasure = require('react-use-measure');
|
|
9
9
|
const itsFine = require('its-fine');
|
|
10
|
+
const fiber = require('@react-three/fiber');
|
|
11
|
+
const GroundedSkybox_js = require('three/examples/jsm/objects/GroundedSkybox.js');
|
|
12
|
+
const HDRLoader_js = require('three/examples/jsm/loaders/HDRLoader.js');
|
|
13
|
+
const EXRLoader_js = require('three/examples/jsm/loaders/EXRLoader.js');
|
|
14
|
+
const UltraHDRLoader_js = require('three/examples/jsm/loaders/UltraHDRLoader.js');
|
|
15
|
+
const gainmapJs = require('@monogrid/gainmap-js');
|
|
10
16
|
const Tb = require('scheduler');
|
|
11
17
|
const traditional = require('zustand/traditional');
|
|
12
18
|
const suspendReact = require('suspend-react');
|
|
13
19
|
|
|
20
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
14
21
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
15
22
|
|
|
16
23
|
function _interopNamespaceCompat(e) {
|
|
@@ -56,6 +63,389 @@ const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
|
56
63
|
WebGLRenderer: three.WebGLRenderer
|
|
57
64
|
}, [webgpu__namespace]);
|
|
58
65
|
|
|
66
|
+
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
67
|
+
const pendingSubscribers = /* @__PURE__ */ new Map();
|
|
68
|
+
function registerPrimary(id, renderer, store) {
|
|
69
|
+
if (primaryRegistry.has(id)) {
|
|
70
|
+
console.warn(`Canvas with id="${id}" already registered. Overwriting.`);
|
|
71
|
+
}
|
|
72
|
+
const entry = { renderer, store };
|
|
73
|
+
primaryRegistry.set(id, entry);
|
|
74
|
+
const subscribers = pendingSubscribers.get(id);
|
|
75
|
+
if (subscribers) {
|
|
76
|
+
subscribers.forEach((callback) => callback(entry));
|
|
77
|
+
pendingSubscribers.delete(id);
|
|
78
|
+
}
|
|
79
|
+
return () => {
|
|
80
|
+
const currentEntry = primaryRegistry.get(id);
|
|
81
|
+
if (currentEntry?.renderer === renderer) {
|
|
82
|
+
primaryRegistry.delete(id);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function getPrimary(id) {
|
|
87
|
+
return primaryRegistry.get(id);
|
|
88
|
+
}
|
|
89
|
+
function waitForPrimary(id, timeout = 5e3) {
|
|
90
|
+
const existing = primaryRegistry.get(id);
|
|
91
|
+
if (existing) {
|
|
92
|
+
return Promise.resolve(existing);
|
|
93
|
+
}
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
const timeoutId = setTimeout(() => {
|
|
96
|
+
const subscribers = pendingSubscribers.get(id);
|
|
97
|
+
if (subscribers) {
|
|
98
|
+
const index = subscribers.indexOf(callback);
|
|
99
|
+
if (index !== -1) subscribers.splice(index, 1);
|
|
100
|
+
if (subscribers.length === 0) pendingSubscribers.delete(id);
|
|
101
|
+
}
|
|
102
|
+
reject(new Error(`Timeout waiting for canvas with id="${id}". Make sure a <Canvas id="${id}"> is mounted.`));
|
|
103
|
+
}, timeout);
|
|
104
|
+
const callback = (entry) => {
|
|
105
|
+
clearTimeout(timeoutId);
|
|
106
|
+
resolve(entry);
|
|
107
|
+
};
|
|
108
|
+
if (!pendingSubscribers.has(id)) {
|
|
109
|
+
pendingSubscribers.set(id, []);
|
|
110
|
+
}
|
|
111
|
+
pendingSubscribers.get(id).push(callback);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function hasPrimary(id) {
|
|
115
|
+
return primaryRegistry.has(id);
|
|
116
|
+
}
|
|
117
|
+
function unregisterPrimary(id) {
|
|
118
|
+
primaryRegistry.delete(id);
|
|
119
|
+
}
|
|
120
|
+
function getPrimaryIds() {
|
|
121
|
+
return Array.from(primaryRegistry.keys());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const presetsObj = {
|
|
125
|
+
apartment: "lebombo_1k.hdr",
|
|
126
|
+
city: "potsdamer_platz_1k.hdr",
|
|
127
|
+
dawn: "kiara_1_dawn_1k.hdr",
|
|
128
|
+
forest: "forest_slope_1k.hdr",
|
|
129
|
+
lobby: "st_fagans_interior_1k.hdr",
|
|
130
|
+
night: "dikhololo_night_1k.hdr",
|
|
131
|
+
park: "rooitou_park_1k.hdr",
|
|
132
|
+
studio: "studio_small_03_1k.hdr",
|
|
133
|
+
sunset: "venice_sunset_1k.hdr",
|
|
134
|
+
warehouse: "empty_warehouse_01_1k.hdr"
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
|
|
138
|
+
const isArray = (arr) => Array.isArray(arr);
|
|
139
|
+
const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
|
|
140
|
+
function useEnvironment({
|
|
141
|
+
files = defaultFiles,
|
|
142
|
+
path = "",
|
|
143
|
+
preset = void 0,
|
|
144
|
+
colorSpace = void 0,
|
|
145
|
+
extensions
|
|
146
|
+
} = {}) {
|
|
147
|
+
if (preset) {
|
|
148
|
+
validatePreset(preset);
|
|
149
|
+
files = presetsObj[preset];
|
|
150
|
+
path = CUBEMAP_ROOT;
|
|
151
|
+
}
|
|
152
|
+
const multiFile = isArray(files);
|
|
153
|
+
const { extension, isCubemap } = getExtension(files);
|
|
154
|
+
const loader = getLoader$1(extension);
|
|
155
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
156
|
+
const renderer = fiber.useThree((state) => state.renderer);
|
|
157
|
+
React.useLayoutEffect(() => {
|
|
158
|
+
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
159
|
+
function clearGainmapTexture() {
|
|
160
|
+
fiber.useLoader.clear(loader, multiFile ? [files] : files);
|
|
161
|
+
}
|
|
162
|
+
renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
|
|
163
|
+
}, [extension, files, loader, multiFile, renderer.domElement]);
|
|
164
|
+
const loaderResult = fiber.useLoader(
|
|
165
|
+
loader,
|
|
166
|
+
multiFile ? [files] : files,
|
|
167
|
+
(loader2) => {
|
|
168
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
169
|
+
loader2.setRenderer?.(renderer);
|
|
170
|
+
}
|
|
171
|
+
loader2.setPath?.(path);
|
|
172
|
+
if (extensions) extensions(loader2);
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
let texture = multiFile ? (
|
|
176
|
+
// @ts-ignore
|
|
177
|
+
loaderResult[0]
|
|
178
|
+
) : loaderResult;
|
|
179
|
+
if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
|
|
180
|
+
texture = texture.renderTarget?.texture;
|
|
181
|
+
}
|
|
182
|
+
texture.mapping = isCubemap ? webgpu.CubeReflectionMapping : webgpu.EquirectangularReflectionMapping;
|
|
183
|
+
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
184
|
+
return texture;
|
|
185
|
+
}
|
|
186
|
+
const preloadDefaultOptions = {
|
|
187
|
+
files: defaultFiles,
|
|
188
|
+
path: "",
|
|
189
|
+
preset: void 0,
|
|
190
|
+
extensions: void 0
|
|
191
|
+
};
|
|
192
|
+
useEnvironment.preload = (preloadOptions) => {
|
|
193
|
+
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
194
|
+
let { files, path = "" } = options;
|
|
195
|
+
const { preset, extensions } = options;
|
|
196
|
+
if (preset) {
|
|
197
|
+
validatePreset(preset);
|
|
198
|
+
files = presetsObj[preset];
|
|
199
|
+
path = CUBEMAP_ROOT;
|
|
200
|
+
}
|
|
201
|
+
const { extension } = getExtension(files);
|
|
202
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
203
|
+
throw new Error("useEnvironment: Preloading gainmaps is not supported");
|
|
204
|
+
}
|
|
205
|
+
const loader = getLoader$1(extension);
|
|
206
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
207
|
+
fiber.useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
|
|
208
|
+
loader2.setPath?.(path);
|
|
209
|
+
if (extensions) extensions(loader2);
|
|
210
|
+
});
|
|
211
|
+
};
|
|
212
|
+
const clearDefaultOptins = {
|
|
213
|
+
files: defaultFiles,
|
|
214
|
+
preset: void 0
|
|
215
|
+
};
|
|
216
|
+
useEnvironment.clear = (clearOptions) => {
|
|
217
|
+
const options = { ...clearDefaultOptins, ...clearOptions };
|
|
218
|
+
let { files } = options;
|
|
219
|
+
const { preset } = options;
|
|
220
|
+
if (preset) {
|
|
221
|
+
validatePreset(preset);
|
|
222
|
+
files = presetsObj[preset];
|
|
223
|
+
}
|
|
224
|
+
const { extension } = getExtension(files);
|
|
225
|
+
const loader = getLoader$1(extension);
|
|
226
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
227
|
+
fiber.useLoader.clear(loader, isArray(files) ? [files] : files);
|
|
228
|
+
};
|
|
229
|
+
function validatePreset(preset) {
|
|
230
|
+
if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
|
|
231
|
+
}
|
|
232
|
+
function getExtension(files) {
|
|
233
|
+
const isCubemap = isArray(files) && files.length === 6;
|
|
234
|
+
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
235
|
+
const firstEntry = isArray(files) ? files[0] : files;
|
|
236
|
+
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();
|
|
237
|
+
return { extension, isCubemap, isGainmap };
|
|
238
|
+
}
|
|
239
|
+
function getLoader$1(extension) {
|
|
240
|
+
const loader = extension === "cube" ? webgpu.CubeTextureLoader : extension === "hdr" ? HDRLoader_js.HDRLoader : extension === "exr" ? EXRLoader_js.EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader_js.UltraHDRLoader : extension === "webp" ? gainmapJs.GainMapLoader : null;
|
|
241
|
+
return loader;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const isRef$1 = (obj) => obj.current && obj.current.isScene;
|
|
245
|
+
const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
|
|
246
|
+
function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
|
|
247
|
+
sceneProps = {
|
|
248
|
+
backgroundBlurriness: 0,
|
|
249
|
+
backgroundIntensity: 1,
|
|
250
|
+
backgroundRotation: [0, 0, 0],
|
|
251
|
+
environmentIntensity: 1,
|
|
252
|
+
environmentRotation: [0, 0, 0],
|
|
253
|
+
...sceneProps
|
|
254
|
+
};
|
|
255
|
+
const target = resolveScene(scene || defaultScene);
|
|
256
|
+
const oldbg = target.background;
|
|
257
|
+
const oldenv = target.environment;
|
|
258
|
+
const oldSceneProps = {
|
|
259
|
+
// @ts-ignore
|
|
260
|
+
backgroundBlurriness: target.backgroundBlurriness,
|
|
261
|
+
// @ts-ignore
|
|
262
|
+
backgroundIntensity: target.backgroundIntensity,
|
|
263
|
+
// @ts-ignore
|
|
264
|
+
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
265
|
+
// @ts-ignore
|
|
266
|
+
environmentIntensity: target.environmentIntensity,
|
|
267
|
+
// @ts-ignore
|
|
268
|
+
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
269
|
+
};
|
|
270
|
+
if (background !== "only") target.environment = texture;
|
|
271
|
+
if (background) target.background = texture;
|
|
272
|
+
fiber.applyProps(target, sceneProps);
|
|
273
|
+
return () => {
|
|
274
|
+
if (background !== "only") target.environment = oldenv;
|
|
275
|
+
if (background) target.background = oldbg;
|
|
276
|
+
fiber.applyProps(target, oldSceneProps);
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function EnvironmentMap({ scene, background = false, map, ...config }) {
|
|
280
|
+
const defaultScene = fiber.useThree((state) => state.scene);
|
|
281
|
+
React__namespace.useLayoutEffect(() => {
|
|
282
|
+
if (map) return setEnvProps(background, scene, defaultScene, map, config);
|
|
283
|
+
});
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
function EnvironmentCube({
|
|
287
|
+
background = false,
|
|
288
|
+
scene,
|
|
289
|
+
blur,
|
|
290
|
+
backgroundBlurriness,
|
|
291
|
+
backgroundIntensity,
|
|
292
|
+
backgroundRotation,
|
|
293
|
+
environmentIntensity,
|
|
294
|
+
environmentRotation,
|
|
295
|
+
...rest
|
|
296
|
+
}) {
|
|
297
|
+
const texture = useEnvironment(rest);
|
|
298
|
+
const defaultScene = fiber.useThree((state) => state.scene);
|
|
299
|
+
React__namespace.useLayoutEffect(() => {
|
|
300
|
+
return setEnvProps(background, scene, defaultScene, texture, {
|
|
301
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
302
|
+
backgroundIntensity,
|
|
303
|
+
backgroundRotation,
|
|
304
|
+
environmentIntensity,
|
|
305
|
+
environmentRotation
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
React__namespace.useEffect(() => {
|
|
309
|
+
return () => {
|
|
310
|
+
texture.dispose();
|
|
311
|
+
};
|
|
312
|
+
}, [texture]);
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
function EnvironmentPortal({
|
|
316
|
+
children,
|
|
317
|
+
near = 0.1,
|
|
318
|
+
far = 1e3,
|
|
319
|
+
resolution = 256,
|
|
320
|
+
frames = 1,
|
|
321
|
+
map,
|
|
322
|
+
background = false,
|
|
323
|
+
blur,
|
|
324
|
+
backgroundBlurriness,
|
|
325
|
+
backgroundIntensity,
|
|
326
|
+
backgroundRotation,
|
|
327
|
+
environmentIntensity,
|
|
328
|
+
environmentRotation,
|
|
329
|
+
scene,
|
|
330
|
+
files,
|
|
331
|
+
path,
|
|
332
|
+
preset = void 0,
|
|
333
|
+
extensions
|
|
334
|
+
}) {
|
|
335
|
+
const gl = fiber.useThree((state) => state.gl);
|
|
336
|
+
const defaultScene = fiber.useThree((state) => state.scene);
|
|
337
|
+
const camera = React__namespace.useRef(null);
|
|
338
|
+
const [virtualScene] = React__namespace.useState(() => new webgpu.Scene());
|
|
339
|
+
const fbo = React__namespace.useMemo(() => {
|
|
340
|
+
const fbo2 = new webgpu.WebGLCubeRenderTarget(resolution);
|
|
341
|
+
fbo2.texture.type = webgpu.HalfFloatType;
|
|
342
|
+
return fbo2;
|
|
343
|
+
}, [resolution]);
|
|
344
|
+
React__namespace.useEffect(() => {
|
|
345
|
+
return () => {
|
|
346
|
+
fbo.dispose();
|
|
347
|
+
};
|
|
348
|
+
}, [fbo]);
|
|
349
|
+
React__namespace.useLayoutEffect(() => {
|
|
350
|
+
if (frames === 1) {
|
|
351
|
+
const autoClear = gl.autoClear;
|
|
352
|
+
gl.autoClear = true;
|
|
353
|
+
camera.current.update(gl, virtualScene);
|
|
354
|
+
gl.autoClear = autoClear;
|
|
355
|
+
}
|
|
356
|
+
return setEnvProps(background, scene, defaultScene, fbo.texture, {
|
|
357
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
358
|
+
backgroundIntensity,
|
|
359
|
+
backgroundRotation,
|
|
360
|
+
environmentIntensity,
|
|
361
|
+
environmentRotation
|
|
362
|
+
});
|
|
363
|
+
}, [
|
|
364
|
+
children,
|
|
365
|
+
virtualScene,
|
|
366
|
+
fbo.texture,
|
|
367
|
+
scene,
|
|
368
|
+
defaultScene,
|
|
369
|
+
background,
|
|
370
|
+
frames,
|
|
371
|
+
gl,
|
|
372
|
+
blur,
|
|
373
|
+
backgroundBlurriness,
|
|
374
|
+
backgroundIntensity,
|
|
375
|
+
backgroundRotation,
|
|
376
|
+
environmentIntensity,
|
|
377
|
+
environmentRotation
|
|
378
|
+
]);
|
|
379
|
+
let count = 1;
|
|
380
|
+
fiber.useFrame(() => {
|
|
381
|
+
if (frames === Infinity || count < frames) {
|
|
382
|
+
const autoClear = gl.autoClear;
|
|
383
|
+
gl.autoClear = true;
|
|
384
|
+
camera.current.update(gl, virtualScene);
|
|
385
|
+
gl.autoClear = autoClear;
|
|
386
|
+
count++;
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fiber.createPortal(
|
|
390
|
+
/* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
391
|
+
children,
|
|
392
|
+
/* @__PURE__ */ jsxRuntime.jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
|
|
393
|
+
files || preset ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { background: true, map, extensions }) : null
|
|
394
|
+
] }),
|
|
395
|
+
virtualScene
|
|
396
|
+
) });
|
|
397
|
+
}
|
|
398
|
+
function EnvironmentGround(props) {
|
|
399
|
+
const textureDefault = useEnvironment(props);
|
|
400
|
+
const texture = props.map || textureDefault;
|
|
401
|
+
React__namespace.useMemo(() => fiber.extend({ GroundProjectedEnvImpl: GroundedSkybox_js.GroundedSkybox }), []);
|
|
402
|
+
React__namespace.useEffect(() => {
|
|
403
|
+
return () => {
|
|
404
|
+
textureDefault.dispose();
|
|
405
|
+
};
|
|
406
|
+
}, [textureDefault]);
|
|
407
|
+
const height = props.ground?.height ?? 15;
|
|
408
|
+
const radius = props.ground?.radius ?? 60;
|
|
409
|
+
const scale = props.ground?.scale ?? 1e3;
|
|
410
|
+
const args = React__namespace.useMemo(
|
|
411
|
+
() => [texture, height, radius],
|
|
412
|
+
[texture, height, radius]
|
|
413
|
+
);
|
|
414
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
415
|
+
/* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props, map: texture }),
|
|
416
|
+
/* @__PURE__ */ jsxRuntime.jsx("groundProjectedEnvImpl", { args, scale })
|
|
417
|
+
] });
|
|
418
|
+
}
|
|
419
|
+
function EnvironmentColor({ color, scene }) {
|
|
420
|
+
const defaultScene = fiber.useThree((state) => state.scene);
|
|
421
|
+
React__namespace.useLayoutEffect(() => {
|
|
422
|
+
if (color === void 0) return;
|
|
423
|
+
const target = resolveScene(scene || defaultScene);
|
|
424
|
+
const oldBg = target.background;
|
|
425
|
+
target.background = new webgpu.Color(color);
|
|
426
|
+
return () => {
|
|
427
|
+
target.background = oldBg;
|
|
428
|
+
};
|
|
429
|
+
});
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
function EnvironmentDualSource(props) {
|
|
433
|
+
const { backgroundFiles, ...envProps } = props;
|
|
434
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
435
|
+
/* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
436
|
+
/* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
|
|
437
|
+
] });
|
|
438
|
+
}
|
|
439
|
+
function Environment(props) {
|
|
440
|
+
if (props.color && !props.files && !props.preset && !props.map) {
|
|
441
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentColor, { ...props });
|
|
442
|
+
}
|
|
443
|
+
if (props.backgroundFiles && props.backgroundFiles !== props.files) {
|
|
444
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentDualSource, { ...props });
|
|
445
|
+
}
|
|
446
|
+
return props.ground ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props });
|
|
447
|
+
}
|
|
448
|
+
|
|
59
449
|
var __defProp$2 = Object.defineProperty;
|
|
60
450
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
61
451
|
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -235,7 +625,8 @@ function prepare(target, root, type, props) {
|
|
|
235
625
|
object,
|
|
236
626
|
eventCount: 0,
|
|
237
627
|
handlers: {},
|
|
238
|
-
isHidden: false
|
|
628
|
+
isHidden: false,
|
|
629
|
+
deferredRefs: []
|
|
239
630
|
};
|
|
240
631
|
if (object) object.__r3f = instance;
|
|
241
632
|
}
|
|
@@ -284,7 +675,7 @@ function createOcclusionObserverNode(store, uniform) {
|
|
|
284
675
|
let occlusionSetupPromise = null;
|
|
285
676
|
function enableOcclusion(store) {
|
|
286
677
|
const state = store.getState();
|
|
287
|
-
const { internal, renderer
|
|
678
|
+
const { internal, renderer } = state;
|
|
288
679
|
if (internal.occlusionEnabled || occlusionSetupPromise) return;
|
|
289
680
|
const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
|
|
290
681
|
if (!hasOcclusionSupport) {
|
|
@@ -447,6 +838,22 @@ function hasVisibilityHandlers(handlers) {
|
|
|
447
838
|
return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
|
|
448
839
|
}
|
|
449
840
|
|
|
841
|
+
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
842
|
+
function fromRef(ref) {
|
|
843
|
+
return { [FROM_REF]: ref };
|
|
844
|
+
}
|
|
845
|
+
function isFromRef(value) {
|
|
846
|
+
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
const ONCE = Symbol.for("@react-three/fiber.once");
|
|
850
|
+
function once(...args) {
|
|
851
|
+
return { [ONCE]: args.length ? args : true };
|
|
852
|
+
}
|
|
853
|
+
function isOnce(value) {
|
|
854
|
+
return value !== null && typeof value === "object" && ONCE in value;
|
|
855
|
+
}
|
|
856
|
+
|
|
450
857
|
const RESERVED_PROPS = [
|
|
451
858
|
"children",
|
|
452
859
|
"key",
|
|
@@ -517,7 +924,7 @@ function getMemoizedPrototype(root) {
|
|
|
517
924
|
ctor = new root.constructor();
|
|
518
925
|
MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
|
|
519
926
|
}
|
|
520
|
-
} catch
|
|
927
|
+
} catch {
|
|
521
928
|
}
|
|
522
929
|
return ctor;
|
|
523
930
|
}
|
|
@@ -548,7 +955,7 @@ function applyProps(object, props) {
|
|
|
548
955
|
const rootState = instance && findInitialRoot(instance).getState();
|
|
549
956
|
const prevHandlers = instance?.eventCount;
|
|
550
957
|
for (const prop in props) {
|
|
551
|
-
|
|
958
|
+
const value = props[prop];
|
|
552
959
|
if (RESERVED_PROPS.includes(prop)) continue;
|
|
553
960
|
if (instance && EVENT_REGEX.test(prop)) {
|
|
554
961
|
if (typeof value === "function") instance.handlers[prop] = value;
|
|
@@ -563,6 +970,25 @@ function applyProps(object, props) {
|
|
|
563
970
|
continue;
|
|
564
971
|
}
|
|
565
972
|
if (value === void 0) continue;
|
|
973
|
+
if (isFromRef(value)) {
|
|
974
|
+
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
977
|
+
if (isOnce(value)) {
|
|
978
|
+
if (instance?.appliedOnce?.has(prop)) continue;
|
|
979
|
+
if (instance) {
|
|
980
|
+
instance.appliedOnce ?? (instance.appliedOnce = /* @__PURE__ */ new Set());
|
|
981
|
+
instance.appliedOnce.add(prop);
|
|
982
|
+
}
|
|
983
|
+
const { root: targetRoot, key: targetKey } = resolve(object, prop);
|
|
984
|
+
const args = value[ONCE];
|
|
985
|
+
if (typeof targetRoot[targetKey] === "function") {
|
|
986
|
+
targetRoot[targetKey](...args === true ? [] : args);
|
|
987
|
+
} else if (args !== true && args.length > 0) {
|
|
988
|
+
targetRoot[targetKey] = args[0];
|
|
989
|
+
}
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
566
992
|
let { root, key, target } = resolve(object, prop);
|
|
567
993
|
if (target === void 0 && (typeof root !== "object" || root === null)) {
|
|
568
994
|
throw Error(`R3F: Cannot set "${prop}". Ensure it is an object before setting "${key}".`);
|
|
@@ -585,7 +1011,10 @@ function applyProps(object, props) {
|
|
|
585
1011
|
else target.set(value);
|
|
586
1012
|
} else {
|
|
587
1013
|
root[key] = value;
|
|
588
|
-
if (
|
|
1014
|
+
if (key.endsWith("Node") && root.isMaterial) {
|
|
1015
|
+
root.needsUpdate = true;
|
|
1016
|
+
}
|
|
1017
|
+
if (rootState && rootState.renderer?.outputColorSpace === webgpu.SRGBColorSpace && colorMaps.includes(key) && isTexture(value) && root[key]?.isTexture && // sRGB textures must be RGBA8 since r137 https://github.com/mrdoob/three.js/pull/23129
|
|
589
1018
|
root[key].format === webgpu.RGBAFormat && root[key].type === webgpu.UnsignedByteType) {
|
|
590
1019
|
root[key].colorSpace = rootState.textureColorSpace;
|
|
591
1020
|
}
|
|
@@ -618,38 +1047,60 @@ function applyProps(object, props) {
|
|
|
618
1047
|
return object;
|
|
619
1048
|
}
|
|
620
1049
|
|
|
1050
|
+
const DEFAULT_POINTER_ID = 0;
|
|
1051
|
+
const XR_POINTER_ID_START = 1e3;
|
|
1052
|
+
function getPointerState(internal, pointerId) {
|
|
1053
|
+
let state = internal.pointerMap.get(pointerId);
|
|
1054
|
+
if (!state) {
|
|
1055
|
+
state = {
|
|
1056
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
1057
|
+
captured: /* @__PURE__ */ new Map(),
|
|
1058
|
+
initialClick: [0, 0],
|
|
1059
|
+
initialHits: []
|
|
1060
|
+
};
|
|
1061
|
+
internal.pointerMap.set(pointerId, state);
|
|
1062
|
+
}
|
|
1063
|
+
return state;
|
|
1064
|
+
}
|
|
1065
|
+
function getPointerId(event) {
|
|
1066
|
+
return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
|
|
1067
|
+
}
|
|
621
1068
|
function makeId(event) {
|
|
622
1069
|
return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
|
|
623
1070
|
}
|
|
624
|
-
function releaseInternalPointerCapture(
|
|
625
|
-
const
|
|
1071
|
+
function releaseInternalPointerCapture(internal, obj, pointerId) {
|
|
1072
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1073
|
+
if (!pointerState) return;
|
|
1074
|
+
const captureData = pointerState.captured.get(obj);
|
|
626
1075
|
if (captureData) {
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
capturedMap.delete(pointerId);
|
|
630
|
-
captureData.target.releasePointerCapture(pointerId);
|
|
631
|
-
}
|
|
1076
|
+
pointerState.captured.delete(obj);
|
|
1077
|
+
captureData.target.releasePointerCapture(pointerId);
|
|
632
1078
|
}
|
|
633
1079
|
}
|
|
634
1080
|
function removeInteractivity(store, object) {
|
|
635
1081
|
const { internal } = store.getState();
|
|
636
1082
|
internal.interaction = internal.interaction.filter((o) => o !== object);
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
1083
|
+
for (const [pointerId, pointerState] of internal.pointerMap) {
|
|
1084
|
+
pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
|
|
1085
|
+
pointerState.hovered.forEach((value, key) => {
|
|
1086
|
+
if (value.eventObject === object || value.object === object) {
|
|
1087
|
+
pointerState.hovered.delete(key);
|
|
1088
|
+
}
|
|
1089
|
+
});
|
|
1090
|
+
if (pointerState.captured.has(object)) {
|
|
1091
|
+
releaseInternalPointerCapture(internal, object, pointerId);
|
|
641
1092
|
}
|
|
642
|
-
}
|
|
643
|
-
internal.capturedMap.forEach((captures, pointerId) => {
|
|
644
|
-
releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
|
|
645
|
-
});
|
|
1093
|
+
}
|
|
646
1094
|
unregisterVisibility(store, object);
|
|
647
1095
|
}
|
|
648
1096
|
function createEvents(store) {
|
|
649
|
-
function calculateDistance(event) {
|
|
1097
|
+
function calculateDistance(event, pointerId) {
|
|
650
1098
|
const { internal } = store.getState();
|
|
651
|
-
const
|
|
652
|
-
|
|
1099
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1100
|
+
if (!pointerState) return 0;
|
|
1101
|
+
const [initialX, initialY] = pointerState.initialClick;
|
|
1102
|
+
const dx = event.offsetX - initialX;
|
|
1103
|
+
const dy = event.offsetY - initialY;
|
|
653
1104
|
return Math.round(Math.sqrt(dx * dx + dy * dy));
|
|
654
1105
|
}
|
|
655
1106
|
function filterPointerEvents(objects) {
|
|
@@ -685,6 +1136,15 @@ function createEvents(store) {
|
|
|
685
1136
|
return state2.raycaster.camera ? state2.raycaster.intersectObject(obj, true) : [];
|
|
686
1137
|
}
|
|
687
1138
|
let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
|
|
1139
|
+
const aInteractivePriority = a.object.userData?.interactivePriority;
|
|
1140
|
+
const bInteractivePriority = b.object.userData?.interactivePriority;
|
|
1141
|
+
if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
|
|
1142
|
+
if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
|
|
1143
|
+
if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
|
|
1144
|
+
if (aInteractivePriority !== bInteractivePriority) {
|
|
1145
|
+
return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
688
1148
|
const aState = getRootState(a.object);
|
|
689
1149
|
const bState = getRootState(b.object);
|
|
690
1150
|
const aPriority = aState?.events?.priority ?? 1;
|
|
@@ -700,14 +1160,19 @@ function createEvents(store) {
|
|
|
700
1160
|
for (const hit of hits) {
|
|
701
1161
|
let eventObject = hit.object;
|
|
702
1162
|
while (eventObject) {
|
|
703
|
-
if (eventObject.__r3f?.eventCount)
|
|
1163
|
+
if (eventObject.__r3f?.eventCount) {
|
|
704
1164
|
intersections.push({ ...hit, eventObject });
|
|
1165
|
+
}
|
|
705
1166
|
eventObject = eventObject.parent;
|
|
706
1167
|
}
|
|
707
1168
|
}
|
|
708
|
-
if ("pointerId" in event
|
|
709
|
-
|
|
710
|
-
|
|
1169
|
+
if ("pointerId" in event) {
|
|
1170
|
+
const pointerId = event.pointerId;
|
|
1171
|
+
const pointerState = state.internal.pointerMap.get(pointerId);
|
|
1172
|
+
if (pointerState?.captured.size) {
|
|
1173
|
+
for (const captureData of pointerState.captured.values()) {
|
|
1174
|
+
if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
|
|
1175
|
+
}
|
|
711
1176
|
}
|
|
712
1177
|
}
|
|
713
1178
|
return intersections;
|
|
@@ -720,28 +1185,26 @@ function createEvents(store) {
|
|
|
720
1185
|
if (state) {
|
|
721
1186
|
const { raycaster, pointer, camera, internal } = state;
|
|
722
1187
|
const unprojectedPoint = new webgpu.Vector3(pointer.x, pointer.y, 0).unproject(camera);
|
|
723
|
-
const hasPointerCapture = (id) =>
|
|
1188
|
+
const hasPointerCapture = (id) => {
|
|
1189
|
+
const pointerState = internal.pointerMap.get(id);
|
|
1190
|
+
return pointerState?.captured.has(hit.eventObject) ?? false;
|
|
1191
|
+
};
|
|
724
1192
|
const setPointerCapture = (id) => {
|
|
725
1193
|
const captureData = { intersection: hit, target: event.target };
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
} else {
|
|
729
|
-
internal.capturedMap.set(id, /* @__PURE__ */ new Map([[hit.eventObject, captureData]]));
|
|
730
|
-
}
|
|
1194
|
+
const pointerState = getPointerState(internal, id);
|
|
1195
|
+
pointerState.captured.set(hit.eventObject, captureData);
|
|
731
1196
|
event.target.setPointerCapture(id);
|
|
732
1197
|
};
|
|
733
1198
|
const releasePointerCapture = (id) => {
|
|
734
|
-
|
|
735
|
-
if (captures) {
|
|
736
|
-
releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
|
|
737
|
-
}
|
|
1199
|
+
releaseInternalPointerCapture(internal, hit.eventObject, id);
|
|
738
1200
|
};
|
|
739
|
-
|
|
740
|
-
for (
|
|
741
|
-
|
|
1201
|
+
const extractEventProps = {};
|
|
1202
|
+
for (const prop in event) {
|
|
1203
|
+
const property = event[prop];
|
|
742
1204
|
if (typeof property !== "function") extractEventProps[prop] = property;
|
|
743
1205
|
}
|
|
744
|
-
|
|
1206
|
+
const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
|
|
1207
|
+
const raycastEvent = {
|
|
745
1208
|
...hit,
|
|
746
1209
|
...extractEventProps,
|
|
747
1210
|
pointer,
|
|
@@ -751,18 +1214,19 @@ function createEvents(store) {
|
|
|
751
1214
|
unprojectedPoint,
|
|
752
1215
|
ray: raycaster.ray,
|
|
753
1216
|
camera,
|
|
1217
|
+
pointerId: eventPointerId,
|
|
754
1218
|
// Hijack stopPropagation, which just sets a flag
|
|
755
1219
|
stopPropagation() {
|
|
756
|
-
const
|
|
1220
|
+
const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
|
|
757
1221
|
if (
|
|
758
1222
|
// ...if this pointer hasn't been captured
|
|
759
|
-
!
|
|
760
|
-
|
|
1223
|
+
!pointerState?.captured.size || // ... or if the hit object is capturing the pointer
|
|
1224
|
+
pointerState.captured.has(hit.eventObject)
|
|
761
1225
|
) {
|
|
762
1226
|
raycastEvent.stopped = localState.stopped = true;
|
|
763
|
-
if (
|
|
1227
|
+
if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
|
|
764
1228
|
const higher = intersections.slice(0, intersections.indexOf(hit));
|
|
765
|
-
cancelPointer([...higher, hit]);
|
|
1229
|
+
cancelPointer([...higher, hit], eventPointerId);
|
|
766
1230
|
}
|
|
767
1231
|
}
|
|
768
1232
|
},
|
|
@@ -778,15 +1242,18 @@ function createEvents(store) {
|
|
|
778
1242
|
}
|
|
779
1243
|
return intersections;
|
|
780
1244
|
}
|
|
781
|
-
function cancelPointer(intersections) {
|
|
1245
|
+
function cancelPointer(intersections, pointerId) {
|
|
782
1246
|
const { internal } = store.getState();
|
|
783
|
-
|
|
1247
|
+
const pid = pointerId ?? DEFAULT_POINTER_ID;
|
|
1248
|
+
const pointerState = internal.pointerMap.get(pid);
|
|
1249
|
+
if (!pointerState) return;
|
|
1250
|
+
for (const [hoveredId, hoveredObj] of pointerState.hovered) {
|
|
784
1251
|
if (!intersections.length || !intersections.find(
|
|
785
1252
|
(hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
|
|
786
1253
|
)) {
|
|
787
1254
|
const eventObject = hoveredObj.eventObject;
|
|
788
1255
|
const instance = eventObject.__r3f;
|
|
789
|
-
|
|
1256
|
+
pointerState.hovered.delete(hoveredId);
|
|
790
1257
|
if (instance?.eventCount) {
|
|
791
1258
|
const handlers = instance.handlers;
|
|
792
1259
|
const data = { ...hoveredObj, intersections };
|
|
@@ -815,41 +1282,118 @@ function createEvents(store) {
|
|
|
815
1282
|
instance?.handlers.onDropMissed?.(event);
|
|
816
1283
|
}
|
|
817
1284
|
}
|
|
1285
|
+
function cleanupPointer(pointerId) {
|
|
1286
|
+
const { internal } = store.getState();
|
|
1287
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1288
|
+
if (pointerState) {
|
|
1289
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
1290
|
+
const eventObject = hoveredObj.eventObject;
|
|
1291
|
+
const instance = eventObject.__r3f;
|
|
1292
|
+
if (instance?.eventCount) {
|
|
1293
|
+
const handlers = instance.handlers;
|
|
1294
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
1295
|
+
handlers.onPointerOut?.(data);
|
|
1296
|
+
handlers.onPointerLeave?.(data);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
internal.pointerMap.delete(pointerId);
|
|
1300
|
+
}
|
|
1301
|
+
internal.pointerDirty.delete(pointerId);
|
|
1302
|
+
}
|
|
1303
|
+
function processDeferredPointer(event, pointerId) {
|
|
1304
|
+
const state = store.getState();
|
|
1305
|
+
const { internal } = state;
|
|
1306
|
+
if (!state.events.enabled) return;
|
|
1307
|
+
const filter = filterPointerEvents;
|
|
1308
|
+
const hits = intersect(event, filter);
|
|
1309
|
+
cancelPointer(hits, pointerId);
|
|
1310
|
+
function onIntersect(data) {
|
|
1311
|
+
const eventObject = data.eventObject;
|
|
1312
|
+
const instance = eventObject.__r3f;
|
|
1313
|
+
if (!instance?.eventCount) return;
|
|
1314
|
+
const handlers = instance.handlers;
|
|
1315
|
+
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
1316
|
+
const id = makeId(data);
|
|
1317
|
+
const pointerState = getPointerState(internal, pointerId);
|
|
1318
|
+
const hoveredItem = pointerState.hovered.get(id);
|
|
1319
|
+
if (!hoveredItem) {
|
|
1320
|
+
pointerState.hovered.set(id, data);
|
|
1321
|
+
handlers.onPointerOver?.(data);
|
|
1322
|
+
handlers.onPointerEnter?.(data);
|
|
1323
|
+
} else if (hoveredItem.stopped) {
|
|
1324
|
+
data.stopPropagation();
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
handlers.onPointerMove?.(data);
|
|
1328
|
+
}
|
|
1329
|
+
handleIntersects(hits, event, 0, onIntersect);
|
|
1330
|
+
}
|
|
818
1331
|
function handlePointer(name) {
|
|
819
1332
|
switch (name) {
|
|
820
1333
|
case "onPointerLeave":
|
|
821
|
-
case "onPointerCancel":
|
|
822
1334
|
case "onDragLeave":
|
|
823
1335
|
return () => cancelPointer([]);
|
|
1336
|
+
// Global cancel of these events
|
|
1337
|
+
case "onPointerCancel":
|
|
1338
|
+
return (event) => {
|
|
1339
|
+
const pointerId = getPointerId(event);
|
|
1340
|
+
cleanupPointer(pointerId);
|
|
1341
|
+
};
|
|
824
1342
|
case "onLostPointerCapture":
|
|
825
1343
|
return (event) => {
|
|
826
1344
|
const { internal } = store.getState();
|
|
827
|
-
|
|
1345
|
+
const pointerId = getPointerId(event);
|
|
1346
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1347
|
+
if (pointerState?.captured.size) {
|
|
828
1348
|
requestAnimationFrame(() => {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
1349
|
+
const pointerState2 = internal.pointerMap.get(pointerId);
|
|
1350
|
+
if (pointerState2?.captured.size) {
|
|
1351
|
+
pointerState2.captured.clear();
|
|
832
1352
|
}
|
|
1353
|
+
cancelPointer([], pointerId);
|
|
833
1354
|
});
|
|
834
1355
|
}
|
|
835
1356
|
};
|
|
836
1357
|
}
|
|
837
1358
|
return function handleEvent(event) {
|
|
838
1359
|
const state = store.getState();
|
|
839
|
-
const { onPointerMissed, onDragOverMissed, onDropMissed, internal } = state;
|
|
1360
|
+
const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
|
|
1361
|
+
const pointerId = getPointerId(event);
|
|
840
1362
|
internal.lastEvent.current = event;
|
|
841
|
-
if (!
|
|
1363
|
+
if (!events.enabled) return;
|
|
842
1364
|
const isPointerMove = name === "onPointerMove";
|
|
843
1365
|
const isDragOver = name === "onDragOver";
|
|
844
1366
|
const isDrop = name === "onDrop";
|
|
845
1367
|
const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
|
|
1368
|
+
const isPointerDown = name === "onPointerDown";
|
|
1369
|
+
const isPointerUp = name === "onPointerUp";
|
|
1370
|
+
const isWheel = name === "onWheel";
|
|
1371
|
+
const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
|
|
1372
|
+
if (isPointerMove && canDeferRaycasts) {
|
|
1373
|
+
events.compute?.(event, state);
|
|
1374
|
+
internal.pointerDirty.set(pointerId, event);
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1377
|
+
if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
|
|
1378
|
+
events.compute?.(event, state);
|
|
1379
|
+
internal.pointerDirty.set(pointerId, event);
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
|
|
1383
|
+
const deferredEvent = internal.pointerDirty.get(pointerId);
|
|
1384
|
+
internal.pointerDirty.delete(pointerId);
|
|
1385
|
+
processDeferredPointer(deferredEvent, pointerId);
|
|
1386
|
+
}
|
|
846
1387
|
const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
|
|
847
1388
|
const hits = intersect(event, filter);
|
|
848
|
-
const delta = isClickEvent ? calculateDistance(event) : 0;
|
|
849
|
-
if (
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
1389
|
+
const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
|
|
1390
|
+
if (isPointerDown) {
|
|
1391
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1392
|
+
pointerState2.initialClick = [event.offsetX, event.offsetY];
|
|
1393
|
+
pointerState2.initialHits = hits.map((hit) => hit.eventObject);
|
|
1394
|
+
}
|
|
1395
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1396
|
+
const initialHits = pointerState?.initialHits ?? [];
|
|
853
1397
|
if (isClickEvent && !hits.length) {
|
|
854
1398
|
if (delta <= 2) {
|
|
855
1399
|
pointerMissed(event, internal.interaction);
|
|
@@ -864,7 +1408,9 @@ function createEvents(store) {
|
|
|
864
1408
|
dropMissed(event, internal.interaction);
|
|
865
1409
|
if (onDropMissed) onDropMissed(event);
|
|
866
1410
|
}
|
|
867
|
-
if (isPointerMove || isDragOver)
|
|
1411
|
+
if (isPointerMove || isDragOver) {
|
|
1412
|
+
cancelPointer(hits, pointerId);
|
|
1413
|
+
}
|
|
868
1414
|
function onIntersect(data) {
|
|
869
1415
|
const eventObject = data.eventObject;
|
|
870
1416
|
const instance = eventObject.__r3f;
|
|
@@ -873,9 +1419,10 @@ function createEvents(store) {
|
|
|
873
1419
|
if (isPointerMove) {
|
|
874
1420
|
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
875
1421
|
const id = makeId(data);
|
|
876
|
-
const
|
|
1422
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1423
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
877
1424
|
if (!hoveredItem) {
|
|
878
|
-
|
|
1425
|
+
pointerState2.hovered.set(id, data);
|
|
879
1426
|
handlers.onPointerOver?.(data);
|
|
880
1427
|
handlers.onPointerEnter?.(data);
|
|
881
1428
|
} else if (hoveredItem.stopped) {
|
|
@@ -885,9 +1432,10 @@ function createEvents(store) {
|
|
|
885
1432
|
handlers.onPointerMove?.(data);
|
|
886
1433
|
} else if (isDragOver) {
|
|
887
1434
|
const id = makeId(data);
|
|
888
|
-
const
|
|
1435
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
1436
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
889
1437
|
if (!hoveredItem) {
|
|
890
|
-
|
|
1438
|
+
pointerState2.hovered.set(id, data);
|
|
891
1439
|
handlers.onDragOverEnter?.(data);
|
|
892
1440
|
} else if (hoveredItem.stopped) {
|
|
893
1441
|
data.stopPropagation();
|
|
@@ -898,18 +1446,18 @@ function createEvents(store) {
|
|
|
898
1446
|
} else {
|
|
899
1447
|
const handler = handlers[name];
|
|
900
1448
|
if (handler) {
|
|
901
|
-
if (!isClickEvent ||
|
|
1449
|
+
if (!isClickEvent || initialHits.includes(eventObject)) {
|
|
902
1450
|
pointerMissed(
|
|
903
1451
|
event,
|
|
904
|
-
internal.interaction.filter((object) => !
|
|
1452
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
905
1453
|
);
|
|
906
1454
|
handler(data);
|
|
907
1455
|
}
|
|
908
1456
|
} else {
|
|
909
|
-
if (isClickEvent &&
|
|
1457
|
+
if (isClickEvent && initialHits.includes(eventObject)) {
|
|
910
1458
|
pointerMissed(
|
|
911
1459
|
event,
|
|
912
|
-
internal.interaction.filter((object) => !
|
|
1460
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
913
1461
|
);
|
|
914
1462
|
}
|
|
915
1463
|
}
|
|
@@ -918,7 +1466,15 @@ function createEvents(store) {
|
|
|
918
1466
|
handleIntersects(hits, event, delta, onIntersect);
|
|
919
1467
|
};
|
|
920
1468
|
}
|
|
921
|
-
|
|
1469
|
+
function flushDeferredPointers() {
|
|
1470
|
+
const { internal, events } = store.getState();
|
|
1471
|
+
if (!events.frameTimedRaycasts) return;
|
|
1472
|
+
for (const [pointerId, event] of internal.pointerDirty) {
|
|
1473
|
+
processDeferredPointer(event, pointerId);
|
|
1474
|
+
}
|
|
1475
|
+
internal.pointerDirty.clear();
|
|
1476
|
+
}
|
|
1477
|
+
return { handlePointer, flushDeferredPointers, processDeferredPointer };
|
|
922
1478
|
}
|
|
923
1479
|
const DOM_EVENTS = {
|
|
924
1480
|
onClick: ["click", false],
|
|
@@ -937,11 +1493,16 @@ const DOM_EVENTS = {
|
|
|
937
1493
|
onLostPointerCapture: ["lostpointercapture", true]
|
|
938
1494
|
};
|
|
939
1495
|
function createPointerEvents(store) {
|
|
940
|
-
const { handlePointer } = createEvents(store);
|
|
1496
|
+
const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
|
|
1497
|
+
let nextXRPointerId = XR_POINTER_ID_START;
|
|
1498
|
+
const xrPointers = /* @__PURE__ */ new Map();
|
|
941
1499
|
return {
|
|
942
1500
|
priority: 1,
|
|
943
1501
|
enabled: true,
|
|
944
|
-
|
|
1502
|
+
frameTimedRaycasts: true,
|
|
1503
|
+
alwaysFireOnScroll: true,
|
|
1504
|
+
updateOnFrame: false,
|
|
1505
|
+
compute(event, state) {
|
|
945
1506
|
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
946
1507
|
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
947
1508
|
},
|
|
@@ -950,11 +1511,33 @@ function createPointerEvents(store) {
|
|
|
950
1511
|
(acc, key) => ({ ...acc, [key]: handlePointer(key) }),
|
|
951
1512
|
{}
|
|
952
1513
|
),
|
|
953
|
-
update: () => {
|
|
1514
|
+
update: (pointerId) => {
|
|
1515
|
+
const { events, internal } = store.getState();
|
|
1516
|
+
if (!events.handlers) return;
|
|
1517
|
+
if (pointerId !== void 0) {
|
|
1518
|
+
const event = internal.pointerDirty.get(pointerId);
|
|
1519
|
+
if (event) {
|
|
1520
|
+
internal.pointerDirty.delete(pointerId);
|
|
1521
|
+
processDeferredPointer(event, pointerId);
|
|
1522
|
+
} else if (internal.lastEvent?.current) {
|
|
1523
|
+
processDeferredPointer(internal.lastEvent.current, pointerId);
|
|
1524
|
+
}
|
|
1525
|
+
} else {
|
|
1526
|
+
flushDeferredPointers();
|
|
1527
|
+
if (internal.lastEvent?.current) {
|
|
1528
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
},
|
|
1532
|
+
flush: () => {
|
|
954
1533
|
const { events, internal } = store.getState();
|
|
955
|
-
|
|
1534
|
+
flushDeferredPointers();
|
|
1535
|
+
if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
|
|
1536
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1537
|
+
}
|
|
956
1538
|
},
|
|
957
1539
|
connect: (target) => {
|
|
1540
|
+
if (!target) return;
|
|
958
1541
|
const { set, events } = store.getState();
|
|
959
1542
|
events.disconnect?.();
|
|
960
1543
|
set((state) => ({ events: { ...state.events, connected: target } }));
|
|
@@ -978,6 +1561,32 @@ function createPointerEvents(store) {
|
|
|
978
1561
|
}
|
|
979
1562
|
set((state) => ({ events: { ...state.events, connected: void 0 } }));
|
|
980
1563
|
}
|
|
1564
|
+
},
|
|
1565
|
+
registerPointer: (config) => {
|
|
1566
|
+
const pointerId = nextXRPointerId++;
|
|
1567
|
+
xrPointers.set(pointerId, config);
|
|
1568
|
+
const { internal } = store.getState();
|
|
1569
|
+
getPointerState(internal, pointerId);
|
|
1570
|
+
return pointerId;
|
|
1571
|
+
},
|
|
1572
|
+
unregisterPointer: (pointerId) => {
|
|
1573
|
+
xrPointers.delete(pointerId);
|
|
1574
|
+
const { internal } = store.getState();
|
|
1575
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
1576
|
+
if (pointerState) {
|
|
1577
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
1578
|
+
const eventObject = hoveredObj.eventObject;
|
|
1579
|
+
const instance = eventObject.__r3f;
|
|
1580
|
+
if (instance?.eventCount) {
|
|
1581
|
+
const handlers = instance.handlers;
|
|
1582
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
1583
|
+
handlers.onPointerOut?.(data);
|
|
1584
|
+
handlers.onPointerLeave?.(data);
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
internal.pointerMap.delete(pointerId);
|
|
1588
|
+
}
|
|
1589
|
+
internal.pointerDirty.delete(pointerId);
|
|
981
1590
|
}
|
|
982
1591
|
};
|
|
983
1592
|
}
|
|
@@ -1039,300 +1648,26 @@ function notifyAlpha({ message, link }) {
|
|
|
1039
1648
|
}
|
|
1040
1649
|
}
|
|
1041
1650
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
let performanceTimeout = void 0;
|
|
1065
|
-
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
1066
|
-
const pointer = new webgpu.Vector2();
|
|
1067
|
-
const rootState = {
|
|
1068
|
-
set,
|
|
1069
|
-
get,
|
|
1070
|
-
// Mock objects that have to be configured
|
|
1071
|
-
gl: null,
|
|
1072
|
-
renderer: null,
|
|
1073
|
-
camera: null,
|
|
1074
|
-
frustum: new webgpu.Frustum(),
|
|
1075
|
-
autoUpdateFrustum: true,
|
|
1076
|
-
raycaster: null,
|
|
1077
|
-
events: { priority: 1, enabled: true, connected: false },
|
|
1078
|
-
scene: null,
|
|
1079
|
-
rootScene: null,
|
|
1080
|
-
xr: null,
|
|
1081
|
-
inspector: null,
|
|
1082
|
-
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
1083
|
-
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1084
|
-
legacy: false,
|
|
1085
|
-
linear: false,
|
|
1086
|
-
flat: false,
|
|
1087
|
-
textureColorSpace: "srgb",
|
|
1088
|
-
isLegacy: false,
|
|
1089
|
-
webGPUSupported: false,
|
|
1090
|
-
isNative: false,
|
|
1091
|
-
controls: null,
|
|
1092
|
-
pointer,
|
|
1093
|
-
mouse: pointer,
|
|
1094
|
-
frameloop: "always",
|
|
1095
|
-
onPointerMissed: void 0,
|
|
1096
|
-
onDragOverMissed: void 0,
|
|
1097
|
-
onDropMissed: void 0,
|
|
1098
|
-
performance: {
|
|
1099
|
-
current: 1,
|
|
1100
|
-
min: 0.5,
|
|
1101
|
-
max: 1,
|
|
1102
|
-
debounce: 200,
|
|
1103
|
-
regress: () => {
|
|
1104
|
-
const state2 = get();
|
|
1105
|
-
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
1106
|
-
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
1107
|
-
performanceTimeout = setTimeout(
|
|
1108
|
-
() => setPerformanceCurrent(get().performance.max),
|
|
1109
|
-
state2.performance.debounce
|
|
1110
|
-
);
|
|
1111
|
-
}
|
|
1112
|
-
},
|
|
1113
|
-
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
1114
|
-
viewport: {
|
|
1115
|
-
initialDpr: 0,
|
|
1116
|
-
dpr: 0,
|
|
1117
|
-
width: 0,
|
|
1118
|
-
height: 0,
|
|
1119
|
-
top: 0,
|
|
1120
|
-
left: 0,
|
|
1121
|
-
aspect: 0,
|
|
1122
|
-
distance: 0,
|
|
1123
|
-
factor: 0,
|
|
1124
|
-
getCurrentViewport
|
|
1125
|
-
},
|
|
1126
|
-
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
1127
|
-
setSize: (width, height, top = 0, left = 0) => {
|
|
1128
|
-
const camera = get().camera;
|
|
1129
|
-
const size = { width, height, top, left };
|
|
1130
|
-
set((state2) => ({ size, viewport: { ...state2.viewport, ...getCurrentViewport(camera, defaultTarget, size) } }));
|
|
1131
|
-
},
|
|
1132
|
-
setDpr: (dpr) => set((state2) => {
|
|
1133
|
-
const resolved = calculateDpr(dpr);
|
|
1134
|
-
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
1135
|
-
}),
|
|
1136
|
-
setFrameloop: (frameloop = "always") => {
|
|
1137
|
-
set(() => ({ frameloop }));
|
|
1138
|
-
},
|
|
1139
|
-
setError: (error) => set(() => ({ error })),
|
|
1140
|
-
error: null,
|
|
1141
|
-
//* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
|
|
1142
|
-
uniforms: {},
|
|
1143
|
-
nodes: {},
|
|
1144
|
-
textures: /* @__PURE__ */ new Map(),
|
|
1145
|
-
postProcessing: null,
|
|
1146
|
-
passes: {},
|
|
1147
|
-
previousRoot: void 0,
|
|
1148
|
-
internal: {
|
|
1149
|
-
// Events
|
|
1150
|
-
interaction: [],
|
|
1151
|
-
hovered: /* @__PURE__ */ new Map(),
|
|
1152
|
-
subscribers: [],
|
|
1153
|
-
initialClick: [0, 0],
|
|
1154
|
-
initialHits: [],
|
|
1155
|
-
capturedMap: /* @__PURE__ */ new Map(),
|
|
1156
|
-
lastEvent: React__namespace.createRef(),
|
|
1157
|
-
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
1158
|
-
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
1159
|
-
// Occlusion system (WebGPU only)
|
|
1160
|
-
occlusionEnabled: false,
|
|
1161
|
-
occlusionObserver: null,
|
|
1162
|
-
occlusionCache: /* @__PURE__ */ new Map(),
|
|
1163
|
-
helperGroup: null,
|
|
1164
|
-
// Updates
|
|
1165
|
-
active: false,
|
|
1166
|
-
frames: 0,
|
|
1167
|
-
priority: 0,
|
|
1168
|
-
subscribe: (ref, priority, store) => {
|
|
1169
|
-
const internal = get().internal;
|
|
1170
|
-
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
1171
|
-
internal.subscribers.push({ ref, priority, store });
|
|
1172
|
-
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
1173
|
-
return () => {
|
|
1174
|
-
const internal2 = get().internal;
|
|
1175
|
-
if (internal2?.subscribers) {
|
|
1176
|
-
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
1177
|
-
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
1178
|
-
}
|
|
1179
|
-
};
|
|
1180
|
-
},
|
|
1181
|
-
// Renderer Storage (single source of truth)
|
|
1182
|
-
actualRenderer: null,
|
|
1183
|
-
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
1184
|
-
scheduler: null
|
|
1185
|
-
}
|
|
1186
|
-
};
|
|
1187
|
-
return rootState;
|
|
1188
|
-
});
|
|
1189
|
-
const state = rootStore.getState();
|
|
1190
|
-
Object.defineProperty(state, "gl", {
|
|
1191
|
-
get() {
|
|
1192
|
-
const currentState = rootStore.getState();
|
|
1193
|
-
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1194
|
-
const stack = new Error().stack || "";
|
|
1195
|
-
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
1196
|
-
if (!isInternalAccess) {
|
|
1197
|
-
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1198
|
-
notifyDepreciated({
|
|
1199
|
-
heading: "Accessing state.gl in WebGPU mode",
|
|
1200
|
-
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
|
|
1201
|
-
});
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
return currentState.internal.actualRenderer;
|
|
1205
|
-
},
|
|
1206
|
-
set(value) {
|
|
1207
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1208
|
-
},
|
|
1209
|
-
enumerable: true,
|
|
1210
|
-
configurable: true
|
|
1211
|
-
});
|
|
1212
|
-
Object.defineProperty(state, "renderer", {
|
|
1213
|
-
get() {
|
|
1214
|
-
return rootStore.getState().internal.actualRenderer;
|
|
1215
|
-
},
|
|
1216
|
-
set(value) {
|
|
1217
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1218
|
-
},
|
|
1219
|
-
enumerable: true,
|
|
1220
|
-
configurable: true
|
|
1221
|
-
});
|
|
1222
|
-
let oldScene = state.scene;
|
|
1223
|
-
rootStore.subscribe(() => {
|
|
1224
|
-
const currentState = rootStore.getState();
|
|
1225
|
-
const { scene, rootScene, set } = currentState;
|
|
1226
|
-
if (scene !== oldScene) {
|
|
1227
|
-
oldScene = scene;
|
|
1228
|
-
if (scene?.isScene && scene !== rootScene) {
|
|
1229
|
-
set({ rootScene: scene });
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
});
|
|
1233
|
-
let oldSize = state.size;
|
|
1234
|
-
let oldDpr = state.viewport.dpr;
|
|
1235
|
-
let oldCamera = state.camera;
|
|
1236
|
-
rootStore.subscribe(() => {
|
|
1237
|
-
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
1238
|
-
const actualRenderer = internal.actualRenderer;
|
|
1239
|
-
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
1240
|
-
oldSize = size;
|
|
1241
|
-
oldDpr = viewport.dpr;
|
|
1242
|
-
updateCamera(camera, size);
|
|
1243
|
-
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1244
|
-
const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
|
|
1245
|
-
actualRenderer.setSize(size.width, size.height, updateStyle);
|
|
1246
|
-
}
|
|
1247
|
-
if (camera !== oldCamera) {
|
|
1248
|
-
oldCamera = camera;
|
|
1249
|
-
const { rootScene } = rootStore.getState();
|
|
1250
|
-
if (camera && rootScene && !camera.parent) {
|
|
1251
|
-
rootScene.add(camera);
|
|
1252
|
-
}
|
|
1253
|
-
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
1254
|
-
const currentState = rootStore.getState();
|
|
1255
|
-
if (currentState.autoUpdateFrustum && camera) {
|
|
1256
|
-
updateFrustum(camera, currentState.frustum);
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
});
|
|
1260
|
-
rootStore.subscribe((state2) => invalidate(state2));
|
|
1261
|
-
return rootStore;
|
|
1262
|
-
};
|
|
1263
|
-
|
|
1264
|
-
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
1265
|
-
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
1266
|
-
function getLoader(Proto) {
|
|
1267
|
-
if (isConstructor$1(Proto)) {
|
|
1268
|
-
let loader = memoizedLoaders.get(Proto);
|
|
1269
|
-
if (!loader) {
|
|
1270
|
-
loader = new Proto();
|
|
1271
|
-
memoizedLoaders.set(Proto, loader);
|
|
1272
|
-
}
|
|
1273
|
-
return loader;
|
|
1274
|
-
}
|
|
1275
|
-
return Proto;
|
|
1276
|
-
}
|
|
1277
|
-
function loadingFn(extensions, onProgress) {
|
|
1278
|
-
return function(Proto, input) {
|
|
1279
|
-
const loader = getLoader(Proto);
|
|
1280
|
-
if (extensions) extensions(loader);
|
|
1281
|
-
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
1282
|
-
return loader.loadAsync(input, onProgress).then((data) => {
|
|
1283
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1284
|
-
return data;
|
|
1285
|
-
});
|
|
1286
|
-
}
|
|
1287
|
-
return new Promise(
|
|
1288
|
-
(res, reject) => loader.load(
|
|
1289
|
-
input,
|
|
1290
|
-
(data) => {
|
|
1291
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1292
|
-
res(data);
|
|
1293
|
-
},
|
|
1294
|
-
onProgress,
|
|
1295
|
-
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
1296
|
-
)
|
|
1297
|
-
);
|
|
1298
|
-
};
|
|
1299
|
-
}
|
|
1300
|
-
function useLoader(loader, input, extensions, onProgress) {
|
|
1301
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1302
|
-
const fn = loadingFn(extensions, onProgress);
|
|
1303
|
-
const results = keys.map((key) => suspendReact.suspend(fn, [loader, key], { equal: is.equ }));
|
|
1304
|
-
return Array.isArray(input) ? results : results[0];
|
|
1305
|
-
}
|
|
1306
|
-
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
1307
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1308
|
-
keys.forEach((key) => suspendReact.preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
1309
|
-
};
|
|
1310
|
-
useLoader.clear = function(loader, input) {
|
|
1311
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1312
|
-
keys.forEach((key) => suspendReact.clear([loader, key]));
|
|
1313
|
-
};
|
|
1314
|
-
useLoader.loader = getLoader;
|
|
1315
|
-
|
|
1316
|
-
var __defProp$1 = Object.defineProperty;
|
|
1317
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1318
|
-
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1319
|
-
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1320
|
-
class PhaseGraph {
|
|
1321
|
-
constructor() {
|
|
1322
|
-
/** Ordered list of phase nodes */
|
|
1323
|
-
__publicField$1(this, "phases", []);
|
|
1324
|
-
/** Quick lookup by name */
|
|
1325
|
-
__publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1326
|
-
/** Cached ordered names (invalidated on changes) */
|
|
1327
|
-
__publicField$1(this, "orderedNamesCache", null);
|
|
1328
|
-
this.initializeDefaultPhases();
|
|
1329
|
-
}
|
|
1330
|
-
//* Initialization --------------------------------
|
|
1331
|
-
initializeDefaultPhases() {
|
|
1332
|
-
for (const name of DEFAULT_PHASES) {
|
|
1333
|
-
const node = { name, isAutoGenerated: false };
|
|
1334
|
-
this.phases.push(node);
|
|
1335
|
-
this.phaseMap.set(name, node);
|
|
1651
|
+
var __defProp$1 = Object.defineProperty;
|
|
1652
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1653
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1654
|
+
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1655
|
+
class PhaseGraph {
|
|
1656
|
+
constructor() {
|
|
1657
|
+
/** Ordered list of phase nodes */
|
|
1658
|
+
__publicField$1(this, "phases", []);
|
|
1659
|
+
/** Quick lookup by name */
|
|
1660
|
+
__publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1661
|
+
/** Cached ordered names (invalidated on changes) */
|
|
1662
|
+
__publicField$1(this, "orderedNamesCache", null);
|
|
1663
|
+
this.initializeDefaultPhases();
|
|
1664
|
+
}
|
|
1665
|
+
//* Initialization --------------------------------
|
|
1666
|
+
initializeDefaultPhases() {
|
|
1667
|
+
for (const name of DEFAULT_PHASES) {
|
|
1668
|
+
const node = { name, isAutoGenerated: false };
|
|
1669
|
+
this.phases.push(node);
|
|
1670
|
+
this.phaseMap.set(name, node);
|
|
1336
1671
|
}
|
|
1337
1672
|
this.invalidateCache();
|
|
1338
1673
|
}
|
|
@@ -1351,8 +1686,9 @@ class PhaseGraph {
|
|
|
1351
1686
|
const node = { name, isAutoGenerated: false };
|
|
1352
1687
|
let insertIndex = this.phases.length;
|
|
1353
1688
|
const targetIndex = this.getPhaseIndex(before ?? after);
|
|
1354
|
-
if (targetIndex !== -1)
|
|
1355
|
-
|
|
1689
|
+
if (targetIndex !== -1) {
|
|
1690
|
+
insertIndex = before ? targetIndex : targetIndex + 1;
|
|
1691
|
+
} else {
|
|
1356
1692
|
const constraintType = before ? "before" : "after";
|
|
1357
1693
|
console.warn(`[useFrame] Phase "${before ?? after}" not found for '${constraintType}' constraint`);
|
|
1358
1694
|
}
|
|
@@ -1564,7 +1900,7 @@ function shouldRun(job, now) {
|
|
|
1564
1900
|
const minInterval = 1e3 / job.fps;
|
|
1565
1901
|
const lastRun = job.lastRun ?? 0;
|
|
1566
1902
|
const elapsed = now - lastRun;
|
|
1567
|
-
if (elapsed < minInterval) return false;
|
|
1903
|
+
if (elapsed < minInterval - 1) return false;
|
|
1568
1904
|
if (job.drop) {
|
|
1569
1905
|
job.lastRun = now;
|
|
1570
1906
|
} else {
|
|
@@ -2251,98 +2587,426 @@ const _Scheduler = class _Scheduler {
|
|
|
2251
2587
|
this.triggerError(error instanceof Error ? error : new Error(String(error)));
|
|
2252
2588
|
}
|
|
2253
2589
|
}
|
|
2254
|
-
}
|
|
2255
|
-
//* Debug & Inspection Methods ================================
|
|
2256
|
-
/**
|
|
2257
|
-
* Get the total number of registered jobs across all roots.
|
|
2258
|
-
* Includes both per-root jobs and global before/after jobs.
|
|
2259
|
-
* @returns {number} Total job count
|
|
2260
|
-
*/
|
|
2261
|
-
getJobCount() {
|
|
2262
|
-
let count = 0;
|
|
2263
|
-
for (const root of this.roots.values()) {
|
|
2264
|
-
count += root.jobs.size;
|
|
2590
|
+
}
|
|
2591
|
+
//* Debug & Inspection Methods ================================
|
|
2592
|
+
/**
|
|
2593
|
+
* Get the total number of registered jobs across all roots.
|
|
2594
|
+
* Includes both per-root jobs and global before/after jobs.
|
|
2595
|
+
* @returns {number} Total job count
|
|
2596
|
+
*/
|
|
2597
|
+
getJobCount() {
|
|
2598
|
+
let count = 0;
|
|
2599
|
+
for (const root of this.roots.values()) {
|
|
2600
|
+
count += root.jobs.size;
|
|
2601
|
+
}
|
|
2602
|
+
return count + this.globalBeforeJobs.size + this.globalAfterJobs.size;
|
|
2603
|
+
}
|
|
2604
|
+
/**
|
|
2605
|
+
* Get all registered job IDs across all roots.
|
|
2606
|
+
* Includes both per-root jobs and global before/after jobs.
|
|
2607
|
+
* @returns {string[]} Array of all job IDs
|
|
2608
|
+
*/
|
|
2609
|
+
getJobIds() {
|
|
2610
|
+
const ids = [];
|
|
2611
|
+
for (const root of this.roots.values()) {
|
|
2612
|
+
ids.push(...root.jobs.keys());
|
|
2613
|
+
}
|
|
2614
|
+
ids.push(...this.globalBeforeJobs.keys());
|
|
2615
|
+
ids.push(...this.globalAfterJobs.keys());
|
|
2616
|
+
return ids;
|
|
2617
|
+
}
|
|
2618
|
+
/**
|
|
2619
|
+
* Get the number of registered roots (Canvas instances).
|
|
2620
|
+
* @returns {number} Number of registered roots
|
|
2621
|
+
*/
|
|
2622
|
+
getRootCount() {
|
|
2623
|
+
return this.roots.size;
|
|
2624
|
+
}
|
|
2625
|
+
/**
|
|
2626
|
+
* Check if any user (non-system) jobs are registered in a specific phase.
|
|
2627
|
+
* Used by the default render job to know if a user has taken over rendering.
|
|
2628
|
+
*
|
|
2629
|
+
* @param phase The phase to check
|
|
2630
|
+
* @param rootId Optional root ID to check (checks all roots if not provided)
|
|
2631
|
+
* @returns true if any user jobs exist in the phase
|
|
2632
|
+
*/
|
|
2633
|
+
hasUserJobsInPhase(phase, rootId) {
|
|
2634
|
+
const rootsToCheck = rootId ? [this.roots.get(rootId)].filter(Boolean) : Array.from(this.roots.values());
|
|
2635
|
+
return rootsToCheck.some((root) => {
|
|
2636
|
+
if (!root) return false;
|
|
2637
|
+
for (const job of root.jobs.values()) {
|
|
2638
|
+
if (job.phase === phase && !job.system && job.enabled) return true;
|
|
2639
|
+
}
|
|
2640
|
+
return false;
|
|
2641
|
+
});
|
|
2642
|
+
}
|
|
2643
|
+
//* Utility Methods ================================
|
|
2644
|
+
/**
|
|
2645
|
+
* Generate a unique root ID for automatic root registration.
|
|
2646
|
+
* @returns {string} A unique root ID in the format 'root_N'
|
|
2647
|
+
*/
|
|
2648
|
+
generateRootId() {
|
|
2649
|
+
return `root_${this.nextRootIndex++}`;
|
|
2650
|
+
}
|
|
2651
|
+
/**
|
|
2652
|
+
* Generate a unique job ID.
|
|
2653
|
+
* @returns {string} A unique job ID in the format 'job_N'
|
|
2654
|
+
* @private
|
|
2655
|
+
*/
|
|
2656
|
+
generateJobId() {
|
|
2657
|
+
return `job_${this.nextJobIndex}`;
|
|
2658
|
+
}
|
|
2659
|
+
/**
|
|
2660
|
+
* Normalize before/after constraints to a Set.
|
|
2661
|
+
* Handles undefined, single string, or array inputs.
|
|
2662
|
+
* @param {string | string[] | undefined} value - The constraint value(s)
|
|
2663
|
+
* @returns {Set<string>} Normalized Set of constraint strings
|
|
2664
|
+
* @private
|
|
2665
|
+
*/
|
|
2666
|
+
normalizeConstraints(value) {
|
|
2667
|
+
if (!value) return /* @__PURE__ */ new Set();
|
|
2668
|
+
if (Array.isArray(value)) return new Set(value);
|
|
2669
|
+
return /* @__PURE__ */ new Set([value]);
|
|
2670
|
+
}
|
|
2671
|
+
};
|
|
2672
|
+
//* Static State & Methods (Singleton Usage) ================================
|
|
2673
|
+
//* Cross-Bundle Singleton Key ==============================
|
|
2674
|
+
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2675
|
+
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2676
|
+
__publicField(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2677
|
+
let Scheduler = _Scheduler;
|
|
2678
|
+
const getScheduler = () => Scheduler.get();
|
|
2679
|
+
if (hmrData) {
|
|
2680
|
+
hmrData.accept?.();
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
2684
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React__namespace.createContext(null));
|
|
2685
|
+
const createStore = (invalidate, advance) => {
|
|
2686
|
+
const rootStore = traditional.createWithEqualityFn((set, get) => {
|
|
2687
|
+
const position = new webgpu.Vector3();
|
|
2688
|
+
const defaultTarget = new webgpu.Vector3();
|
|
2689
|
+
const tempTarget = new webgpu.Vector3();
|
|
2690
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
2691
|
+
const { width, height, top, left } = size;
|
|
2692
|
+
const aspect = width / height;
|
|
2693
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
2694
|
+
else tempTarget.set(...target);
|
|
2695
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
2696
|
+
if (isOrthographicCamera(camera)) {
|
|
2697
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
2698
|
+
} else {
|
|
2699
|
+
const fov = camera.fov * Math.PI / 180;
|
|
2700
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
2701
|
+
const w = h * (width / height);
|
|
2702
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
let performanceTimeout = void 0;
|
|
2706
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
2707
|
+
const pointer = new webgpu.Vector2();
|
|
2708
|
+
const rootState = {
|
|
2709
|
+
set,
|
|
2710
|
+
get,
|
|
2711
|
+
// Mock objects that have to be configured
|
|
2712
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
2713
|
+
primaryStore: null,
|
|
2714
|
+
gl: null,
|
|
2715
|
+
renderer: null,
|
|
2716
|
+
camera: null,
|
|
2717
|
+
frustum: new webgpu.Frustum(),
|
|
2718
|
+
autoUpdateFrustum: true,
|
|
2719
|
+
raycaster: null,
|
|
2720
|
+
events: {
|
|
2721
|
+
priority: 1,
|
|
2722
|
+
enabled: true,
|
|
2723
|
+
connected: false,
|
|
2724
|
+
frameTimedRaycasts: true,
|
|
2725
|
+
alwaysFireOnScroll: true,
|
|
2726
|
+
updateOnFrame: false
|
|
2727
|
+
},
|
|
2728
|
+
scene: null,
|
|
2729
|
+
rootScene: null,
|
|
2730
|
+
xr: null,
|
|
2731
|
+
inspector: null,
|
|
2732
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
2733
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
2734
|
+
textureColorSpace: webgpu.SRGBColorSpace,
|
|
2735
|
+
isLegacy: false,
|
|
2736
|
+
webGPUSupported: false,
|
|
2737
|
+
isNative: false,
|
|
2738
|
+
controls: null,
|
|
2739
|
+
pointer,
|
|
2740
|
+
mouse: pointer,
|
|
2741
|
+
frameloop: "always",
|
|
2742
|
+
onPointerMissed: void 0,
|
|
2743
|
+
onDragOverMissed: void 0,
|
|
2744
|
+
onDropMissed: void 0,
|
|
2745
|
+
performance: {
|
|
2746
|
+
current: 1,
|
|
2747
|
+
min: 0.5,
|
|
2748
|
+
max: 1,
|
|
2749
|
+
debounce: 200,
|
|
2750
|
+
regress: () => {
|
|
2751
|
+
const state2 = get();
|
|
2752
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
2753
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
2754
|
+
performanceTimeout = setTimeout(
|
|
2755
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
2756
|
+
state2.performance.debounce
|
|
2757
|
+
);
|
|
2758
|
+
}
|
|
2759
|
+
},
|
|
2760
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
2761
|
+
viewport: {
|
|
2762
|
+
initialDpr: 0,
|
|
2763
|
+
dpr: 0,
|
|
2764
|
+
width: 0,
|
|
2765
|
+
height: 0,
|
|
2766
|
+
top: 0,
|
|
2767
|
+
left: 0,
|
|
2768
|
+
aspect: 0,
|
|
2769
|
+
distance: 0,
|
|
2770
|
+
factor: 0,
|
|
2771
|
+
getCurrentViewport
|
|
2772
|
+
},
|
|
2773
|
+
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
2774
|
+
setSize: (width, height, top, left) => {
|
|
2775
|
+
const state2 = get();
|
|
2776
|
+
if (width === void 0) {
|
|
2777
|
+
set({ _sizeImperative: false });
|
|
2778
|
+
if (state2._sizeProps) {
|
|
2779
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
2780
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
2781
|
+
const currentSize = state2.size;
|
|
2782
|
+
const newSize = {
|
|
2783
|
+
width: propW ?? currentSize.width,
|
|
2784
|
+
height: propH ?? currentSize.height,
|
|
2785
|
+
top: currentSize.top,
|
|
2786
|
+
left: currentSize.left
|
|
2787
|
+
};
|
|
2788
|
+
set((s) => ({
|
|
2789
|
+
size: newSize,
|
|
2790
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
2791
|
+
}));
|
|
2792
|
+
getScheduler().invalidate();
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
return;
|
|
2796
|
+
}
|
|
2797
|
+
const w = width;
|
|
2798
|
+
const h = height ?? width;
|
|
2799
|
+
const t = top ?? state2.size.top;
|
|
2800
|
+
const l = left ?? state2.size.left;
|
|
2801
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
2802
|
+
set((s) => ({
|
|
2803
|
+
size,
|
|
2804
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
2805
|
+
_sizeImperative: true
|
|
2806
|
+
}));
|
|
2807
|
+
getScheduler().invalidate();
|
|
2808
|
+
},
|
|
2809
|
+
setDpr: (dpr) => set((state2) => {
|
|
2810
|
+
const resolved = calculateDpr(dpr);
|
|
2811
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
2812
|
+
}),
|
|
2813
|
+
setFrameloop: (frameloop = "always") => {
|
|
2814
|
+
set(() => ({ frameloop }));
|
|
2815
|
+
},
|
|
2816
|
+
setError: (error) => set(() => ({ error })),
|
|
2817
|
+
error: null,
|
|
2818
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useBuffers, useGPUStorage, useTextures, useRenderPipeline) ==============================
|
|
2819
|
+
uniforms: {},
|
|
2820
|
+
nodes: {},
|
|
2821
|
+
buffers: {},
|
|
2822
|
+
gpuStorage: {},
|
|
2823
|
+
textures: /* @__PURE__ */ new Map(),
|
|
2824
|
+
renderPipeline: null,
|
|
2825
|
+
passes: {},
|
|
2826
|
+
_hmrVersion: 0,
|
|
2827
|
+
_sizeImperative: false,
|
|
2828
|
+
_sizeProps: null,
|
|
2829
|
+
previousRoot: void 0,
|
|
2830
|
+
internal: {
|
|
2831
|
+
// Events
|
|
2832
|
+
interaction: [],
|
|
2833
|
+
subscribers: [],
|
|
2834
|
+
// Per-pointer state (new unified structure)
|
|
2835
|
+
pointerMap: /* @__PURE__ */ new Map(),
|
|
2836
|
+
pointerDirty: /* @__PURE__ */ new Map(),
|
|
2837
|
+
lastEvent: React__namespace.createRef(),
|
|
2838
|
+
// Deprecated but kept for backwards compatibility
|
|
2839
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
2840
|
+
initialClick: [0, 0],
|
|
2841
|
+
initialHits: [],
|
|
2842
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
2843
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
2844
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
2845
|
+
// Occlusion system (WebGPU only)
|
|
2846
|
+
occlusionEnabled: false,
|
|
2847
|
+
occlusionObserver: null,
|
|
2848
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
2849
|
+
helperGroup: null,
|
|
2850
|
+
// Updates
|
|
2851
|
+
active: false,
|
|
2852
|
+
frames: 0,
|
|
2853
|
+
priority: 0,
|
|
2854
|
+
subscribe: (ref, priority, store) => {
|
|
2855
|
+
const internal = get().internal;
|
|
2856
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
2857
|
+
internal.subscribers.push({ ref, priority, store });
|
|
2858
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
2859
|
+
return () => {
|
|
2860
|
+
const internal2 = get().internal;
|
|
2861
|
+
if (internal2?.subscribers) {
|
|
2862
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
2863
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
2864
|
+
}
|
|
2865
|
+
};
|
|
2866
|
+
},
|
|
2867
|
+
// Renderer Storage (single source of truth)
|
|
2868
|
+
actualRenderer: null,
|
|
2869
|
+
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
2870
|
+
scheduler: null
|
|
2871
|
+
}
|
|
2872
|
+
};
|
|
2873
|
+
return rootState;
|
|
2874
|
+
});
|
|
2875
|
+
const state = rootStore.getState();
|
|
2876
|
+
Object.defineProperty(state, "gl", {
|
|
2877
|
+
get() {
|
|
2878
|
+
const currentState = rootStore.getState();
|
|
2879
|
+
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
2880
|
+
const stack = new Error().stack || "";
|
|
2881
|
+
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
2882
|
+
if (!isInternalAccess) {
|
|
2883
|
+
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
2884
|
+
notifyDepreciated({
|
|
2885
|
+
heading: "Accessing state.gl in WebGPU mode",
|
|
2886
|
+
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
|
|
2887
|
+
});
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
return currentState.internal.actualRenderer;
|
|
2891
|
+
},
|
|
2892
|
+
set(value) {
|
|
2893
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2894
|
+
},
|
|
2895
|
+
enumerable: true,
|
|
2896
|
+
configurable: true
|
|
2897
|
+
});
|
|
2898
|
+
Object.defineProperty(state, "renderer", {
|
|
2899
|
+
get() {
|
|
2900
|
+
return rootStore.getState().internal.actualRenderer;
|
|
2901
|
+
},
|
|
2902
|
+
set(value) {
|
|
2903
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2904
|
+
},
|
|
2905
|
+
enumerable: true,
|
|
2906
|
+
configurable: true
|
|
2907
|
+
});
|
|
2908
|
+
let oldScene = state.scene;
|
|
2909
|
+
rootStore.subscribe(() => {
|
|
2910
|
+
const currentState = rootStore.getState();
|
|
2911
|
+
const { scene, rootScene, set } = currentState;
|
|
2912
|
+
if (scene !== oldScene) {
|
|
2913
|
+
oldScene = scene;
|
|
2914
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
2915
|
+
set({ rootScene: scene });
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
});
|
|
2919
|
+
let oldSize = state.size;
|
|
2920
|
+
let oldDpr = state.viewport.dpr;
|
|
2921
|
+
let oldCamera = state.camera;
|
|
2922
|
+
rootStore.subscribe(() => {
|
|
2923
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
2924
|
+
const actualRenderer = internal.actualRenderer;
|
|
2925
|
+
const canvasTarget = internal.canvasTarget;
|
|
2926
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
2927
|
+
oldSize = size;
|
|
2928
|
+
oldDpr = viewport.dpr;
|
|
2929
|
+
updateCamera(camera, size);
|
|
2930
|
+
if (internal.isSecondary && canvasTarget) {
|
|
2931
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2932
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
2933
|
+
} else {
|
|
2934
|
+
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
2935
|
+
actualRenderer.setSize(size.width, size.height, false);
|
|
2936
|
+
if (canvasTarget) {
|
|
2937
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2938
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
if (camera !== oldCamera) {
|
|
2943
|
+
oldCamera = camera;
|
|
2944
|
+
const { rootScene } = rootStore.getState();
|
|
2945
|
+
if (camera && rootScene && !camera.parent) {
|
|
2946
|
+
rootScene.add(camera);
|
|
2947
|
+
}
|
|
2948
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
2949
|
+
const currentState = rootStore.getState();
|
|
2950
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
2951
|
+
updateFrustum(camera, currentState.frustum);
|
|
2952
|
+
}
|
|
2265
2953
|
}
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2954
|
+
});
|
|
2955
|
+
rootStore.subscribe((state2) => invalidate(state2));
|
|
2956
|
+
return rootStore;
|
|
2957
|
+
};
|
|
2958
|
+
|
|
2959
|
+
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
2960
|
+
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
2961
|
+
function getLoader(Proto) {
|
|
2962
|
+
if (isConstructor$1(Proto)) {
|
|
2963
|
+
let loader = memoizedLoaders.get(Proto);
|
|
2964
|
+
if (!loader) {
|
|
2965
|
+
loader = new Proto();
|
|
2966
|
+
memoizedLoaders.set(Proto, loader);
|
|
2277
2967
|
}
|
|
2278
|
-
|
|
2279
|
-
ids.push(...this.globalAfterJobs.keys());
|
|
2280
|
-
return ids;
|
|
2281
|
-
}
|
|
2282
|
-
/**
|
|
2283
|
-
* Get the number of registered roots (Canvas instances).
|
|
2284
|
-
* @returns {number} Number of registered roots
|
|
2285
|
-
*/
|
|
2286
|
-
getRootCount() {
|
|
2287
|
-
return this.roots.size;
|
|
2288
|
-
}
|
|
2289
|
-
/**
|
|
2290
|
-
* Check if any user (non-system) jobs are registered in a specific phase.
|
|
2291
|
-
* Used by the default render job to know if a user has taken over rendering.
|
|
2292
|
-
*
|
|
2293
|
-
* @param phase The phase to check
|
|
2294
|
-
* @param rootId Optional root ID to check (checks all roots if not provided)
|
|
2295
|
-
* @returns true if any user jobs exist in the phase
|
|
2296
|
-
*/
|
|
2297
|
-
hasUserJobsInPhase(phase, rootId) {
|
|
2298
|
-
const rootsToCheck = rootId ? [this.roots.get(rootId)].filter(Boolean) : Array.from(this.roots.values());
|
|
2299
|
-
return rootsToCheck.some((root) => {
|
|
2300
|
-
if (!root) return false;
|
|
2301
|
-
for (const job of root.jobs.values()) {
|
|
2302
|
-
if (job.phase === phase && !job.system && job.enabled) return true;
|
|
2303
|
-
}
|
|
2304
|
-
return false;
|
|
2305
|
-
});
|
|
2306
|
-
}
|
|
2307
|
-
//* Utility Methods ================================
|
|
2308
|
-
/**
|
|
2309
|
-
* Generate a unique root ID for automatic root registration.
|
|
2310
|
-
* @returns {string} A unique root ID in the format 'root_N'
|
|
2311
|
-
*/
|
|
2312
|
-
generateRootId() {
|
|
2313
|
-
return `root_${this.nextRootIndex++}`;
|
|
2314
|
-
}
|
|
2315
|
-
/**
|
|
2316
|
-
* Generate a unique job ID.
|
|
2317
|
-
* @returns {string} A unique job ID in the format 'job_N'
|
|
2318
|
-
* @private
|
|
2319
|
-
*/
|
|
2320
|
-
generateJobId() {
|
|
2321
|
-
return `job_${this.nextJobIndex}`;
|
|
2322
|
-
}
|
|
2323
|
-
/**
|
|
2324
|
-
* Normalize before/after constraints to a Set.
|
|
2325
|
-
* Handles undefined, single string, or array inputs.
|
|
2326
|
-
* @param {string | string[] | undefined} value - The constraint value(s)
|
|
2327
|
-
* @returns {Set<string>} Normalized Set of constraint strings
|
|
2328
|
-
* @private
|
|
2329
|
-
*/
|
|
2330
|
-
normalizeConstraints(value) {
|
|
2331
|
-
if (!value) return /* @__PURE__ */ new Set();
|
|
2332
|
-
if (Array.isArray(value)) return new Set(value);
|
|
2333
|
-
return /* @__PURE__ */ new Set([value]);
|
|
2968
|
+
return loader;
|
|
2334
2969
|
}
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
if (
|
|
2344
|
-
|
|
2970
|
+
return Proto;
|
|
2971
|
+
}
|
|
2972
|
+
function loadingFn(extensions, onProgress) {
|
|
2973
|
+
return function(Proto, input) {
|
|
2974
|
+
const loader = getLoader(Proto);
|
|
2975
|
+
if (extensions) extensions(loader);
|
|
2976
|
+
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
2977
|
+
return loader.loadAsync(input, onProgress).then((data) => {
|
|
2978
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2979
|
+
return data;
|
|
2980
|
+
});
|
|
2981
|
+
}
|
|
2982
|
+
return new Promise(
|
|
2983
|
+
(res, reject) => loader.load(
|
|
2984
|
+
input,
|
|
2985
|
+
(data) => {
|
|
2986
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2987
|
+
res(data);
|
|
2988
|
+
},
|
|
2989
|
+
onProgress,
|
|
2990
|
+
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
2991
|
+
)
|
|
2992
|
+
);
|
|
2993
|
+
};
|
|
2345
2994
|
}
|
|
2995
|
+
function useLoader(loader, input, extensions, onProgress) {
|
|
2996
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2997
|
+
const fn = loadingFn(extensions, onProgress);
|
|
2998
|
+
const results = keys.map((key) => suspendReact.suspend(fn, [loader, key], { equal: is.equ }));
|
|
2999
|
+
return Array.isArray(input) ? results : results[0];
|
|
3000
|
+
}
|
|
3001
|
+
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
3002
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
3003
|
+
keys.forEach((key) => suspendReact.preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
3004
|
+
};
|
|
3005
|
+
useLoader.clear = function(loader, input) {
|
|
3006
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
3007
|
+
keys.forEach((key) => suspendReact.clear([loader, key]));
|
|
3008
|
+
};
|
|
3009
|
+
useLoader.loader = getLoader;
|
|
2346
3010
|
|
|
2347
3011
|
function useFrame(callback, priorityOrOptions) {
|
|
2348
3012
|
const store = React__namespace.useContext(context);
|
|
@@ -2523,6 +3187,9 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2523
3187
|
const textureCache = useThree((state) => state.textures);
|
|
2524
3188
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
2525
3189
|
const { onLoad, cache = false } = options;
|
|
3190
|
+
const onLoadRef = React.useRef(onLoad);
|
|
3191
|
+
onLoadRef.current = onLoad;
|
|
3192
|
+
const onLoadCalledForRef = React.useRef(null);
|
|
2526
3193
|
const urls = React.useMemo(() => getUrls(input), [input]);
|
|
2527
3194
|
const cachedResult = React.useMemo(() => {
|
|
2528
3195
|
if (!cache) return null;
|
|
@@ -2533,9 +3200,13 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2533
3200
|
webgpu.TextureLoader,
|
|
2534
3201
|
IsObject(input) ? Object.values(input) : input
|
|
2535
3202
|
);
|
|
3203
|
+
const inputKey = urls.join("\0");
|
|
2536
3204
|
React.useLayoutEffect(() => {
|
|
2537
|
-
if (
|
|
2538
|
-
|
|
3205
|
+
if (cachedResult) return;
|
|
3206
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
3207
|
+
onLoadCalledForRef.current = inputKey;
|
|
3208
|
+
onLoadRef.current?.(loadedTextures);
|
|
3209
|
+
}, [cachedResult, loadedTextures, inputKey]);
|
|
2539
3210
|
React.useEffect(() => {
|
|
2540
3211
|
if (cachedResult) return;
|
|
2541
3212
|
if ("initTexture" in renderer) {
|
|
@@ -2702,16 +3373,33 @@ function useTextures() {
|
|
|
2702
3373
|
}, [store]);
|
|
2703
3374
|
}
|
|
2704
3375
|
|
|
2705
|
-
function useRenderTarget(
|
|
3376
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
2706
3377
|
const isLegacy = useThree((s) => s.isLegacy);
|
|
2707
3378
|
const size = useThree((s) => s.size);
|
|
3379
|
+
let width;
|
|
3380
|
+
let height;
|
|
3381
|
+
let opts;
|
|
3382
|
+
if (typeof widthOrOptions === "object") {
|
|
3383
|
+
opts = widthOrOptions;
|
|
3384
|
+
} else if (typeof widthOrOptions === "number") {
|
|
3385
|
+
width = widthOrOptions;
|
|
3386
|
+
if (typeof heightOrOptions === "object") {
|
|
3387
|
+
height = widthOrOptions;
|
|
3388
|
+
opts = heightOrOptions;
|
|
3389
|
+
} else if (typeof heightOrOptions === "number") {
|
|
3390
|
+
height = heightOrOptions;
|
|
3391
|
+
opts = options;
|
|
3392
|
+
} else {
|
|
3393
|
+
height = widthOrOptions;
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
2708
3396
|
return React.useMemo(() => {
|
|
2709
3397
|
const w = width ?? size.width;
|
|
2710
3398
|
const h = height ?? size.height;
|
|
2711
3399
|
{
|
|
2712
|
-
return isLegacy ? new three.WebGLRenderTarget(w, h,
|
|
3400
|
+
return isLegacy ? new three.WebGLRenderTarget(w, h, opts) : new webgpu.RenderTarget(w, h, opts);
|
|
2713
3401
|
}
|
|
2714
|
-
}, [width, height, size.width, size.height,
|
|
3402
|
+
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
2715
3403
|
}
|
|
2716
3404
|
|
|
2717
3405
|
function useStore() {
|
|
@@ -2761,28 +3449,18 @@ function addTail(callback) {
|
|
|
2761
3449
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
2762
3450
|
getScheduler().invalidate(frames, stackFrames);
|
|
2763
3451
|
}
|
|
2764
|
-
function advance(timestamp
|
|
3452
|
+
function advance(timestamp) {
|
|
2765
3453
|
getScheduler().step(timestamp);
|
|
2766
3454
|
}
|
|
2767
3455
|
|
|
2768
|
-
const version = "10.0.0-alpha.
|
|
3456
|
+
const version = "10.0.0-alpha.2";
|
|
2769
3457
|
const packageData = {
|
|
2770
3458
|
version: version};
|
|
2771
3459
|
|
|
2772
3460
|
function Xb(Tt) {
|
|
2773
3461
|
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
2774
3462
|
}
|
|
2775
|
-
var Rm = { exports: {} }, Og = { exports: {} };
|
|
2776
|
-
/**
|
|
2777
|
-
* @license React
|
|
2778
|
-
* react-reconciler.production.js
|
|
2779
|
-
*
|
|
2780
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2781
|
-
*
|
|
2782
|
-
* This source code is licensed under the MIT license found in the
|
|
2783
|
-
* LICENSE file in the root directory of this source tree.
|
|
2784
|
-
*/
|
|
2785
|
-
var _b;
|
|
3463
|
+
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
2786
3464
|
function Kb() {
|
|
2787
3465
|
return _b || (_b = 1, (function(Tt) {
|
|
2788
3466
|
Tt.exports = function(m) {
|
|
@@ -3854,7 +4532,6 @@ Error generating stack: ` + l.message + `
|
|
|
3854
4532
|
if (J === cl || J === jc) throw J;
|
|
3855
4533
|
var Ge = Yn(29, J, null, P.mode);
|
|
3856
4534
|
return Ge.lanes = H, Ge.return = P, Ge;
|
|
3857
|
-
} finally {
|
|
3858
4535
|
}
|
|
3859
4536
|
};
|
|
3860
4537
|
}
|
|
@@ -4508,7 +5185,6 @@ Error generating stack: ` + l.message + `
|
|
|
4508
5185
|
var h = r.lastRenderedState, y = d(h, a);
|
|
4509
5186
|
if (c.hasEagerState = true, c.eagerState = y, jn(y, h)) return go(t, r, c, 0), Ne === null && Bn(), false;
|
|
4510
5187
|
} catch {
|
|
4511
|
-
} finally {
|
|
4512
5188
|
}
|
|
4513
5189
|
if (a = yo(t, r, c, l), a !== null) return nt(a, t, l), ns(a, r, l), true;
|
|
4514
5190
|
}
|
|
@@ -6929,10 +7605,7 @@ Error generating stack: ` + l.message + `
|
|
|
6929
7605
|
function vr(t, r) {
|
|
6930
7606
|
Sf(t, r), (t = t.alternate) && Sf(t, r);
|
|
6931
7607
|
}
|
|
6932
|
-
var ie = {}, Fm = React__default, tt = Tb__default, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy");
|
|
6933
|
-
var gc = Symbol.for("react.activity");
|
|
6934
|
-
var $r = Symbol.for("react.memo_cache_sentinel");
|
|
6935
|
-
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;
|
|
7608
|
+
var ie = {}, Fm = React__default, tt = Tb__default, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy"), gc = Symbol.for("react.activity"), $r = Symbol.for("react.memo_cache_sentinel"), Pf = Symbol.iterator, xf = Symbol.for("react.client.reference"), ca = Array.isArray, M = Fm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Yp = m.rendererVersion, zf = m.rendererPackageName, Cf = m.extraDevToolsConfig, Ts = m.getPublicInstance, Hm = m.getRootHostContext, Xp = m.getChildHostContext, Am = m.prepareForCommit, _s = m.resetAfterCommit, Vr = m.createInstance;
|
|
6936
7609
|
m.cloneMutableInstance;
|
|
6937
7610
|
var yc = m.appendInitialChild, Kp = m.finalizeInitialChildren, Rs = m.shouldSetTextContent, bc = m.createTextInstance;
|
|
6938
7611
|
m.cloneMutableTextInstance;
|
|
@@ -7301,17 +7974,7 @@ No matching component was found for:
|
|
|
7301
7974
|
}, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true });
|
|
7302
7975
|
})(Og)), Og.exports;
|
|
7303
7976
|
}
|
|
7304
|
-
var Mg = { exports: {} };
|
|
7305
|
-
/**
|
|
7306
|
-
* @license React
|
|
7307
|
-
* react-reconciler.development.js
|
|
7308
|
-
*
|
|
7309
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
7310
|
-
*
|
|
7311
|
-
* This source code is licensed under the MIT license found in the
|
|
7312
|
-
* LICENSE file in the root directory of this source tree.
|
|
7313
|
-
*/
|
|
7314
|
-
var Rb;
|
|
7977
|
+
var Mg = { exports: {} }, Rb;
|
|
7315
7978
|
function e0() {
|
|
7316
7979
|
return Rb || (Rb = 1, (function(Tt) {
|
|
7317
7980
|
process.env.NODE_ENV !== "production" && (Tt.exports = function(m) {
|
|
@@ -13078,10 +13741,7 @@ Check the render method of %s.`, G(di) || "Unknown")), i = zo(n), i.payload = {
|
|
|
13078
13741
|
function Ic() {
|
|
13079
13742
|
return di;
|
|
13080
13743
|
}
|
|
13081
|
-
var le = {}, qm = React__default, St = Tb__default, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy");
|
|
13082
|
-
var Ds = Symbol.for("react.activity");
|
|
13083
|
-
var Bh = Symbol.for("react.memo_cache_sentinel");
|
|
13084
|
-
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;
|
|
13744
|
+
var le = {}, qm = React__default, St = Tb__default, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy"), Ds = Symbol.for("react.activity"), Bh = Symbol.for("react.memo_cache_sentinel"), ni = Symbol.iterator, il = Symbol.for("react.client.reference"), fn = Array.isArray, x = qm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Jt = m.rendererVersion, Zt = m.rendererPackageName, jo = m.extraDevToolsConfig, ot = m.getPublicInstance, Zr = m.getRootHostContext, Dn = m.getChildHostContext, Ws = m.prepareForCommit, pa = m.resetAfterCommit, Fc = m.createInstance;
|
|
13085
13745
|
m.cloneMutableInstance;
|
|
13086
13746
|
var bn = m.appendInitialChild, Ue = m.finalizeInitialChildren, ue = m.shouldSetTextContent, Do = m.createTextInstance;
|
|
13087
13747
|
m.cloneMutableTextInstance;
|
|
@@ -14049,15 +14709,6 @@ function n0() {
|
|
|
14049
14709
|
var t0 = n0();
|
|
14050
14710
|
const r0 = Xb(t0);
|
|
14051
14711
|
|
|
14052
|
-
/**
|
|
14053
|
-
* @license React
|
|
14054
|
-
* react-reconciler-constants.production.js
|
|
14055
|
-
*
|
|
14056
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14057
|
-
*
|
|
14058
|
-
* This source code is licensed under the MIT license found in the
|
|
14059
|
-
* LICENSE file in the root directory of this source tree.
|
|
14060
|
-
*/
|
|
14061
14712
|
const t = 1, o = 8, r = 32, e = 2;
|
|
14062
14713
|
|
|
14063
14714
|
function createReconciler(config) {
|
|
@@ -14084,10 +14735,11 @@ function extend(objects) {
|
|
|
14084
14735
|
function validateInstance(type, props) {
|
|
14085
14736
|
const name = toPascalCase(type);
|
|
14086
14737
|
const target = catalogue[name];
|
|
14087
|
-
if (type !== "primitive" && !target)
|
|
14738
|
+
if (type !== "primitive" && !target) {
|
|
14088
14739
|
throw new Error(
|
|
14089
14740
|
`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`
|
|
14090
14741
|
);
|
|
14742
|
+
}
|
|
14091
14743
|
if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
|
|
14092
14744
|
if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
|
|
14093
14745
|
}
|
|
@@ -14251,6 +14903,7 @@ function swapInstances() {
|
|
|
14251
14903
|
instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
|
|
14252
14904
|
instance.object.__r3f = instance;
|
|
14253
14905
|
setFiberRef(fiber, instance.object);
|
|
14906
|
+
delete instance.appliedOnce;
|
|
14254
14907
|
applyProps(instance.object, instance.props);
|
|
14255
14908
|
if (instance.props.attach) {
|
|
14256
14909
|
attach(parent, instance);
|
|
@@ -14324,8 +14977,22 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14324
14977
|
const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
|
|
14325
14978
|
if (isTailSibling) swapInstances();
|
|
14326
14979
|
},
|
|
14327
|
-
finalizeInitialChildren: () =>
|
|
14328
|
-
|
|
14980
|
+
finalizeInitialChildren: (instance) => {
|
|
14981
|
+
for (const prop in instance.props) {
|
|
14982
|
+
if (isFromRef(instance.props[prop])) return true;
|
|
14983
|
+
}
|
|
14984
|
+
return false;
|
|
14985
|
+
},
|
|
14986
|
+
commitMount(instance) {
|
|
14987
|
+
const resolved = {};
|
|
14988
|
+
for (const prop in instance.props) {
|
|
14989
|
+
const value = instance.props[prop];
|
|
14990
|
+
if (isFromRef(value)) {
|
|
14991
|
+
const ref = value[FROM_REF];
|
|
14992
|
+
if (ref.current != null) resolved[prop] = ref.current;
|
|
14993
|
+
}
|
|
14994
|
+
}
|
|
14995
|
+
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
14329
14996
|
},
|
|
14330
14997
|
getPublicInstance: (instance) => instance?.object,
|
|
14331
14998
|
prepareForCommit: () => null,
|
|
@@ -14538,14 +15205,17 @@ function createRoot(canvas) {
|
|
|
14538
15205
|
if (!prevRoot) _roots.set(canvas, { fiber, store });
|
|
14539
15206
|
let onCreated;
|
|
14540
15207
|
let lastCamera;
|
|
14541
|
-
|
|
15208
|
+
const lastConfiguredProps = {};
|
|
14542
15209
|
let configured = false;
|
|
14543
15210
|
let pending = null;
|
|
14544
15211
|
return {
|
|
14545
15212
|
async configure(props = {}) {
|
|
14546
15213
|
let resolve;
|
|
14547
15214
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14548
|
-
|
|
15215
|
+
const {
|
|
15216
|
+
id: canvasId,
|
|
15217
|
+
primaryCanvas,
|
|
15218
|
+
scheduler: schedulerConfig,
|
|
14549
15219
|
gl: glConfig,
|
|
14550
15220
|
renderer: rendererConfig,
|
|
14551
15221
|
size: propsSize,
|
|
@@ -14553,10 +15223,6 @@ function createRoot(canvas) {
|
|
|
14553
15223
|
events,
|
|
14554
15224
|
onCreated: onCreatedCallback,
|
|
14555
15225
|
shadows = false,
|
|
14556
|
-
linear = false,
|
|
14557
|
-
flat = false,
|
|
14558
|
-
textureColorSpace = webgpu.SRGBColorSpace,
|
|
14559
|
-
legacy = false,
|
|
14560
15226
|
orthographic = false,
|
|
14561
15227
|
frameloop = "always",
|
|
14562
15228
|
dpr = [1, 2],
|
|
@@ -14567,9 +15233,12 @@ function createRoot(canvas) {
|
|
|
14567
15233
|
onDragOverMissed,
|
|
14568
15234
|
onDropMissed,
|
|
14569
15235
|
autoUpdateFrustum = true,
|
|
14570
|
-
occlusion = false
|
|
15236
|
+
occlusion = false,
|
|
15237
|
+
_sizeProps,
|
|
15238
|
+
forceEven
|
|
14571
15239
|
} = props;
|
|
14572
|
-
|
|
15240
|
+
const textureColorSpace = is.obj(glConfig) && !is.fun(glConfig) && !isRenderer(glConfig) && glConfig.textureColorSpace || is.obj(rendererConfig) && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && rendererConfig.textureColorSpace || webgpu.SRGBColorSpace;
|
|
15241
|
+
const state = store.getState();
|
|
14573
15242
|
const defaultGLProps = {
|
|
14574
15243
|
canvas,
|
|
14575
15244
|
powerPreference: "high-performance",
|
|
@@ -14577,7 +15246,8 @@ function createRoot(canvas) {
|
|
|
14577
15246
|
alpha: true
|
|
14578
15247
|
};
|
|
14579
15248
|
const defaultGPUProps = {
|
|
14580
|
-
canvas
|
|
15249
|
+
canvas,
|
|
15250
|
+
antialias: true
|
|
14581
15251
|
};
|
|
14582
15252
|
const wantsGL = (state.isLegacy || glConfig || !R3F_BUILD_WEBGPU || !rendererConfig);
|
|
14583
15253
|
if (glConfig && rendererConfig) {
|
|
@@ -14591,26 +15261,70 @@ function createRoot(canvas) {
|
|
|
14591
15261
|
});
|
|
14592
15262
|
}
|
|
14593
15263
|
let renderer = state.internal.actualRenderer;
|
|
15264
|
+
if (primaryCanvas && wantsGL) {
|
|
15265
|
+
throw new Error(
|
|
15266
|
+
"The `primaryCanvas` prop for multi-canvas rendering cannot be used with WebGL. Remove the `gl` prop or use WebGPU."
|
|
15267
|
+
);
|
|
15268
|
+
}
|
|
14594
15269
|
if (wantsGL && !state.internal.actualRenderer) {
|
|
14595
15270
|
renderer = await resolveRenderer(glConfig, defaultGLProps, three.WebGLRenderer);
|
|
14596
15271
|
state.internal.actualRenderer = renderer;
|
|
14597
|
-
state.set({ isLegacy: true, gl: renderer, renderer });
|
|
15272
|
+
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
15273
|
+
} else if (!wantsGL && primaryCanvas && !state.internal.actualRenderer) {
|
|
15274
|
+
const primary = await waitForPrimary(primaryCanvas);
|
|
15275
|
+
renderer = primary.renderer;
|
|
15276
|
+
state.internal.actualRenderer = renderer;
|
|
15277
|
+
const canvasTarget = new webgpu.CanvasTarget(canvas);
|
|
15278
|
+
primary.store.setState((prev) => ({
|
|
15279
|
+
internal: { ...prev.internal, isMultiCanvas: true }
|
|
15280
|
+
}));
|
|
15281
|
+
state.set((prev) => ({
|
|
15282
|
+
webGPUSupported: primary.store.getState().webGPUSupported,
|
|
15283
|
+
renderer,
|
|
15284
|
+
primaryStore: primary.store,
|
|
15285
|
+
internal: {
|
|
15286
|
+
...prev.internal,
|
|
15287
|
+
canvasTarget,
|
|
15288
|
+
isMultiCanvas: true,
|
|
15289
|
+
isSecondary: true,
|
|
15290
|
+
targetId: primaryCanvas
|
|
15291
|
+
}
|
|
15292
|
+
}));
|
|
14598
15293
|
} else if (!wantsGL && !state.internal.actualRenderer) {
|
|
14599
15294
|
renderer = await resolveRenderer(rendererConfig, defaultGPUProps, webgpu.WebGPURenderer);
|
|
14600
15295
|
if (!renderer.hasInitialized?.()) {
|
|
15296
|
+
const size2 = computeInitialSize(canvas, propsSize);
|
|
15297
|
+
if (size2.width > 0 && size2.height > 0) {
|
|
15298
|
+
const pixelRatio = calculateDpr(dpr);
|
|
15299
|
+
canvas.width = size2.width * pixelRatio;
|
|
15300
|
+
canvas.height = size2.height * pixelRatio;
|
|
15301
|
+
}
|
|
14601
15302
|
await renderer.init();
|
|
14602
15303
|
}
|
|
14603
15304
|
const backend = renderer.backend;
|
|
14604
15305
|
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
14605
15306
|
state.internal.actualRenderer = renderer;
|
|
14606
|
-
state.set({ webGPUSupported: isWebGPUBackend, renderer });
|
|
15307
|
+
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
15308
|
+
if (canvasId && !state.internal.isSecondary) {
|
|
15309
|
+
const canvasTarget = new webgpu.CanvasTarget(canvas);
|
|
15310
|
+
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
15311
|
+
state.set((prev) => ({
|
|
15312
|
+
internal: {
|
|
15313
|
+
...prev.internal,
|
|
15314
|
+
canvasTarget,
|
|
15315
|
+
unregisterPrimary
|
|
15316
|
+
}
|
|
15317
|
+
}));
|
|
15318
|
+
}
|
|
14607
15319
|
}
|
|
14608
15320
|
let raycaster = state.raycaster;
|
|
14609
15321
|
if (!raycaster) state.set({ raycaster: raycaster = new webgpu.Raycaster() });
|
|
14610
15322
|
const { params, ...options } = raycastOptions || {};
|
|
14611
15323
|
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options });
|
|
14612
|
-
if (!is.equ(params, raycaster.params, shallowLoose))
|
|
15324
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) {
|
|
14613
15325
|
applyProps(raycaster, { params: { ...raycaster.params, ...params } });
|
|
15326
|
+
}
|
|
15327
|
+
let tempCamera = state.camera;
|
|
14614
15328
|
if (!state.camera || state.camera === lastCamera && !is.equ(lastCamera, cameraOptions, shallowLoose)) {
|
|
14615
15329
|
lastCamera = cameraOptions;
|
|
14616
15330
|
const isCamera = cameraOptions?.isCamera;
|
|
@@ -14630,6 +15344,7 @@ function createRoot(canvas) {
|
|
|
14630
15344
|
if (!state.camera && !cameraOptions?.rotation) camera.lookAt(0, 0, 0);
|
|
14631
15345
|
}
|
|
14632
15346
|
state.set({ camera });
|
|
15347
|
+
tempCamera = camera;
|
|
14633
15348
|
raycaster.camera = camera;
|
|
14634
15349
|
}
|
|
14635
15350
|
if (!state.scene) {
|
|
@@ -14647,7 +15362,7 @@ function createRoot(canvas) {
|
|
|
14647
15362
|
rootScene: scene,
|
|
14648
15363
|
internal: { ...prev.internal, container: scene }
|
|
14649
15364
|
}));
|
|
14650
|
-
const camera =
|
|
15365
|
+
const camera = tempCamera;
|
|
14651
15366
|
if (camera && !camera.parent) scene.add(camera);
|
|
14652
15367
|
}
|
|
14653
15368
|
if (events && !state.events.handlers) {
|
|
@@ -14661,9 +15376,17 @@ function createRoot(canvas) {
|
|
|
14661
15376
|
wasEnabled = enabled;
|
|
14662
15377
|
});
|
|
14663
15378
|
}
|
|
15379
|
+
if (_sizeProps !== void 0) {
|
|
15380
|
+
state.set({ _sizeProps });
|
|
15381
|
+
}
|
|
15382
|
+
if (forceEven !== void 0 && state.internal.forceEven !== forceEven) {
|
|
15383
|
+
state.set((prev) => ({ internal: { ...prev.internal, forceEven } }));
|
|
15384
|
+
}
|
|
14664
15385
|
const size = computeInitialSize(canvas, propsSize);
|
|
14665
|
-
if (!is.equ(size, state.size, shallowLoose)) {
|
|
15386
|
+
if (!state._sizeImperative && !is.equ(size, state.size, shallowLoose)) {
|
|
15387
|
+
const wasImperative = state._sizeImperative;
|
|
14666
15388
|
state.setSize(size.width, size.height, size.top, size.left);
|
|
15389
|
+
if (!wasImperative) state.set({ _sizeImperative: false });
|
|
14667
15390
|
}
|
|
14668
15391
|
if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
|
|
14669
15392
|
state.setDpr(dpr);
|
|
@@ -14685,10 +15408,10 @@ function createRoot(canvas) {
|
|
|
14685
15408
|
lastConfiguredProps.performance = performance;
|
|
14686
15409
|
}
|
|
14687
15410
|
if (!state.xr) {
|
|
14688
|
-
const handleXRFrame = (timestamp,
|
|
15411
|
+
const handleXRFrame = (timestamp, _frame) => {
|
|
14689
15412
|
const state2 = store.getState();
|
|
14690
15413
|
if (state2.frameloop === "never") return;
|
|
14691
|
-
advance(timestamp
|
|
15414
|
+
advance(timestamp);
|
|
14692
15415
|
};
|
|
14693
15416
|
const actualRenderer = state.internal.actualRenderer;
|
|
14694
15417
|
const handleSessionChange = () => {
|
|
@@ -14700,16 +15423,16 @@ function createRoot(canvas) {
|
|
|
14700
15423
|
};
|
|
14701
15424
|
const xr = {
|
|
14702
15425
|
connect() {
|
|
14703
|
-
const { gl, renderer: renderer2
|
|
14704
|
-
const
|
|
14705
|
-
|
|
14706
|
-
|
|
15426
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15427
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15428
|
+
xrManager.addEventListener("sessionstart", handleSessionChange);
|
|
15429
|
+
xrManager.addEventListener("sessionend", handleSessionChange);
|
|
14707
15430
|
},
|
|
14708
15431
|
disconnect() {
|
|
14709
|
-
const { gl, renderer: renderer2
|
|
14710
|
-
const
|
|
14711
|
-
|
|
14712
|
-
|
|
15432
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15433
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15434
|
+
xrManager.removeEventListener("sessionstart", handleSessionChange);
|
|
15435
|
+
xrManager.removeEventListener("sessionend", handleSessionChange);
|
|
14713
15436
|
}
|
|
14714
15437
|
};
|
|
14715
15438
|
if (typeof renderer.xr?.addEventListener === "function") xr.connect();
|
|
@@ -14721,69 +15444,92 @@ function createRoot(canvas) {
|
|
|
14721
15444
|
const oldType = renderer.shadowMap.type;
|
|
14722
15445
|
renderer.shadowMap.enabled = !!shadows;
|
|
14723
15446
|
if (is.boo(shadows)) {
|
|
14724
|
-
renderer.shadowMap.type = webgpu.
|
|
15447
|
+
renderer.shadowMap.type = webgpu.PCFShadowMap;
|
|
14725
15448
|
} else if (is.str(shadows)) {
|
|
15449
|
+
if (shadows === "soft") {
|
|
15450
|
+
notifyDepreciated({
|
|
15451
|
+
heading: 'shadows="soft" is deprecated',
|
|
15452
|
+
body: "Three has depreciated soft and improved basic PCFShadows, we converted for you.",
|
|
15453
|
+
link: "https://github.com/mrdoob/three.js/wiki/Migration-Guide?utm_source=chatgpt.com#181--182"
|
|
15454
|
+
});
|
|
15455
|
+
}
|
|
14726
15456
|
const types = {
|
|
14727
15457
|
basic: webgpu.BasicShadowMap,
|
|
14728
15458
|
percentage: webgpu.PCFShadowMap,
|
|
14729
|
-
soft: webgpu.
|
|
15459
|
+
soft: webgpu.PCFShadowMap,
|
|
14730
15460
|
variance: webgpu.VSMShadowMap
|
|
14731
15461
|
};
|
|
14732
|
-
renderer.shadowMap.type = types[shadows] ?? webgpu.
|
|
15462
|
+
renderer.shadowMap.type = types[shadows] ?? webgpu.PCFShadowMap;
|
|
14733
15463
|
} else if (is.obj(shadows)) {
|
|
14734
15464
|
Object.assign(renderer.shadowMap, shadows);
|
|
14735
15465
|
}
|
|
14736
|
-
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type)
|
|
15466
|
+
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type) {
|
|
14737
15467
|
renderer.shadowMap.needsUpdate = true;
|
|
14738
|
-
}
|
|
14739
|
-
{
|
|
14740
|
-
const legacyChanged = legacy !== lastConfiguredProps.legacy;
|
|
14741
|
-
const linearChanged = linear !== lastConfiguredProps.linear;
|
|
14742
|
-
const flatChanged = flat !== lastConfiguredProps.flat;
|
|
14743
|
-
if (legacyChanged) {
|
|
14744
|
-
if (legacy)
|
|
14745
|
-
notifyDepreciated({
|
|
14746
|
-
heading: "Legacy Color Management",
|
|
14747
|
-
body: "Legacy color management is deprecated and will be removed in a future version.",
|
|
14748
|
-
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
14749
|
-
});
|
|
14750
|
-
}
|
|
14751
|
-
if (legacyChanged) {
|
|
14752
|
-
webgpu.ColorManagement.enabled = !legacy;
|
|
14753
|
-
lastConfiguredProps.legacy = legacy;
|
|
14754
15468
|
}
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
|
|
14759
|
-
if (!configured || flatChanged) {
|
|
14760
|
-
renderer.toneMapping = flat ? webgpu.NoToneMapping : webgpu.ACESFilmicToneMapping;
|
|
14761
|
-
lastConfiguredProps.flat = flat;
|
|
14762
|
-
}
|
|
14763
|
-
if (legacyChanged && state.legacy !== legacy) state.set(() => ({ legacy }));
|
|
14764
|
-
if (linearChanged && state.linear !== linear) state.set(() => ({ linear }));
|
|
14765
|
-
if (flatChanged && state.flat !== flat) state.set(() => ({ flat }));
|
|
15469
|
+
}
|
|
15470
|
+
if (!configured) {
|
|
15471
|
+
renderer.outputColorSpace = webgpu.SRGBColorSpace;
|
|
15472
|
+
renderer.toneMapping = webgpu.ACESFilmicToneMapping;
|
|
14766
15473
|
}
|
|
14767
15474
|
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
14768
15475
|
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
14769
15476
|
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
14770
15477
|
}
|
|
14771
|
-
|
|
14772
|
-
|
|
15478
|
+
const r3fProps = ["textureColorSpace"];
|
|
15479
|
+
const constructorOnlyProps = ["samples", "antialias", "alpha", "canvas", "powerPreference"];
|
|
15480
|
+
const nonApplyProps = [...r3fProps, ...constructorOnlyProps];
|
|
15481
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
|
|
15482
|
+
const glProps = {};
|
|
15483
|
+
for (const key in glConfig) {
|
|
15484
|
+
if (!nonApplyProps.includes(key)) glProps[key] = glConfig[key];
|
|
15485
|
+
}
|
|
15486
|
+
applyProps(renderer, glProps);
|
|
15487
|
+
}
|
|
14773
15488
|
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
|
|
14774
15489
|
const currentRenderer = state.renderer;
|
|
14775
15490
|
if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
|
|
14776
|
-
|
|
15491
|
+
const rendererProps = {};
|
|
15492
|
+
for (const key in rendererConfig) {
|
|
15493
|
+
if (!nonApplyProps.includes(key)) rendererProps[key] = rendererConfig[key];
|
|
15494
|
+
}
|
|
15495
|
+
applyProps(currentRenderer, rendererProps);
|
|
14777
15496
|
}
|
|
14778
15497
|
}
|
|
14779
15498
|
const scheduler = getScheduler();
|
|
14780
15499
|
const rootId = state.internal.rootId;
|
|
14781
15500
|
if (!rootId) {
|
|
14782
|
-
const newRootId = scheduler.generateRootId();
|
|
15501
|
+
const newRootId = canvasId || scheduler.generateRootId();
|
|
14783
15502
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14784
15503
|
getState: () => store.getState(),
|
|
14785
15504
|
onError: (err) => store.getState().setError(err)
|
|
14786
15505
|
});
|
|
15506
|
+
const unregisterCanvasTarget = scheduler.register(
|
|
15507
|
+
() => {
|
|
15508
|
+
const state2 = store.getState();
|
|
15509
|
+
if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
|
|
15510
|
+
const renderer2 = state2.internal.actualRenderer;
|
|
15511
|
+
renderer2.setCanvasTarget(state2.internal.canvasTarget);
|
|
15512
|
+
}
|
|
15513
|
+
},
|
|
15514
|
+
{
|
|
15515
|
+
id: `${newRootId}_canvasTarget`,
|
|
15516
|
+
rootId: newRootId,
|
|
15517
|
+
phase: "start",
|
|
15518
|
+
system: true
|
|
15519
|
+
}
|
|
15520
|
+
);
|
|
15521
|
+
const unregisterEventsFlush = scheduler.register(
|
|
15522
|
+
() => {
|
|
15523
|
+
const state2 = store.getState();
|
|
15524
|
+
state2.events.flush?.();
|
|
15525
|
+
},
|
|
15526
|
+
{
|
|
15527
|
+
id: `${newRootId}_events`,
|
|
15528
|
+
rootId: newRootId,
|
|
15529
|
+
phase: "input",
|
|
15530
|
+
system: true
|
|
15531
|
+
}
|
|
15532
|
+
);
|
|
14787
15533
|
const unregisterFrustum = scheduler.register(
|
|
14788
15534
|
() => {
|
|
14789
15535
|
const state2 = store.getState();
|
|
@@ -14818,18 +15564,22 @@ function createRoot(canvas) {
|
|
|
14818
15564
|
const userHandlesRender = scheduler.hasUserJobsInPhase("render", newRootId);
|
|
14819
15565
|
if (userHandlesRender || state2.internal.priority) return;
|
|
14820
15566
|
try {
|
|
14821
|
-
if (state2.
|
|
15567
|
+
if (state2.renderPipeline?.render) state2.renderPipeline.render();
|
|
14822
15568
|
else if (renderer2?.render) renderer2.render(state2.scene, state2.camera);
|
|
14823
15569
|
} catch (error) {
|
|
14824
15570
|
state2.setError(error instanceof Error ? error : new Error(String(error)));
|
|
14825
15571
|
}
|
|
14826
15572
|
},
|
|
14827
15573
|
{
|
|
14828
|
-
|
|
15574
|
+
// Use canvas ID directly as job ID if available, otherwise use generated rootId
|
|
15575
|
+
id: canvasId || `${newRootId}_render`,
|
|
14829
15576
|
rootId: newRootId,
|
|
14830
15577
|
phase: "render",
|
|
14831
|
-
system: true
|
|
15578
|
+
system: true,
|
|
14832
15579
|
// Internal flag: this is a system job, not user-controlled
|
|
15580
|
+
// Apply scheduler config for render ordering and rate limiting
|
|
15581
|
+
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
15582
|
+
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14833
15583
|
}
|
|
14834
15584
|
);
|
|
14835
15585
|
state.set((state2) => ({
|
|
@@ -14838,6 +15588,8 @@ function createRoot(canvas) {
|
|
|
14838
15588
|
rootId: newRootId,
|
|
14839
15589
|
unregisterRoot: () => {
|
|
14840
15590
|
unregisterRoot();
|
|
15591
|
+
unregisterCanvasTarget();
|
|
15592
|
+
unregisterEventsFlush();
|
|
14841
15593
|
unregisterFrustum();
|
|
14842
15594
|
unregisterVisibility();
|
|
14843
15595
|
unregisterRender();
|
|
@@ -14896,15 +15648,24 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14896
15648
|
const renderer = state.internal.actualRenderer;
|
|
14897
15649
|
const unregisterRoot = state.internal.unregisterRoot;
|
|
14898
15650
|
if (unregisterRoot) unregisterRoot();
|
|
15651
|
+
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
15652
|
+
if (unregisterPrimary) unregisterPrimary();
|
|
15653
|
+
const canvasTarget = state.internal.canvasTarget;
|
|
15654
|
+
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14899
15655
|
state.events.disconnect?.();
|
|
14900
15656
|
cleanupHelperGroup(root.store);
|
|
14901
|
-
renderer
|
|
14902
|
-
|
|
14903
|
-
|
|
15657
|
+
if (state.isLegacy && renderer) {
|
|
15658
|
+
;
|
|
15659
|
+
renderer.renderLists?.dispose?.();
|
|
15660
|
+
renderer.forceContextLoss?.();
|
|
15661
|
+
}
|
|
15662
|
+
if (!state.internal.isSecondary) {
|
|
15663
|
+
if (renderer?.xr) state.xr.disconnect();
|
|
15664
|
+
}
|
|
14904
15665
|
dispose(state.scene);
|
|
14905
15666
|
_roots.delete(canvas);
|
|
14906
15667
|
if (callback) callback(canvas);
|
|
14907
|
-
} catch
|
|
15668
|
+
} catch {
|
|
14908
15669
|
}
|
|
14909
15670
|
}, 500);
|
|
14910
15671
|
}
|
|
@@ -14912,36 +15673,34 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14912
15673
|
}
|
|
14913
15674
|
}
|
|
14914
15675
|
function createPortal(children, container, state) {
|
|
14915
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15676
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Portal, { children, container, state });
|
|
14916
15677
|
}
|
|
14917
|
-
function
|
|
15678
|
+
function Portal({ children, container, state }) {
|
|
14918
15679
|
const isRef = React.useCallback((obj) => obj && "current" in obj, []);
|
|
14919
|
-
const [resolvedContainer,
|
|
15680
|
+
const [resolvedContainer, _setResolvedContainer] = React.useState(() => {
|
|
14920
15681
|
if (isRef(container)) return container.current ?? null;
|
|
14921
15682
|
return container;
|
|
14922
15683
|
});
|
|
15684
|
+
const setResolvedContainer = React.useCallback(
|
|
15685
|
+
(newContainer) => {
|
|
15686
|
+
if (!newContainer || newContainer === resolvedContainer) return;
|
|
15687
|
+
_setResolvedContainer(isRef(newContainer) ? newContainer.current : newContainer);
|
|
15688
|
+
},
|
|
15689
|
+
[resolvedContainer, _setResolvedContainer, isRef]
|
|
15690
|
+
);
|
|
14923
15691
|
React.useMemo(() => {
|
|
14924
|
-
if (isRef(container)) {
|
|
14925
|
-
|
|
14926
|
-
|
|
14927
|
-
|
|
14928
|
-
const updated = container.current;
|
|
14929
|
-
if (updated && updated !== resolvedContainer) {
|
|
14930
|
-
setResolvedContainer(updated);
|
|
14931
|
-
}
|
|
14932
|
-
});
|
|
14933
|
-
} else if (current !== resolvedContainer) {
|
|
14934
|
-
setResolvedContainer(current);
|
|
14935
|
-
}
|
|
14936
|
-
} else if (container !== resolvedContainer) {
|
|
14937
|
-
setResolvedContainer(container);
|
|
15692
|
+
if (isRef(container) && !container.current) {
|
|
15693
|
+
return queueMicrotask(() => {
|
|
15694
|
+
setResolvedContainer(container.current);
|
|
15695
|
+
});
|
|
14938
15696
|
}
|
|
14939
|
-
|
|
15697
|
+
setResolvedContainer(container);
|
|
15698
|
+
}, [container, isRef, setResolvedContainer]);
|
|
14940
15699
|
if (!resolvedContainer) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
14941
15700
|
const portalKey = resolvedContainer.uuid ?? `portal-${resolvedContainer.id ?? "unknown"}`;
|
|
14942
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15701
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PortalInner, { children, container: resolvedContainer, state }, portalKey);
|
|
14943
15702
|
}
|
|
14944
|
-
function
|
|
15703
|
+
function PortalInner({ state = {}, children, container }) {
|
|
14945
15704
|
const { events, size, injectScene = true, ...rest } = state;
|
|
14946
15705
|
const previousRoot = useStore();
|
|
14947
15706
|
const [raycaster] = React.useState(() => new webgpu.Raycaster());
|
|
@@ -14962,11 +15721,12 @@ function Portal({ state = {}, children, container }) {
|
|
|
14962
15721
|
};
|
|
14963
15722
|
}, [portalScene, container, injectScene]);
|
|
14964
15723
|
const inject = useMutableCallback((rootState, injectState) => {
|
|
15724
|
+
const resolvedSize = { ...rootState.size, ...injectState.size, ...size };
|
|
14965
15725
|
let viewport = void 0;
|
|
14966
|
-
if (injectState.camera && size) {
|
|
15726
|
+
if (injectState.camera && (size || injectState.size)) {
|
|
14967
15727
|
const camera = injectState.camera;
|
|
14968
|
-
viewport = rootState.viewport.getCurrentViewport(camera, new webgpu.Vector3(),
|
|
14969
|
-
if (camera !== rootState.camera) updateCamera(camera,
|
|
15728
|
+
viewport = rootState.viewport.getCurrentViewport(camera, new webgpu.Vector3(), resolvedSize);
|
|
15729
|
+
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14970
15730
|
}
|
|
14971
15731
|
return {
|
|
14972
15732
|
// The intersect consists of the previous root state
|
|
@@ -14983,7 +15743,7 @@ function Portal({ state = {}, children, container }) {
|
|
|
14983
15743
|
previousRoot,
|
|
14984
15744
|
// Events, size and viewport can be overridden by the inject layer
|
|
14985
15745
|
events: { ...rootState.events, ...injectState.events, ...events },
|
|
14986
|
-
size:
|
|
15746
|
+
size: resolvedSize,
|
|
14987
15747
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14988
15748
|
// Layers are allowed to override events
|
|
14989
15749
|
setEvents: (events2) => injectState.set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
@@ -14995,9 +15755,13 @@ function Portal({ state = {}, children, container }) {
|
|
|
14995
15755
|
const store = traditional.createWithEqualityFn((set, get) => ({ ...rest, set, get }));
|
|
14996
15756
|
const onMutate = (prev) => store.setState((state2) => inject.current(prev, state2));
|
|
14997
15757
|
onMutate(previousRoot.getState());
|
|
14998
|
-
previousRoot.subscribe(onMutate);
|
|
14999
15758
|
return store;
|
|
15000
15759
|
}, [previousRoot, container]);
|
|
15760
|
+
useIsomorphicLayoutEffect(() => {
|
|
15761
|
+
const onMutate = (prev) => usePortalStore.setState((state2) => inject.current(prev, state2));
|
|
15762
|
+
const unsubscribe = previousRoot.subscribe(onMutate);
|
|
15763
|
+
return unsubscribe;
|
|
15764
|
+
}, [previousRoot, usePortalStore]);
|
|
15001
15765
|
return (
|
|
15002
15766
|
// @ts-ignore, reconciler types are not maintained
|
|
15003
15767
|
/* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: reconciler.createPortal(
|
|
@@ -15017,15 +15781,13 @@ function CanvasImpl({
|
|
|
15017
15781
|
fallback,
|
|
15018
15782
|
resize,
|
|
15019
15783
|
style,
|
|
15784
|
+
id,
|
|
15020
15785
|
gl,
|
|
15021
|
-
renderer,
|
|
15786
|
+
renderer: rendererProp,
|
|
15022
15787
|
events = createPointerEvents,
|
|
15023
15788
|
eventSource,
|
|
15024
15789
|
eventPrefix,
|
|
15025
15790
|
shadows,
|
|
15026
|
-
linear,
|
|
15027
|
-
flat,
|
|
15028
|
-
legacy,
|
|
15029
15791
|
orthographic,
|
|
15030
15792
|
frameloop,
|
|
15031
15793
|
dpr,
|
|
@@ -15037,10 +15799,56 @@ function CanvasImpl({
|
|
|
15037
15799
|
onDragOverMissed,
|
|
15038
15800
|
onDropMissed,
|
|
15039
15801
|
onCreated,
|
|
15802
|
+
hmr,
|
|
15803
|
+
width,
|
|
15804
|
+
height,
|
|
15805
|
+
background,
|
|
15806
|
+
forceEven,
|
|
15040
15807
|
...props
|
|
15041
15808
|
}) {
|
|
15809
|
+
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
15810
|
+
let primaryCanvas;
|
|
15811
|
+
let scheduler;
|
|
15812
|
+
let renderer;
|
|
15813
|
+
if (isRendererConfig) {
|
|
15814
|
+
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
15815
|
+
primaryCanvas = pc;
|
|
15816
|
+
scheduler = sc;
|
|
15817
|
+
renderer = Object.keys(rest).length > 0 ? rest : rendererProp;
|
|
15818
|
+
} else {
|
|
15819
|
+
renderer = rendererProp;
|
|
15820
|
+
}
|
|
15042
15821
|
React__namespace.useMemo(() => extend(THREE), []);
|
|
15043
15822
|
const Bridge = useBridge();
|
|
15823
|
+
const backgroundProps = React__namespace.useMemo(() => {
|
|
15824
|
+
if (!background) return null;
|
|
15825
|
+
if (typeof background === "object" && !background.isColor) {
|
|
15826
|
+
const { backgroundMap, envMap, files, preset, ...rest } = background;
|
|
15827
|
+
return {
|
|
15828
|
+
...rest,
|
|
15829
|
+
preset,
|
|
15830
|
+
files: envMap || files,
|
|
15831
|
+
backgroundFiles: backgroundMap,
|
|
15832
|
+
background: true
|
|
15833
|
+
};
|
|
15834
|
+
}
|
|
15835
|
+
if (typeof background === "number") {
|
|
15836
|
+
return { color: background, background: true };
|
|
15837
|
+
}
|
|
15838
|
+
if (typeof background === "string") {
|
|
15839
|
+
if (background in presetsObj) {
|
|
15840
|
+
return { preset: background, background: true };
|
|
15841
|
+
}
|
|
15842
|
+
if (/^(https?:\/\/|\/|\.\/|\.\.\/)|\\.(hdr|exr|jpg|jpeg|png|webp|gif)$/i.test(background)) {
|
|
15843
|
+
return { files: background, background: true };
|
|
15844
|
+
}
|
|
15845
|
+
return { color: background, background: true };
|
|
15846
|
+
}
|
|
15847
|
+
if (background.isColor) {
|
|
15848
|
+
return { color: background, background: true };
|
|
15849
|
+
}
|
|
15850
|
+
return null;
|
|
15851
|
+
}, [background]);
|
|
15044
15852
|
const hasInitialSizeRef = React__namespace.useRef(false);
|
|
15045
15853
|
const measureConfig = React__namespace.useMemo(() => {
|
|
15046
15854
|
if (!hasInitialSizeRef.current) {
|
|
@@ -15057,7 +15865,21 @@ function CanvasImpl({
|
|
|
15057
15865
|
};
|
|
15058
15866
|
}, [resize, hasInitialSizeRef.current]);
|
|
15059
15867
|
const [containerRef, containerRect] = useMeasure__default(measureConfig);
|
|
15060
|
-
|
|
15868
|
+
const effectiveSize = React__namespace.useMemo(() => {
|
|
15869
|
+
let w = width ?? containerRect.width;
|
|
15870
|
+
let h = height ?? containerRect.height;
|
|
15871
|
+
if (forceEven) {
|
|
15872
|
+
w = Math.ceil(w / 2) * 2;
|
|
15873
|
+
h = Math.ceil(h / 2) * 2;
|
|
15874
|
+
}
|
|
15875
|
+
return {
|
|
15876
|
+
width: w,
|
|
15877
|
+
height: h,
|
|
15878
|
+
top: containerRect.top,
|
|
15879
|
+
left: containerRect.left
|
|
15880
|
+
};
|
|
15881
|
+
}, [width, height, containerRect, forceEven]);
|
|
15882
|
+
if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
|
|
15061
15883
|
hasInitialSizeRef.current = true;
|
|
15062
15884
|
}
|
|
15063
15885
|
const canvasRef = React__namespace.useRef(null);
|
|
@@ -15076,7 +15898,7 @@ function CanvasImpl({
|
|
|
15076
15898
|
useIsomorphicLayoutEffect(() => {
|
|
15077
15899
|
effectActiveRef.current = true;
|
|
15078
15900
|
const canvas = canvasRef.current;
|
|
15079
|
-
if (
|
|
15901
|
+
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
15080
15902
|
if (!root.current) {
|
|
15081
15903
|
root.current = createRoot(canvas);
|
|
15082
15904
|
notifyAlpha({
|
|
@@ -15096,21 +15918,24 @@ function CanvasImpl({
|
|
|
15096
15918
|
async function run() {
|
|
15097
15919
|
if (!effectActiveRef.current || !root.current) return;
|
|
15098
15920
|
await root.current.configure({
|
|
15921
|
+
id,
|
|
15922
|
+
primaryCanvas,
|
|
15923
|
+
scheduler,
|
|
15099
15924
|
gl,
|
|
15100
15925
|
renderer,
|
|
15101
15926
|
scene,
|
|
15102
15927
|
events,
|
|
15103
15928
|
shadows,
|
|
15104
|
-
linear,
|
|
15105
|
-
flat,
|
|
15106
|
-
legacy,
|
|
15107
15929
|
orthographic,
|
|
15108
15930
|
frameloop,
|
|
15109
15931
|
dpr,
|
|
15110
15932
|
performance,
|
|
15111
15933
|
raycaster,
|
|
15112
15934
|
camera,
|
|
15113
|
-
size:
|
|
15935
|
+
size: effectiveSize,
|
|
15936
|
+
// Store size props for reset functionality
|
|
15937
|
+
_sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
|
|
15938
|
+
forceEven,
|
|
15114
15939
|
// Pass mutable reference to onPointerMissed so it's free to update
|
|
15115
15940
|
onPointerMissed: (...args) => handlePointerMissed.current?.(...args),
|
|
15116
15941
|
onDragOverMissed: (...args) => handleDragOverMissed.current?.(...args),
|
|
@@ -15134,7 +15959,10 @@ function CanvasImpl({
|
|
|
15134
15959
|
});
|
|
15135
15960
|
if (!effectActiveRef.current || !root.current) return;
|
|
15136
15961
|
root.current.render(
|
|
15137
|
-
/* @__PURE__ */ jsxRuntime.jsx(Bridge, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxRuntime.
|
|
15962
|
+
/* @__PURE__ */ jsxRuntime.jsx(Bridge, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxRuntime.jsxs(React__namespace.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(Block, { set: setBlock }), children: [
|
|
15963
|
+
backgroundProps && /* @__PURE__ */ jsxRuntime.jsx(Environment, { ...backgroundProps }),
|
|
15964
|
+
children ?? null
|
|
15965
|
+
] }) }) })
|
|
15138
15966
|
);
|
|
15139
15967
|
}
|
|
15140
15968
|
run();
|
|
@@ -15156,6 +15984,35 @@ function CanvasImpl({
|
|
|
15156
15984
|
};
|
|
15157
15985
|
}
|
|
15158
15986
|
}, []);
|
|
15987
|
+
React__namespace.useEffect(() => {
|
|
15988
|
+
if (hmr === false) return;
|
|
15989
|
+
const canvas = canvasRef.current;
|
|
15990
|
+
if (!canvas) return;
|
|
15991
|
+
const handleHMR = () => {
|
|
15992
|
+
queueMicrotask(() => {
|
|
15993
|
+
const rootEntry = _roots.get(canvas);
|
|
15994
|
+
if (rootEntry?.store) {
|
|
15995
|
+
console.log("[R3F] HMR detected \u2014 rebuilding nodes/uniforms");
|
|
15996
|
+
rootEntry.store.setState((state) => ({
|
|
15997
|
+
nodes: {},
|
|
15998
|
+
uniforms: {},
|
|
15999
|
+
_hmrVersion: state._hmrVersion + 1
|
|
16000
|
+
}));
|
|
16001
|
+
}
|
|
16002
|
+
});
|
|
16003
|
+
};
|
|
16004
|
+
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && undefined) {
|
|
16005
|
+
const hot = undefined;
|
|
16006
|
+
hot.on("vite:afterUpdate", handleHMR);
|
|
16007
|
+
return () => hot.off?.("vite:afterUpdate", handleHMR);
|
|
16008
|
+
}
|
|
16009
|
+
if (typeof module !== "undefined" && module.hot) {
|
|
16010
|
+
const hot = module.hot;
|
|
16011
|
+
hot.addStatusHandler((status) => {
|
|
16012
|
+
if (status === "idle") handleHMR();
|
|
16013
|
+
});
|
|
16014
|
+
}
|
|
16015
|
+
}, [hmr]);
|
|
15159
16016
|
const pointerEvents = eventSource ? "none" : "auto";
|
|
15160
16017
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15161
16018
|
"div",
|
|
@@ -15170,7 +16027,16 @@ function CanvasImpl({
|
|
|
15170
16027
|
...style
|
|
15171
16028
|
},
|
|
15172
16029
|
...props,
|
|
15173
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
16030
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
16031
|
+
"canvas",
|
|
16032
|
+
{
|
|
16033
|
+
ref: canvasRef,
|
|
16034
|
+
id,
|
|
16035
|
+
className: "r3f-canvas",
|
|
16036
|
+
style: { display: "block", width: "100%", height: "100%" },
|
|
16037
|
+
children: fallback
|
|
16038
|
+
}
|
|
16039
|
+
) })
|
|
15174
16040
|
}
|
|
15175
16041
|
);
|
|
15176
16042
|
}
|
|
@@ -15182,8 +16048,15 @@ extend(THREE);
|
|
|
15182
16048
|
|
|
15183
16049
|
exports.Block = Block;
|
|
15184
16050
|
exports.Canvas = Canvas;
|
|
16051
|
+
exports.Environment = Environment;
|
|
16052
|
+
exports.EnvironmentCube = EnvironmentCube;
|
|
16053
|
+
exports.EnvironmentMap = EnvironmentMap;
|
|
16054
|
+
exports.EnvironmentPortal = EnvironmentPortal;
|
|
15185
16055
|
exports.ErrorBoundary = ErrorBoundary;
|
|
16056
|
+
exports.FROM_REF = FROM_REF;
|
|
15186
16057
|
exports.IsObject = IsObject;
|
|
16058
|
+
exports.ONCE = ONCE;
|
|
16059
|
+
exports.Portal = Portal;
|
|
15187
16060
|
exports.R3F_BUILD_LEGACY = R3F_BUILD_LEGACY;
|
|
15188
16061
|
exports.R3F_BUILD_WEBGPU = R3F_BUILD_WEBGPU;
|
|
15189
16062
|
exports.REACT_INTERNAL_PROPS = REACT_INTERNAL_PROPS;
|
|
@@ -15213,30 +16086,41 @@ exports.events = createPointerEvents;
|
|
|
15213
16086
|
exports.extend = extend;
|
|
15214
16087
|
exports.findInitialRoot = findInitialRoot;
|
|
15215
16088
|
exports.flushSync = flushSync;
|
|
16089
|
+
exports.fromRef = fromRef;
|
|
15216
16090
|
exports.getInstanceProps = getInstanceProps;
|
|
16091
|
+
exports.getPrimary = getPrimary;
|
|
16092
|
+
exports.getPrimaryIds = getPrimaryIds;
|
|
15217
16093
|
exports.getRootState = getRootState;
|
|
15218
16094
|
exports.getScheduler = getScheduler;
|
|
15219
16095
|
exports.getUuidPrefix = getUuidPrefix;
|
|
15220
16096
|
exports.hasConstructor = hasConstructor;
|
|
16097
|
+
exports.hasPrimary = hasPrimary;
|
|
15221
16098
|
exports.invalidate = invalidate;
|
|
15222
16099
|
exports.invalidateInstance = invalidateInstance;
|
|
15223
16100
|
exports.is = is;
|
|
15224
16101
|
exports.isColorRepresentation = isColorRepresentation;
|
|
15225
16102
|
exports.isCopyable = isCopyable;
|
|
16103
|
+
exports.isFromRef = isFromRef;
|
|
15226
16104
|
exports.isObject3D = isObject3D;
|
|
16105
|
+
exports.isOnce = isOnce;
|
|
15227
16106
|
exports.isOrthographicCamera = isOrthographicCamera;
|
|
15228
16107
|
exports.isRef = isRef;
|
|
15229
16108
|
exports.isRenderer = isRenderer;
|
|
15230
16109
|
exports.isTexture = isTexture;
|
|
15231
16110
|
exports.isVectorLike = isVectorLike;
|
|
16111
|
+
exports.once = once;
|
|
15232
16112
|
exports.prepare = prepare;
|
|
16113
|
+
exports.presetsObj = presetsObj;
|
|
15233
16114
|
exports.reconciler = reconciler;
|
|
16115
|
+
exports.registerPrimary = registerPrimary;
|
|
15234
16116
|
exports.removeInteractivity = removeInteractivity;
|
|
15235
16117
|
exports.resolve = resolve;
|
|
15236
16118
|
exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
16119
|
+
exports.unregisterPrimary = unregisterPrimary;
|
|
15237
16120
|
exports.updateCamera = updateCamera;
|
|
15238
16121
|
exports.updateFrustum = updateFrustum;
|
|
15239
16122
|
exports.useBridge = useBridge;
|
|
16123
|
+
exports.useEnvironment = useEnvironment;
|
|
15240
16124
|
exports.useFrame = useFrame;
|
|
15241
16125
|
exports.useGraph = useGraph;
|
|
15242
16126
|
exports.useInstanceHandle = useInstanceHandle;
|
|
@@ -15248,3 +16132,4 @@ exports.useStore = useStore;
|
|
|
15248
16132
|
exports.useTexture = useTexture;
|
|
15249
16133
|
exports.useTextures = useTextures;
|
|
15250
16134
|
exports.useThree = useThree;
|
|
16135
|
+
exports.waitForPrimary = waitForPrimary;
|