@react-three/fiber 10.0.0-alpha.1 → 10.0.0-canary.b0fafc8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/dist/index.cjs +1170 -557
- package/dist/index.d.cts +2001 -1274
- package/dist/index.d.mts +2001 -1274
- package/dist/index.d.ts +2001 -1274
- package/dist/index.mjs +1154 -561
- package/dist/legacy.cjs +1158 -564
- package/dist/legacy.d.cts +2002 -1275
- package/dist/legacy.d.mts +2002 -1275
- package/dist/legacy.d.ts +2002 -1275
- package/dist/legacy.mjs +1142 -568
- package/dist/webgpu/index.cjs +1365 -504
- package/dist/webgpu/index.d.cts +2180 -1290
- package/dist/webgpu/index.d.mts +2180 -1290
- package/dist/webgpu/index.d.ts +2180 -1290
- package/dist/webgpu/index.mjs +1346 -508
- package/package.json +7 -5
- package/react-reconciler/constants.js +1 -9
- package/react-reconciler/index.js +4 -20
- package/readme.md +244 -318
package/dist/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,374 @@ 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
|
+
}, [files, 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
|
+
}, [children, virtualScene, fbo.texture, scene, defaultScene, background, frames, gl]);
|
|
364
|
+
let count = 1;
|
|
365
|
+
fiber.useFrame(() => {
|
|
366
|
+
if (frames === Infinity || count < frames) {
|
|
367
|
+
const autoClear = gl.autoClear;
|
|
368
|
+
gl.autoClear = true;
|
|
369
|
+
camera.current.update(gl, virtualScene);
|
|
370
|
+
gl.autoClear = autoClear;
|
|
371
|
+
count++;
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fiber.createPortal(
|
|
375
|
+
/* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
376
|
+
children,
|
|
377
|
+
/* @__PURE__ */ jsxRuntime.jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
|
|
378
|
+
files || preset ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { background: true, map, extensions }) : null
|
|
379
|
+
] }),
|
|
380
|
+
virtualScene
|
|
381
|
+
) });
|
|
382
|
+
}
|
|
383
|
+
function EnvironmentGround(props) {
|
|
384
|
+
const textureDefault = useEnvironment(props);
|
|
385
|
+
const texture = props.map || textureDefault;
|
|
386
|
+
React__namespace.useMemo(() => fiber.extend({ GroundProjectedEnvImpl: GroundedSkybox_js.GroundedSkybox }), []);
|
|
387
|
+
React__namespace.useEffect(() => {
|
|
388
|
+
return () => {
|
|
389
|
+
textureDefault.dispose();
|
|
390
|
+
};
|
|
391
|
+
}, [textureDefault]);
|
|
392
|
+
const height = props.ground?.height ?? 15;
|
|
393
|
+
const radius = props.ground?.radius ?? 60;
|
|
394
|
+
const scale = props.ground?.scale ?? 1e3;
|
|
395
|
+
const args = React__namespace.useMemo(
|
|
396
|
+
() => [texture, height, radius],
|
|
397
|
+
[texture, height, radius]
|
|
398
|
+
);
|
|
399
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
400
|
+
/* @__PURE__ */ jsxRuntime.jsx(EnvironmentMap, { ...props, map: texture }),
|
|
401
|
+
/* @__PURE__ */ jsxRuntime.jsx("groundProjectedEnvImpl", { args, scale })
|
|
402
|
+
] });
|
|
403
|
+
}
|
|
404
|
+
function EnvironmentColor({ color, scene }) {
|
|
405
|
+
const defaultScene = fiber.useThree((state) => state.scene);
|
|
406
|
+
React__namespace.useLayoutEffect(() => {
|
|
407
|
+
if (color === void 0) return;
|
|
408
|
+
const target = resolveScene(scene || defaultScene);
|
|
409
|
+
const oldBg = target.background;
|
|
410
|
+
target.background = new webgpu.Color(color);
|
|
411
|
+
return () => {
|
|
412
|
+
target.background = oldBg;
|
|
413
|
+
};
|
|
414
|
+
});
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
function EnvironmentDualSource(props) {
|
|
418
|
+
const { backgroundFiles, ...envProps } = props;
|
|
419
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
420
|
+
/* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
421
|
+
/* @__PURE__ */ jsxRuntime.jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
|
|
422
|
+
] });
|
|
423
|
+
}
|
|
424
|
+
function Environment(props) {
|
|
425
|
+
if (props.color && !props.files && !props.preset && !props.map) {
|
|
426
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentColor, { ...props });
|
|
427
|
+
}
|
|
428
|
+
if (props.backgroundFiles && props.backgroundFiles !== props.files) {
|
|
429
|
+
return /* @__PURE__ */ jsxRuntime.jsx(EnvironmentDualSource, { ...props });
|
|
430
|
+
}
|
|
431
|
+
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 });
|
|
432
|
+
}
|
|
433
|
+
|
|
59
434
|
var __defProp$2 = Object.defineProperty;
|
|
60
435
|
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
61
436
|
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -235,7 +610,8 @@ function prepare(target, root, type, props) {
|
|
|
235
610
|
object,
|
|
236
611
|
eventCount: 0,
|
|
237
612
|
handlers: {},
|
|
238
|
-
isHidden: false
|
|
613
|
+
isHidden: false,
|
|
614
|
+
deferredRefs: []
|
|
239
615
|
};
|
|
240
616
|
if (object) object.__r3f = instance;
|
|
241
617
|
}
|
|
@@ -284,7 +660,7 @@ function createOcclusionObserverNode(store, uniform) {
|
|
|
284
660
|
let occlusionSetupPromise = null;
|
|
285
661
|
function enableOcclusion(store) {
|
|
286
662
|
const state = store.getState();
|
|
287
|
-
const { internal, renderer
|
|
663
|
+
const { internal, renderer } = state;
|
|
288
664
|
if (internal.occlusionEnabled || occlusionSetupPromise) return;
|
|
289
665
|
const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
|
|
290
666
|
if (!hasOcclusionSupport) {
|
|
@@ -447,6 +823,22 @@ function hasVisibilityHandlers(handlers) {
|
|
|
447
823
|
return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
|
|
448
824
|
}
|
|
449
825
|
|
|
826
|
+
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
827
|
+
function fromRef(ref) {
|
|
828
|
+
return { [FROM_REF]: ref };
|
|
829
|
+
}
|
|
830
|
+
function isFromRef(value) {
|
|
831
|
+
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
const ONCE = Symbol.for("@react-three/fiber.once");
|
|
835
|
+
function once(...args) {
|
|
836
|
+
return { [ONCE]: args.length ? args : true };
|
|
837
|
+
}
|
|
838
|
+
function isOnce(value) {
|
|
839
|
+
return value !== null && typeof value === "object" && ONCE in value;
|
|
840
|
+
}
|
|
841
|
+
|
|
450
842
|
const RESERVED_PROPS = [
|
|
451
843
|
"children",
|
|
452
844
|
"key",
|
|
@@ -517,7 +909,7 @@ function getMemoizedPrototype(root) {
|
|
|
517
909
|
ctor = new root.constructor();
|
|
518
910
|
MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
|
|
519
911
|
}
|
|
520
|
-
} catch
|
|
912
|
+
} catch {
|
|
521
913
|
}
|
|
522
914
|
return ctor;
|
|
523
915
|
}
|
|
@@ -548,7 +940,7 @@ function applyProps(object, props) {
|
|
|
548
940
|
const rootState = instance && findInitialRoot(instance).getState();
|
|
549
941
|
const prevHandlers = instance?.eventCount;
|
|
550
942
|
for (const prop in props) {
|
|
551
|
-
|
|
943
|
+
const value = props[prop];
|
|
552
944
|
if (RESERVED_PROPS.includes(prop)) continue;
|
|
553
945
|
if (instance && EVENT_REGEX.test(prop)) {
|
|
554
946
|
if (typeof value === "function") instance.handlers[prop] = value;
|
|
@@ -563,6 +955,25 @@ function applyProps(object, props) {
|
|
|
563
955
|
continue;
|
|
564
956
|
}
|
|
565
957
|
if (value === void 0) continue;
|
|
958
|
+
if (isFromRef(value)) {
|
|
959
|
+
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
960
|
+
continue;
|
|
961
|
+
}
|
|
962
|
+
if (isOnce(value)) {
|
|
963
|
+
if (instance?.appliedOnce?.has(prop)) continue;
|
|
964
|
+
if (instance) {
|
|
965
|
+
instance.appliedOnce ?? (instance.appliedOnce = /* @__PURE__ */ new Set());
|
|
966
|
+
instance.appliedOnce.add(prop);
|
|
967
|
+
}
|
|
968
|
+
const { root: targetRoot, key: targetKey } = resolve(object, prop);
|
|
969
|
+
const args = value[ONCE];
|
|
970
|
+
if (typeof targetRoot[targetKey] === "function") {
|
|
971
|
+
targetRoot[targetKey](...args === true ? [] : args);
|
|
972
|
+
} else if (args !== true && args.length > 0) {
|
|
973
|
+
targetRoot[targetKey] = args[0];
|
|
974
|
+
}
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
566
977
|
let { root, key, target } = resolve(object, prop);
|
|
567
978
|
if (target === void 0 && (typeof root !== "object" || root === null)) {
|
|
568
979
|
throw Error(`R3F: Cannot set "${prop}". Ensure it is an object before setting "${key}".`);
|
|
@@ -585,7 +996,7 @@ function applyProps(object, props) {
|
|
|
585
996
|
else target.set(value);
|
|
586
997
|
} else {
|
|
587
998
|
root[key] = value;
|
|
588
|
-
if (rootState &&
|
|
999
|
+
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
1000
|
root[key].format === webgpu.RGBAFormat && root[key].type === webgpu.UnsignedByteType) {
|
|
590
1001
|
root[key].colorSpace = rootState.textureColorSpace;
|
|
591
1002
|
}
|
|
@@ -700,13 +1111,14 @@ function createEvents(store) {
|
|
|
700
1111
|
for (const hit of hits) {
|
|
701
1112
|
let eventObject = hit.object;
|
|
702
1113
|
while (eventObject) {
|
|
703
|
-
if (eventObject.__r3f?.eventCount)
|
|
1114
|
+
if (eventObject.__r3f?.eventCount) {
|
|
704
1115
|
intersections.push({ ...hit, eventObject });
|
|
1116
|
+
}
|
|
705
1117
|
eventObject = eventObject.parent;
|
|
706
1118
|
}
|
|
707
1119
|
}
|
|
708
1120
|
if ("pointerId" in event && state.internal.capturedMap.has(event.pointerId)) {
|
|
709
|
-
for (
|
|
1121
|
+
for (const captureData of state.internal.capturedMap.get(event.pointerId).values()) {
|
|
710
1122
|
if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
|
|
711
1123
|
}
|
|
712
1124
|
}
|
|
@@ -736,12 +1148,12 @@ function createEvents(store) {
|
|
|
736
1148
|
releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
|
|
737
1149
|
}
|
|
738
1150
|
};
|
|
739
|
-
|
|
740
|
-
for (
|
|
741
|
-
|
|
1151
|
+
const extractEventProps = {};
|
|
1152
|
+
for (const prop in event) {
|
|
1153
|
+
const property = event[prop];
|
|
742
1154
|
if (typeof property !== "function") extractEventProps[prop] = property;
|
|
743
1155
|
}
|
|
744
|
-
|
|
1156
|
+
const raycastEvent = {
|
|
745
1157
|
...hit,
|
|
746
1158
|
...extractEventProps,
|
|
747
1159
|
pointer,
|
|
@@ -941,7 +1353,7 @@ function createPointerEvents(store) {
|
|
|
941
1353
|
return {
|
|
942
1354
|
priority: 1,
|
|
943
1355
|
enabled: true,
|
|
944
|
-
compute(event, state
|
|
1356
|
+
compute(event, state) {
|
|
945
1357
|
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
946
1358
|
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
947
1359
|
},
|
|
@@ -1039,300 +1451,26 @@ function notifyAlpha({ message, link }) {
|
|
|
1039
1451
|
}
|
|
1040
1452
|
}
|
|
1041
1453
|
|
|
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);
|
|
1454
|
+
var __defProp$1 = Object.defineProperty;
|
|
1455
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1456
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1457
|
+
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1458
|
+
class PhaseGraph {
|
|
1459
|
+
constructor() {
|
|
1460
|
+
/** Ordered list of phase nodes */
|
|
1461
|
+
__publicField$1(this, "phases", []);
|
|
1462
|
+
/** Quick lookup by name */
|
|
1463
|
+
__publicField$1(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1464
|
+
/** Cached ordered names (invalidated on changes) */
|
|
1465
|
+
__publicField$1(this, "orderedNamesCache", null);
|
|
1466
|
+
this.initializeDefaultPhases();
|
|
1467
|
+
}
|
|
1468
|
+
//* Initialization --------------------------------
|
|
1469
|
+
initializeDefaultPhases() {
|
|
1470
|
+
for (const name of DEFAULT_PHASES) {
|
|
1471
|
+
const node = { name, isAutoGenerated: false };
|
|
1472
|
+
this.phases.push(node);
|
|
1473
|
+
this.phaseMap.set(name, node);
|
|
1336
1474
|
}
|
|
1337
1475
|
this.invalidateCache();
|
|
1338
1476
|
}
|
|
@@ -1351,8 +1489,9 @@ class PhaseGraph {
|
|
|
1351
1489
|
const node = { name, isAutoGenerated: false };
|
|
1352
1490
|
let insertIndex = this.phases.length;
|
|
1353
1491
|
const targetIndex = this.getPhaseIndex(before ?? after);
|
|
1354
|
-
if (targetIndex !== -1)
|
|
1355
|
-
|
|
1492
|
+
if (targetIndex !== -1) {
|
|
1493
|
+
insertIndex = before ? targetIndex : targetIndex + 1;
|
|
1494
|
+
} else {
|
|
1356
1495
|
const constraintType = before ? "before" : "after";
|
|
1357
1496
|
console.warn(`[useFrame] Phase "${before ?? after}" not found for '${constraintType}' constraint`);
|
|
1358
1497
|
}
|
|
@@ -2233,116 +2372,429 @@ const _Scheduler = class _Scheduler {
|
|
|
2233
2372
|
root.sortedJobs = rebuildSortedJobs(root.jobs, this.phaseGraph);
|
|
2234
2373
|
root.needsRebuild = false;
|
|
2235
2374
|
}
|
|
2236
|
-
const providedState = root.getState?.() ?? {};
|
|
2237
|
-
const frameState = {
|
|
2238
|
-
...providedState,
|
|
2239
|
-
time: timestamp,
|
|
2240
|
-
delta,
|
|
2241
|
-
elapsed: this.loopState.elapsedTime / 1e3,
|
|
2242
|
-
// Convert ms to seconds
|
|
2243
|
-
frame: this.loopState.frameCount
|
|
2244
|
-
};
|
|
2245
|
-
for (const job of root.sortedJobs) {
|
|
2246
|
-
if (!shouldRun(job, timestamp)) continue;
|
|
2247
|
-
try {
|
|
2248
|
-
job.callback(frameState, delta);
|
|
2249
|
-
} catch (error) {
|
|
2250
|
-
console.error(`[Scheduler] Error in job "${job.id}":`, error);
|
|
2251
|
-
this.triggerError(error instanceof Error ? error : new Error(String(error)));
|
|
2375
|
+
const providedState = root.getState?.() ?? {};
|
|
2376
|
+
const frameState = {
|
|
2377
|
+
...providedState,
|
|
2378
|
+
time: timestamp,
|
|
2379
|
+
delta,
|
|
2380
|
+
elapsed: this.loopState.elapsedTime / 1e3,
|
|
2381
|
+
// Convert ms to seconds
|
|
2382
|
+
frame: this.loopState.frameCount
|
|
2383
|
+
};
|
|
2384
|
+
for (const job of root.sortedJobs) {
|
|
2385
|
+
if (!shouldRun(job, timestamp)) continue;
|
|
2386
|
+
try {
|
|
2387
|
+
job.callback(frameState, delta);
|
|
2388
|
+
} catch (error) {
|
|
2389
|
+
console.error(`[Scheduler] Error in job "${job.id}":`, error);
|
|
2390
|
+
this.triggerError(error instanceof Error ? error : new Error(String(error)));
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
//* Debug & Inspection Methods ================================
|
|
2395
|
+
/**
|
|
2396
|
+
* Get the total number of registered jobs across all roots.
|
|
2397
|
+
* Includes both per-root jobs and global before/after jobs.
|
|
2398
|
+
* @returns {number} Total job count
|
|
2399
|
+
*/
|
|
2400
|
+
getJobCount() {
|
|
2401
|
+
let count = 0;
|
|
2402
|
+
for (const root of this.roots.values()) {
|
|
2403
|
+
count += root.jobs.size;
|
|
2404
|
+
}
|
|
2405
|
+
return count + this.globalBeforeJobs.size + this.globalAfterJobs.size;
|
|
2406
|
+
}
|
|
2407
|
+
/**
|
|
2408
|
+
* Get all registered job IDs across all roots.
|
|
2409
|
+
* Includes both per-root jobs and global before/after jobs.
|
|
2410
|
+
* @returns {string[]} Array of all job IDs
|
|
2411
|
+
*/
|
|
2412
|
+
getJobIds() {
|
|
2413
|
+
const ids = [];
|
|
2414
|
+
for (const root of this.roots.values()) {
|
|
2415
|
+
ids.push(...root.jobs.keys());
|
|
2416
|
+
}
|
|
2417
|
+
ids.push(...this.globalBeforeJobs.keys());
|
|
2418
|
+
ids.push(...this.globalAfterJobs.keys());
|
|
2419
|
+
return ids;
|
|
2420
|
+
}
|
|
2421
|
+
/**
|
|
2422
|
+
* Get the number of registered roots (Canvas instances).
|
|
2423
|
+
* @returns {number} Number of registered roots
|
|
2424
|
+
*/
|
|
2425
|
+
getRootCount() {
|
|
2426
|
+
return this.roots.size;
|
|
2427
|
+
}
|
|
2428
|
+
/**
|
|
2429
|
+
* Check if any user (non-system) jobs are registered in a specific phase.
|
|
2430
|
+
* Used by the default render job to know if a user has taken over rendering.
|
|
2431
|
+
*
|
|
2432
|
+
* @param phase The phase to check
|
|
2433
|
+
* @param rootId Optional root ID to check (checks all roots if not provided)
|
|
2434
|
+
* @returns true if any user jobs exist in the phase
|
|
2435
|
+
*/
|
|
2436
|
+
hasUserJobsInPhase(phase, rootId) {
|
|
2437
|
+
const rootsToCheck = rootId ? [this.roots.get(rootId)].filter(Boolean) : Array.from(this.roots.values());
|
|
2438
|
+
return rootsToCheck.some((root) => {
|
|
2439
|
+
if (!root) return false;
|
|
2440
|
+
for (const job of root.jobs.values()) {
|
|
2441
|
+
if (job.phase === phase && !job.system && job.enabled) return true;
|
|
2442
|
+
}
|
|
2443
|
+
return false;
|
|
2444
|
+
});
|
|
2445
|
+
}
|
|
2446
|
+
//* Utility Methods ================================
|
|
2447
|
+
/**
|
|
2448
|
+
* Generate a unique root ID for automatic root registration.
|
|
2449
|
+
* @returns {string} A unique root ID in the format 'root_N'
|
|
2450
|
+
*/
|
|
2451
|
+
generateRootId() {
|
|
2452
|
+
return `root_${this.nextRootIndex++}`;
|
|
2453
|
+
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Generate a unique job ID.
|
|
2456
|
+
* @returns {string} A unique job ID in the format 'job_N'
|
|
2457
|
+
* @private
|
|
2458
|
+
*/
|
|
2459
|
+
generateJobId() {
|
|
2460
|
+
return `job_${this.nextJobIndex}`;
|
|
2461
|
+
}
|
|
2462
|
+
/**
|
|
2463
|
+
* Normalize before/after constraints to a Set.
|
|
2464
|
+
* Handles undefined, single string, or array inputs.
|
|
2465
|
+
* @param {string | string[] | undefined} value - The constraint value(s)
|
|
2466
|
+
* @returns {Set<string>} Normalized Set of constraint strings
|
|
2467
|
+
* @private
|
|
2468
|
+
*/
|
|
2469
|
+
normalizeConstraints(value) {
|
|
2470
|
+
if (!value) return /* @__PURE__ */ new Set();
|
|
2471
|
+
if (Array.isArray(value)) return new Set(value);
|
|
2472
|
+
return /* @__PURE__ */ new Set([value]);
|
|
2473
|
+
}
|
|
2474
|
+
};
|
|
2475
|
+
//* Static State & Methods (Singleton Usage) ================================
|
|
2476
|
+
//* Cross-Bundle Singleton Key ==============================
|
|
2477
|
+
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2478
|
+
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2479
|
+
__publicField(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2480
|
+
let Scheduler = _Scheduler;
|
|
2481
|
+
const getScheduler = () => Scheduler.get();
|
|
2482
|
+
if (hmrData) {
|
|
2483
|
+
hmrData.accept?.();
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2486
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
2487
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React__namespace.createContext(null));
|
|
2488
|
+
const createStore = (invalidate, advance) => {
|
|
2489
|
+
const rootStore = traditional.createWithEqualityFn((set, get) => {
|
|
2490
|
+
const position = new webgpu.Vector3();
|
|
2491
|
+
const defaultTarget = new webgpu.Vector3();
|
|
2492
|
+
const tempTarget = new webgpu.Vector3();
|
|
2493
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
2494
|
+
const { width, height, top, left } = size;
|
|
2495
|
+
const aspect = width / height;
|
|
2496
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
2497
|
+
else tempTarget.set(...target);
|
|
2498
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
2499
|
+
if (isOrthographicCamera(camera)) {
|
|
2500
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
2501
|
+
} else {
|
|
2502
|
+
const fov = camera.fov * Math.PI / 180;
|
|
2503
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
2504
|
+
const w = h * (width / height);
|
|
2505
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
let performanceTimeout = void 0;
|
|
2509
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
2510
|
+
const pointer = new webgpu.Vector2();
|
|
2511
|
+
const rootState = {
|
|
2512
|
+
set,
|
|
2513
|
+
get,
|
|
2514
|
+
// Mock objects that have to be configured
|
|
2515
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
2516
|
+
primaryStore: null,
|
|
2517
|
+
gl: null,
|
|
2518
|
+
renderer: null,
|
|
2519
|
+
camera: null,
|
|
2520
|
+
frustum: new webgpu.Frustum(),
|
|
2521
|
+
autoUpdateFrustum: true,
|
|
2522
|
+
raycaster: null,
|
|
2523
|
+
events: { priority: 1, enabled: true, connected: false },
|
|
2524
|
+
scene: null,
|
|
2525
|
+
rootScene: null,
|
|
2526
|
+
xr: null,
|
|
2527
|
+
inspector: null,
|
|
2528
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
2529
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
2530
|
+
textureColorSpace: webgpu.SRGBColorSpace,
|
|
2531
|
+
isLegacy: false,
|
|
2532
|
+
webGPUSupported: false,
|
|
2533
|
+
isNative: false,
|
|
2534
|
+
controls: null,
|
|
2535
|
+
pointer,
|
|
2536
|
+
mouse: pointer,
|
|
2537
|
+
frameloop: "always",
|
|
2538
|
+
onPointerMissed: void 0,
|
|
2539
|
+
onDragOverMissed: void 0,
|
|
2540
|
+
onDropMissed: void 0,
|
|
2541
|
+
performance: {
|
|
2542
|
+
current: 1,
|
|
2543
|
+
min: 0.5,
|
|
2544
|
+
max: 1,
|
|
2545
|
+
debounce: 200,
|
|
2546
|
+
regress: () => {
|
|
2547
|
+
const state2 = get();
|
|
2548
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
2549
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
2550
|
+
performanceTimeout = setTimeout(
|
|
2551
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
2552
|
+
state2.performance.debounce
|
|
2553
|
+
);
|
|
2554
|
+
}
|
|
2555
|
+
},
|
|
2556
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
2557
|
+
viewport: {
|
|
2558
|
+
initialDpr: 0,
|
|
2559
|
+
dpr: 0,
|
|
2560
|
+
width: 0,
|
|
2561
|
+
height: 0,
|
|
2562
|
+
top: 0,
|
|
2563
|
+
left: 0,
|
|
2564
|
+
aspect: 0,
|
|
2565
|
+
distance: 0,
|
|
2566
|
+
factor: 0,
|
|
2567
|
+
getCurrentViewport
|
|
2568
|
+
},
|
|
2569
|
+
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
2570
|
+
setSize: (width, height, top, left) => {
|
|
2571
|
+
const state2 = get();
|
|
2572
|
+
if (width === void 0) {
|
|
2573
|
+
set({ _sizeImperative: false });
|
|
2574
|
+
if (state2._sizeProps) {
|
|
2575
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
2576
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
2577
|
+
const currentSize = state2.size;
|
|
2578
|
+
const newSize = {
|
|
2579
|
+
width: propW ?? currentSize.width,
|
|
2580
|
+
height: propH ?? currentSize.height,
|
|
2581
|
+
top: currentSize.top,
|
|
2582
|
+
left: currentSize.left
|
|
2583
|
+
};
|
|
2584
|
+
set((s) => ({
|
|
2585
|
+
size: newSize,
|
|
2586
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
2587
|
+
}));
|
|
2588
|
+
getScheduler().invalidate();
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
return;
|
|
2592
|
+
}
|
|
2593
|
+
const w = width;
|
|
2594
|
+
const h = height ?? width;
|
|
2595
|
+
const t = top ?? state2.size.top;
|
|
2596
|
+
const l = left ?? state2.size.left;
|
|
2597
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
2598
|
+
set((s) => ({
|
|
2599
|
+
size,
|
|
2600
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
2601
|
+
_sizeImperative: true
|
|
2602
|
+
}));
|
|
2603
|
+
getScheduler().invalidate();
|
|
2604
|
+
},
|
|
2605
|
+
setDpr: (dpr) => set((state2) => {
|
|
2606
|
+
const resolved = calculateDpr(dpr);
|
|
2607
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
2608
|
+
}),
|
|
2609
|
+
setFrameloop: (frameloop = "always") => {
|
|
2610
|
+
set(() => ({ frameloop }));
|
|
2611
|
+
},
|
|
2612
|
+
setError: (error) => set(() => ({ error })),
|
|
2613
|
+
error: null,
|
|
2614
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useTextures, usePostProcessing) ==============================
|
|
2615
|
+
uniforms: {},
|
|
2616
|
+
nodes: {},
|
|
2617
|
+
textures: /* @__PURE__ */ new Map(),
|
|
2618
|
+
postProcessing: null,
|
|
2619
|
+
passes: {},
|
|
2620
|
+
_hmrVersion: 0,
|
|
2621
|
+
_sizeImperative: false,
|
|
2622
|
+
_sizeProps: null,
|
|
2623
|
+
previousRoot: void 0,
|
|
2624
|
+
internal: {
|
|
2625
|
+
// Events
|
|
2626
|
+
interaction: [],
|
|
2627
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
2628
|
+
subscribers: [],
|
|
2629
|
+
initialClick: [0, 0],
|
|
2630
|
+
initialHits: [],
|
|
2631
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
2632
|
+
lastEvent: React__namespace.createRef(),
|
|
2633
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
2634
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
2635
|
+
// Occlusion system (WebGPU only)
|
|
2636
|
+
occlusionEnabled: false,
|
|
2637
|
+
occlusionObserver: null,
|
|
2638
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
2639
|
+
helperGroup: null,
|
|
2640
|
+
// Updates
|
|
2641
|
+
active: false,
|
|
2642
|
+
frames: 0,
|
|
2643
|
+
priority: 0,
|
|
2644
|
+
subscribe: (ref, priority, store) => {
|
|
2645
|
+
const internal = get().internal;
|
|
2646
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
2647
|
+
internal.subscribers.push({ ref, priority, store });
|
|
2648
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
2649
|
+
return () => {
|
|
2650
|
+
const internal2 = get().internal;
|
|
2651
|
+
if (internal2?.subscribers) {
|
|
2652
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
2653
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
2654
|
+
}
|
|
2655
|
+
};
|
|
2656
|
+
},
|
|
2657
|
+
// Renderer Storage (single source of truth)
|
|
2658
|
+
actualRenderer: null,
|
|
2659
|
+
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
2660
|
+
scheduler: null
|
|
2661
|
+
}
|
|
2662
|
+
};
|
|
2663
|
+
return rootState;
|
|
2664
|
+
});
|
|
2665
|
+
const state = rootStore.getState();
|
|
2666
|
+
Object.defineProperty(state, "gl", {
|
|
2667
|
+
get() {
|
|
2668
|
+
const currentState = rootStore.getState();
|
|
2669
|
+
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
2670
|
+
const stack = new Error().stack || "";
|
|
2671
|
+
const isInternalAccess = stack.includes("zustand") || stack.includes("setState") || stack.includes("Object.assign") || stack.includes("react-three-fiber/packages/fiber/src/core");
|
|
2672
|
+
if (!isInternalAccess) {
|
|
2673
|
+
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
2674
|
+
notifyDepreciated({
|
|
2675
|
+
heading: "Accessing state.gl in WebGPU mode",
|
|
2676
|
+
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
|
|
2677
|
+
});
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
return currentState.internal.actualRenderer;
|
|
2681
|
+
},
|
|
2682
|
+
set(value) {
|
|
2683
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2684
|
+
},
|
|
2685
|
+
enumerable: true,
|
|
2686
|
+
configurable: true
|
|
2687
|
+
});
|
|
2688
|
+
Object.defineProperty(state, "renderer", {
|
|
2689
|
+
get() {
|
|
2690
|
+
return rootStore.getState().internal.actualRenderer;
|
|
2691
|
+
},
|
|
2692
|
+
set(value) {
|
|
2693
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
2694
|
+
},
|
|
2695
|
+
enumerable: true,
|
|
2696
|
+
configurable: true
|
|
2697
|
+
});
|
|
2698
|
+
let oldScene = state.scene;
|
|
2699
|
+
rootStore.subscribe(() => {
|
|
2700
|
+
const currentState = rootStore.getState();
|
|
2701
|
+
const { scene, rootScene, set } = currentState;
|
|
2702
|
+
if (scene !== oldScene) {
|
|
2703
|
+
oldScene = scene;
|
|
2704
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
2705
|
+
set({ rootScene: scene });
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
});
|
|
2709
|
+
let oldSize = state.size;
|
|
2710
|
+
let oldDpr = state.viewport.dpr;
|
|
2711
|
+
let oldCamera = state.camera;
|
|
2712
|
+
rootStore.subscribe(() => {
|
|
2713
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
2714
|
+
const actualRenderer = internal.actualRenderer;
|
|
2715
|
+
const canvasTarget = internal.canvasTarget;
|
|
2716
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
2717
|
+
oldSize = size;
|
|
2718
|
+
oldDpr = viewport.dpr;
|
|
2719
|
+
updateCamera(camera, size);
|
|
2720
|
+
if (canvasTarget) {
|
|
2721
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
2722
|
+
const updateStyle = typeof HTMLCanvasElement !== "undefined" && canvasTarget.domElement instanceof HTMLCanvasElement;
|
|
2723
|
+
canvasTarget.setSize(size.width, size.height, updateStyle);
|
|
2724
|
+
} else {
|
|
2725
|
+
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
2726
|
+
const updateStyle = typeof HTMLCanvasElement !== "undefined" && actualRenderer.domElement instanceof HTMLCanvasElement;
|
|
2727
|
+
actualRenderer.setSize(size.width, size.height, updateStyle);
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
if (camera !== oldCamera) {
|
|
2731
|
+
oldCamera = camera;
|
|
2732
|
+
const { rootScene } = rootStore.getState();
|
|
2733
|
+
if (camera && rootScene && !camera.parent) {
|
|
2734
|
+
rootScene.add(camera);
|
|
2735
|
+
}
|
|
2736
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
2737
|
+
const currentState = rootStore.getState();
|
|
2738
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
2739
|
+
updateFrustum(camera, currentState.frustum);
|
|
2252
2740
|
}
|
|
2253
2741
|
}
|
|
2254
|
-
}
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2742
|
+
});
|
|
2743
|
+
rootStore.subscribe((state2) => invalidate(state2));
|
|
2744
|
+
return rootStore;
|
|
2745
|
+
};
|
|
2746
|
+
|
|
2747
|
+
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
2748
|
+
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
2749
|
+
function getLoader(Proto) {
|
|
2750
|
+
if (isConstructor$1(Proto)) {
|
|
2751
|
+
let loader = memoizedLoaders.get(Proto);
|
|
2752
|
+
if (!loader) {
|
|
2753
|
+
loader = new Proto();
|
|
2754
|
+
memoizedLoaders.set(Proto, loader);
|
|
2265
2755
|
}
|
|
2266
|
-
return
|
|
2756
|
+
return loader;
|
|
2267
2757
|
}
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2758
|
+
return Proto;
|
|
2759
|
+
}
|
|
2760
|
+
function loadingFn(extensions, onProgress) {
|
|
2761
|
+
return function(Proto, input) {
|
|
2762
|
+
const loader = getLoader(Proto);
|
|
2763
|
+
if (extensions) extensions(loader);
|
|
2764
|
+
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
2765
|
+
return loader.loadAsync(input, onProgress).then((data) => {
|
|
2766
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2767
|
+
return data;
|
|
2768
|
+
});
|
|
2277
2769
|
}
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
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]);
|
|
2334
|
-
}
|
|
2335
|
-
};
|
|
2336
|
-
//* Static State & Methods (Singleton Usage) ================================
|
|
2337
|
-
//* Cross-Bundle Singleton Key ==============================
|
|
2338
|
-
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2339
|
-
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2340
|
-
__publicField(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2341
|
-
let Scheduler = _Scheduler;
|
|
2342
|
-
const getScheduler = () => Scheduler.get();
|
|
2343
|
-
if (hmrData) {
|
|
2344
|
-
hmrData.accept?.();
|
|
2770
|
+
return new Promise(
|
|
2771
|
+
(res, reject) => loader.load(
|
|
2772
|
+
input,
|
|
2773
|
+
(data) => {
|
|
2774
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
2775
|
+
res(data);
|
|
2776
|
+
},
|
|
2777
|
+
onProgress,
|
|
2778
|
+
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
2779
|
+
)
|
|
2780
|
+
);
|
|
2781
|
+
};
|
|
2782
|
+
}
|
|
2783
|
+
function useLoader(loader, input, extensions, onProgress) {
|
|
2784
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2785
|
+
const fn = loadingFn(extensions, onProgress);
|
|
2786
|
+
const results = keys.map((key) => suspendReact.suspend(fn, [loader, key], { equal: is.equ }));
|
|
2787
|
+
return Array.isArray(input) ? results : results[0];
|
|
2345
2788
|
}
|
|
2789
|
+
useLoader.preload = function(loader, input, extensions, onProgress) {
|
|
2790
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2791
|
+
keys.forEach((key) => suspendReact.preload(loadingFn(extensions, onProgress), [loader, key]));
|
|
2792
|
+
};
|
|
2793
|
+
useLoader.clear = function(loader, input) {
|
|
2794
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
2795
|
+
keys.forEach((key) => suspendReact.clear([loader, key]));
|
|
2796
|
+
};
|
|
2797
|
+
useLoader.loader = getLoader;
|
|
2346
2798
|
|
|
2347
2799
|
function useFrame(callback, priorityOrOptions) {
|
|
2348
2800
|
const store = React__namespace.useContext(context);
|
|
@@ -2523,6 +2975,9 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2523
2975
|
const textureCache = useThree((state) => state.textures);
|
|
2524
2976
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
2525
2977
|
const { onLoad, cache = false } = options;
|
|
2978
|
+
const onLoadRef = React.useRef(onLoad);
|
|
2979
|
+
onLoadRef.current = onLoad;
|
|
2980
|
+
const onLoadCalledForRef = React.useRef(null);
|
|
2526
2981
|
const urls = React.useMemo(() => getUrls(input), [input]);
|
|
2527
2982
|
const cachedResult = React.useMemo(() => {
|
|
2528
2983
|
if (!cache) return null;
|
|
@@ -2533,9 +2988,13 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
2533
2988
|
webgpu.TextureLoader,
|
|
2534
2989
|
IsObject(input) ? Object.values(input) : input
|
|
2535
2990
|
);
|
|
2991
|
+
const inputKey = urls.join("\0");
|
|
2536
2992
|
React.useLayoutEffect(() => {
|
|
2537
|
-
if (
|
|
2538
|
-
|
|
2993
|
+
if (cachedResult) return;
|
|
2994
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
2995
|
+
onLoadCalledForRef.current = inputKey;
|
|
2996
|
+
onLoadRef.current?.(loadedTextures);
|
|
2997
|
+
}, [cachedResult, loadedTextures, inputKey]);
|
|
2539
2998
|
React.useEffect(() => {
|
|
2540
2999
|
if (cachedResult) return;
|
|
2541
3000
|
if ("initTexture" in renderer) {
|
|
@@ -2702,16 +3161,33 @@ function useTextures() {
|
|
|
2702
3161
|
}, [store]);
|
|
2703
3162
|
}
|
|
2704
3163
|
|
|
2705
|
-
function useRenderTarget(
|
|
3164
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
2706
3165
|
const isLegacy = useThree((s) => s.isLegacy);
|
|
2707
3166
|
const size = useThree((s) => s.size);
|
|
3167
|
+
let width;
|
|
3168
|
+
let height;
|
|
3169
|
+
let opts;
|
|
3170
|
+
if (typeof widthOrOptions === "object") {
|
|
3171
|
+
opts = widthOrOptions;
|
|
3172
|
+
} else if (typeof widthOrOptions === "number") {
|
|
3173
|
+
width = widthOrOptions;
|
|
3174
|
+
if (typeof heightOrOptions === "object") {
|
|
3175
|
+
height = widthOrOptions;
|
|
3176
|
+
opts = heightOrOptions;
|
|
3177
|
+
} else if (typeof heightOrOptions === "number") {
|
|
3178
|
+
height = heightOrOptions;
|
|
3179
|
+
opts = options;
|
|
3180
|
+
} else {
|
|
3181
|
+
height = widthOrOptions;
|
|
3182
|
+
}
|
|
3183
|
+
}
|
|
2708
3184
|
return React.useMemo(() => {
|
|
2709
3185
|
const w = width ?? size.width;
|
|
2710
3186
|
const h = height ?? size.height;
|
|
2711
3187
|
{
|
|
2712
|
-
return isLegacy ? new three.WebGLRenderTarget(w, h,
|
|
3188
|
+
return isLegacy ? new three.WebGLRenderTarget(w, h, opts) : new webgpu.RenderTarget(w, h, opts);
|
|
2713
3189
|
}
|
|
2714
|
-
}, [width, height, size.width, size.height,
|
|
3190
|
+
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
2715
3191
|
}
|
|
2716
3192
|
|
|
2717
3193
|
function useStore() {
|
|
@@ -2761,28 +3237,18 @@ function addTail(callback) {
|
|
|
2761
3237
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
2762
3238
|
getScheduler().invalidate(frames, stackFrames);
|
|
2763
3239
|
}
|
|
2764
|
-
function advance(timestamp
|
|
3240
|
+
function advance(timestamp) {
|
|
2765
3241
|
getScheduler().step(timestamp);
|
|
2766
3242
|
}
|
|
2767
3243
|
|
|
2768
|
-
const version = "10.0.0-alpha.
|
|
3244
|
+
const version = "10.0.0-alpha.2";
|
|
2769
3245
|
const packageData = {
|
|
2770
3246
|
version: version};
|
|
2771
3247
|
|
|
2772
3248
|
function Xb(Tt) {
|
|
2773
3249
|
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
2774
3250
|
}
|
|
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;
|
|
3251
|
+
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
2786
3252
|
function Kb() {
|
|
2787
3253
|
return _b || (_b = 1, (function(Tt) {
|
|
2788
3254
|
Tt.exports = function(m) {
|
|
@@ -3854,7 +4320,6 @@ Error generating stack: ` + l.message + `
|
|
|
3854
4320
|
if (J === cl || J === jc) throw J;
|
|
3855
4321
|
var Ge = Yn(29, J, null, P.mode);
|
|
3856
4322
|
return Ge.lanes = H, Ge.return = P, Ge;
|
|
3857
|
-
} finally {
|
|
3858
4323
|
}
|
|
3859
4324
|
};
|
|
3860
4325
|
}
|
|
@@ -4508,7 +4973,6 @@ Error generating stack: ` + l.message + `
|
|
|
4508
4973
|
var h = r.lastRenderedState, y = d(h, a);
|
|
4509
4974
|
if (c.hasEagerState = true, c.eagerState = y, jn(y, h)) return go(t, r, c, 0), Ne === null && Bn(), false;
|
|
4510
4975
|
} catch {
|
|
4511
|
-
} finally {
|
|
4512
4976
|
}
|
|
4513
4977
|
if (a = yo(t, r, c, l), a !== null) return nt(a, t, l), ns(a, r, l), true;
|
|
4514
4978
|
}
|
|
@@ -6929,10 +7393,7 @@ Error generating stack: ` + l.message + `
|
|
|
6929
7393
|
function vr(t, r) {
|
|
6930
7394
|
Sf(t, r), (t = t.alternate) && Sf(t, r);
|
|
6931
7395
|
}
|
|
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;
|
|
7396
|
+
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
7397
|
m.cloneMutableInstance;
|
|
6937
7398
|
var yc = m.appendInitialChild, Kp = m.finalizeInitialChildren, Rs = m.shouldSetTextContent, bc = m.createTextInstance;
|
|
6938
7399
|
m.cloneMutableTextInstance;
|
|
@@ -7301,17 +7762,7 @@ No matching component was found for:
|
|
|
7301
7762
|
}, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true });
|
|
7302
7763
|
})(Og)), Og.exports;
|
|
7303
7764
|
}
|
|
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;
|
|
7765
|
+
var Mg = { exports: {} }, Rb;
|
|
7315
7766
|
function e0() {
|
|
7316
7767
|
return Rb || (Rb = 1, (function(Tt) {
|
|
7317
7768
|
process.env.NODE_ENV !== "production" && (Tt.exports = function(m) {
|
|
@@ -13078,10 +13529,7 @@ Check the render method of %s.`, G(di) || "Unknown")), i = zo(n), i.payload = {
|
|
|
13078
13529
|
function Ic() {
|
|
13079
13530
|
return di;
|
|
13080
13531
|
}
|
|
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;
|
|
13532
|
+
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
13533
|
m.cloneMutableInstance;
|
|
13086
13534
|
var bn = m.appendInitialChild, Ue = m.finalizeInitialChildren, ue = m.shouldSetTextContent, Do = m.createTextInstance;
|
|
13087
13535
|
m.cloneMutableTextInstance;
|
|
@@ -14049,15 +14497,6 @@ function n0() {
|
|
|
14049
14497
|
var t0 = n0();
|
|
14050
14498
|
const r0 = Xb(t0);
|
|
14051
14499
|
|
|
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
14500
|
const t = 1, o = 8, r = 32, e = 2;
|
|
14062
14501
|
|
|
14063
14502
|
function createReconciler(config) {
|
|
@@ -14084,10 +14523,11 @@ function extend(objects) {
|
|
|
14084
14523
|
function validateInstance(type, props) {
|
|
14085
14524
|
const name = toPascalCase(type);
|
|
14086
14525
|
const target = catalogue[name];
|
|
14087
|
-
if (type !== "primitive" && !target)
|
|
14526
|
+
if (type !== "primitive" && !target) {
|
|
14088
14527
|
throw new Error(
|
|
14089
14528
|
`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
14529
|
);
|
|
14530
|
+
}
|
|
14091
14531
|
if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
|
|
14092
14532
|
if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
|
|
14093
14533
|
}
|
|
@@ -14251,6 +14691,7 @@ function swapInstances() {
|
|
|
14251
14691
|
instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
|
|
14252
14692
|
instance.object.__r3f = instance;
|
|
14253
14693
|
setFiberRef(fiber, instance.object);
|
|
14694
|
+
delete instance.appliedOnce;
|
|
14254
14695
|
applyProps(instance.object, instance.props);
|
|
14255
14696
|
if (instance.props.attach) {
|
|
14256
14697
|
attach(parent, instance);
|
|
@@ -14324,8 +14765,22 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14324
14765
|
const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
|
|
14325
14766
|
if (isTailSibling) swapInstances();
|
|
14326
14767
|
},
|
|
14327
|
-
finalizeInitialChildren: () =>
|
|
14328
|
-
|
|
14768
|
+
finalizeInitialChildren: (instance) => {
|
|
14769
|
+
for (const prop in instance.props) {
|
|
14770
|
+
if (isFromRef(instance.props[prop])) return true;
|
|
14771
|
+
}
|
|
14772
|
+
return false;
|
|
14773
|
+
},
|
|
14774
|
+
commitMount(instance) {
|
|
14775
|
+
const resolved = {};
|
|
14776
|
+
for (const prop in instance.props) {
|
|
14777
|
+
const value = instance.props[prop];
|
|
14778
|
+
if (isFromRef(value)) {
|
|
14779
|
+
const ref = value[FROM_REF];
|
|
14780
|
+
if (ref.current != null) resolved[prop] = ref.current;
|
|
14781
|
+
}
|
|
14782
|
+
}
|
|
14783
|
+
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
14329
14784
|
},
|
|
14330
14785
|
getPublicInstance: (instance) => instance?.object,
|
|
14331
14786
|
prepareForCommit: () => null,
|
|
@@ -14538,14 +14993,17 @@ function createRoot(canvas) {
|
|
|
14538
14993
|
if (!prevRoot) _roots.set(canvas, { fiber, store });
|
|
14539
14994
|
let onCreated;
|
|
14540
14995
|
let lastCamera;
|
|
14541
|
-
|
|
14996
|
+
const lastConfiguredProps = {};
|
|
14542
14997
|
let configured = false;
|
|
14543
14998
|
let pending = null;
|
|
14544
14999
|
return {
|
|
14545
15000
|
async configure(props = {}) {
|
|
14546
15001
|
let resolve;
|
|
14547
15002
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14548
|
-
|
|
15003
|
+
const {
|
|
15004
|
+
id: canvasId,
|
|
15005
|
+
primaryCanvas,
|
|
15006
|
+
scheduler: schedulerConfig,
|
|
14549
15007
|
gl: glConfig,
|
|
14550
15008
|
renderer: rendererConfig,
|
|
14551
15009
|
size: propsSize,
|
|
@@ -14553,10 +15011,7 @@ function createRoot(canvas) {
|
|
|
14553
15011
|
events,
|
|
14554
15012
|
onCreated: onCreatedCallback,
|
|
14555
15013
|
shadows = false,
|
|
14556
|
-
linear = false,
|
|
14557
|
-
flat = false,
|
|
14558
15014
|
textureColorSpace = webgpu.SRGBColorSpace,
|
|
14559
|
-
legacy = false,
|
|
14560
15015
|
orthographic = false,
|
|
14561
15016
|
frameloop = "always",
|
|
14562
15017
|
dpr = [1, 2],
|
|
@@ -14567,9 +15022,11 @@ function createRoot(canvas) {
|
|
|
14567
15022
|
onDragOverMissed,
|
|
14568
15023
|
onDropMissed,
|
|
14569
15024
|
autoUpdateFrustum = true,
|
|
14570
|
-
occlusion = false
|
|
15025
|
+
occlusion = false,
|
|
15026
|
+
_sizeProps,
|
|
15027
|
+
forceEven
|
|
14571
15028
|
} = props;
|
|
14572
|
-
|
|
15029
|
+
const state = store.getState();
|
|
14573
15030
|
const defaultGLProps = {
|
|
14574
15031
|
canvas,
|
|
14575
15032
|
powerPreference: "high-performance",
|
|
@@ -14577,7 +15034,8 @@ function createRoot(canvas) {
|
|
|
14577
15034
|
alpha: true
|
|
14578
15035
|
};
|
|
14579
15036
|
const defaultGPUProps = {
|
|
14580
|
-
canvas
|
|
15037
|
+
canvas,
|
|
15038
|
+
antialias: true
|
|
14581
15039
|
};
|
|
14582
15040
|
const wantsGL = (state.isLegacy || glConfig || !R3F_BUILD_WEBGPU || !rendererConfig);
|
|
14583
15041
|
if (glConfig && rendererConfig) {
|
|
@@ -14591,10 +15049,35 @@ function createRoot(canvas) {
|
|
|
14591
15049
|
});
|
|
14592
15050
|
}
|
|
14593
15051
|
let renderer = state.internal.actualRenderer;
|
|
15052
|
+
if (primaryCanvas && wantsGL) {
|
|
15053
|
+
throw new Error(
|
|
15054
|
+
"The `primaryCanvas` prop for multi-canvas rendering cannot be used with WebGL. Remove the `gl` prop or use WebGPU."
|
|
15055
|
+
);
|
|
15056
|
+
}
|
|
14594
15057
|
if (wantsGL && !state.internal.actualRenderer) {
|
|
14595
15058
|
renderer = await resolveRenderer(glConfig, defaultGLProps, three.WebGLRenderer);
|
|
14596
15059
|
state.internal.actualRenderer = renderer;
|
|
14597
|
-
state.set({ isLegacy: true, gl: renderer, renderer });
|
|
15060
|
+
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
15061
|
+
} else if (!wantsGL && primaryCanvas && !state.internal.actualRenderer) {
|
|
15062
|
+
const primary = await waitForPrimary(primaryCanvas);
|
|
15063
|
+
renderer = primary.renderer;
|
|
15064
|
+
state.internal.actualRenderer = renderer;
|
|
15065
|
+
const canvasTarget = new webgpu.CanvasTarget(canvas);
|
|
15066
|
+
primary.store.setState((prev) => ({
|
|
15067
|
+
internal: { ...prev.internal, isMultiCanvas: true }
|
|
15068
|
+
}));
|
|
15069
|
+
state.set((prev) => ({
|
|
15070
|
+
webGPUSupported: primary.store.getState().webGPUSupported,
|
|
15071
|
+
renderer,
|
|
15072
|
+
primaryStore: primary.store,
|
|
15073
|
+
internal: {
|
|
15074
|
+
...prev.internal,
|
|
15075
|
+
canvasTarget,
|
|
15076
|
+
isMultiCanvas: true,
|
|
15077
|
+
isSecondary: true,
|
|
15078
|
+
targetId: primaryCanvas
|
|
15079
|
+
}
|
|
15080
|
+
}));
|
|
14598
15081
|
} else if (!wantsGL && !state.internal.actualRenderer) {
|
|
14599
15082
|
renderer = await resolveRenderer(rendererConfig, defaultGPUProps, webgpu.WebGPURenderer);
|
|
14600
15083
|
if (!renderer.hasInitialized?.()) {
|
|
@@ -14603,14 +15086,27 @@ function createRoot(canvas) {
|
|
|
14603
15086
|
const backend = renderer.backend;
|
|
14604
15087
|
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
14605
15088
|
state.internal.actualRenderer = renderer;
|
|
14606
|
-
state.set({ webGPUSupported: isWebGPUBackend, renderer });
|
|
15089
|
+
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
15090
|
+
if (canvasId && !state.internal.isSecondary) {
|
|
15091
|
+
const canvasTarget = new webgpu.CanvasTarget(canvas);
|
|
15092
|
+
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
15093
|
+
state.set((prev) => ({
|
|
15094
|
+
internal: {
|
|
15095
|
+
...prev.internal,
|
|
15096
|
+
canvasTarget,
|
|
15097
|
+
unregisterPrimary
|
|
15098
|
+
}
|
|
15099
|
+
}));
|
|
15100
|
+
}
|
|
14607
15101
|
}
|
|
14608
15102
|
let raycaster = state.raycaster;
|
|
14609
15103
|
if (!raycaster) state.set({ raycaster: raycaster = new webgpu.Raycaster() });
|
|
14610
15104
|
const { params, ...options } = raycastOptions || {};
|
|
14611
15105
|
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options });
|
|
14612
|
-
if (!is.equ(params, raycaster.params, shallowLoose))
|
|
15106
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) {
|
|
14613
15107
|
applyProps(raycaster, { params: { ...raycaster.params, ...params } });
|
|
15108
|
+
}
|
|
15109
|
+
let tempCamera = state.camera;
|
|
14614
15110
|
if (!state.camera || state.camera === lastCamera && !is.equ(lastCamera, cameraOptions, shallowLoose)) {
|
|
14615
15111
|
lastCamera = cameraOptions;
|
|
14616
15112
|
const isCamera = cameraOptions?.isCamera;
|
|
@@ -14630,6 +15126,7 @@ function createRoot(canvas) {
|
|
|
14630
15126
|
if (!state.camera && !cameraOptions?.rotation) camera.lookAt(0, 0, 0);
|
|
14631
15127
|
}
|
|
14632
15128
|
state.set({ camera });
|
|
15129
|
+
tempCamera = camera;
|
|
14633
15130
|
raycaster.camera = camera;
|
|
14634
15131
|
}
|
|
14635
15132
|
if (!state.scene) {
|
|
@@ -14647,7 +15144,7 @@ function createRoot(canvas) {
|
|
|
14647
15144
|
rootScene: scene,
|
|
14648
15145
|
internal: { ...prev.internal, container: scene }
|
|
14649
15146
|
}));
|
|
14650
|
-
const camera =
|
|
15147
|
+
const camera = tempCamera;
|
|
14651
15148
|
if (camera && !camera.parent) scene.add(camera);
|
|
14652
15149
|
}
|
|
14653
15150
|
if (events && !state.events.handlers) {
|
|
@@ -14661,9 +15158,17 @@ function createRoot(canvas) {
|
|
|
14661
15158
|
wasEnabled = enabled;
|
|
14662
15159
|
});
|
|
14663
15160
|
}
|
|
15161
|
+
if (_sizeProps !== void 0) {
|
|
15162
|
+
state.set({ _sizeProps });
|
|
15163
|
+
}
|
|
15164
|
+
if (forceEven !== void 0 && state.internal.forceEven !== forceEven) {
|
|
15165
|
+
state.set((prev) => ({ internal: { ...prev.internal, forceEven } }));
|
|
15166
|
+
}
|
|
14664
15167
|
const size = computeInitialSize(canvas, propsSize);
|
|
14665
|
-
if (!is.equ(size, state.size, shallowLoose)) {
|
|
15168
|
+
if (!state._sizeImperative && !is.equ(size, state.size, shallowLoose)) {
|
|
15169
|
+
const wasImperative = state._sizeImperative;
|
|
14666
15170
|
state.setSize(size.width, size.height, size.top, size.left);
|
|
15171
|
+
if (!wasImperative) state.set({ _sizeImperative: false });
|
|
14667
15172
|
}
|
|
14668
15173
|
if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
|
|
14669
15174
|
state.setDpr(dpr);
|
|
@@ -14688,7 +15193,7 @@ function createRoot(canvas) {
|
|
|
14688
15193
|
const handleXRFrame = (timestamp, frame) => {
|
|
14689
15194
|
const state2 = store.getState();
|
|
14690
15195
|
if (state2.frameloop === "never") return;
|
|
14691
|
-
advance(timestamp
|
|
15196
|
+
advance(timestamp);
|
|
14692
15197
|
};
|
|
14693
15198
|
const actualRenderer = state.internal.actualRenderer;
|
|
14694
15199
|
const handleSessionChange = () => {
|
|
@@ -14700,16 +15205,16 @@ function createRoot(canvas) {
|
|
|
14700
15205
|
};
|
|
14701
15206
|
const xr = {
|
|
14702
15207
|
connect() {
|
|
14703
|
-
const { gl, renderer: renderer2
|
|
14704
|
-
const
|
|
14705
|
-
|
|
14706
|
-
|
|
15208
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15209
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15210
|
+
xrManager.addEventListener("sessionstart", handleSessionChange);
|
|
15211
|
+
xrManager.addEventListener("sessionend", handleSessionChange);
|
|
14707
15212
|
},
|
|
14708
15213
|
disconnect() {
|
|
14709
|
-
const { gl, renderer: renderer2
|
|
14710
|
-
const
|
|
14711
|
-
|
|
14712
|
-
|
|
15214
|
+
const { gl, renderer: renderer2 } = store.getState();
|
|
15215
|
+
const xrManager = (renderer2 || gl).xr;
|
|
15216
|
+
xrManager.removeEventListener("sessionstart", handleSessionChange);
|
|
15217
|
+
xrManager.removeEventListener("sessionend", handleSessionChange);
|
|
14713
15218
|
}
|
|
14714
15219
|
};
|
|
14715
15220
|
if (typeof renderer.xr?.addEventListener === "function") xr.connect();
|
|
@@ -14733,43 +15238,21 @@ function createRoot(canvas) {
|
|
|
14733
15238
|
} else if (is.obj(shadows)) {
|
|
14734
15239
|
Object.assign(renderer.shadowMap, shadows);
|
|
14735
15240
|
}
|
|
14736
|
-
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type)
|
|
15241
|
+
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type) {
|
|
14737
15242
|
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
15243
|
}
|
|
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 }));
|
|
15244
|
+
}
|
|
15245
|
+
if (!configured) {
|
|
15246
|
+
renderer.outputColorSpace = webgpu.SRGBColorSpace;
|
|
15247
|
+
renderer.toneMapping = webgpu.ACESFilmicToneMapping;
|
|
14766
15248
|
}
|
|
14767
15249
|
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
14768
15250
|
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
14769
15251
|
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
14770
15252
|
}
|
|
14771
|
-
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose))
|
|
15253
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
|
|
14772
15254
|
applyProps(renderer, glConfig);
|
|
15255
|
+
}
|
|
14773
15256
|
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
|
|
14774
15257
|
const currentRenderer = state.renderer;
|
|
14775
15258
|
if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
|
|
@@ -14779,11 +15262,26 @@ function createRoot(canvas) {
|
|
|
14779
15262
|
const scheduler = getScheduler();
|
|
14780
15263
|
const rootId = state.internal.rootId;
|
|
14781
15264
|
if (!rootId) {
|
|
14782
|
-
const newRootId = scheduler.generateRootId();
|
|
15265
|
+
const newRootId = canvasId || scheduler.generateRootId();
|
|
14783
15266
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14784
15267
|
getState: () => store.getState(),
|
|
14785
15268
|
onError: (err) => store.getState().setError(err)
|
|
14786
15269
|
});
|
|
15270
|
+
const unregisterCanvasTarget = scheduler.register(
|
|
15271
|
+
() => {
|
|
15272
|
+
const state2 = store.getState();
|
|
15273
|
+
if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
|
|
15274
|
+
const renderer2 = state2.internal.actualRenderer;
|
|
15275
|
+
renderer2.setCanvasTarget(state2.internal.canvasTarget);
|
|
15276
|
+
}
|
|
15277
|
+
},
|
|
15278
|
+
{
|
|
15279
|
+
id: `${newRootId}_canvasTarget`,
|
|
15280
|
+
rootId: newRootId,
|
|
15281
|
+
phase: "start",
|
|
15282
|
+
system: true
|
|
15283
|
+
}
|
|
15284
|
+
);
|
|
14787
15285
|
const unregisterFrustum = scheduler.register(
|
|
14788
15286
|
() => {
|
|
14789
15287
|
const state2 = store.getState();
|
|
@@ -14825,11 +15323,15 @@ function createRoot(canvas) {
|
|
|
14825
15323
|
}
|
|
14826
15324
|
},
|
|
14827
15325
|
{
|
|
14828
|
-
|
|
15326
|
+
// Use canvas ID directly as job ID if available, otherwise use generated rootId
|
|
15327
|
+
id: canvasId || `${newRootId}_render`,
|
|
14829
15328
|
rootId: newRootId,
|
|
14830
15329
|
phase: "render",
|
|
14831
|
-
system: true
|
|
15330
|
+
system: true,
|
|
14832
15331
|
// Internal flag: this is a system job, not user-controlled
|
|
15332
|
+
// Apply scheduler config for render ordering and rate limiting
|
|
15333
|
+
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
15334
|
+
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14833
15335
|
}
|
|
14834
15336
|
);
|
|
14835
15337
|
state.set((state2) => ({
|
|
@@ -14838,6 +15340,7 @@ function createRoot(canvas) {
|
|
|
14838
15340
|
rootId: newRootId,
|
|
14839
15341
|
unregisterRoot: () => {
|
|
14840
15342
|
unregisterRoot();
|
|
15343
|
+
unregisterCanvasTarget();
|
|
14841
15344
|
unregisterFrustum();
|
|
14842
15345
|
unregisterVisibility();
|
|
14843
15346
|
unregisterRender();
|
|
@@ -14896,15 +15399,24 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14896
15399
|
const renderer = state.internal.actualRenderer;
|
|
14897
15400
|
const unregisterRoot = state.internal.unregisterRoot;
|
|
14898
15401
|
if (unregisterRoot) unregisterRoot();
|
|
15402
|
+
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
15403
|
+
if (unregisterPrimary) unregisterPrimary();
|
|
15404
|
+
const canvasTarget = state.internal.canvasTarget;
|
|
15405
|
+
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14899
15406
|
state.events.disconnect?.();
|
|
14900
15407
|
cleanupHelperGroup(root.store);
|
|
14901
|
-
renderer
|
|
14902
|
-
|
|
14903
|
-
|
|
15408
|
+
if (state.isLegacy && renderer) {
|
|
15409
|
+
;
|
|
15410
|
+
renderer.renderLists?.dispose?.();
|
|
15411
|
+
renderer.forceContextLoss?.();
|
|
15412
|
+
}
|
|
15413
|
+
if (!state.internal.isSecondary) {
|
|
15414
|
+
if (renderer?.xr) state.xr.disconnect();
|
|
15415
|
+
}
|
|
14904
15416
|
dispose(state.scene);
|
|
14905
15417
|
_roots.delete(canvas);
|
|
14906
15418
|
if (callback) callback(canvas);
|
|
14907
|
-
} catch
|
|
15419
|
+
} catch {
|
|
14908
15420
|
}
|
|
14909
15421
|
}, 500);
|
|
14910
15422
|
}
|
|
@@ -14912,36 +15424,34 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14912
15424
|
}
|
|
14913
15425
|
}
|
|
14914
15426
|
function createPortal(children, container, state) {
|
|
14915
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15427
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Portal, { children, container, state });
|
|
14916
15428
|
}
|
|
14917
|
-
function
|
|
15429
|
+
function Portal({ children, container, state }) {
|
|
14918
15430
|
const isRef = React.useCallback((obj) => obj && "current" in obj, []);
|
|
14919
|
-
const [resolvedContainer,
|
|
15431
|
+
const [resolvedContainer, _setResolvedContainer] = React.useState(() => {
|
|
14920
15432
|
if (isRef(container)) return container.current ?? null;
|
|
14921
15433
|
return container;
|
|
14922
15434
|
});
|
|
15435
|
+
const setResolvedContainer = React.useCallback(
|
|
15436
|
+
(newContainer) => {
|
|
15437
|
+
if (!newContainer || newContainer === resolvedContainer) return;
|
|
15438
|
+
_setResolvedContainer(isRef(newContainer) ? newContainer.current : newContainer);
|
|
15439
|
+
},
|
|
15440
|
+
[resolvedContainer, _setResolvedContainer, isRef]
|
|
15441
|
+
);
|
|
14923
15442
|
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);
|
|
15443
|
+
if (isRef(container) && !container.current) {
|
|
15444
|
+
return queueMicrotask(() => {
|
|
15445
|
+
setResolvedContainer(container.current);
|
|
15446
|
+
});
|
|
14938
15447
|
}
|
|
14939
|
-
|
|
15448
|
+
setResolvedContainer(container);
|
|
15449
|
+
}, [container, isRef, setResolvedContainer]);
|
|
14940
15450
|
if (!resolvedContainer) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
14941
15451
|
const portalKey = resolvedContainer.uuid ?? `portal-${resolvedContainer.id ?? "unknown"}`;
|
|
14942
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15452
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PortalInner, { children, container: resolvedContainer, state }, portalKey);
|
|
14943
15453
|
}
|
|
14944
|
-
function
|
|
15454
|
+
function PortalInner({ state = {}, children, container }) {
|
|
14945
15455
|
const { events, size, injectScene = true, ...rest } = state;
|
|
14946
15456
|
const previousRoot = useStore();
|
|
14947
15457
|
const [raycaster] = React.useState(() => new webgpu.Raycaster());
|
|
@@ -14962,11 +15472,12 @@ function Portal({ state = {}, children, container }) {
|
|
|
14962
15472
|
};
|
|
14963
15473
|
}, [portalScene, container, injectScene]);
|
|
14964
15474
|
const inject = useMutableCallback((rootState, injectState) => {
|
|
15475
|
+
const resolvedSize = { ...rootState.size, ...injectState.size, ...size };
|
|
14965
15476
|
let viewport = void 0;
|
|
14966
|
-
if (injectState.camera && size) {
|
|
15477
|
+
if (injectState.camera && (size || injectState.size)) {
|
|
14967
15478
|
const camera = injectState.camera;
|
|
14968
|
-
viewport = rootState.viewport.getCurrentViewport(camera, new webgpu.Vector3(),
|
|
14969
|
-
if (camera !== rootState.camera) updateCamera(camera,
|
|
15479
|
+
viewport = rootState.viewport.getCurrentViewport(camera, new webgpu.Vector3(), resolvedSize);
|
|
15480
|
+
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14970
15481
|
}
|
|
14971
15482
|
return {
|
|
14972
15483
|
// The intersect consists of the previous root state
|
|
@@ -14983,7 +15494,7 @@ function Portal({ state = {}, children, container }) {
|
|
|
14983
15494
|
previousRoot,
|
|
14984
15495
|
// Events, size and viewport can be overridden by the inject layer
|
|
14985
15496
|
events: { ...rootState.events, ...injectState.events, ...events },
|
|
14986
|
-
size:
|
|
15497
|
+
size: resolvedSize,
|
|
14987
15498
|
viewport: { ...rootState.viewport, ...viewport },
|
|
14988
15499
|
// Layers are allowed to override events
|
|
14989
15500
|
setEvents: (events2) => injectState.set((state2) => ({ ...state2, events: { ...state2.events, ...events2 } })),
|
|
@@ -15017,15 +15528,13 @@ function CanvasImpl({
|
|
|
15017
15528
|
fallback,
|
|
15018
15529
|
resize,
|
|
15019
15530
|
style,
|
|
15531
|
+
id,
|
|
15020
15532
|
gl,
|
|
15021
|
-
renderer,
|
|
15533
|
+
renderer: rendererProp,
|
|
15022
15534
|
events = createPointerEvents,
|
|
15023
15535
|
eventSource,
|
|
15024
15536
|
eventPrefix,
|
|
15025
15537
|
shadows,
|
|
15026
|
-
linear,
|
|
15027
|
-
flat,
|
|
15028
|
-
legacy,
|
|
15029
15538
|
orthographic,
|
|
15030
15539
|
frameloop,
|
|
15031
15540
|
dpr,
|
|
@@ -15037,10 +15546,46 @@ function CanvasImpl({
|
|
|
15037
15546
|
onDragOverMissed,
|
|
15038
15547
|
onDropMissed,
|
|
15039
15548
|
onCreated,
|
|
15549
|
+
hmr,
|
|
15550
|
+
width,
|
|
15551
|
+
height,
|
|
15552
|
+
background,
|
|
15553
|
+
forceEven,
|
|
15040
15554
|
...props
|
|
15041
15555
|
}) {
|
|
15556
|
+
const { primaryCanvas, scheduler, ...rendererConfig } = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp) ? rendererProp : { primaryCanvas: void 0, scheduler: void 0 };
|
|
15557
|
+
const renderer = Object.keys(rendererConfig).length > 0 ? rendererConfig : rendererProp;
|
|
15042
15558
|
React__namespace.useMemo(() => extend(THREE), []);
|
|
15043
15559
|
const Bridge = useBridge();
|
|
15560
|
+
const backgroundProps = React__namespace.useMemo(() => {
|
|
15561
|
+
if (!background) return null;
|
|
15562
|
+
if (typeof background === "object" && !background.isColor) {
|
|
15563
|
+
const { backgroundMap, envMap, files, preset, ...rest } = background;
|
|
15564
|
+
return {
|
|
15565
|
+
...rest,
|
|
15566
|
+
preset,
|
|
15567
|
+
files: envMap || files,
|
|
15568
|
+
backgroundFiles: backgroundMap,
|
|
15569
|
+
background: true
|
|
15570
|
+
};
|
|
15571
|
+
}
|
|
15572
|
+
if (typeof background === "number") {
|
|
15573
|
+
return { color: background, background: true };
|
|
15574
|
+
}
|
|
15575
|
+
if (typeof background === "string") {
|
|
15576
|
+
if (background in presetsObj) {
|
|
15577
|
+
return { preset: background, background: true };
|
|
15578
|
+
}
|
|
15579
|
+
if (/^(https?:\/\/|\/|\.\/|\.\.\/)|\\.(hdr|exr|jpg|jpeg|png|webp|gif)$/i.test(background)) {
|
|
15580
|
+
return { files: background, background: true };
|
|
15581
|
+
}
|
|
15582
|
+
return { color: background, background: true };
|
|
15583
|
+
}
|
|
15584
|
+
if (background.isColor) {
|
|
15585
|
+
return { color: background, background: true };
|
|
15586
|
+
}
|
|
15587
|
+
return null;
|
|
15588
|
+
}, [background]);
|
|
15044
15589
|
const hasInitialSizeRef = React__namespace.useRef(false);
|
|
15045
15590
|
const measureConfig = React__namespace.useMemo(() => {
|
|
15046
15591
|
if (!hasInitialSizeRef.current) {
|
|
@@ -15057,7 +15602,21 @@ function CanvasImpl({
|
|
|
15057
15602
|
};
|
|
15058
15603
|
}, [resize, hasInitialSizeRef.current]);
|
|
15059
15604
|
const [containerRef, containerRect] = useMeasure__default(measureConfig);
|
|
15060
|
-
|
|
15605
|
+
const effectiveSize = React__namespace.useMemo(() => {
|
|
15606
|
+
let w = width ?? containerRect.width;
|
|
15607
|
+
let h = height ?? containerRect.height;
|
|
15608
|
+
if (forceEven) {
|
|
15609
|
+
w = Math.ceil(w / 2) * 2;
|
|
15610
|
+
h = Math.ceil(h / 2) * 2;
|
|
15611
|
+
}
|
|
15612
|
+
return {
|
|
15613
|
+
width: w,
|
|
15614
|
+
height: h,
|
|
15615
|
+
top: containerRect.top,
|
|
15616
|
+
left: containerRect.left
|
|
15617
|
+
};
|
|
15618
|
+
}, [width, height, containerRect, forceEven]);
|
|
15619
|
+
if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
|
|
15061
15620
|
hasInitialSizeRef.current = true;
|
|
15062
15621
|
}
|
|
15063
15622
|
const canvasRef = React__namespace.useRef(null);
|
|
@@ -15076,7 +15635,7 @@ function CanvasImpl({
|
|
|
15076
15635
|
useIsomorphicLayoutEffect(() => {
|
|
15077
15636
|
effectActiveRef.current = true;
|
|
15078
15637
|
const canvas = canvasRef.current;
|
|
15079
|
-
if (
|
|
15638
|
+
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
15080
15639
|
if (!root.current) {
|
|
15081
15640
|
root.current = createRoot(canvas);
|
|
15082
15641
|
notifyAlpha({
|
|
@@ -15096,21 +15655,24 @@ function CanvasImpl({
|
|
|
15096
15655
|
async function run() {
|
|
15097
15656
|
if (!effectActiveRef.current || !root.current) return;
|
|
15098
15657
|
await root.current.configure({
|
|
15658
|
+
id,
|
|
15659
|
+
primaryCanvas,
|
|
15660
|
+
scheduler,
|
|
15099
15661
|
gl,
|
|
15100
15662
|
renderer,
|
|
15101
15663
|
scene,
|
|
15102
15664
|
events,
|
|
15103
15665
|
shadows,
|
|
15104
|
-
linear,
|
|
15105
|
-
flat,
|
|
15106
|
-
legacy,
|
|
15107
15666
|
orthographic,
|
|
15108
15667
|
frameloop,
|
|
15109
15668
|
dpr,
|
|
15110
15669
|
performance,
|
|
15111
15670
|
raycaster,
|
|
15112
15671
|
camera,
|
|
15113
|
-
size:
|
|
15672
|
+
size: effectiveSize,
|
|
15673
|
+
// Store size props for reset functionality
|
|
15674
|
+
_sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
|
|
15675
|
+
forceEven,
|
|
15114
15676
|
// Pass mutable reference to onPointerMissed so it's free to update
|
|
15115
15677
|
onPointerMissed: (...args) => handlePointerMissed.current?.(...args),
|
|
15116
15678
|
onDragOverMissed: (...args) => handleDragOverMissed.current?.(...args),
|
|
@@ -15134,7 +15696,10 @@ function CanvasImpl({
|
|
|
15134
15696
|
});
|
|
15135
15697
|
if (!effectActiveRef.current || !root.current) return;
|
|
15136
15698
|
root.current.render(
|
|
15137
|
-
/* @__PURE__ */ jsxRuntime.jsx(Bridge, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxRuntime.
|
|
15699
|
+
/* @__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: [
|
|
15700
|
+
backgroundProps && /* @__PURE__ */ jsxRuntime.jsx(Environment, { ...backgroundProps }),
|
|
15701
|
+
children ?? null
|
|
15702
|
+
] }) }) })
|
|
15138
15703
|
);
|
|
15139
15704
|
}
|
|
15140
15705
|
run();
|
|
@@ -15156,6 +15721,35 @@ function CanvasImpl({
|
|
|
15156
15721
|
};
|
|
15157
15722
|
}
|
|
15158
15723
|
}, []);
|
|
15724
|
+
React__namespace.useEffect(() => {
|
|
15725
|
+
if (hmr === false) return;
|
|
15726
|
+
const canvas = canvasRef.current;
|
|
15727
|
+
if (!canvas) return;
|
|
15728
|
+
const handleHMR = () => {
|
|
15729
|
+
queueMicrotask(() => {
|
|
15730
|
+
const rootEntry = _roots.get(canvas);
|
|
15731
|
+
if (rootEntry?.store) {
|
|
15732
|
+
rootEntry.store.setState((state) => ({
|
|
15733
|
+
nodes: {},
|
|
15734
|
+
uniforms: {},
|
|
15735
|
+
_hmrVersion: state._hmrVersion + 1
|
|
15736
|
+
}));
|
|
15737
|
+
}
|
|
15738
|
+
});
|
|
15739
|
+
};
|
|
15740
|
+
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) {
|
|
15741
|
+
const hot = undefined;
|
|
15742
|
+
hot.on("vite:afterUpdate", handleHMR);
|
|
15743
|
+
return () => hot.dispose?.(() => {
|
|
15744
|
+
});
|
|
15745
|
+
}
|
|
15746
|
+
if (typeof module !== "undefined" && module.hot) {
|
|
15747
|
+
const hot = module.hot;
|
|
15748
|
+
hot.addStatusHandler((status) => {
|
|
15749
|
+
if (status === "idle") handleHMR();
|
|
15750
|
+
});
|
|
15751
|
+
}
|
|
15752
|
+
}, [hmr]);
|
|
15159
15753
|
const pointerEvents = eventSource ? "none" : "auto";
|
|
15160
15754
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15161
15755
|
"div",
|
|
@@ -15170,7 +15764,7 @@ function CanvasImpl({
|
|
|
15170
15764
|
...style
|
|
15171
15765
|
},
|
|
15172
15766
|
...props,
|
|
15173
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, className: "r3f-canvas", style: { display: "block" }, children: fallback }) })
|
|
15767
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, id, className: "r3f-canvas", style: { display: "block" }, children: fallback }) })
|
|
15174
15768
|
}
|
|
15175
15769
|
);
|
|
15176
15770
|
}
|
|
@@ -15182,8 +15776,15 @@ extend(THREE);
|
|
|
15182
15776
|
|
|
15183
15777
|
exports.Block = Block;
|
|
15184
15778
|
exports.Canvas = Canvas;
|
|
15779
|
+
exports.Environment = Environment;
|
|
15780
|
+
exports.EnvironmentCube = EnvironmentCube;
|
|
15781
|
+
exports.EnvironmentMap = EnvironmentMap;
|
|
15782
|
+
exports.EnvironmentPortal = EnvironmentPortal;
|
|
15185
15783
|
exports.ErrorBoundary = ErrorBoundary;
|
|
15784
|
+
exports.FROM_REF = FROM_REF;
|
|
15186
15785
|
exports.IsObject = IsObject;
|
|
15786
|
+
exports.ONCE = ONCE;
|
|
15787
|
+
exports.Portal = Portal;
|
|
15187
15788
|
exports.R3F_BUILD_LEGACY = R3F_BUILD_LEGACY;
|
|
15188
15789
|
exports.R3F_BUILD_WEBGPU = R3F_BUILD_WEBGPU;
|
|
15189
15790
|
exports.REACT_INTERNAL_PROPS = REACT_INTERNAL_PROPS;
|
|
@@ -15213,30 +15814,41 @@ exports.events = createPointerEvents;
|
|
|
15213
15814
|
exports.extend = extend;
|
|
15214
15815
|
exports.findInitialRoot = findInitialRoot;
|
|
15215
15816
|
exports.flushSync = flushSync;
|
|
15817
|
+
exports.fromRef = fromRef;
|
|
15216
15818
|
exports.getInstanceProps = getInstanceProps;
|
|
15819
|
+
exports.getPrimary = getPrimary;
|
|
15820
|
+
exports.getPrimaryIds = getPrimaryIds;
|
|
15217
15821
|
exports.getRootState = getRootState;
|
|
15218
15822
|
exports.getScheduler = getScheduler;
|
|
15219
15823
|
exports.getUuidPrefix = getUuidPrefix;
|
|
15220
15824
|
exports.hasConstructor = hasConstructor;
|
|
15825
|
+
exports.hasPrimary = hasPrimary;
|
|
15221
15826
|
exports.invalidate = invalidate;
|
|
15222
15827
|
exports.invalidateInstance = invalidateInstance;
|
|
15223
15828
|
exports.is = is;
|
|
15224
15829
|
exports.isColorRepresentation = isColorRepresentation;
|
|
15225
15830
|
exports.isCopyable = isCopyable;
|
|
15831
|
+
exports.isFromRef = isFromRef;
|
|
15226
15832
|
exports.isObject3D = isObject3D;
|
|
15833
|
+
exports.isOnce = isOnce;
|
|
15227
15834
|
exports.isOrthographicCamera = isOrthographicCamera;
|
|
15228
15835
|
exports.isRef = isRef;
|
|
15229
15836
|
exports.isRenderer = isRenderer;
|
|
15230
15837
|
exports.isTexture = isTexture;
|
|
15231
15838
|
exports.isVectorLike = isVectorLike;
|
|
15839
|
+
exports.once = once;
|
|
15232
15840
|
exports.prepare = prepare;
|
|
15841
|
+
exports.presetsObj = presetsObj;
|
|
15233
15842
|
exports.reconciler = reconciler;
|
|
15843
|
+
exports.registerPrimary = registerPrimary;
|
|
15234
15844
|
exports.removeInteractivity = removeInteractivity;
|
|
15235
15845
|
exports.resolve = resolve;
|
|
15236
15846
|
exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
15847
|
+
exports.unregisterPrimary = unregisterPrimary;
|
|
15237
15848
|
exports.updateCamera = updateCamera;
|
|
15238
15849
|
exports.updateFrustum = updateFrustum;
|
|
15239
15850
|
exports.useBridge = useBridge;
|
|
15851
|
+
exports.useEnvironment = useEnvironment;
|
|
15240
15852
|
exports.useFrame = useFrame;
|
|
15241
15853
|
exports.useGraph = useGraph;
|
|
15242
15854
|
exports.useInstanceHandle = useInstanceHandle;
|
|
@@ -15248,3 +15860,4 @@ exports.useStore = useStore;
|
|
|
15248
15860
|
exports.useTexture = useTexture;
|
|
15249
15861
|
exports.useTextures = useTextures;
|
|
15250
15862
|
exports.useThree = useThree;
|
|
15863
|
+
exports.waitForPrimary = waitForPrimary;
|