@react-three/fiber 10.0.0-canary.54ec785 → 10.0.0-canary.58acabc
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/dist/extension.cjs +8 -8
- package/dist/extension.d.cts +50 -6
- package/dist/extension.d.mts +50 -6
- package/dist/extension.d.ts +50 -6
- package/dist/extension.mjs +1 -1
- package/dist/index.cjs +17 -19
- package/dist/index.d.cts +15 -47
- package/dist/index.d.mts +15 -47
- package/dist/index.d.ts +15 -47
- package/dist/index.mjs +7 -8
- package/dist/legacy.cjs +37 -15
- package/dist/legacy.d.cts +10 -7
- package/dist/legacy.d.mts +10 -7
- package/dist/legacy.d.ts +10 -7
- package/dist/legacy.mjs +13 -5
- package/dist/shared/{fiber.BcNm6NAg.d.cts → fiber.34TOMPo3.d.cts} +83 -464
- package/dist/shared/fiber.BFuGd7gN.d.cts +90 -0
- package/dist/shared/{fiber.khFlPHPf.cjs → fiber.BO8-26r8.cjs} +206 -62
- package/dist/shared/fiber.BSXtODQl.cjs +14 -0
- package/dist/shared/fiber.Bll9fqKA.d.mts +90 -0
- package/dist/shared/{fiber.5Q8N6Hhq.mjs → fiber.BuWl08aJ.mjs} +2375 -1941
- package/dist/shared/{fiber.CUKAa7Rv.mjs → fiber.C-3TIsF8.mjs} +200 -64
- package/dist/shared/{fiber.CQDCACCJ.d.mts → fiber.CjMAAsJy.d.ts} +83 -464
- package/dist/shared/fiber.DEWBFQJe.mjs +9 -0
- package/dist/shared/{fiber.CZLeHcML.d.cts → fiber.DQTSZ24m.d.cts} +469 -29
- package/dist/shared/{fiber.CZLeHcML.d.mts → fiber.DQTSZ24m.d.mts} +469 -29
- package/dist/shared/{fiber.CZLeHcML.d.ts → fiber.DQTSZ24m.d.ts} +469 -29
- package/dist/shared/fiber.DuA4F8L5.d.ts +90 -0
- package/dist/shared/{fiber.DeBIf2pk.d.ts → fiber.Dy7Uz273.d.mts} +83 -464
- package/dist/shared/{fiber.BegWBc5_.cjs → fiber.TRm3lZ7I.cjs} +2407 -1973
- package/dist/webgpu/index.cjs +16 -18
- package/dist/webgpu/index.d.cts +17 -78
- package/dist/webgpu/index.d.mts +17 -78
- package/dist/webgpu/index.d.ts +17 -78
- package/dist/webgpu/index.mjs +7 -9
- package/package.json +3 -3
- package/readme.md +10 -1
- package/dist/chunks/webgl.cjs +0 -27
- package/dist/chunks/webgl.mjs +0 -11
- package/dist/shared/fiber.B_GGVI86.d.ts +0 -48
- package/dist/shared/fiber.ColkapKS.d.mts +0 -48
- package/dist/shared/fiber.DRfTw2kk.d.cts +0 -48
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { i as isDevelopment, n as notifyDepreciated, p as preserveAccessors, h as defineRendererAccessors, j as stateForScheduler, k as detachRootExtensions, l as attachRootExtensions, d as useIsomorphicLayoutEffect, c as context, a as useThree, u as useStore, m as unstageTextures, o as stageTextures, e as useMutableCallback, q as isAccessor, t as cloneState, v as keepAccessors, b as useFrame, f as useBridge, w as useGate, x as notifyAlpha, E as ErrorBoundary, B as Block, y as notifyRootExtensionsHmr } from './fiber.C-3TIsF8.mjs';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import React__default, { useRef, useMemo, useLayoutEffect, useEffect, useImperativeHandle, useCallback, useState } from 'react';
|
|
5
5
|
import useMeasure from 'react-use-measure';
|
|
@@ -107,6 +107,20 @@ function updateFrustum(camera, frustum) {
|
|
|
107
107
|
target.setFromProjectionMatrix(frustumMatrix);
|
|
108
108
|
return target;
|
|
109
109
|
}
|
|
110
|
+
function computeInitialSize(canvas, size) {
|
|
111
|
+
if (!size && typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement && canvas.parentElement) {
|
|
112
|
+
const { width, height, top, left } = canvas.parentElement.getBoundingClientRect();
|
|
113
|
+
return { width, height, top, left };
|
|
114
|
+
} else if (!size && typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas) {
|
|
115
|
+
return {
|
|
116
|
+
width: canvas.width,
|
|
117
|
+
height: canvas.height,
|
|
118
|
+
top: 0,
|
|
119
|
+
left: 0
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return { width: 0, height: 0, top: 0, left: 0, ...size };
|
|
123
|
+
}
|
|
110
124
|
|
|
111
125
|
const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
|
|
112
126
|
function findInitialRoot(instance) {
|
|
@@ -174,6 +188,7 @@ function prepare(target, root, type, props) {
|
|
|
174
188
|
object,
|
|
175
189
|
eventCount: 0,
|
|
176
190
|
handlers: {},
|
|
191
|
+
previousVisible: void 0,
|
|
177
192
|
isHidden: false
|
|
178
193
|
};
|
|
179
194
|
if (object) object.__r3f = instance;
|
|
@@ -401,7 +416,19 @@ function assertNodeMaterialSupported(state, value) {
|
|
|
401
416
|
const material = (Array.isArray(value) ? value : [value]).find((m) => m?.isNodeMaterial);
|
|
402
417
|
if (!material) return;
|
|
403
418
|
throw new Error(
|
|
404
|
-
`R3F: ${material.type ?? "Node material"} requires WebGPURenderer (it falls back to WebGL2 automatically).
|
|
419
|
+
`R3F: ${material.type ?? "Node material"} requires WebGPURenderer (it falls back to WebGL2 automatically). Import Canvas from @react-three/fiber or @react-three/fiber/webgpu instead of @react-three/fiber/legacy.`
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
const warnedGLSL = /* @__PURE__ */ new Set();
|
|
423
|
+
function warnGLSLMaterialUnsupported(state, value) {
|
|
424
|
+
if (!state || state.isLegacy || state.internal?.support?.kind !== "webgpu" || !isDevelopment()) return;
|
|
425
|
+
const material = (Array.isArray(value) ? value : [value]).find((m) => m?.isShaderMaterial && !m.isNodeMaterial);
|
|
426
|
+
if (!material) return;
|
|
427
|
+
const type = material.type ?? "ShaderMaterial";
|
|
428
|
+
if (warnedGLSL.has(type)) return;
|
|
429
|
+
warnedGLSL.add(type);
|
|
430
|
+
console.warn(
|
|
431
|
+
`R3F: ${type} is a GLSL material, which WebGPURenderer cannot compile; three draws it with a blank default material. @react-three/fiber renders with WebGPU: import Canvas from @react-three/fiber/legacy to keep WebGLRenderer, or port the shader to a node material (TSL).`
|
|
405
432
|
);
|
|
406
433
|
}
|
|
407
434
|
|
|
@@ -422,6 +449,28 @@ const VISIBILITY_EVENT_REGEX = /^on(Framed|Occluded|Visible)$/;
|
|
|
422
449
|
const INDEX_REGEX = /-\d+$/;
|
|
423
450
|
const MEMOIZED_PROTOTYPES = /* @__PURE__ */ new Map();
|
|
424
451
|
const colorMaps = ["map", "emissiveMap", "sheenColorMap", "specularColorMap", "envMap"];
|
|
452
|
+
const programProps = /* @__PURE__ */ new Set([
|
|
453
|
+
"transparent",
|
|
454
|
+
"vertexColors",
|
|
455
|
+
"flatShading",
|
|
456
|
+
"fog",
|
|
457
|
+
// Culling is live, but DOUBLE_SIDED / FLIP_SIDED normal flipping is compiled in
|
|
458
|
+
"side",
|
|
459
|
+
"alphaHash",
|
|
460
|
+
"premultipliedAlpha",
|
|
461
|
+
// Both feed the OPAQUE define when the material is not transparent
|
|
462
|
+
"blending",
|
|
463
|
+
"alphaToCoverage",
|
|
464
|
+
"dithering",
|
|
465
|
+
"sizeAttenuation",
|
|
466
|
+
"combine",
|
|
467
|
+
"normalMapType",
|
|
468
|
+
"depthPacking"
|
|
469
|
+
]);
|
|
470
|
+
function changesProgram(root, key, previous, next) {
|
|
471
|
+
if (!root?.isMaterial || previous === next) return false;
|
|
472
|
+
return programProps.has(key) || isTexture(previous) !== isTexture(next);
|
|
473
|
+
}
|
|
425
474
|
function resolve(root, key) {
|
|
426
475
|
if (!key.includes("-")) return { root, key, target: root[key] };
|
|
427
476
|
if (key in root) return { root, key, target: root[key] };
|
|
@@ -452,6 +501,7 @@ function attach(parent, child) {
|
|
|
452
501
|
const { root, key } = resolve(parent.object, child.props.attach);
|
|
453
502
|
child.previousAttach = root[key];
|
|
454
503
|
root[key] = child.object;
|
|
504
|
+
if (changesProgram(root, key, child.previousAttach, child.object)) root.needsUpdate = true;
|
|
455
505
|
} else if (is.fun(child.props.attach)) {
|
|
456
506
|
child.previousAttach = child.props.attach(parent.object, child.object);
|
|
457
507
|
}
|
|
@@ -462,6 +512,7 @@ function detach(parent, child) {
|
|
|
462
512
|
const previous = child.previousAttach;
|
|
463
513
|
if (previous === void 0) delete root[key];
|
|
464
514
|
else root[key] = previous;
|
|
515
|
+
if (changesProgram(root, key, child.object, previous)) root.needsUpdate = true;
|
|
465
516
|
} else {
|
|
466
517
|
child.previousAttach?.(parent.object, child.object);
|
|
467
518
|
}
|
|
@@ -541,6 +592,10 @@ function applyProps(object, props) {
|
|
|
541
592
|
}
|
|
542
593
|
continue;
|
|
543
594
|
}
|
|
595
|
+
if (prop === "visible" && instance?.isHidden && instance.previousVisible !== void 0) {
|
|
596
|
+
instance.previousVisible = value;
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
544
599
|
let { root, key, target } = resolve(object, prop);
|
|
545
600
|
if (target === void 0 && (typeof root !== "object" || root === null)) {
|
|
546
601
|
throw Error(`R3F: Cannot set "${prop}". Ensure it is an object before setting "${key}".`);
|
|
@@ -568,17 +623,24 @@ function applyProps(object, props) {
|
|
|
568
623
|
for (const name in nextUniforms) {
|
|
569
624
|
const uniform = nextUniforms[name];
|
|
570
625
|
const targetUniform = uniforms[name];
|
|
571
|
-
if (targetUniform)
|
|
572
|
-
|
|
626
|
+
if (targetUniform) {
|
|
627
|
+
Object.assign(targetUniform, uniform);
|
|
628
|
+
} else {
|
|
573
629
|
const nextUniform = isUniform(uniform) ? uniform.clone() : new (getThree()).Uniform(uniform.value);
|
|
574
630
|
uniforms[name] = nextUniform;
|
|
575
631
|
}
|
|
576
632
|
}
|
|
577
633
|
} else {
|
|
578
|
-
if (key === "material")
|
|
634
|
+
if (key === "material") {
|
|
635
|
+
assertNodeMaterialSupported(rootState, value);
|
|
636
|
+
warnGLSLMaterialUnsupported(rootState, value);
|
|
637
|
+
}
|
|
638
|
+
const previous = root[key];
|
|
579
639
|
root[key] = value;
|
|
580
640
|
if (key.endsWith("Node") && root.isMaterial) {
|
|
581
641
|
root.needsUpdate = true;
|
|
642
|
+
} else if (changesProgram(root, key, previous, value)) {
|
|
643
|
+
root.needsUpdate = true;
|
|
582
644
|
}
|
|
583
645
|
const three = rootState && getThree();
|
|
584
646
|
if (three && rootState.renderer?.outputColorSpace === three.SRGBColorSpace && colorMaps.includes(key) && isTexture(value) && root[key]?.isTexture && // sRGB textures must be RGBA8 since r137 https://github.com/mrdoob/three.js/pull/23129
|
|
@@ -619,468 +681,390 @@ function applyProps(object, props) {
|
|
|
619
681
|
return object;
|
|
620
682
|
}
|
|
621
683
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
memoizedLoaders.set(Proto, loader);
|
|
630
|
-
}
|
|
631
|
-
return loader;
|
|
632
|
-
}
|
|
633
|
-
return Proto;
|
|
634
|
-
}
|
|
635
|
-
function loadingFn(extensions, onProgress) {
|
|
636
|
-
return function(Proto, input) {
|
|
637
|
-
const loader = getLoader(Proto);
|
|
638
|
-
if (extensions) extensions(loader);
|
|
639
|
-
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
640
|
-
return loader.loadAsync(input, onProgress).then((data) => {
|
|
641
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
642
|
-
return data;
|
|
643
|
-
});
|
|
644
|
-
}
|
|
645
|
-
return new Promise(
|
|
646
|
-
(res, reject) => loader.load(
|
|
647
|
-
input,
|
|
648
|
-
(data) => {
|
|
649
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
650
|
-
res(data);
|
|
651
|
-
},
|
|
652
|
-
onProgress,
|
|
653
|
-
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
654
|
-
)
|
|
655
|
-
);
|
|
656
|
-
};
|
|
657
|
-
}
|
|
658
|
-
function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
659
|
-
const inputs = Array.isArray(input) ? input : [input];
|
|
660
|
-
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
661
|
-
const fn = loadingFn(extensions, onProgress);
|
|
662
|
-
const results = cacheKeys.map(
|
|
663
|
-
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
664
|
-
);
|
|
665
|
-
const stableRef = useRef(null);
|
|
666
|
-
const previous = stableRef.current;
|
|
667
|
-
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
668
|
-
stableRef.current = stable;
|
|
669
|
-
return Array.isArray(input) ? stable : stable[0];
|
|
670
|
-
}
|
|
671
|
-
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
672
|
-
const inputs = Array.isArray(input) ? input : [input];
|
|
673
|
-
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
674
|
-
cacheKeys.forEach(
|
|
675
|
-
(key, index) => preload(() => loadingFn(extensions, onProgress)(loader, inputs[index]), [loader, key])
|
|
676
|
-
);
|
|
677
|
-
};
|
|
678
|
-
useLoader.clear = function(loader, input, cacheKey) {
|
|
679
|
-
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
680
|
-
cacheKeys.forEach((key) => clear([loader, key]));
|
|
681
|
-
};
|
|
682
|
-
useLoader.loader = getLoader;
|
|
683
|
-
|
|
684
|
-
const IsObject = (url) => url === Object(url) && !Array.isArray(url) && typeof url !== "function";
|
|
685
|
-
function getUrls(input) {
|
|
686
|
-
if (typeof input === "string") return [input];
|
|
687
|
-
if (Array.isArray(input)) return input;
|
|
688
|
-
return Object.values(input);
|
|
689
|
-
}
|
|
690
|
-
function inputSignature(input) {
|
|
691
|
-
if (typeof input === "string") return input;
|
|
692
|
-
if (Array.isArray(input)) return input.join("\0");
|
|
693
|
-
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
694
|
-
}
|
|
695
|
-
function allUrlsCached(urls, textureCache) {
|
|
696
|
-
return urls.every((url) => textureCache.has(url));
|
|
684
|
+
function updateSize(state, size, imperative) {
|
|
685
|
+
state.set((current) => ({
|
|
686
|
+
size,
|
|
687
|
+
viewport: { ...current.viewport, ...current.viewport.getCurrentViewport(current.camera, void 0, size) },
|
|
688
|
+
_sizeImperative: imperative
|
|
689
|
+
}));
|
|
690
|
+
state.invalidate();
|
|
697
691
|
}
|
|
698
|
-
function
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
return input.map((url) => textureCache.get(url));
|
|
703
|
-
} else {
|
|
704
|
-
const result = {};
|
|
705
|
-
const objInput = input;
|
|
706
|
-
for (const key in objInput) {
|
|
707
|
-
result[key] = textureCache.get(objInput[key]);
|
|
708
|
-
}
|
|
709
|
-
return result;
|
|
710
|
-
}
|
|
692
|
+
function configureSize(store, size) {
|
|
693
|
+
const state = store.getState();
|
|
694
|
+
if (state._sizeImperative || is.equ(size, state.size, { objects: "shallow", strict: false })) return;
|
|
695
|
+
updateSize(state, size, false);
|
|
711
696
|
}
|
|
712
|
-
|
|
713
|
-
const
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
const keyed = {};
|
|
737
|
-
const textureArray = loadedTextures;
|
|
738
|
-
let i = 0;
|
|
739
|
-
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
740
|
-
return keyed;
|
|
741
|
-
} else {
|
|
742
|
-
return loadedTextures;
|
|
743
|
-
}
|
|
744
|
-
}, [stableInput, loadedTextures, cachedResult]);
|
|
745
|
-
useLayoutEffect(() => {
|
|
746
|
-
if (cachedResult) return;
|
|
747
|
-
if (onLoadCalledForRef.current === inputKey) return;
|
|
748
|
-
onLoadCalledForRef.current = inputKey;
|
|
749
|
-
onLoadRef.current?.(mappedTextures);
|
|
750
|
-
}, [cachedResult, mappedTextures, inputKey]);
|
|
751
|
-
useEffect(() => {
|
|
752
|
-
if (cachedResult) return;
|
|
753
|
-
if ("initTexture" in renderer) {
|
|
754
|
-
let textureArray = [];
|
|
755
|
-
if (Array.isArray(loadedTextures)) {
|
|
756
|
-
textureArray = loadedTextures;
|
|
757
|
-
} else if (loadedTextures.isTexture) {
|
|
758
|
-
textureArray = [loadedTextures];
|
|
759
|
-
} else if (IsObject(loadedTextures)) {
|
|
760
|
-
textureArray = Object.values(loadedTextures);
|
|
697
|
+
const createStore = (invalidate, advance) => {
|
|
698
|
+
const rootStore = createWithEqualityFn((rawSet, get, api) => {
|
|
699
|
+
const set = api.setState = preserveAccessors(rawSet, get);
|
|
700
|
+
let position;
|
|
701
|
+
let defaultTarget;
|
|
702
|
+
let tempTarget;
|
|
703
|
+
function getCurrentViewport(camera = get().camera, target = void 0, size = get().size) {
|
|
704
|
+
const { Vector3 } = getThree();
|
|
705
|
+
position ?? (position = new Vector3());
|
|
706
|
+
defaultTarget ?? (defaultTarget = new Vector3());
|
|
707
|
+
tempTarget ?? (tempTarget = new Vector3());
|
|
708
|
+
target ?? (target = defaultTarget);
|
|
709
|
+
const { width, height, top, left } = size;
|
|
710
|
+
const aspect = width / height;
|
|
711
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
712
|
+
else tempTarget.set(...target);
|
|
713
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
714
|
+
if (isOrthographicCamera(camera)) {
|
|
715
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
716
|
+
} else {
|
|
717
|
+
const fov = camera.fov * Math.PI / 180;
|
|
718
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
719
|
+
const w = h * (width / height);
|
|
720
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
761
721
|
}
|
|
762
|
-
textureArray.forEach((texture) => {
|
|
763
|
-
if (texture?.isTexture) {
|
|
764
|
-
renderer.initTexture(texture);
|
|
765
|
-
}
|
|
766
|
-
});
|
|
767
722
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
urlTextureMap.map(([url]) => url)
|
|
791
|
-
);
|
|
792
|
-
return () => store.setState((state) => {
|
|
793
|
-
const refs = new Map(state._textureRefs);
|
|
794
|
-
for (const [url] of urlTextureMap) {
|
|
795
|
-
const next = (refs.get(url) ?? 0) - 1;
|
|
796
|
-
if (next <= 0) refs.delete(url);
|
|
797
|
-
else refs.set(url, next);
|
|
798
|
-
}
|
|
799
|
-
return { _textureRefs: refs };
|
|
800
|
-
});
|
|
801
|
-
}, [cache, stableInput, mappedTextures, store]);
|
|
802
|
-
if (cache && !cachedResult) stageTextures(store, urlTextureEntries(stableInput, mappedTextures));
|
|
803
|
-
return mappedTextures;
|
|
804
|
-
}
|
|
805
|
-
function urlTextureEntries(input, textures) {
|
|
806
|
-
if (typeof input === "string") return [[input, textures]];
|
|
807
|
-
if (Array.isArray(input)) return input.map((url, i) => [url, textures[i]]);
|
|
808
|
-
const record = textures;
|
|
809
|
-
return Object.keys(input).map((key) => [input[key], record[key]]);
|
|
810
|
-
}
|
|
811
|
-
useTexture.preload = (url) => {
|
|
812
|
-
whenThree().then((three) => useLoader.preload(three.TextureLoader, url));
|
|
813
|
-
};
|
|
814
|
-
useTexture.clear = (input) => {
|
|
815
|
-
if (hasThree()) useLoader.clear(getThree().TextureLoader, input);
|
|
816
|
-
};
|
|
817
|
-
const Texture = ({
|
|
818
|
-
children,
|
|
819
|
-
input,
|
|
820
|
-
onLoad,
|
|
821
|
-
cache
|
|
822
|
-
}) => {
|
|
823
|
-
const options = typeof onLoad === "function" ? { onLoad, cache } : { ...onLoad, cache };
|
|
824
|
-
const ret = useTexture(input, options);
|
|
825
|
-
return /* @__PURE__ */ jsx(Fragment, { children: children?.(ret) });
|
|
826
|
-
};
|
|
827
|
-
|
|
828
|
-
function useTextures(selector) {
|
|
829
|
-
const store = useStore();
|
|
830
|
-
const registry = useMemo(() => {
|
|
831
|
-
const getState = store.getState;
|
|
832
|
-
const setState = store.setState;
|
|
833
|
-
const getOne = (key) => getState().textures.get(key);
|
|
834
|
-
return {
|
|
835
|
-
get all() {
|
|
836
|
-
return getState().textures;
|
|
723
|
+
let performanceTimeout = void 0;
|
|
724
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
725
|
+
const rootState = {
|
|
726
|
+
set,
|
|
727
|
+
get,
|
|
728
|
+
// Mock objects that have to be configured
|
|
729
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
730
|
+
primaryStore: null,
|
|
731
|
+
gl: null,
|
|
732
|
+
renderer: null,
|
|
733
|
+
camera: null,
|
|
734
|
+
// frustum, pointer and mouse are three objects; configure() creates them with the renderer
|
|
735
|
+
frustum: null,
|
|
736
|
+
autoUpdateFrustum: true,
|
|
737
|
+
raycaster: null,
|
|
738
|
+
events: {
|
|
739
|
+
priority: 1,
|
|
740
|
+
enabled: true,
|
|
741
|
+
connected: false,
|
|
742
|
+
frameTimedRaycasts: true,
|
|
743
|
+
alwaysFireOnScroll: true,
|
|
744
|
+
updateOnFrame: false
|
|
837
745
|
},
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
746
|
+
scene: null,
|
|
747
|
+
rootScene: null,
|
|
748
|
+
xr: null,
|
|
749
|
+
inspector: null,
|
|
750
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
751
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
752
|
+
textureColorSpace: "srgb",
|
|
753
|
+
// THREE.SRGBColorSpace
|
|
754
|
+
isLegacy: false,
|
|
755
|
+
webGPUSupported: false,
|
|
756
|
+
isNative: false,
|
|
757
|
+
controls: null,
|
|
758
|
+
pointer: null,
|
|
759
|
+
mouse: null,
|
|
760
|
+
frameloop: "always",
|
|
761
|
+
onPointerMissed: void 0,
|
|
762
|
+
onDragOverMissed: void 0,
|
|
763
|
+
onDropMissed: void 0,
|
|
764
|
+
performance: {
|
|
765
|
+
current: 1,
|
|
766
|
+
min: 0.5,
|
|
767
|
+
max: 1,
|
|
768
|
+
debounce: 200,
|
|
769
|
+
regress: () => {
|
|
770
|
+
const state2 = get();
|
|
771
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
772
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
773
|
+
performanceTimeout = setTimeout(
|
|
774
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
775
|
+
state2.performance.debounce
|
|
776
|
+
);
|
|
777
|
+
}
|
|
844
778
|
},
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
779
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
780
|
+
viewport: {
|
|
781
|
+
initialDpr: 0,
|
|
782
|
+
dpr: 0,
|
|
783
|
+
width: 0,
|
|
784
|
+
height: 0,
|
|
785
|
+
top: 0,
|
|
786
|
+
left: 0,
|
|
787
|
+
aspect: 0,
|
|
788
|
+
distance: 0,
|
|
789
|
+
factor: 0,
|
|
790
|
+
getCurrentViewport
|
|
856
791
|
},
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
const
|
|
860
|
-
if (
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
792
|
+
setEvents: (events) => set((state2) => ({ events: { ...state2.events, ...events } })),
|
|
793
|
+
setSize: (width, height, top, left) => {
|
|
794
|
+
const state2 = get();
|
|
795
|
+
if (width === void 0) {
|
|
796
|
+
if (state2._sizeProps) {
|
|
797
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
798
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
799
|
+
const currentSize = state2.size;
|
|
800
|
+
const newSize = {
|
|
801
|
+
width: propW ?? currentSize.width,
|
|
802
|
+
height: propH ?? currentSize.height,
|
|
803
|
+
top: currentSize.top,
|
|
804
|
+
left: currentSize.left
|
|
805
|
+
};
|
|
806
|
+
updateSize(state2, newSize, false);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
set({ _sizeImperative: false });
|
|
811
|
+
return;
|
|
865
812
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
return { textures, _textureRefs: nextRefs };
|
|
873
|
-
});
|
|
874
|
-
return true;
|
|
813
|
+
const w = width;
|
|
814
|
+
const h = height ?? width;
|
|
815
|
+
const t = top ?? state2.size.top;
|
|
816
|
+
const l = left ?? state2.size.left;
|
|
817
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
818
|
+
updateSize(state2, size, true);
|
|
875
819
|
},
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
820
|
+
setDpr: (dpr) => set((state2) => {
|
|
821
|
+
const resolved = calculateDpr(dpr);
|
|
822
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
823
|
+
}),
|
|
824
|
+
setFrameloop: (frameloop = "always") => {
|
|
825
|
+
const rootId = get().internal.rootId;
|
|
826
|
+
if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
|
|
827
|
+
set(() => ({ frameloop }));
|
|
828
|
+
},
|
|
829
|
+
setError: (error) => set(() => ({ error })),
|
|
830
|
+
error: null,
|
|
831
|
+
//* Texture registry (useTextures) ==============================
|
|
832
|
+
// TSL fields (uniforms, nodes, ..., renderPipeline) are added by @react-three/tsl's root extension.
|
|
833
|
+
textures: /* @__PURE__ */ new Map(),
|
|
834
|
+
_textureRefs: /* @__PURE__ */ new Map(),
|
|
835
|
+
_sizeImperative: false,
|
|
836
|
+
_sizeProps: null,
|
|
837
|
+
previousRoot: void 0,
|
|
838
|
+
internal: {
|
|
839
|
+
// Events
|
|
840
|
+
interaction: [],
|
|
841
|
+
subscribers: [],
|
|
842
|
+
// Per-pointer state (new unified structure)
|
|
843
|
+
pointerMap: /* @__PURE__ */ new Map(),
|
|
844
|
+
pointerDirty: /* @__PURE__ */ new Map(),
|
|
845
|
+
lastEvent: React.createRef(),
|
|
846
|
+
// Deprecated but kept for backwards compatibility
|
|
847
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
848
|
+
initialClick: [0, 0],
|
|
849
|
+
initialHits: [],
|
|
850
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
851
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
852
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
853
|
+
// Occlusion system (WebGPU only)
|
|
854
|
+
occlusionEnabled: false,
|
|
855
|
+
occlusionObserver: null,
|
|
856
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
857
|
+
helperGroup: null,
|
|
858
|
+
// Updates
|
|
859
|
+
active: false,
|
|
860
|
+
frames: 0,
|
|
861
|
+
priority: 0,
|
|
862
|
+
subscribe: (ref, priority, store) => {
|
|
863
|
+
const internal = get().internal;
|
|
864
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
865
|
+
internal.subscribers.push({ ref, priority, store });
|
|
866
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
867
|
+
return () => {
|
|
868
|
+
const internal2 = get().internal;
|
|
869
|
+
if (internal2?.subscribers) {
|
|
870
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
871
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
},
|
|
875
|
+
// Renderer Storage (single source of truth)
|
|
876
|
+
actualRenderer: null,
|
|
877
|
+
// The renderer support configure() loads for this root
|
|
878
|
+
support: null,
|
|
879
|
+
// Scheduler for useFrameNext (initialized in loop.ts)
|
|
880
|
+
scheduler: null,
|
|
881
|
+
// Replaces the default render call when set (see setRenderOverride)
|
|
882
|
+
renderOverride: null
|
|
879
883
|
}
|
|
880
884
|
};
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
const
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
opts = widthOrOptions;
|
|
895
|
-
} else if (typeof widthOrOptions === "number") {
|
|
896
|
-
width = widthOrOptions;
|
|
897
|
-
if (typeof heightOrOptions === "object") {
|
|
898
|
-
height = widthOrOptions;
|
|
899
|
-
opts = heightOrOptions;
|
|
900
|
-
} else if (typeof heightOrOptions === "number") {
|
|
901
|
-
height = heightOrOptions;
|
|
902
|
-
opts = options;
|
|
903
|
-
} else {
|
|
904
|
-
height = widthOrOptions;
|
|
885
|
+
return rootState;
|
|
886
|
+
});
|
|
887
|
+
const state = rootStore.getState();
|
|
888
|
+
defineRendererAccessors(state);
|
|
889
|
+
let oldScene = state.scene;
|
|
890
|
+
rootStore.subscribe(() => {
|
|
891
|
+
const currentState = rootStore.getState();
|
|
892
|
+
const { scene, rootScene, set } = currentState;
|
|
893
|
+
if (scene !== oldScene) {
|
|
894
|
+
oldScene = scene;
|
|
895
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
896
|
+
set({ rootScene: scene });
|
|
897
|
+
}
|
|
905
898
|
}
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
};
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
let pending = pendingLoaders.get(format);
|
|
935
|
-
if (!pending) {
|
|
936
|
-
pending = importLoader(format).then(
|
|
937
|
-
(loader) => {
|
|
938
|
-
loadedLoaders.set(format, loader);
|
|
939
|
-
return loader;
|
|
940
|
-
},
|
|
941
|
-
(error) => {
|
|
942
|
-
pendingLoaders.delete(format);
|
|
943
|
-
throw error;
|
|
899
|
+
});
|
|
900
|
+
let oldSize = state.size;
|
|
901
|
+
let oldDpr = state.viewport.dpr;
|
|
902
|
+
let oldCamera = state.camera;
|
|
903
|
+
rootStore.subscribe(() => {
|
|
904
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
905
|
+
const actualRenderer = internal.actualRenderer;
|
|
906
|
+
const canvasTarget = internal.canvasTarget;
|
|
907
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
908
|
+
oldSize = size;
|
|
909
|
+
oldDpr = viewport.dpr;
|
|
910
|
+
updateCamera(camera, size);
|
|
911
|
+
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
912
|
+
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
913
|
+
resizeTarget.setSize(size.width, size.height, false);
|
|
914
|
+
const activeTarget = actualRenderer.getCanvasTarget?.();
|
|
915
|
+
if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
|
|
916
|
+
}
|
|
917
|
+
if (camera !== oldCamera) {
|
|
918
|
+
oldCamera = camera;
|
|
919
|
+
const { rootScene } = rootStore.getState();
|
|
920
|
+
if (camera && rootScene && !camera.parent) {
|
|
921
|
+
rootScene.add(camera);
|
|
922
|
+
}
|
|
923
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
924
|
+
const currentState = rootStore.getState();
|
|
925
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
926
|
+
updateFrustum(camera, currentState.frustum);
|
|
944
927
|
}
|
|
945
|
-
);
|
|
946
|
-
pendingLoaders.set(format, pending);
|
|
947
|
-
}
|
|
948
|
-
return pending;
|
|
949
|
-
}
|
|
950
|
-
async function importLoader(format) {
|
|
951
|
-
let loader;
|
|
952
|
-
switch (format) {
|
|
953
|
-
case "cube":
|
|
954
|
-
loader = getThree().CubeTextureLoader;
|
|
955
|
-
break;
|
|
956
|
-
case "hdr-cube":
|
|
957
|
-
loader = (await import('three/examples/jsm/loaders/HDRCubeTextureLoader.js')).HDRCubeTextureLoader;
|
|
958
|
-
break;
|
|
959
|
-
case "hdr":
|
|
960
|
-
loader = (await import('three/examples/jsm/loaders/HDRLoader.js')).HDRLoader;
|
|
961
|
-
break;
|
|
962
|
-
case "exr":
|
|
963
|
-
loader = (await import('three/examples/jsm/loaders/EXRLoader.js')).EXRLoader;
|
|
964
|
-
break;
|
|
965
|
-
case "jpg":
|
|
966
|
-
loader = (await import('three/examples/jsm/loaders/UltraHDRLoader.js')).UltraHDRLoader;
|
|
967
|
-
break;
|
|
968
|
-
}
|
|
969
|
-
return loader;
|
|
970
|
-
}
|
|
971
|
-
const LOADER_KEY = Symbol("r3f-environment-loader");
|
|
972
|
-
function useEnvironmentLoader(format) {
|
|
973
|
-
return suspend(() => loadLoader(format), [LOADER_KEY, format]);
|
|
974
|
-
}
|
|
975
|
-
function useEnvironment({
|
|
976
|
-
files = defaultFiles,
|
|
977
|
-
path = "",
|
|
978
|
-
preset = void 0,
|
|
979
|
-
colorSpace = void 0,
|
|
980
|
-
extensions
|
|
981
|
-
} = {}) {
|
|
982
|
-
if (preset) {
|
|
983
|
-
validatePreset(preset);
|
|
984
|
-
files = presetsObj[preset];
|
|
985
|
-
path = CUBEMAP_ROOT;
|
|
986
|
-
}
|
|
987
|
-
const multiFile = isArray(files);
|
|
988
|
-
const { format, isCubemap } = getFormat(files);
|
|
989
|
-
if (!format) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
990
|
-
const loader = useEnvironmentLoader(format);
|
|
991
|
-
const loaderResult = useLoader(
|
|
992
|
-
loader,
|
|
993
|
-
multiFile ? [files] : files,
|
|
994
|
-
(loader2) => {
|
|
995
|
-
loader2.setPath?.(path);
|
|
996
|
-
if (extensions) extensions(loader2);
|
|
997
928
|
}
|
|
998
|
-
);
|
|
999
|
-
const texture = multiFile ? (
|
|
1000
|
-
// @ts-ignore
|
|
1001
|
-
loaderResult[0]
|
|
1002
|
-
) : loaderResult;
|
|
1003
|
-
const three = getThree();
|
|
1004
|
-
texture.mapping = isCubemap ? three.CubeReflectionMapping : three.EquirectangularReflectionMapping;
|
|
1005
|
-
texture.colorSpace = colorSpace ?? (isCubemap && format !== "hdr-cube" ? "srgb" : "srgb-linear");
|
|
1006
|
-
return texture;
|
|
1007
|
-
}
|
|
1008
|
-
const preloadDefaultOptions = {
|
|
1009
|
-
files: defaultFiles,
|
|
1010
|
-
path: "",
|
|
1011
|
-
preset: void 0,
|
|
1012
|
-
extensions: void 0
|
|
1013
|
-
};
|
|
1014
|
-
useEnvironment.preload = (preloadOptions) => {
|
|
1015
|
-
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
1016
|
-
let { files, path = "" } = options;
|
|
1017
|
-
const { preset, extensions } = options;
|
|
1018
|
-
if (preset) {
|
|
1019
|
-
validatePreset(preset);
|
|
1020
|
-
files = presetsObj[preset];
|
|
1021
|
-
path = CUBEMAP_ROOT;
|
|
1022
|
-
}
|
|
1023
|
-
const { format } = getFormat(files);
|
|
1024
|
-
if (!format) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1025
|
-
const input = isArray(files) ? [files] : files;
|
|
1026
|
-
loadLoader(format).then((loader) => {
|
|
1027
|
-
useLoader.preload(loader, input, (loader2) => {
|
|
1028
|
-
loader2.setPath?.(path);
|
|
1029
|
-
if (extensions) extensions(loader2);
|
|
1030
|
-
});
|
|
1031
929
|
});
|
|
930
|
+
rootStore.subscribe((state2) => {
|
|
931
|
+
if (state2.internal.active) invalidate(state2);
|
|
932
|
+
});
|
|
933
|
+
return rootStore;
|
|
1032
934
|
};
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
const
|
|
1039
|
-
|
|
1040
|
-
const
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
} else {
|
|
1053
|
-
const pending = pendingLoaders.get(format);
|
|
1054
|
-
if (pending) void pending.then(clear, () => {
|
|
935
|
+
|
|
936
|
+
const shallowLoose$1 = { objects: "shallow", strict: false };
|
|
937
|
+
function configureScheduler(store, canvasId, schedulerConfig, previous) {
|
|
938
|
+
const state = store.getState();
|
|
939
|
+
const scheduler = getScheduler();
|
|
940
|
+
const rootId = state.internal.rootId;
|
|
941
|
+
const ordersItself = schedulerConfig?.before !== void 0 || schedulerConfig?.after !== void 0;
|
|
942
|
+
const rootBefore = schedulerConfig?.before;
|
|
943
|
+
const rootAfter = ordersItself ? schedulerConfig?.after : state.internal.sharedAfter;
|
|
944
|
+
if (!rootId) {
|
|
945
|
+
const newRootId = state.internal.pendingRootId ?? canvasId ?? scheduler.generateRootId();
|
|
946
|
+
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
947
|
+
// The scheduler spreads this into each frame state; see stateForScheduler
|
|
948
|
+
getState: () => stateForScheduler(store.getState()),
|
|
949
|
+
onError: (err) => store.getState().setError(err),
|
|
950
|
+
frameloop: store.getState().frameloop,
|
|
951
|
+
before: rootBefore,
|
|
952
|
+
after: rootAfter,
|
|
953
|
+
order: schedulerConfig?.order
|
|
1055
954
|
});
|
|
955
|
+
const unregisterCanvasTarget = scheduler.register(
|
|
956
|
+
() => {
|
|
957
|
+
const state2 = store.getState();
|
|
958
|
+
const canvasTarget = state2.internal.canvasTarget;
|
|
959
|
+
if (canvasTarget) {
|
|
960
|
+
const renderer = state2.internal.actualRenderer;
|
|
961
|
+
if (renderer.getCanvasTarget() !== canvasTarget) renderer.setCanvasTarget(canvasTarget);
|
|
962
|
+
if (state2.internal.canvasTargetSizeDirty) {
|
|
963
|
+
state2.internal.canvasTargetSizeDirty = false;
|
|
964
|
+
renderer.backend?.updateSize?.();
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
},
|
|
968
|
+
{
|
|
969
|
+
id: `${newRootId}_canvasTarget`,
|
|
970
|
+
rootId: newRootId,
|
|
971
|
+
phase: "start",
|
|
972
|
+
system: true
|
|
973
|
+
}
|
|
974
|
+
);
|
|
975
|
+
const unregisterEventsFlush = scheduler.register(
|
|
976
|
+
() => {
|
|
977
|
+
const state2 = store.getState();
|
|
978
|
+
state2.events.flush?.();
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
id: `${newRootId}_events`,
|
|
982
|
+
rootId: newRootId,
|
|
983
|
+
phase: "input",
|
|
984
|
+
system: true
|
|
985
|
+
}
|
|
986
|
+
);
|
|
987
|
+
const unregisterFrustum = scheduler.register(
|
|
988
|
+
() => {
|
|
989
|
+
const state2 = store.getState();
|
|
990
|
+
if (state2.autoUpdateFrustum && state2.camera) {
|
|
991
|
+
updateFrustum(state2.camera, state2.frustum);
|
|
992
|
+
}
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
id: `${newRootId}_frustum`,
|
|
996
|
+
rootId: newRootId,
|
|
997
|
+
before: "render",
|
|
998
|
+
system: true
|
|
999
|
+
}
|
|
1000
|
+
);
|
|
1001
|
+
const unregisterVisibility = scheduler.register(
|
|
1002
|
+
() => {
|
|
1003
|
+
const state2 = store.getState();
|
|
1004
|
+
checkVisibility(state2);
|
|
1005
|
+
},
|
|
1006
|
+
{
|
|
1007
|
+
id: `${newRootId}_visibility`,
|
|
1008
|
+
rootId: newRootId,
|
|
1009
|
+
before: "render",
|
|
1010
|
+
system: true,
|
|
1011
|
+
after: `${newRootId}_frustum`
|
|
1012
|
+
}
|
|
1013
|
+
);
|
|
1014
|
+
const unregisterRender = scheduler.register(
|
|
1015
|
+
() => {
|
|
1016
|
+
const state2 = store.getState();
|
|
1017
|
+
const renderer = state2.internal.actualRenderer;
|
|
1018
|
+
const userHandlesRender = scheduler.hasUserJobsInPhase("render", newRootId);
|
|
1019
|
+
if (userHandlesRender || state2.internal.priority) return;
|
|
1020
|
+
try {
|
|
1021
|
+
const renderOverride = state2.internal.renderOverride;
|
|
1022
|
+
if (renderOverride) renderOverride();
|
|
1023
|
+
else if (renderer?.render) renderer.render(state2.scene, state2.camera);
|
|
1024
|
+
} catch (error) {
|
|
1025
|
+
state2.setError(error instanceof Error ? error : new Error(String(error)));
|
|
1026
|
+
}
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
// Use canvas ID directly as job ID if available, otherwise use generated rootId
|
|
1030
|
+
id: canvasId || `${newRootId}_render`,
|
|
1031
|
+
rootId: newRootId,
|
|
1032
|
+
phase: "render",
|
|
1033
|
+
system: true,
|
|
1034
|
+
// Internal flag: this is a system job, not user-controlled
|
|
1035
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
1036
|
+
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
1037
|
+
}
|
|
1038
|
+
);
|
|
1039
|
+
state.set((state2) => ({
|
|
1040
|
+
internal: {
|
|
1041
|
+
...state2.internal,
|
|
1042
|
+
rootId: newRootId,
|
|
1043
|
+
pendingRootId: void 0,
|
|
1044
|
+
unregisterRoot: () => {
|
|
1045
|
+
unregisterRoot();
|
|
1046
|
+
unregisterCanvasTarget();
|
|
1047
|
+
unregisterEventsFlush();
|
|
1048
|
+
unregisterFrustum();
|
|
1049
|
+
unregisterVisibility();
|
|
1050
|
+
unregisterRender();
|
|
1051
|
+
},
|
|
1052
|
+
scheduler
|
|
1053
|
+
}
|
|
1054
|
+
}));
|
|
1055
|
+
} else {
|
|
1056
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, previous?.before, shallowLoose$1) || !is.equ(schedulerConfig?.after, previous?.after, shallowLoose$1);
|
|
1057
|
+
if (constraintsChanged) {
|
|
1058
|
+
scheduler.setRootConstraints(rootId, {
|
|
1059
|
+
before: rootBefore,
|
|
1060
|
+
after: rootAfter
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
if (schedulerConfig?.order !== previous?.order) {
|
|
1064
|
+
scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
1065
|
+
}
|
|
1056
1066
|
}
|
|
1057
|
-
};
|
|
1058
|
-
function validatePreset(preset) {
|
|
1059
|
-
if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
|
|
1060
|
-
}
|
|
1061
|
-
function getFormat(files) {
|
|
1062
|
-
const isCubemap = isArray(files) && files.length === 6;
|
|
1063
|
-
const firstEntry = isArray(files) ? files[0] : files;
|
|
1064
|
-
const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
1065
|
-
let format;
|
|
1066
|
-
if (isCubemap) format = firstExtension === "hdr" ? "hdr-cube" : "cube";
|
|
1067
|
-
else if (firstEntry.startsWith("data:application/exr")) format = "exr";
|
|
1068
|
-
else if (firstEntry.startsWith("data:application/hdr")) format = "hdr";
|
|
1069
|
-
else if (firstEntry.startsWith("data:image/jpeg")) format = "jpg";
|
|
1070
|
-
else if (firstExtension === "hdr" || firstExtension === "exr") format = firstExtension;
|
|
1071
|
-
else if (firstExtension === "jpg" || firstExtension === "jpeg") format = "jpg";
|
|
1072
|
-
return { format, isCubemap };
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
function useInstanceHandle(ref) {
|
|
1076
|
-
const instance = useRef(null);
|
|
1077
|
-
useImperativeHandle(instance, () => ref.current.__r3f, [ref]);
|
|
1078
|
-
return instance;
|
|
1079
|
-
}
|
|
1080
|
-
function useGraph(object) {
|
|
1081
|
-
return useMemo(() => buildGraph(object), [object]);
|
|
1082
1067
|
}
|
|
1083
|
-
|
|
1084
1068
|
let effectId = 0;
|
|
1085
1069
|
function addEffect(callback) {
|
|
1086
1070
|
notifyDepreciated({
|
|
@@ -1121,340 +1105,974 @@ function advance(timestamp, runGlobalEffects, state) {
|
|
|
1121
1105
|
else scheduler.step(timestamp);
|
|
1122
1106
|
}
|
|
1123
1107
|
|
|
1124
|
-
const
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1108
|
+
const isPromiseLike = (value) => typeof value?.then === "function";
|
|
1109
|
+
const fulfilled = (value) => Object.assign(Promise.resolve(value), { status: "fulfilled", value });
|
|
1110
|
+
const rejected = (reason) => {
|
|
1111
|
+
const promise = Promise.reject(reason);
|
|
1112
|
+
promise.catch(() => {
|
|
1113
|
+
});
|
|
1114
|
+
return Object.assign(promise, { status: "rejected", reason });
|
|
1115
|
+
};
|
|
1116
|
+
const deferred = () => {
|
|
1117
|
+
let resolve;
|
|
1118
|
+
let reject;
|
|
1119
|
+
const promise = new Promise((yes, no) => {
|
|
1120
|
+
resolve = (value) => {
|
|
1121
|
+
Object.assign(promise, { status: "fulfilled", value });
|
|
1122
|
+
yes(value);
|
|
1123
|
+
};
|
|
1124
|
+
reject = (reason) => {
|
|
1125
|
+
Object.assign(promise, { status: "rejected", reason });
|
|
1126
|
+
no(reason);
|
|
1127
|
+
};
|
|
1128
|
+
});
|
|
1129
|
+
promise.status = "pending";
|
|
1130
|
+
promise.catch(() => {
|
|
1131
|
+
});
|
|
1132
|
+
return { promise, resolve, reject };
|
|
1133
|
+
};
|
|
1134
|
+
function resolveThen(value, apply) {
|
|
1135
|
+
return isPromiseLike(value) ? Promise.resolve(value).then(apply) : apply(value);
|
|
1136
|
+
}
|
|
1127
1137
|
|
|
1128
|
-
|
|
1129
|
-
|
|
1138
|
+
const isRenderer = (def) => !!def?.render;
|
|
1139
|
+
function ensureStoreThreeObjects(store) {
|
|
1140
|
+
const state = store.getState();
|
|
1141
|
+
if (state.pointer) return;
|
|
1142
|
+
const { Vector2, Frustum } = getThree();
|
|
1143
|
+
const pointer = new Vector2();
|
|
1144
|
+
state.set({ pointer, mouse: pointer, frustum: new Frustum() });
|
|
1130
1145
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1146
|
+
const R3F_RENDERER_SETTINGS = ["textureColorSpace", "shadows"];
|
|
1147
|
+
const NON_APPLIED_RENDERER_PROPS = /* @__PURE__ */ new Set([
|
|
1148
|
+
...R3F_RENDERER_SETTINGS,
|
|
1149
|
+
"canvas",
|
|
1150
|
+
"antialias",
|
|
1151
|
+
"alpha",
|
|
1152
|
+
"samples",
|
|
1153
|
+
"powerPreference",
|
|
1154
|
+
"depth",
|
|
1155
|
+
"stencil",
|
|
1156
|
+
"logarithmicDepthBuffer",
|
|
1157
|
+
"reversedDepthBuffer",
|
|
1158
|
+
// WebGPURenderer only
|
|
1159
|
+
"forceWebGL",
|
|
1160
|
+
"outputBufferType",
|
|
1161
|
+
"multiview",
|
|
1162
|
+
"getFallback",
|
|
1163
|
+
"trackTimestamp"
|
|
1164
|
+
]);
|
|
1165
|
+
function settingsBag(config) {
|
|
1166
|
+
return is.obj(config) && !isRenderer(config) ? config : void 0;
|
|
1167
|
+
}
|
|
1168
|
+
function isInstanceOrFactory(config) {
|
|
1169
|
+
return is.fun(config) || isRenderer(config);
|
|
1170
|
+
}
|
|
1171
|
+
function assertNoRemovedConfig(props) {
|
|
1172
|
+
if (props.primaryCanvas !== void 0) {
|
|
1173
|
+
throw new Error(
|
|
1174
|
+
'R3F: `primaryCanvas` was removed: mark the owner <Canvas primary> and other canvases share it automatically (or use share="id")'
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1177
|
+
if (props.shadows !== void 0) {
|
|
1178
|
+
throw new Error(
|
|
1179
|
+
"R3F: the `shadows` Canvas prop moved into the renderer settings: use `renderer={{ shadows }}` (or `gl={{ shadows }}` for WebGL and @react-three/fiber/legacy)"
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
for (const name of ["renderer", "gl"]) {
|
|
1183
|
+
const bag = settingsBag(props[name]);
|
|
1184
|
+
if (!bag) continue;
|
|
1185
|
+
if ("primaryCanvas" in bag) {
|
|
1186
|
+
throw new Error(
|
|
1187
|
+
`R3F: \`${name}={{ primaryCanvas }}\` was removed: mark the owner <Canvas primary> and other canvases share it automatically (or use share="id")`
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
if ("scheduler" in bag) {
|
|
1191
|
+
throw new Error(`R3F: \`${name}={{ scheduler }}\` moved to <Canvas scheduler>`);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
function resolveRenderer(config, defaultProps, RendererClass) {
|
|
1196
|
+
if (typeof config === "function") {
|
|
1197
|
+
return resolveThen(config(defaultProps), (renderer) => ({
|
|
1198
|
+
renderer,
|
|
1199
|
+
owned: true
|
|
1200
|
+
}));
|
|
1201
|
+
}
|
|
1202
|
+
if (isRenderer(config)) return { renderer: config, owned: false };
|
|
1203
|
+
const params = { ...defaultProps };
|
|
1204
|
+
for (const key in settingsBag(config)) if (!R3F_RENDERER_SETTINGS.includes(key)) params[key] = config[key];
|
|
1205
|
+
return { renderer: new RendererClass(params), owned: true };
|
|
1206
|
+
}
|
|
1207
|
+
function createOwnedWebGPURenderer(rendererConfig, defaultGPUProps, canvas, propsSize, dpr, support) {
|
|
1208
|
+
return resolveThen(resolveRenderer(rendererConfig, defaultGPUProps, support.Renderer), (resolved) => {
|
|
1209
|
+
const renderer = resolved.renderer;
|
|
1210
|
+
if (!renderer.hasInitialized?.()) {
|
|
1211
|
+
const size = computeInitialSize(canvas, propsSize);
|
|
1212
|
+
if (size.width > 0 && size.height > 0) {
|
|
1213
|
+
renderer.setPixelRatio(calculateDpr(dpr));
|
|
1214
|
+
renderer.setSize(size.width, size.height, false);
|
|
1147
1215
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1216
|
+
return resolveThen(renderer.init(), () => ({ renderer, owned: resolved.owned }));
|
|
1217
|
+
}
|
|
1218
|
+
return { renderer, owned: resolved.owned };
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
function initializeRenderer(canvas, provider, store, props) {
|
|
1222
|
+
const {
|
|
1223
|
+
id: canvasId,
|
|
1224
|
+
primary = false,
|
|
1225
|
+
share,
|
|
1226
|
+
gl: glConfig,
|
|
1227
|
+
renderer: rendererConfig,
|
|
1228
|
+
size: propsSize,
|
|
1229
|
+
dpr = [1, 2],
|
|
1230
|
+
_primaryToken
|
|
1231
|
+
} = props;
|
|
1232
|
+
assertNoRemovedConfig(props);
|
|
1233
|
+
const rendererBag = settingsBag(rendererConfig);
|
|
1234
|
+
const state = store.getState();
|
|
1235
|
+
const { webgl, webgpu } = provider;
|
|
1236
|
+
const defaultGLProps = {
|
|
1237
|
+
canvas,
|
|
1238
|
+
powerPreference: "high-performance",
|
|
1239
|
+
antialias: true,
|
|
1240
|
+
alpha: true
|
|
1241
|
+
};
|
|
1242
|
+
const defaultGPUProps = {
|
|
1243
|
+
canvas,
|
|
1244
|
+
antialias: true
|
|
1245
|
+
};
|
|
1246
|
+
if (glConfig && !webgl) {
|
|
1247
|
+
throw new Error(
|
|
1248
|
+
"R3F: the `gl` prop configures WebGLRenderer, which is only available on @react-three/fiber/legacy. Import Canvas from @react-three/fiber/legacy to keep WebGL, or move these settings to the `renderer` prop for WebGPU."
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1251
|
+
if (rendererConfig && !webgpu) {
|
|
1252
|
+
throw new Error(
|
|
1253
|
+
"WebGPURenderer (renderer prop) is not available on this entry. Use @react-three/fiber or @react-three/fiber/webgpu instead."
|
|
1254
|
+
);
|
|
1255
|
+
}
|
|
1256
|
+
if (glConfig && rendererConfig) {
|
|
1257
|
+
throw new Error("Cannot use both gl and renderer props at the same time");
|
|
1258
|
+
}
|
|
1259
|
+
if (primary && !webgpu) {
|
|
1260
|
+
throw new Error(
|
|
1261
|
+
"R3F: <Canvas primary> shares a WebGPU renderer and is not available on this entry. Use @react-three/fiber or @react-three/fiber/webgpu instead."
|
|
1262
|
+
);
|
|
1263
|
+
}
|
|
1264
|
+
if (primary && glConfig) {
|
|
1265
|
+
throw new Error(
|
|
1266
|
+
"R3F: <Canvas primary> shares a WebGPU renderer and cannot be used with WebGL. Remove the `gl` prop or use the `renderer` prop."
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
if (primary && is.str(share)) {
|
|
1270
|
+
throw new Error(`R3F: a <Canvas primary> owns its renderer; remove share="${share}" from it.`);
|
|
1271
|
+
}
|
|
1272
|
+
if (is.str(share)) {
|
|
1273
|
+
if (!webgpu || glConfig) {
|
|
1274
|
+
throw new Error(
|
|
1275
|
+
`R3F: share="${share}" borrows a WebGPU renderer and cannot be used with WebGL. Remove the \`gl\` prop, or use @react-three/fiber or @react-three/fiber/webgpu.`
|
|
1276
|
+
);
|
|
1277
|
+
}
|
|
1278
|
+
if (isInstanceOrFactory(rendererConfig)) {
|
|
1279
|
+
throw new Error(
|
|
1280
|
+
`R3F: share="${share}" borrows the primary's renderer, so it cannot be combined with a renderer instance or factory. Remove one of the two.`
|
|
1281
|
+
);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
const primaryKey = canvasId || DEFAULT_PRIMARY;
|
|
1285
|
+
const primaryToken = _primaryToken ?? store;
|
|
1286
|
+
if (primary && !state.internal.actualRenderer) {
|
|
1287
|
+
announcePrimary(primaryKey, primaryToken);
|
|
1288
|
+
state.internal.unregisterPrimary = () => withdrawPrimary(primaryKey, primaryToken);
|
|
1289
|
+
if (primaryConflict(primaryKey, primaryToken)) {
|
|
1290
|
+
throw new Error(
|
|
1291
|
+
primaryKey === DEFAULT_PRIMARY ? 'R3F: two <Canvas primary> are mounted without ids. Give each primary a distinct `id`, and point the other canvases at one with share="id".' : `R3F: two <Canvas primary> use the id "${primaryKey}". Give each primary a distinct \`id\`.`
|
|
1292
|
+
);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
let shareKey;
|
|
1296
|
+
if (!state.internal.actualRenderer && webgpu && !primary && !glConfig && !state.isLegacy) {
|
|
1297
|
+
if (is.str(share)) {
|
|
1298
|
+
shareKey = share;
|
|
1299
|
+
} else if (share !== false && !isInstanceOrFactory(rendererConfig)) {
|
|
1300
|
+
const live = livePrimaryKeys();
|
|
1301
|
+
if (live.length > 1) {
|
|
1302
|
+
throw new Error(
|
|
1303
|
+
`R3F: ${live.length} primaries are mounted (${live.map(describePrimary).join(", ")}), so this canvas cannot pick one to share. Pass share="id" to name one, or share={false} for its own renderer.`
|
|
1304
|
+
);
|
|
1152
1305
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1306
|
+
shareKey = live[0];
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
const explicitShare = is.str(share);
|
|
1310
|
+
const wantsGL = !!webgl && (state.isLegacy || !!glConfig || !webgpu || !rendererConfig && !primary && shareKey === void 0);
|
|
1311
|
+
let renderer = state.internal.actualRenderer;
|
|
1312
|
+
if (!state.internal.actualRenderer) {
|
|
1313
|
+
return resolveThen(wantsGL ? webgl() : webgpu(), (support) => {
|
|
1314
|
+
registerThree(support.three);
|
|
1315
|
+
state.internal.support = support;
|
|
1316
|
+
ensureStoreThreeObjects(store);
|
|
1317
|
+
if (support.kind === "webgl") {
|
|
1318
|
+
return resolveThen(resolveRenderer(glConfig, defaultGLProps, support.Renderer), (resolved) => {
|
|
1319
|
+
renderer = resolved.renderer;
|
|
1320
|
+
state.internal.actualRenderer = renderer;
|
|
1321
|
+
state.internal.releaseRenderer = leaseRenderer(renderer, resolved.owned);
|
|
1322
|
+
state.set({ isLegacy: true, gl: renderer, renderer, primaryStore: store });
|
|
1323
|
+
});
|
|
1155
1324
|
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
if (
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
d = d.sibling;
|
|
1178
|
-
}
|
|
1179
|
-
throw Error(F(188));
|
|
1180
|
-
}
|
|
1181
|
-
if (a.return !== l.return) a = c, l = d;
|
|
1182
|
-
else {
|
|
1183
|
-
for (var h = false, y = c.child; y; ) {
|
|
1184
|
-
if (y === a) {
|
|
1185
|
-
h = true, a = c, l = d;
|
|
1186
|
-
break;
|
|
1187
|
-
}
|
|
1188
|
-
if (y === l) {
|
|
1189
|
-
h = true, l = c, a = d;
|
|
1190
|
-
break;
|
|
1191
|
-
}
|
|
1192
|
-
y = y.sibling;
|
|
1325
|
+
const primaryReady = shareKey === void 0 ? null : explicitShare ? waitForPrimary(shareKey) : waitForAnnouncedPrimary(shareKey);
|
|
1326
|
+
return resolveThen(primaryReady, (primaryEntry) => {
|
|
1327
|
+
if (primaryEntry && primaryEntry.store.getState().webGPUSupported) {
|
|
1328
|
+
renderer = primaryEntry.renderer;
|
|
1329
|
+
state.internal.actualRenderer = renderer;
|
|
1330
|
+
state.internal.releaseRenderer = borrowRenderer(renderer);
|
|
1331
|
+
state.internal.sharedAfter = primaryEntry.rootId;
|
|
1332
|
+
const canvasTarget = new support.CanvasTarget(canvas);
|
|
1333
|
+
primaryEntry.store.setState((prev) => ({
|
|
1334
|
+
internal: { ...prev.internal, isMultiCanvas: true }
|
|
1335
|
+
}));
|
|
1336
|
+
state.set((prev) => ({
|
|
1337
|
+
webGPUSupported: primaryEntry.store.getState().webGPUSupported,
|
|
1338
|
+
renderer,
|
|
1339
|
+
primaryStore: primaryEntry.store,
|
|
1340
|
+
internal: {
|
|
1341
|
+
...prev.internal,
|
|
1342
|
+
canvasTarget,
|
|
1343
|
+
isMultiCanvas: true,
|
|
1344
|
+
isSecondary: true,
|
|
1345
|
+
targetId: shareKey === DEFAULT_PRIMARY ? void 0 : shareKey
|
|
1193
1346
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1347
|
+
}));
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
if (primaryEntry) {
|
|
1351
|
+
return resolveThen(
|
|
1352
|
+
createOwnedWebGPURenderer(
|
|
1353
|
+
{ ...rendererBag, forceWebGL: true },
|
|
1354
|
+
defaultGPUProps,
|
|
1355
|
+
canvas,
|
|
1356
|
+
propsSize,
|
|
1357
|
+
dpr,
|
|
1358
|
+
support
|
|
1359
|
+
),
|
|
1360
|
+
(resolved) => {
|
|
1361
|
+
renderer = resolved.renderer;
|
|
1362
|
+
const backend = renderer.backend;
|
|
1363
|
+
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
1364
|
+
state.internal.actualRenderer = renderer;
|
|
1365
|
+
state.internal.releaseRenderer = leaseRenderer(renderer, resolved.owned);
|
|
1366
|
+
state.set((prev) => ({
|
|
1367
|
+
webGPUSupported: isWebGPUBackend,
|
|
1368
|
+
renderer,
|
|
1369
|
+
primaryStore: store,
|
|
1370
|
+
internal: {
|
|
1371
|
+
...prev.internal,
|
|
1372
|
+
canvasTarget: renderer.getCanvasTarget?.(),
|
|
1373
|
+
sharedRendererFallback: true
|
|
1203
1374
|
}
|
|
1204
|
-
|
|
1205
|
-
}
|
|
1206
|
-
if (!h) throw Error(F(189));
|
|
1375
|
+
}));
|
|
1207
1376
|
}
|
|
1208
|
-
|
|
1209
|
-
if (a.alternate !== l) throw Error(F(190));
|
|
1210
|
-
}
|
|
1211
|
-
if (a.tag !== 3) throw Error(F(188));
|
|
1212
|
-
return a.stateNode.current === a ? t : r;
|
|
1213
|
-
}
|
|
1214
|
-
function mc(t) {
|
|
1215
|
-
var r = t.tag;
|
|
1216
|
-
if (r === 5 || r === 26 || r === 27 || r === 6) return t;
|
|
1217
|
-
for (t = t.child; t !== null; ) {
|
|
1218
|
-
if (r = mc(t), r !== null) return r;
|
|
1219
|
-
t = t.sibling;
|
|
1220
|
-
}
|
|
1221
|
-
return null;
|
|
1222
|
-
}
|
|
1223
|
-
function ht(t) {
|
|
1224
|
-
var r = t.tag;
|
|
1225
|
-
if (r === 5 || r === 26 || r === 27 || r === 6) return t;
|
|
1226
|
-
for (t = t.child; t !== null; ) {
|
|
1227
|
-
if (t.tag !== 4 && (r = ht(t), r !== null)) return r;
|
|
1228
|
-
t = t.sibling;
|
|
1229
|
-
}
|
|
1230
|
-
return null;
|
|
1231
|
-
}
|
|
1232
|
-
function Ss(t) {
|
|
1233
|
-
return t === null || typeof t != "object" ? null : (t = ki && t[ki] || t["@@iterator"], typeof t == "function" ? t : null);
|
|
1234
|
-
}
|
|
1235
|
-
function gc(t) {
|
|
1236
|
-
if (t == null) return null;
|
|
1237
|
-
if (typeof t == "function") return t.$$typeof === Po ? null : t.displayName || t.name || null;
|
|
1238
|
-
if (typeof t == "string") return t;
|
|
1239
|
-
switch (t) {
|
|
1240
|
-
case wo:
|
|
1241
|
-
return "Fragment";
|
|
1242
|
-
case Pu:
|
|
1243
|
-
return "Profiler";
|
|
1244
|
-
case md:
|
|
1245
|
-
return "StrictMode";
|
|
1246
|
-
case xu:
|
|
1247
|
-
return "Suspense";
|
|
1248
|
-
case Cu:
|
|
1249
|
-
return "SuspenseList";
|
|
1250
|
-
case zu:
|
|
1251
|
-
return "Activity";
|
|
1252
|
-
case yd:
|
|
1253
|
-
return "ViewTransition";
|
|
1377
|
+
);
|
|
1254
1378
|
}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1379
|
+
return resolveThen(
|
|
1380
|
+
createOwnedWebGPURenderer(rendererConfig, defaultGPUProps, canvas, propsSize, dpr, support),
|
|
1381
|
+
(resolved) => {
|
|
1382
|
+
var _a;
|
|
1383
|
+
renderer = resolved.renderer;
|
|
1384
|
+
const backend = renderer.backend;
|
|
1385
|
+
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
1386
|
+
state.internal.actualRenderer = renderer;
|
|
1387
|
+
state.internal.releaseRenderer = leaseRenderer(renderer, resolved.owned);
|
|
1388
|
+
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
1389
|
+
if (primary) {
|
|
1390
|
+
const canvasTarget = renderer.getCanvasTarget?.();
|
|
1391
|
+
(_a = state.internal).pendingRootId ?? (_a.pendingRootId = canvasId || getScheduler().generateRootId());
|
|
1392
|
+
registerPrimary(primaryKey, renderer, store, {
|
|
1393
|
+
token: primaryToken,
|
|
1394
|
+
rootId: state.internal.pendingRootId
|
|
1395
|
+
});
|
|
1396
|
+
state.set((prev) => ({ internal: { ...prev.internal, canvasTarget } }));
|
|
1397
|
+
} else if (share !== false && !isInstanceOrFactory(rendererConfig)) {
|
|
1398
|
+
state.internal.untrackStandalone = trackStandalone(store);
|
|
1272
1399
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1400
|
+
}
|
|
1401
|
+
);
|
|
1402
|
+
});
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
const records = /* @__PURE__ */ new WeakMap();
|
|
1407
|
+
function take(renderer, record) {
|
|
1408
|
+
record.leases++;
|
|
1409
|
+
let released = false;
|
|
1410
|
+
return () => {
|
|
1411
|
+
if (released) return;
|
|
1412
|
+
released = true;
|
|
1413
|
+
if (--record.leases > 0) return;
|
|
1414
|
+
records.delete(renderer);
|
|
1415
|
+
if (record.owned) return disposeRenderer(renderer);
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
function leaseRenderer(renderer, owned) {
|
|
1419
|
+
let record = records.get(renderer);
|
|
1420
|
+
if (!record) records.set(renderer, record = { owned, leases: 0 });
|
|
1421
|
+
return take(renderer, record);
|
|
1422
|
+
}
|
|
1423
|
+
function borrowRenderer(renderer) {
|
|
1424
|
+
const record = records.get(renderer);
|
|
1425
|
+
if (!record) throw new Error("R3F: cannot share a renderer whose canvas has already unmounted");
|
|
1426
|
+
return take(renderer, record);
|
|
1427
|
+
}
|
|
1428
|
+
function disposeRenderer(renderer) {
|
|
1429
|
+
if (renderer.hasInitialized?.() === false) return;
|
|
1430
|
+
const warn = (error) => console.warn("[R3F] Error disposing renderer", error);
|
|
1431
|
+
const loseContext = () => {
|
|
1432
|
+
try {
|
|
1433
|
+
;
|
|
1434
|
+
renderer.forceContextLoss?.();
|
|
1435
|
+
} catch (error) {
|
|
1436
|
+
warn(error);
|
|
1437
|
+
}
|
|
1438
|
+
};
|
|
1439
|
+
let disposed;
|
|
1440
|
+
try {
|
|
1441
|
+
disposed = renderer.dispose ? renderer.dispose() : renderer.renderLists?.dispose?.();
|
|
1442
|
+
} catch (error) {
|
|
1443
|
+
warn(error);
|
|
1444
|
+
}
|
|
1445
|
+
if (typeof disposed?.then === "function") {
|
|
1446
|
+
return Promise.resolve(disposed).then(loseContext, (error) => {
|
|
1447
|
+
warn(error);
|
|
1448
|
+
loseContext();
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
loseContext();
|
|
1452
|
+
}
|
|
1453
|
+
const DEFAULT_PRIMARY = "\0r3f:primary";
|
|
1454
|
+
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
1455
|
+
const announcements = /* @__PURE__ */ new Map();
|
|
1456
|
+
const withdrawing = /* @__PURE__ */ new Set();
|
|
1457
|
+
const pendingSubscribers = /* @__PURE__ */ new Map();
|
|
1458
|
+
const standaloneRoots = /* @__PURE__ */ new Set();
|
|
1459
|
+
const warnedLatePrimary = /* @__PURE__ */ new WeakSet();
|
|
1460
|
+
function describePrimary(key) {
|
|
1461
|
+
return key === DEFAULT_PRIMARY ? "<Canvas primary>" : `<Canvas id="${key}" primary>`;
|
|
1462
|
+
}
|
|
1463
|
+
function notify(key, entry) {
|
|
1464
|
+
const subscribers = pendingSubscribers.get(key);
|
|
1465
|
+
if (!subscribers) return;
|
|
1466
|
+
pendingSubscribers.delete(key);
|
|
1467
|
+
subscribers.forEach((callback) => callback(entry));
|
|
1468
|
+
}
|
|
1469
|
+
function isLive(key) {
|
|
1470
|
+
const owners = announcements.get(key);
|
|
1471
|
+
if (owners) {
|
|
1472
|
+
for (const owner of owners) if (!withdrawing.has(owner)) return true;
|
|
1473
|
+
}
|
|
1474
|
+
const entry = primaryRegistry.get(key);
|
|
1475
|
+
return !!entry && !(entry.token && withdrawing.has(entry.token));
|
|
1476
|
+
}
|
|
1477
|
+
function announcePrimary(key, owner) {
|
|
1478
|
+
withdrawing.delete(owner);
|
|
1479
|
+
let owners = announcements.get(key);
|
|
1480
|
+
if (!owners) announcements.set(key, owners = /* @__PURE__ */ new Set());
|
|
1481
|
+
if (owners.has(owner)) return;
|
|
1482
|
+
owners.add(owner);
|
|
1483
|
+
if (standaloneRoots.size > 0 && !warnedLatePrimary.has(owner) && isDevelopment()) {
|
|
1484
|
+
warnedLatePrimary.add(owner);
|
|
1485
|
+
console.warn(
|
|
1486
|
+
`R3F: ${describePrimary(key)} mounted after ${standaloneRoots.size} other WebGPU canvas(es) had already created their own renderer; those keep it and do not share the primary. Mount the primary with or before the canvases that share it, or give them share="id" so they wait for it.`
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
function markWithdrawing(owner) {
|
|
1491
|
+
withdrawing.add(owner);
|
|
1492
|
+
}
|
|
1493
|
+
function withdrawPrimary(key, owner) {
|
|
1494
|
+
withdrawing.delete(owner);
|
|
1495
|
+
const owners = announcements.get(key);
|
|
1496
|
+
if (owners) {
|
|
1497
|
+
owners.delete(owner);
|
|
1498
|
+
if (owners.size === 0) announcements.delete(key);
|
|
1499
|
+
}
|
|
1500
|
+
const entry = primaryRegistry.get(key);
|
|
1501
|
+
if (entry?.token === owner) primaryRegistry.delete(key);
|
|
1502
|
+
if (!isLive(key)) notify(key, null);
|
|
1503
|
+
}
|
|
1504
|
+
function primaryConflict(key, owner) {
|
|
1505
|
+
const owners = announcements.get(key);
|
|
1506
|
+
if (owners) {
|
|
1507
|
+
for (const other of owners) {
|
|
1508
|
+
if (other === owner) break;
|
|
1509
|
+
if (!withdrawing.has(other)) return true;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
const entry = primaryRegistry.get(key);
|
|
1513
|
+
return !!entry && entry.token !== owner && !(entry.token && withdrawing.has(entry.token));
|
|
1514
|
+
}
|
|
1515
|
+
function livePrimaryKeys() {
|
|
1516
|
+
const keys = /* @__PURE__ */ new Set([...announcements.keys(), ...primaryRegistry.keys()]);
|
|
1517
|
+
return [...keys].filter(isLive);
|
|
1518
|
+
}
|
|
1519
|
+
function trackStandalone(owner) {
|
|
1520
|
+
standaloneRoots.add(owner);
|
|
1521
|
+
return () => {
|
|
1522
|
+
standaloneRoots.delete(owner);
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
function registerPrimary(id, renderer, store, options = {}) {
|
|
1526
|
+
if (options.token && !announcements.get(id)?.has(options.token)) return () => {
|
|
1527
|
+
};
|
|
1528
|
+
if (primaryRegistry.has(id)) {
|
|
1529
|
+
console.warn(`Canvas with id="${id}" already registered. Overwriting.`);
|
|
1530
|
+
}
|
|
1531
|
+
const entry = { renderer, store, rootId: options.rootId, token: options.token };
|
|
1532
|
+
primaryRegistry.set(id, entry);
|
|
1533
|
+
notify(id, entry);
|
|
1534
|
+
return () => {
|
|
1535
|
+
const currentEntry = primaryRegistry.get(id);
|
|
1536
|
+
if (currentEntry?.renderer === renderer) {
|
|
1537
|
+
primaryRegistry.delete(id);
|
|
1538
|
+
}
|
|
1539
|
+
};
|
|
1540
|
+
}
|
|
1541
|
+
function getPrimary(id) {
|
|
1542
|
+
return primaryRegistry.get(id);
|
|
1543
|
+
}
|
|
1544
|
+
function subscribe(id, callback) {
|
|
1545
|
+
if (!pendingSubscribers.has(id)) pendingSubscribers.set(id, []);
|
|
1546
|
+
pendingSubscribers.get(id).push(callback);
|
|
1547
|
+
return () => {
|
|
1548
|
+
const subscribers = pendingSubscribers.get(id);
|
|
1549
|
+
if (!subscribers) return;
|
|
1550
|
+
const index = subscribers.indexOf(callback);
|
|
1551
|
+
if (index !== -1) subscribers.splice(index, 1);
|
|
1552
|
+
if (subscribers.length === 0) pendingSubscribers.delete(id);
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
function waitForPrimary(id, timeout = 5e3) {
|
|
1556
|
+
const existing = primaryRegistry.get(id);
|
|
1557
|
+
if (existing) {
|
|
1558
|
+
return Promise.resolve(existing);
|
|
1559
|
+
}
|
|
1560
|
+
return new Promise((resolve, reject) => {
|
|
1561
|
+
let unsubscribe = () => {
|
|
1562
|
+
};
|
|
1563
|
+
const timeoutId = setTimeout(() => {
|
|
1564
|
+
unsubscribe();
|
|
1565
|
+
reject(
|
|
1566
|
+
new Error(
|
|
1567
|
+
`Timeout waiting for canvas with id="${id}". Make sure a <Canvas id="${id}" primary> is mounted for share="${id}".`
|
|
1568
|
+
)
|
|
1569
|
+
);
|
|
1570
|
+
}, timeout);
|
|
1571
|
+
const callback = (entry) => {
|
|
1572
|
+
if (!entry) {
|
|
1573
|
+
unsubscribe = subscribe(id, callback);
|
|
1574
|
+
return;
|
|
1411
1575
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1576
|
+
clearTimeout(timeoutId);
|
|
1577
|
+
resolve(entry);
|
|
1578
|
+
};
|
|
1579
|
+
unsubscribe = subscribe(id, callback);
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
function waitForAnnouncedPrimary(key, timeout = 5e3) {
|
|
1583
|
+
const existing = primaryRegistry.get(key);
|
|
1584
|
+
if (existing && isLive(key)) return Promise.resolve(existing);
|
|
1585
|
+
if (!isLive(key)) return Promise.resolve(null);
|
|
1586
|
+
return new Promise((resolve, reject) => {
|
|
1587
|
+
const timeoutId = setTimeout(() => {
|
|
1588
|
+
unsubscribe();
|
|
1589
|
+
reject(
|
|
1590
|
+
new Error(
|
|
1591
|
+
`Timeout waiting for ${describePrimary(key)} to create its renderer. A canvas mounted next to it shares its renderer automatically; pass share={false} to give it its own.`
|
|
1592
|
+
)
|
|
1593
|
+
);
|
|
1594
|
+
}, timeout);
|
|
1595
|
+
const unsubscribe = subscribe(key, (entry) => {
|
|
1596
|
+
clearTimeout(timeoutId);
|
|
1597
|
+
resolve(entry);
|
|
1598
|
+
});
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
function hasPrimary(id) {
|
|
1602
|
+
return primaryRegistry.has(id);
|
|
1603
|
+
}
|
|
1604
|
+
function unregisterPrimary(id) {
|
|
1605
|
+
primaryRegistry.delete(id);
|
|
1606
|
+
}
|
|
1607
|
+
function getPrimaryIds() {
|
|
1608
|
+
return Array.from(primaryRegistry.keys());
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
const shallowLoose = { objects: "shallow", strict: false };
|
|
1612
|
+
function watchDpr(onChange) {
|
|
1613
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function" || !window.devicePixelRatio) {
|
|
1614
|
+
return () => {
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
let watching = true;
|
|
1618
|
+
let query;
|
|
1619
|
+
const listen = () => {
|
|
1620
|
+
try {
|
|
1621
|
+
query = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
1622
|
+
if (typeof query?.addEventListener === "function") query.addEventListener("change", handleChange);
|
|
1623
|
+
else query?.addListener?.(handleChange);
|
|
1624
|
+
} catch {
|
|
1625
|
+
query = void 0;
|
|
1626
|
+
}
|
|
1627
|
+
};
|
|
1628
|
+
const unlisten = () => {
|
|
1629
|
+
if (typeof query?.removeEventListener === "function") query.removeEventListener("change", handleChange);
|
|
1630
|
+
else query?.removeListener?.(handleChange);
|
|
1631
|
+
query = void 0;
|
|
1632
|
+
};
|
|
1633
|
+
const handleChange = () => {
|
|
1634
|
+
if (!watching) return;
|
|
1635
|
+
unlisten();
|
|
1636
|
+
listen();
|
|
1637
|
+
onChange();
|
|
1638
|
+
};
|
|
1639
|
+
listen();
|
|
1640
|
+
return () => {
|
|
1641
|
+
watching = false;
|
|
1642
|
+
unlisten();
|
|
1643
|
+
};
|
|
1644
|
+
}
|
|
1645
|
+
function createRootConfiguration(store, canvas) {
|
|
1646
|
+
let previous;
|
|
1647
|
+
let lastCamera;
|
|
1648
|
+
const lastConfiguredProps = {};
|
|
1649
|
+
let resolvedDpr = 0;
|
|
1650
|
+
let dprChangedInXR = false;
|
|
1651
|
+
let unwatchDpr;
|
|
1652
|
+
const resolveDpr = () => {
|
|
1653
|
+
const state = store.getState();
|
|
1654
|
+
const xr = state.internal.actualRenderer?.xr;
|
|
1655
|
+
if (xr?.isPresenting || xr?.getSession?.()) {
|
|
1656
|
+
dprChangedInXR = true;
|
|
1657
|
+
return;
|
|
1658
|
+
}
|
|
1659
|
+
dprChangedInXR = false;
|
|
1660
|
+
const dpr = lastConfiguredProps.dpr;
|
|
1661
|
+
if (dpr === void 0 || state.viewport.dpr !== resolvedDpr || calculateDpr(dpr) === resolvedDpr) return;
|
|
1662
|
+
state.setDpr(dpr);
|
|
1663
|
+
resolvedDpr = store.getState().viewport.dpr;
|
|
1664
|
+
};
|
|
1665
|
+
let warnedSharedSettings = false;
|
|
1666
|
+
let configured = false;
|
|
1667
|
+
return (props) => {
|
|
1668
|
+
const {
|
|
1669
|
+
gl: glConfig,
|
|
1670
|
+
renderer: rendererConfig,
|
|
1671
|
+
size: propsSize,
|
|
1672
|
+
scene: sceneOptions,
|
|
1673
|
+
events,
|
|
1674
|
+
orthographic = false,
|
|
1675
|
+
frameloop = "always",
|
|
1676
|
+
dpr = [1, 2],
|
|
1677
|
+
performance,
|
|
1678
|
+
raycaster: raycastOptions,
|
|
1679
|
+
camera: cameraOptions,
|
|
1680
|
+
onPointerMissed,
|
|
1681
|
+
onDragOverMissed,
|
|
1682
|
+
onDropMissed,
|
|
1683
|
+
autoUpdateFrustum = true,
|
|
1684
|
+
occlusion = false,
|
|
1685
|
+
_sizeProps,
|
|
1686
|
+
forceEven
|
|
1687
|
+
} = props;
|
|
1688
|
+
assertNoRemovedConfig(props);
|
|
1689
|
+
const rendererBag = settingsBag(rendererConfig);
|
|
1690
|
+
const settings = settingsBag(glConfig) ?? rendererBag;
|
|
1691
|
+
const requestedTextureColorSpace = settings?.textureColorSpace || void 0;
|
|
1692
|
+
const shadows = isInstanceOrFactory(glConfig ?? rendererConfig) ? void 0 : settings?.shadows ?? false;
|
|
1693
|
+
const next = { ...props, shadows, frameloop, autoUpdateFrustum, occlusion };
|
|
1694
|
+
const last = previous;
|
|
1695
|
+
const changed = (key) => !last || !is.equ(next[key], last[key], { objects: "shallow" });
|
|
1696
|
+
previous = void 0;
|
|
1697
|
+
const state = store.getState();
|
|
1698
|
+
const renderer = state.internal.actualRenderer;
|
|
1699
|
+
const three = getThree();
|
|
1700
|
+
const borrowsRenderer = state.internal.isSecondary === true;
|
|
1701
|
+
if (borrowsRenderer && !warnedSharedSettings && rendererBag && Object.keys(rendererBag).some((key) => key !== "textureColorSpace") && isDevelopment()) {
|
|
1702
|
+
warnedSharedSettings = true;
|
|
1703
|
+
console.warn(
|
|
1704
|
+
"R3F: renderer settings on a sharing canvas are ignored; set them on the <Canvas primary>. This canvas borrows the primary's renderer, so renderer-wide settings come from the primary. Pass share={false} to give this canvas its own renderer."
|
|
1705
|
+
);
|
|
1706
|
+
}
|
|
1707
|
+
let raycaster = state.raycaster;
|
|
1708
|
+
if (!raycaster) state.set({ raycaster: raycaster = new three.Raycaster() });
|
|
1709
|
+
if (changed("raycaster")) {
|
|
1710
|
+
const { params, ...options } = raycastOptions || {};
|
|
1711
|
+
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options });
|
|
1712
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) {
|
|
1713
|
+
applyProps(raycaster, { params: { ...raycaster.params, ...params } });
|
|
1414
1714
|
}
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1715
|
+
}
|
|
1716
|
+
let tempCamera = state.camera;
|
|
1717
|
+
if (!state.camera || state.camera === lastCamera && changed("camera")) {
|
|
1718
|
+
lastCamera = cameraOptions;
|
|
1719
|
+
const isCamera = cameraOptions?.isCamera;
|
|
1720
|
+
const camera = isCamera ? cameraOptions : orthographic ? new three.OrthographicCamera(0, 0, 0, 0, 0.1, 1e3) : new three.PerspectiveCamera(50, 0, 0.1, 1e3);
|
|
1721
|
+
if (!isCamera) {
|
|
1722
|
+
camera.position.z = 5;
|
|
1723
|
+
if (cameraOptions) {
|
|
1724
|
+
applyProps(camera, cameraOptions);
|
|
1725
|
+
if (!camera.manual) {
|
|
1726
|
+
const projectionProps = ["aspect", "left", "right", "bottom", "top"];
|
|
1727
|
+
if (projectionProps.some((prop) => prop in cameraOptions)) {
|
|
1728
|
+
camera.manual = true;
|
|
1729
|
+
camera.updateProjectionMatrix();
|
|
1730
|
+
}
|
|
1426
1731
|
}
|
|
1427
|
-
a &= ~U;
|
|
1428
1732
|
}
|
|
1429
|
-
|
|
1430
|
-
}
|
|
1431
|
-
function en(t, r, a) {
|
|
1432
|
-
t.pendingLanes |= r, t.suspendedLanes &= ~r;
|
|
1433
|
-
var l = 31 - sn(r);
|
|
1434
|
-
t.entangledLanes |= r, t.entanglements[l] = t.entanglements[l] | 1073741824 | a & 261930;
|
|
1733
|
+
if (!state.camera && !cameraOptions?.rotation) camera.lookAt(0, 0, 0);
|
|
1435
1734
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1735
|
+
state.set({ camera });
|
|
1736
|
+
tempCamera = camera;
|
|
1737
|
+
raycaster.camera = camera;
|
|
1738
|
+
}
|
|
1739
|
+
if (!state.scene) {
|
|
1740
|
+
let scene;
|
|
1741
|
+
if (sceneOptions?.isScene) {
|
|
1742
|
+
scene = sceneOptions;
|
|
1743
|
+
prepare(scene, store, "", {});
|
|
1744
|
+
} else {
|
|
1745
|
+
scene = new three.Scene();
|
|
1746
|
+
prepare(scene, store, "", {});
|
|
1747
|
+
if (sceneOptions) applyProps(scene, sceneOptions);
|
|
1748
|
+
}
|
|
1749
|
+
state.set((prev) => ({
|
|
1750
|
+
scene,
|
|
1751
|
+
rootScene: scene,
|
|
1752
|
+
internal: { ...prev.internal, container: scene }
|
|
1753
|
+
}));
|
|
1754
|
+
const camera = tempCamera;
|
|
1755
|
+
if (camera && !camera.parent) scene.add(camera);
|
|
1756
|
+
}
|
|
1757
|
+
if (events && !state.events.handlers) {
|
|
1758
|
+
state.set({ events: events(store) });
|
|
1759
|
+
let wasEnabled = true;
|
|
1760
|
+
store.subscribe((state2) => {
|
|
1761
|
+
const { enabled } = state2.events;
|
|
1762
|
+
if (enabled && !wasEnabled) {
|
|
1763
|
+
state2.events.update?.();
|
|
1764
|
+
}
|
|
1765
|
+
wasEnabled = enabled;
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
if (_sizeProps !== void 0 && changed("_sizeProps")) {
|
|
1769
|
+
state.set({ _sizeProps });
|
|
1770
|
+
}
|
|
1771
|
+
if (forceEven !== void 0 && state.internal.forceEven !== forceEven) {
|
|
1772
|
+
state.set((prev) => ({ internal: { ...prev.internal, forceEven } }));
|
|
1773
|
+
}
|
|
1774
|
+
configureSize(store, computeInitialSize(canvas, propsSize));
|
|
1775
|
+
if (dpr !== void 0 && (!last || !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose))) {
|
|
1776
|
+
state.setDpr(dpr);
|
|
1777
|
+
lastConfiguredProps.dpr = dpr;
|
|
1778
|
+
resolvedDpr = store.getState().viewport.dpr;
|
|
1779
|
+
}
|
|
1780
|
+
const internal = store.getState().internal;
|
|
1781
|
+
if (Array.isArray(dpr) && (!unwatchDpr || internal.unwatchDpr !== unwatchDpr)) {
|
|
1782
|
+
internal.unwatchDpr?.();
|
|
1783
|
+
internal.unwatchDpr = unwatchDpr = watchDpr(resolveDpr);
|
|
1784
|
+
}
|
|
1785
|
+
resolveDpr();
|
|
1786
|
+
if (frameloop !== void 0 && changed("frameloop")) {
|
|
1787
|
+
state.setFrameloop(frameloop);
|
|
1788
|
+
}
|
|
1789
|
+
if (changed("onPointerMissed")) state.set({ onPointerMissed });
|
|
1790
|
+
if (changed("onDragOverMissed")) state.set({ onDragOverMissed });
|
|
1791
|
+
if (changed("onDropMissed")) state.set({ onDropMissed });
|
|
1792
|
+
if (changed("autoUpdateFrustum") && state.autoUpdateFrustum !== autoUpdateFrustum) {
|
|
1793
|
+
state.set({ autoUpdateFrustum });
|
|
1794
|
+
}
|
|
1795
|
+
if (occlusion && !state.internal.occlusionEnabled) {
|
|
1796
|
+
enableOcclusion(store);
|
|
1797
|
+
}
|
|
1798
|
+
if (performance && changed("performance")) {
|
|
1799
|
+
state.set((state2) => ({ performance: { ...state2.performance, ...performance } }));
|
|
1800
|
+
}
|
|
1801
|
+
if (!state.xr) {
|
|
1802
|
+
const handleXRFrame = (timestamp, _frame) => {
|
|
1803
|
+
const state2 = store.getState();
|
|
1804
|
+
if (state2.frameloop === "never") return;
|
|
1805
|
+
advance(timestamp, true, state2);
|
|
1806
|
+
};
|
|
1807
|
+
const actualRenderer = state.internal.actualRenderer;
|
|
1808
|
+
const handleSessionChange = () => {
|
|
1809
|
+
const state2 = store.getState();
|
|
1810
|
+
const renderer2 = state2.internal.actualRenderer;
|
|
1811
|
+
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
1812
|
+
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
1813
|
+
if (!renderer2.xr.isPresenting) {
|
|
1814
|
+
if (dprChangedInXR) resolveDpr();
|
|
1815
|
+
invalidate(state2);
|
|
1816
|
+
}
|
|
1817
|
+
};
|
|
1818
|
+
const xr = {
|
|
1819
|
+
connect() {
|
|
1820
|
+
const xrManager = store.getState().renderer.xr;
|
|
1821
|
+
xrManager.addEventListener("sessionstart", handleSessionChange);
|
|
1822
|
+
xrManager.addEventListener("sessionend", handleSessionChange);
|
|
1823
|
+
},
|
|
1824
|
+
disconnect() {
|
|
1825
|
+
const xrManager = store.getState().renderer.xr;
|
|
1826
|
+
xrManager.removeEventListener("sessionstart", handleSessionChange);
|
|
1827
|
+
xrManager.removeEventListener("sessionend", handleSessionChange);
|
|
1828
|
+
}
|
|
1829
|
+
};
|
|
1830
|
+
if (!borrowsRenderer && typeof renderer.xr?.addEventListener === "function") xr.connect();
|
|
1831
|
+
state.set({ xr });
|
|
1832
|
+
}
|
|
1833
|
+
if (!borrowsRenderer && shadows !== void 0 && renderer.shadowMap && changed("shadows")) {
|
|
1834
|
+
const oldEnabled = renderer.shadowMap.enabled;
|
|
1835
|
+
const oldType = renderer.shadowMap.type;
|
|
1836
|
+
renderer.shadowMap.enabled = !!shadows;
|
|
1837
|
+
if (is.boo(shadows)) {
|
|
1838
|
+
renderer.shadowMap.type = three.PCFShadowMap;
|
|
1839
|
+
} else if (is.str(shadows)) {
|
|
1840
|
+
if (shadows === "soft") {
|
|
1841
|
+
notifyDepreciated({
|
|
1842
|
+
heading: 'shadows="soft" is deprecated',
|
|
1843
|
+
body: "Three has depreciated soft and improved basic PCFShadows, we converted for you.",
|
|
1844
|
+
link: "https://github.com/mrdoob/three.js/wiki/Migration-Guide?utm_source=chatgpt.com#181--182"
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
const types = {
|
|
1848
|
+
basic: three.BasicShadowMap,
|
|
1849
|
+
percentage: three.PCFShadowMap,
|
|
1850
|
+
soft: three.PCFShadowMap,
|
|
1851
|
+
variance: three.VSMShadowMap
|
|
1852
|
+
};
|
|
1853
|
+
renderer.shadowMap.type = types[shadows] ?? three.PCFShadowMap;
|
|
1854
|
+
} else if (is.obj(shadows)) {
|
|
1855
|
+
Object.assign(renderer.shadowMap, shadows);
|
|
1442
1856
|
}
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
return a = (a & 42) !== 0 ? 1 : mn(a), (a & (t.suspendedLanes | r)) !== 0 ? 0 : a;
|
|
1857
|
+
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type) {
|
|
1858
|
+
renderer.shadowMap.needsUpdate = true;
|
|
1446
1859
|
}
|
|
1447
|
-
|
|
1860
|
+
}
|
|
1861
|
+
if (!configured && !borrowsRenderer) {
|
|
1862
|
+
renderer.outputColorSpace = three.SRGBColorSpace;
|
|
1863
|
+
renderer.toneMapping = three.ACESFilmicToneMapping;
|
|
1864
|
+
}
|
|
1865
|
+
const textureColorSpace = requestedTextureColorSpace ?? three.SRGBColorSpace;
|
|
1866
|
+
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
1867
|
+
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
1868
|
+
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
1869
|
+
}
|
|
1870
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && changed("gl")) {
|
|
1871
|
+
const glProps = {};
|
|
1872
|
+
for (const key in glConfig) {
|
|
1873
|
+
if (!NON_APPLIED_RENDERER_PROPS.has(key)) glProps[key] = glConfig[key];
|
|
1874
|
+
}
|
|
1875
|
+
applyProps(renderer, glProps);
|
|
1876
|
+
}
|
|
1877
|
+
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer && !borrowsRenderer) {
|
|
1878
|
+
const currentRenderer = state.renderer;
|
|
1879
|
+
if (changed("renderer")) {
|
|
1880
|
+
const rendererProps = {};
|
|
1881
|
+
for (const key in rendererConfig) {
|
|
1882
|
+
if (!NON_APPLIED_RENDERER_PROPS.has(key)) rendererProps[key] = rendererConfig[key];
|
|
1883
|
+
}
|
|
1884
|
+
applyProps(currentRenderer, rendererProps);
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
configured = true;
|
|
1888
|
+
previous = next;
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
const version = "10.0.0-alpha.6";
|
|
1893
|
+
const packageData = {
|
|
1894
|
+
version: version};
|
|
1895
|
+
|
|
1896
|
+
function $1(Ut) {
|
|
1897
|
+
return Ut && Ut.__esModule && Object.prototype.hasOwnProperty.call(Ut, "default") ? Ut.default : Ut;
|
|
1898
|
+
}
|
|
1899
|
+
var S0 = { exports: {} }, Ob = { exports: {} }, P1;
|
|
1900
|
+
function Q1() {
|
|
1901
|
+
return P1 || (P1 = 1, (function(Ut) {
|
|
1902
|
+
Ut.exports = function(m) {
|
|
1903
|
+
function et(t, r, a, l) {
|
|
1904
|
+
return new Fe(t, r, a, l);
|
|
1905
|
+
}
|
|
1906
|
+
function zf() {
|
|
1907
|
+
}
|
|
1908
|
+
function F(t) {
|
|
1909
|
+
var r = "https://react.dev/errors/" + t;
|
|
1910
|
+
if (1 < arguments.length) {
|
|
1911
|
+
r += "?args[]=" + encodeURIComponent(arguments[1]);
|
|
1912
|
+
for (var a = 2; a < arguments.length; a++) r += "&args[]=" + encodeURIComponent(arguments[a]);
|
|
1913
|
+
}
|
|
1914
|
+
return "Minified React error #" + t + "; visit " + r + " for the full message or use the non-minified dev environment for full errors and additional helpful warnings.";
|
|
1915
|
+
}
|
|
1916
|
+
function Ef(t) {
|
|
1917
|
+
for (var r = t, a = r; a && !a.alternate; ) r = a, (r.flags & 4098) !== 0 && (t = r.return), a = r.return;
|
|
1918
|
+
for (; r.return; ) r = r.return;
|
|
1919
|
+
return r.tag === 3 ? t : null;
|
|
1920
|
+
}
|
|
1921
|
+
function pc(t) {
|
|
1922
|
+
if (Ef(t) !== t) throw Error(F(188));
|
|
1923
|
+
}
|
|
1924
|
+
function hc(t) {
|
|
1925
|
+
var r = t.alternate;
|
|
1926
|
+
if (!r) {
|
|
1927
|
+
if (r = Ef(t), r === null) throw Error(F(188));
|
|
1928
|
+
return r !== t ? null : t;
|
|
1929
|
+
}
|
|
1930
|
+
for (var a = t, l = r; ; ) {
|
|
1931
|
+
var c = a.return;
|
|
1932
|
+
if (c === null) break;
|
|
1933
|
+
var d = c.alternate;
|
|
1934
|
+
if (d === null) {
|
|
1935
|
+
if (l = c.return, l !== null) {
|
|
1936
|
+
a = l;
|
|
1937
|
+
continue;
|
|
1938
|
+
}
|
|
1939
|
+
break;
|
|
1940
|
+
}
|
|
1941
|
+
if (c.child === d.child) {
|
|
1942
|
+
for (d = c.child; d; ) {
|
|
1943
|
+
if (d === a) return pc(c), t;
|
|
1944
|
+
if (d === l) return pc(c), r;
|
|
1945
|
+
d = d.sibling;
|
|
1946
|
+
}
|
|
1947
|
+
throw Error(F(188));
|
|
1948
|
+
}
|
|
1949
|
+
if (a.return !== l.return) a = c, l = d;
|
|
1950
|
+
else {
|
|
1951
|
+
for (var h = false, y = c.child; y; ) {
|
|
1952
|
+
if (y === a) {
|
|
1953
|
+
h = true, a = c, l = d;
|
|
1954
|
+
break;
|
|
1955
|
+
}
|
|
1956
|
+
if (y === l) {
|
|
1957
|
+
h = true, l = c, a = d;
|
|
1958
|
+
break;
|
|
1959
|
+
}
|
|
1960
|
+
y = y.sibling;
|
|
1961
|
+
}
|
|
1962
|
+
if (!h) {
|
|
1963
|
+
for (y = d.child; y; ) {
|
|
1964
|
+
if (y === a) {
|
|
1965
|
+
h = true, a = d, l = c;
|
|
1966
|
+
break;
|
|
1967
|
+
}
|
|
1968
|
+
if (y === l) {
|
|
1969
|
+
h = true, l = d, a = c;
|
|
1970
|
+
break;
|
|
1971
|
+
}
|
|
1972
|
+
y = y.sibling;
|
|
1973
|
+
}
|
|
1974
|
+
if (!h) throw Error(F(189));
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
if (a.alternate !== l) throw Error(F(190));
|
|
1978
|
+
}
|
|
1979
|
+
if (a.tag !== 3) throw Error(F(188));
|
|
1980
|
+
return a.stateNode.current === a ? t : r;
|
|
1981
|
+
}
|
|
1982
|
+
function mc(t) {
|
|
1983
|
+
var r = t.tag;
|
|
1984
|
+
if (r === 5 || r === 26 || r === 27 || r === 6) return t;
|
|
1985
|
+
for (t = t.child; t !== null; ) {
|
|
1986
|
+
if (r = mc(t), r !== null) return r;
|
|
1987
|
+
t = t.sibling;
|
|
1988
|
+
}
|
|
1989
|
+
return null;
|
|
1990
|
+
}
|
|
1991
|
+
function ht(t) {
|
|
1992
|
+
var r = t.tag;
|
|
1993
|
+
if (r === 5 || r === 26 || r === 27 || r === 6) return t;
|
|
1994
|
+
for (t = t.child; t !== null; ) {
|
|
1995
|
+
if (t.tag !== 4 && (r = ht(t), r !== null)) return r;
|
|
1996
|
+
t = t.sibling;
|
|
1997
|
+
}
|
|
1998
|
+
return null;
|
|
1999
|
+
}
|
|
2000
|
+
function Ss(t) {
|
|
2001
|
+
return t === null || typeof t != "object" ? null : (t = ki && t[ki] || t["@@iterator"], typeof t == "function" ? t : null);
|
|
2002
|
+
}
|
|
2003
|
+
function gc(t) {
|
|
2004
|
+
if (t == null) return null;
|
|
2005
|
+
if (typeof t == "function") return t.$$typeof === Po ? null : t.displayName || t.name || null;
|
|
2006
|
+
if (typeof t == "string") return t;
|
|
1448
2007
|
switch (t) {
|
|
2008
|
+
case wo:
|
|
2009
|
+
return "Fragment";
|
|
2010
|
+
case Pu:
|
|
2011
|
+
return "Profiler";
|
|
2012
|
+
case md:
|
|
2013
|
+
return "StrictMode";
|
|
2014
|
+
case xu:
|
|
2015
|
+
return "Suspense";
|
|
2016
|
+
case Cu:
|
|
2017
|
+
return "SuspenseList";
|
|
2018
|
+
case zu:
|
|
2019
|
+
return "Activity";
|
|
2020
|
+
case yd:
|
|
2021
|
+
return "ViewTransition";
|
|
2022
|
+
}
|
|
2023
|
+
if (typeof t == "object") switch (t.$$typeof) {
|
|
2024
|
+
case Si:
|
|
2025
|
+
return "Portal";
|
|
2026
|
+
case Vr:
|
|
2027
|
+
return t.displayName || "Context";
|
|
2028
|
+
case gd:
|
|
2029
|
+
return (t._context.displayName || "Context") + ".Consumer";
|
|
2030
|
+
case bd:
|
|
2031
|
+
var r = t.render;
|
|
2032
|
+
return t = t.displayName, t || (t = r.displayName || r.name || "", t = t !== "" ? "ForwardRef(" + t + ")" : "ForwardRef"), t;
|
|
2033
|
+
case Fl:
|
|
2034
|
+
return r = t.displayName || null, r !== null ? r : gc(t.type) || "Memo";
|
|
2035
|
+
case Ra:
|
|
2036
|
+
r = t._payload, t = t._init;
|
|
2037
|
+
try {
|
|
2038
|
+
return gc(t(r));
|
|
2039
|
+
} catch {
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
return null;
|
|
2043
|
+
}
|
|
2044
|
+
function oo(t) {
|
|
2045
|
+
return { current: t };
|
|
2046
|
+
}
|
|
2047
|
+
function W(t) {
|
|
2048
|
+
0 > Wa || (t.current = Ml[Wa], Ml[Wa] = null, Wa--);
|
|
2049
|
+
}
|
|
2050
|
+
function Te(t, r) {
|
|
2051
|
+
Wa++, Ml[Wa] = t.current, t.current = r;
|
|
2052
|
+
}
|
|
2053
|
+
function k0(t) {
|
|
2054
|
+
return t >>>= 0, t === 0 ? 32 : 31 - (Fd(t) / lh | 0) | 0;
|
|
2055
|
+
}
|
|
2056
|
+
function ma(t) {
|
|
2057
|
+
var r = t & 42;
|
|
2058
|
+
if (r !== 0) return r;
|
|
2059
|
+
switch (t & -t) {
|
|
2060
|
+
case 1:
|
|
2061
|
+
return 1;
|
|
1449
2062
|
case 2:
|
|
1450
|
-
|
|
1451
|
-
|
|
2063
|
+
return 2;
|
|
2064
|
+
case 4:
|
|
2065
|
+
return 4;
|
|
1452
2066
|
case 8:
|
|
1453
|
-
|
|
1454
|
-
|
|
2067
|
+
return 8;
|
|
2068
|
+
case 16:
|
|
2069
|
+
return 16;
|
|
1455
2070
|
case 32:
|
|
1456
|
-
|
|
1457
|
-
|
|
2071
|
+
return 32;
|
|
2072
|
+
case 64:
|
|
2073
|
+
return 64;
|
|
2074
|
+
case 128:
|
|
2075
|
+
return 128;
|
|
1458
2076
|
case 256:
|
|
1459
2077
|
case 512:
|
|
1460
2078
|
case 1024:
|
|
@@ -1465,30 +2083,180 @@ function Q1() {
|
|
|
1465
2083
|
case 32768:
|
|
1466
2084
|
case 65536:
|
|
1467
2085
|
case 131072:
|
|
2086
|
+
return t & -t;
|
|
1468
2087
|
case 262144:
|
|
1469
2088
|
case 524288:
|
|
1470
2089
|
case 1048576:
|
|
1471
2090
|
case 2097152:
|
|
2091
|
+
return t & 3932160;
|
|
1472
2092
|
case 4194304:
|
|
1473
2093
|
case 8388608:
|
|
1474
2094
|
case 16777216:
|
|
1475
2095
|
case 33554432:
|
|
1476
|
-
t
|
|
1477
|
-
|
|
2096
|
+
return t & 62914560;
|
|
2097
|
+
case 67108864:
|
|
2098
|
+
return 67108864;
|
|
2099
|
+
case 134217728:
|
|
2100
|
+
return 134217728;
|
|
1478
2101
|
case 268435456:
|
|
1479
|
-
|
|
1480
|
-
|
|
2102
|
+
return 268435456;
|
|
2103
|
+
case 536870912:
|
|
2104
|
+
return 536870912;
|
|
2105
|
+
case 1073741824:
|
|
2106
|
+
return 0;
|
|
1481
2107
|
default:
|
|
1482
|
-
t
|
|
2108
|
+
return t;
|
|
1483
2109
|
}
|
|
1484
|
-
return t;
|
|
1485
2110
|
}
|
|
1486
|
-
function
|
|
1487
|
-
|
|
2111
|
+
function ao(t, r, a) {
|
|
2112
|
+
var l = t.pendingLanes;
|
|
2113
|
+
if (l === 0) return 0;
|
|
2114
|
+
var c = 0, d = t.suspendedLanes, h = t.pingedLanes;
|
|
2115
|
+
t = t.warmLanes;
|
|
2116
|
+
var y = l & 134217727;
|
|
2117
|
+
return y !== 0 ? (l = y & ~d, l !== 0 ? c = ma(l) : (h &= y, h !== 0 ? c = ma(h) : a || (a = y & ~t, a !== 0 && (c = ma(a))))) : (y = l & ~d, y !== 0 ? c = ma(y) : h !== 0 ? c = ma(h) : a || (a = l & ~t, a !== 0 && (c = ma(a)))), c === 0 ? 0 : r !== 0 && r !== c && (r & d) === 0 && (d = c & -c, a = r & -r, d >= a || d === 32 && (a & 4194048) !== 0) ? r : c;
|
|
1488
2118
|
}
|
|
1489
|
-
function
|
|
1490
|
-
|
|
1491
|
-
|
|
2119
|
+
function Yi(t, r) {
|
|
2120
|
+
return (t.pendingLanes & ~(t.suspendedLanes & ~t.pingedLanes) & r) === 0;
|
|
2121
|
+
}
|
|
2122
|
+
function _f(t, r) {
|
|
2123
|
+
(r & 8) !== 0 && (r |= r & 32);
|
|
2124
|
+
var a = t.entangledLanes;
|
|
2125
|
+
if (a !== 0) for (t = t.entanglements, a &= r; 0 < a; ) {
|
|
2126
|
+
var l = 31 - sn(a), c = 1 << l;
|
|
2127
|
+
r |= t[l], a &= ~c;
|
|
2128
|
+
}
|
|
2129
|
+
return r;
|
|
2130
|
+
}
|
|
2131
|
+
function am(t, r) {
|
|
2132
|
+
switch (t) {
|
|
2133
|
+
case 1:
|
|
2134
|
+
case 2:
|
|
2135
|
+
case 4:
|
|
2136
|
+
case 8:
|
|
2137
|
+
case 64:
|
|
2138
|
+
return r + 250;
|
|
2139
|
+
case 16:
|
|
2140
|
+
case 32:
|
|
2141
|
+
case 128:
|
|
2142
|
+
case 256:
|
|
2143
|
+
case 512:
|
|
2144
|
+
case 1024:
|
|
2145
|
+
case 2048:
|
|
2146
|
+
case 4096:
|
|
2147
|
+
case 8192:
|
|
2148
|
+
case 16384:
|
|
2149
|
+
case 32768:
|
|
2150
|
+
case 65536:
|
|
2151
|
+
case 131072:
|
|
2152
|
+
case 262144:
|
|
2153
|
+
case 524288:
|
|
2154
|
+
case 1048576:
|
|
2155
|
+
case 2097152:
|
|
2156
|
+
return r + 5e3;
|
|
2157
|
+
case 4194304:
|
|
2158
|
+
case 8388608:
|
|
2159
|
+
case 16777216:
|
|
2160
|
+
case 33554432:
|
|
2161
|
+
return -1;
|
|
2162
|
+
case 67108864:
|
|
2163
|
+
case 134217728:
|
|
2164
|
+
case 268435456:
|
|
2165
|
+
case 536870912:
|
|
2166
|
+
case 1073741824:
|
|
2167
|
+
return -1;
|
|
2168
|
+
default:
|
|
2169
|
+
return -1;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
function Nf() {
|
|
2173
|
+
var t = qn;
|
|
2174
|
+
return qn <<= 1, (qn & 62914560) === 0 && (qn = 4194304), t;
|
|
2175
|
+
}
|
|
2176
|
+
function bc(t) {
|
|
2177
|
+
for (var r = [], a = 0; 31 > a; a++) r.push(t);
|
|
2178
|
+
return r;
|
|
2179
|
+
}
|
|
2180
|
+
function Ki(t, r) {
|
|
2181
|
+
t.pendingLanes |= r, r !== 268435456 && (t.suspendedLanes = 0, t.pingedLanes = 0, t.warmLanes = 0);
|
|
2182
|
+
}
|
|
2183
|
+
function ti(t, r, a, l, c, d) {
|
|
2184
|
+
var h = t.pendingLanes;
|
|
2185
|
+
t.pendingLanes = a, t.suspendedLanes = 0, t.pingedLanes = 0, t.warmLanes = 0, t.expiredLanes &= a, t.entangledLanes &= a, t.errorRecoveryDisabledLanes &= a, t.shellSuspendCounter = 0;
|
|
2186
|
+
var y = t.entanglements, C = t.expirationTimes, R = t.hiddenUpdates;
|
|
2187
|
+
for (a = h & ~a; 0 < a; ) {
|
|
2188
|
+
var D = 31 - sn(a), U = 1 << D;
|
|
2189
|
+
y[D] = 0, C[D] = -1;
|
|
2190
|
+
var A = R[D];
|
|
2191
|
+
if (A !== null) for (R[D] = null, D = 0; D < A.length; D++) {
|
|
2192
|
+
var fe = A[D];
|
|
2193
|
+
fe !== null && (fe.lane &= -536870913);
|
|
2194
|
+
}
|
|
2195
|
+
a &= ~U;
|
|
2196
|
+
}
|
|
2197
|
+
l !== 0 && en(t, l, 0), d !== 0 && c === 0 && t.tag !== 0 && (t.suspendedLanes |= d & ~(h & ~r));
|
|
2198
|
+
}
|
|
2199
|
+
function en(t, r, a) {
|
|
2200
|
+
t.pendingLanes |= r, t.suspendedLanes &= ~r;
|
|
2201
|
+
var l = 31 - sn(r);
|
|
2202
|
+
t.entangledLanes |= r, t.entanglements[l] = t.entanglements[l] | 1073741824 | a & 261930;
|
|
2203
|
+
}
|
|
2204
|
+
function G(t, r) {
|
|
2205
|
+
var a = t.entangledLanes |= r;
|
|
2206
|
+
for (t = t.entanglements; a; ) {
|
|
2207
|
+
var l = 31 - sn(a), c = 1 << l;
|
|
2208
|
+
c & r | t[l] & r && (t[l] |= r), a &= ~c;
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
function Wt(t, r) {
|
|
2212
|
+
var a = r & -r;
|
|
2213
|
+
return a = (a & 42) !== 0 ? 1 : mn(a), (a & (t.suspendedLanes | r)) !== 0 ? 0 : a;
|
|
2214
|
+
}
|
|
2215
|
+
function mn(t) {
|
|
2216
|
+
switch (t) {
|
|
2217
|
+
case 2:
|
|
2218
|
+
t = 1;
|
|
2219
|
+
break;
|
|
2220
|
+
case 8:
|
|
2221
|
+
t = 4;
|
|
2222
|
+
break;
|
|
2223
|
+
case 32:
|
|
2224
|
+
t = 16;
|
|
2225
|
+
break;
|
|
2226
|
+
case 256:
|
|
2227
|
+
case 512:
|
|
2228
|
+
case 1024:
|
|
2229
|
+
case 2048:
|
|
2230
|
+
case 4096:
|
|
2231
|
+
case 8192:
|
|
2232
|
+
case 16384:
|
|
2233
|
+
case 32768:
|
|
2234
|
+
case 65536:
|
|
2235
|
+
case 131072:
|
|
2236
|
+
case 262144:
|
|
2237
|
+
case 524288:
|
|
2238
|
+
case 1048576:
|
|
2239
|
+
case 2097152:
|
|
2240
|
+
case 4194304:
|
|
2241
|
+
case 8388608:
|
|
2242
|
+
case 16777216:
|
|
2243
|
+
case 33554432:
|
|
2244
|
+
t = 128;
|
|
2245
|
+
break;
|
|
2246
|
+
case 268435456:
|
|
2247
|
+
t = 134217728;
|
|
2248
|
+
break;
|
|
2249
|
+
default:
|
|
2250
|
+
t = 0;
|
|
2251
|
+
}
|
|
2252
|
+
return t;
|
|
2253
|
+
}
|
|
2254
|
+
function ze(t) {
|
|
2255
|
+
return t &= -t, 2 < t ? 8 < t ? (t & 134217727) !== 0 ? 32 : 268435456 : 8 : 2;
|
|
2256
|
+
}
|
|
2257
|
+
function ga(t) {
|
|
2258
|
+
if (typeof N == "function" && U0(t), It && typeof It.setStrictMode == "function") try {
|
|
2259
|
+
It.setStrictMode(Lu, t);
|
|
1492
2260
|
} catch {
|
|
1493
2261
|
}
|
|
1494
2262
|
}
|
|
@@ -13319,15 +14087,16 @@ function swapInteractivity(store, object, newObject) {
|
|
|
13319
14087
|
pointerState.hovered.set(makeId(next), next);
|
|
13320
14088
|
}
|
|
13321
14089
|
});
|
|
13322
|
-
const captureData
|
|
13323
|
-
|
|
13324
|
-
|
|
13325
|
-
pointerState.captured.
|
|
14090
|
+
for (const [key, captureData] of Array.from(pointerState.captured)) {
|
|
14091
|
+
const { intersection } = captureData;
|
|
14092
|
+
if (key !== object && intersection.object !== object && intersection.eventObject !== object) continue;
|
|
14093
|
+
if (key === object) pointerState.captured.delete(key);
|
|
14094
|
+
pointerState.captured.set(key === object ? newObject : key, {
|
|
13326
14095
|
...captureData,
|
|
13327
14096
|
intersection: {
|
|
13328
|
-
...
|
|
13329
|
-
object:
|
|
13330
|
-
eventObject:
|
|
14097
|
+
...intersection,
|
|
14098
|
+
object: intersection.object === object ? newObject : intersection.object,
|
|
14099
|
+
eventObject: intersection.eventObject === object ? newObject : intersection.eventObject
|
|
13331
14100
|
}
|
|
13332
14101
|
});
|
|
13333
14102
|
}
|
|
@@ -13856,10 +14625,11 @@ const catalogue = globalThis[R3F_CATALOGUE] ?? (globalThis[R3F_CATALOGUE] = {});
|
|
|
13856
14625
|
const R3F_EXTEND_ID = Symbol.for("@react-three/fiber.extendId");
|
|
13857
14626
|
const ids = globalThis;
|
|
13858
14627
|
const toPascalCase = (type) => `${type[0].toUpperCase()}${type.slice(1)}`;
|
|
13859
|
-
const isConstructor = (object) => typeof object === "function";
|
|
14628
|
+
const isConstructor$1 = (object) => typeof object === "function";
|
|
13860
14629
|
function extend(objects) {
|
|
13861
|
-
if (isConstructor(objects)) {
|
|
13862
|
-
|
|
14630
|
+
if (isConstructor$1(objects)) {
|
|
14631
|
+
let id = ids[R3F_EXTEND_ID] ?? 0;
|
|
14632
|
+
while (`${id}` in catalogue) id++;
|
|
13863
14633
|
ids[R3F_EXTEND_ID] = id + 1;
|
|
13864
14634
|
const Component = `${id}`;
|
|
13865
14635
|
catalogue[Component] = objects;
|
|
@@ -13867,15 +14637,14 @@ function extend(objects) {
|
|
|
13867
14637
|
} else {
|
|
13868
14638
|
for (const name in objects) {
|
|
13869
14639
|
const object = objects[name];
|
|
13870
|
-
if (isConstructor(object)) catalogue[name] = object;
|
|
14640
|
+
if (isConstructor$1(object)) catalogue[name] = object;
|
|
13871
14641
|
}
|
|
13872
14642
|
}
|
|
13873
14643
|
}
|
|
13874
|
-
|
|
13875
14644
|
function resolveConstructor(name, root) {
|
|
13876
14645
|
if (Object.prototype.hasOwnProperty.call(catalogue, name)) return catalogue[name];
|
|
13877
14646
|
const object = root.getState().internal.support?.three[name];
|
|
13878
|
-
return isConstructor(object) ? object : void 0;
|
|
14647
|
+
return isConstructor$1(object) ? object : void 0;
|
|
13879
14648
|
}
|
|
13880
14649
|
|
|
13881
14650
|
function createReconciler(config) {
|
|
@@ -13912,6 +14681,7 @@ function hideInstance(instance) {
|
|
|
13912
14681
|
if (instance.props.attach && instance.parent?.object) {
|
|
13913
14682
|
detach(instance.parent, instance);
|
|
13914
14683
|
} else if (isObject3D(instance.object)) {
|
|
14684
|
+
instance.previousVisible = instance.object.visible;
|
|
13915
14685
|
instance.object.visible = false;
|
|
13916
14686
|
}
|
|
13917
14687
|
instance.isHidden = true;
|
|
@@ -13922,9 +14692,10 @@ function unhideInstance(instance) {
|
|
|
13922
14692
|
if (instance.isHidden) {
|
|
13923
14693
|
if (instance.props.attach && instance.parent?.object) {
|
|
13924
14694
|
attach(instance.parent, instance);
|
|
13925
|
-
} else if (isObject3D(instance.object)
|
|
13926
|
-
instance.object.visible = true;
|
|
14695
|
+
} else if (isObject3D(instance.object)) {
|
|
14696
|
+
instance.object.visible = instance.previousVisible ?? true;
|
|
13927
14697
|
}
|
|
14698
|
+
instance.previousVisible = void 0;
|
|
13928
14699
|
instance.isHidden = false;
|
|
13929
14700
|
invalidateInstance(instance);
|
|
13930
14701
|
}
|
|
@@ -13937,6 +14708,7 @@ function handleContainerEffects(parent, child, beforeChild) {
|
|
|
13937
14708
|
child.object = child.props.object ?? new target(...child.props.args ?? []);
|
|
13938
14709
|
child.object.__r3f = child;
|
|
13939
14710
|
}
|
|
14711
|
+
warnGLSLMaterialUnsupported(state, child.object);
|
|
13940
14712
|
applyProps(child.object, child.props);
|
|
13941
14713
|
if (child.props.attach) {
|
|
13942
14714
|
attach(parent, child);
|
|
@@ -14420,474 +15192,46 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14420
15192
|
deleteChildFromFragmentInstance(_child, _fragmentInstance) {
|
|
14421
15193
|
},
|
|
14422
15194
|
// https://github.com/facebook/react/pull/32653
|
|
14423
|
-
measureClonedInstance: (_instance) => null,
|
|
14424
|
-
// https://github.com/facebook/react/pull/32819
|
|
14425
|
-
maySuspendCommitOnUpdate: (_type, _oldProps, _newProps) => false,
|
|
14426
|
-
maySuspendCommitInSyncRender: (_type, _props) => false,
|
|
14427
|
-
// https://github.com/facebook/react/pull/34486
|
|
14428
|
-
startSuspendingCommit: () => null,
|
|
14429
|
-
// https://github.com/facebook/react/pull/34522
|
|
14430
|
-
getSuspendedCommitReason: (_state, _rootContainer) => null
|
|
14431
|
-
});
|
|
14432
|
-
|
|
14433
|
-
|
|
14434
|
-
|
|
14435
|
-
|
|
14436
|
-
|
|
14437
|
-
|
|
14438
|
-
|
|
14439
|
-
|
|
14440
|
-
const
|
|
14441
|
-
|
|
14442
|
-
|
|
14443
|
-
|
|
14444
|
-
|
|
14445
|
-
|
|
14446
|
-
|
|
14447
|
-
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
|
|
14454
|
-
|
|
14455
|
-
|
|
14456
|
-
if (isOrthographicCamera(camera)) {
|
|
14457
|
-
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
14458
|
-
} else {
|
|
14459
|
-
const fov = camera.fov * Math.PI / 180;
|
|
14460
|
-
const h = 2 * Math.tan(fov / 2) * distance;
|
|
14461
|
-
const w = h * (width / height);
|
|
14462
|
-
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
14463
|
-
}
|
|
14464
|
-
}
|
|
14465
|
-
let performanceTimeout = void 0;
|
|
14466
|
-
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
14467
|
-
const rootState = {
|
|
14468
|
-
set,
|
|
14469
|
-
get,
|
|
14470
|
-
// Mock objects that have to be configured
|
|
14471
|
-
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
14472
|
-
primaryStore: null,
|
|
14473
|
-
gl: null,
|
|
14474
|
-
renderer: null,
|
|
14475
|
-
camera: null,
|
|
14476
|
-
// frustum, pointer and mouse are three objects; configure() creates them with the renderer
|
|
14477
|
-
frustum: null,
|
|
14478
|
-
autoUpdateFrustum: true,
|
|
14479
|
-
raycaster: null,
|
|
14480
|
-
events: {
|
|
14481
|
-
priority: 1,
|
|
14482
|
-
enabled: true,
|
|
14483
|
-
connected: false,
|
|
14484
|
-
frameTimedRaycasts: true,
|
|
14485
|
-
alwaysFireOnScroll: true,
|
|
14486
|
-
updateOnFrame: false
|
|
14487
|
-
},
|
|
14488
|
-
scene: null,
|
|
14489
|
-
rootScene: null,
|
|
14490
|
-
xr: null,
|
|
14491
|
-
inspector: null,
|
|
14492
|
-
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
14493
|
-
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
14494
|
-
textureColorSpace: "srgb",
|
|
14495
|
-
// THREE.SRGBColorSpace
|
|
14496
|
-
isLegacy: false,
|
|
14497
|
-
webGPUSupported: false,
|
|
14498
|
-
isNative: false,
|
|
14499
|
-
controls: null,
|
|
14500
|
-
pointer: null,
|
|
14501
|
-
mouse: null,
|
|
14502
|
-
frameloop: "always",
|
|
14503
|
-
onPointerMissed: void 0,
|
|
14504
|
-
onDragOverMissed: void 0,
|
|
14505
|
-
onDropMissed: void 0,
|
|
14506
|
-
performance: {
|
|
14507
|
-
current: 1,
|
|
14508
|
-
min: 0.5,
|
|
14509
|
-
max: 1,
|
|
14510
|
-
debounce: 200,
|
|
14511
|
-
regress: () => {
|
|
14512
|
-
const state2 = get();
|
|
14513
|
-
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
14514
|
-
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
14515
|
-
performanceTimeout = setTimeout(
|
|
14516
|
-
() => setPerformanceCurrent(get().performance.max),
|
|
14517
|
-
state2.performance.debounce
|
|
14518
|
-
);
|
|
14519
|
-
}
|
|
14520
|
-
},
|
|
14521
|
-
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
14522
|
-
viewport: {
|
|
14523
|
-
initialDpr: 0,
|
|
14524
|
-
dpr: 0,
|
|
14525
|
-
width: 0,
|
|
14526
|
-
height: 0,
|
|
14527
|
-
top: 0,
|
|
14528
|
-
left: 0,
|
|
14529
|
-
aspect: 0,
|
|
14530
|
-
distance: 0,
|
|
14531
|
-
factor: 0,
|
|
14532
|
-
getCurrentViewport
|
|
14533
|
-
},
|
|
14534
|
-
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
14535
|
-
setSize: (width, height, top, left) => {
|
|
14536
|
-
const state2 = get();
|
|
14537
|
-
if (width === void 0) {
|
|
14538
|
-
set({ _sizeImperative: false });
|
|
14539
|
-
if (state2._sizeProps) {
|
|
14540
|
-
const { width: propW, height: propH } = state2._sizeProps;
|
|
14541
|
-
if (propW !== void 0 || propH !== void 0) {
|
|
14542
|
-
const currentSize = state2.size;
|
|
14543
|
-
const newSize = {
|
|
14544
|
-
width: propW ?? currentSize.width,
|
|
14545
|
-
height: propH ?? currentSize.height,
|
|
14546
|
-
top: currentSize.top,
|
|
14547
|
-
left: currentSize.left
|
|
14548
|
-
};
|
|
14549
|
-
set((s) => ({
|
|
14550
|
-
size: newSize,
|
|
14551
|
-
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
14552
|
-
}));
|
|
14553
|
-
get().invalidate();
|
|
14554
|
-
}
|
|
14555
|
-
}
|
|
14556
|
-
return;
|
|
14557
|
-
}
|
|
14558
|
-
const w = width;
|
|
14559
|
-
const h = height ?? width;
|
|
14560
|
-
const t = top ?? state2.size.top;
|
|
14561
|
-
const l = left ?? state2.size.left;
|
|
14562
|
-
const size = { width: w, height: h, top: t, left: l };
|
|
14563
|
-
set((s) => ({
|
|
14564
|
-
size,
|
|
14565
|
-
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
14566
|
-
_sizeImperative: true
|
|
14567
|
-
}));
|
|
14568
|
-
get().invalidate();
|
|
14569
|
-
},
|
|
14570
|
-
setDpr: (dpr) => set((state2) => {
|
|
14571
|
-
const resolved = calculateDpr(dpr);
|
|
14572
|
-
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
14573
|
-
}),
|
|
14574
|
-
setFrameloop: (frameloop = "always") => {
|
|
14575
|
-
const rootId = get().internal.rootId;
|
|
14576
|
-
if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
|
|
14577
|
-
set(() => ({ frameloop }));
|
|
14578
|
-
},
|
|
14579
|
-
setError: (error) => set(() => ({ error })),
|
|
14580
|
-
error: null,
|
|
14581
|
-
//* Texture registry (useTextures) ==============================
|
|
14582
|
-
// TSL fields (uniforms, nodes, ..., renderPipeline) are added by @react-three/tsl's root extension.
|
|
14583
|
-
textures: /* @__PURE__ */ new Map(),
|
|
14584
|
-
_textureRefs: /* @__PURE__ */ new Map(),
|
|
14585
|
-
_sizeImperative: false,
|
|
14586
|
-
_sizeProps: null,
|
|
14587
|
-
previousRoot: void 0,
|
|
14588
|
-
internal: {
|
|
14589
|
-
// Events
|
|
14590
|
-
interaction: [],
|
|
14591
|
-
subscribers: [],
|
|
14592
|
-
// Per-pointer state (new unified structure)
|
|
14593
|
-
pointerMap: /* @__PURE__ */ new Map(),
|
|
14594
|
-
pointerDirty: /* @__PURE__ */ new Map(),
|
|
14595
|
-
lastEvent: React.createRef(),
|
|
14596
|
-
// Deprecated but kept for backwards compatibility
|
|
14597
|
-
hovered: /* @__PURE__ */ new Map(),
|
|
14598
|
-
initialClick: [0, 0],
|
|
14599
|
-
initialHits: [],
|
|
14600
|
-
capturedMap: /* @__PURE__ */ new Map(),
|
|
14601
|
-
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
14602
|
-
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
14603
|
-
// Occlusion system (WebGPU only)
|
|
14604
|
-
occlusionEnabled: false,
|
|
14605
|
-
occlusionObserver: null,
|
|
14606
|
-
occlusionCache: /* @__PURE__ */ new Map(),
|
|
14607
|
-
helperGroup: null,
|
|
14608
|
-
// Updates
|
|
14609
|
-
active: false,
|
|
14610
|
-
frames: 0,
|
|
14611
|
-
priority: 0,
|
|
14612
|
-
subscribe: (ref, priority, store) => {
|
|
14613
|
-
const internal = get().internal;
|
|
14614
|
-
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
14615
|
-
internal.subscribers.push({ ref, priority, store });
|
|
14616
|
-
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
14617
|
-
return () => {
|
|
14618
|
-
const internal2 = get().internal;
|
|
14619
|
-
if (internal2?.subscribers) {
|
|
14620
|
-
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
14621
|
-
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
14622
|
-
}
|
|
14623
|
-
};
|
|
14624
|
-
},
|
|
14625
|
-
// Renderer Storage (single source of truth)
|
|
14626
|
-
actualRenderer: null,
|
|
14627
|
-
// The renderer support configure() loads for this root
|
|
14628
|
-
support: null,
|
|
14629
|
-
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
14630
|
-
scheduler: null,
|
|
14631
|
-
// Replaces the default render call when set (see setRenderOverride)
|
|
14632
|
-
renderOverride: null
|
|
14633
|
-
}
|
|
14634
|
-
};
|
|
14635
|
-
return rootState;
|
|
14636
|
-
});
|
|
14637
|
-
const state = rootStore.getState();
|
|
14638
|
-
Object.defineProperty(state, "gl", {
|
|
14639
|
-
get() {
|
|
14640
|
-
const currentState = rootStore.getState();
|
|
14641
|
-
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
14642
|
-
const stack = new Error().stack || "";
|
|
14643
|
-
if (!isInternalRendererAccess(stack)) {
|
|
14644
|
-
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
14645
|
-
notifyDepreciated({
|
|
14646
|
-
heading: "Accessing state.gl in WebGPU mode",
|
|
14647
|
-
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
|
|
14648
|
-
});
|
|
14649
|
-
}
|
|
14650
|
-
}
|
|
14651
|
-
return currentState.internal.actualRenderer;
|
|
14652
|
-
},
|
|
14653
|
-
set(value) {
|
|
14654
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
14655
|
-
},
|
|
14656
|
-
enumerable: true,
|
|
14657
|
-
configurable: true
|
|
14658
|
-
});
|
|
14659
|
-
Object.defineProperty(state, "renderer", {
|
|
14660
|
-
get() {
|
|
14661
|
-
return rootStore.getState().internal.actualRenderer;
|
|
14662
|
-
},
|
|
14663
|
-
set(value) {
|
|
14664
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
14665
|
-
},
|
|
14666
|
-
enumerable: true,
|
|
14667
|
-
configurable: true
|
|
14668
|
-
});
|
|
14669
|
-
let oldScene = state.scene;
|
|
14670
|
-
rootStore.subscribe(() => {
|
|
14671
|
-
const currentState = rootStore.getState();
|
|
14672
|
-
const { scene, rootScene, set } = currentState;
|
|
14673
|
-
if (scene !== oldScene) {
|
|
14674
|
-
oldScene = scene;
|
|
14675
|
-
if (scene?.isScene && scene !== rootScene) {
|
|
14676
|
-
set({ rootScene: scene });
|
|
14677
|
-
}
|
|
14678
|
-
}
|
|
14679
|
-
});
|
|
14680
|
-
let oldSize = state.size;
|
|
14681
|
-
let oldDpr = state.viewport.dpr;
|
|
14682
|
-
let oldCamera = state.camera;
|
|
14683
|
-
rootStore.subscribe(() => {
|
|
14684
|
-
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
14685
|
-
const actualRenderer = internal.actualRenderer;
|
|
14686
|
-
const canvasTarget = internal.canvasTarget;
|
|
14687
|
-
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
14688
|
-
oldSize = size;
|
|
14689
|
-
oldDpr = viewport.dpr;
|
|
14690
|
-
updateCamera(camera, size);
|
|
14691
|
-
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
14692
|
-
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
14693
|
-
resizeTarget.setSize(size.width, size.height, false);
|
|
14694
|
-
const activeTarget = actualRenderer.getCanvasTarget?.();
|
|
14695
|
-
if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
|
|
14696
|
-
}
|
|
14697
|
-
if (camera !== oldCamera) {
|
|
14698
|
-
oldCamera = camera;
|
|
14699
|
-
const { rootScene } = rootStore.getState();
|
|
14700
|
-
if (camera && rootScene && !camera.parent) {
|
|
14701
|
-
rootScene.add(camera);
|
|
14702
|
-
}
|
|
14703
|
-
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
14704
|
-
const currentState = rootStore.getState();
|
|
14705
|
-
if (currentState.autoUpdateFrustum && camera) {
|
|
14706
|
-
updateFrustum(camera, currentState.frustum);
|
|
14707
|
-
}
|
|
14708
|
-
}
|
|
14709
|
-
});
|
|
14710
|
-
rootStore.subscribe((state2) => invalidate(state2));
|
|
14711
|
-
return rootStore;
|
|
14712
|
-
};
|
|
14713
|
-
|
|
14714
|
-
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
14715
|
-
const pendingSubscribers = /* @__PURE__ */ new Map();
|
|
14716
|
-
function registerPrimary(id, renderer, store) {
|
|
14717
|
-
if (primaryRegistry.has(id)) {
|
|
14718
|
-
console.warn(`Canvas with id="${id}" already registered. Overwriting.`);
|
|
14719
|
-
}
|
|
14720
|
-
const entry = { renderer, store };
|
|
14721
|
-
primaryRegistry.set(id, entry);
|
|
14722
|
-
const subscribers = pendingSubscribers.get(id);
|
|
14723
|
-
if (subscribers) {
|
|
14724
|
-
subscribers.forEach((callback) => callback(entry));
|
|
14725
|
-
pendingSubscribers.delete(id);
|
|
14726
|
-
}
|
|
14727
|
-
return () => {
|
|
14728
|
-
const currentEntry = primaryRegistry.get(id);
|
|
14729
|
-
if (currentEntry?.renderer === renderer) {
|
|
14730
|
-
primaryRegistry.delete(id);
|
|
14731
|
-
}
|
|
14732
|
-
};
|
|
14733
|
-
}
|
|
14734
|
-
function getPrimary(id) {
|
|
14735
|
-
return primaryRegistry.get(id);
|
|
14736
|
-
}
|
|
14737
|
-
function waitForPrimary(id, timeout = 5e3) {
|
|
14738
|
-
const existing = primaryRegistry.get(id);
|
|
14739
|
-
if (existing) {
|
|
14740
|
-
return Promise.resolve(existing);
|
|
14741
|
-
}
|
|
14742
|
-
return new Promise((resolve, reject) => {
|
|
14743
|
-
const timeoutId = setTimeout(() => {
|
|
14744
|
-
const subscribers = pendingSubscribers.get(id);
|
|
14745
|
-
if (subscribers) {
|
|
14746
|
-
const index = subscribers.indexOf(callback);
|
|
14747
|
-
if (index !== -1) subscribers.splice(index, 1);
|
|
14748
|
-
if (subscribers.length === 0) pendingSubscribers.delete(id);
|
|
14749
|
-
}
|
|
14750
|
-
reject(new Error(`Timeout waiting for canvas with id="${id}". Make sure a <Canvas id="${id}"> is mounted.`));
|
|
14751
|
-
}, timeout);
|
|
14752
|
-
const callback = (entry) => {
|
|
14753
|
-
clearTimeout(timeoutId);
|
|
14754
|
-
resolve(entry);
|
|
14755
|
-
};
|
|
14756
|
-
if (!pendingSubscribers.has(id)) {
|
|
14757
|
-
pendingSubscribers.set(id, []);
|
|
14758
|
-
}
|
|
14759
|
-
pendingSubscribers.get(id).push(callback);
|
|
14760
|
-
});
|
|
14761
|
-
}
|
|
14762
|
-
function hasPrimary(id) {
|
|
14763
|
-
return primaryRegistry.has(id);
|
|
14764
|
-
}
|
|
14765
|
-
function unregisterPrimary(id) {
|
|
14766
|
-
primaryRegistry.delete(id);
|
|
14767
|
-
}
|
|
14768
|
-
function getPrimaryIds() {
|
|
14769
|
-
return Array.from(primaryRegistry.keys());
|
|
14770
|
-
}
|
|
14771
|
-
|
|
14772
|
-
const fulfilled = (value) => Object.assign(Promise.resolve(value), { status: "fulfilled", value });
|
|
14773
|
-
const tracked = (promise) => {
|
|
14774
|
-
const result = Promise.resolve(promise);
|
|
14775
|
-
result.status = "pending";
|
|
14776
|
-
result.then(
|
|
14777
|
-
(value) => {
|
|
14778
|
-
Object.assign(result, { status: "fulfilled", value });
|
|
14779
|
-
},
|
|
14780
|
-
(reason) => {
|
|
14781
|
-
Object.assign(result, { status: "rejected", reason });
|
|
14782
|
-
}
|
|
14783
|
-
);
|
|
14784
|
-
return result;
|
|
14785
|
-
};
|
|
14786
|
-
|
|
14787
|
-
const records = /* @__PURE__ */ new WeakMap();
|
|
14788
|
-
function take(renderer, record) {
|
|
14789
|
-
record.leases++;
|
|
14790
|
-
let released = false;
|
|
14791
|
-
return () => {
|
|
14792
|
-
if (released) return;
|
|
14793
|
-
released = true;
|
|
14794
|
-
if (--record.leases > 0) return;
|
|
14795
|
-
records.delete(renderer);
|
|
14796
|
-
if (record.owned) return disposeRenderer(renderer);
|
|
14797
|
-
};
|
|
14798
|
-
}
|
|
14799
|
-
function leaseRenderer(renderer, owned) {
|
|
14800
|
-
let record = records.get(renderer);
|
|
14801
|
-
if (!record) records.set(renderer, record = { owned, leases: 0 });
|
|
14802
|
-
return take(renderer, record);
|
|
14803
|
-
}
|
|
14804
|
-
function borrowRenderer(renderer) {
|
|
14805
|
-
const record = records.get(renderer);
|
|
14806
|
-
if (!record) throw new Error("R3F: cannot share a renderer whose canvas has already unmounted");
|
|
14807
|
-
return take(renderer, record);
|
|
14808
|
-
}
|
|
14809
|
-
function disposeRenderer(renderer) {
|
|
14810
|
-
if (renderer.hasInitialized?.() === false) return;
|
|
14811
|
-
const warn = (error) => console.warn("[R3F] Error disposing renderer", error);
|
|
14812
|
-
const loseContext = () => {
|
|
14813
|
-
try {
|
|
14814
|
-
;
|
|
14815
|
-
renderer.forceContextLoss?.();
|
|
14816
|
-
} catch (error) {
|
|
14817
|
-
warn(error);
|
|
14818
|
-
}
|
|
14819
|
-
};
|
|
14820
|
-
let disposed;
|
|
14821
|
-
try {
|
|
14822
|
-
disposed = renderer.dispose();
|
|
14823
|
-
} catch (error) {
|
|
14824
|
-
warn(error);
|
|
14825
|
-
}
|
|
14826
|
-
if (typeof disposed?.then === "function") {
|
|
14827
|
-
return Promise.resolve(disposed).then(loseContext, (error) => {
|
|
14828
|
-
warn(error);
|
|
14829
|
-
loseContext();
|
|
14830
|
-
});
|
|
14831
|
-
}
|
|
14832
|
-
loseContext();
|
|
14833
|
-
}
|
|
14834
|
-
|
|
14835
|
-
const isRenderer = (def) => !!def?.render;
|
|
14836
|
-
const _roots = /* @__PURE__ */ new Map();
|
|
14837
|
-
function ensureStoreThreeObjects(store) {
|
|
14838
|
-
const state = store.getState();
|
|
14839
|
-
if (state.pointer) return;
|
|
14840
|
-
const { Vector2, Frustum } = getThree();
|
|
14841
|
-
const pointer = new Vector2();
|
|
14842
|
-
state.set({ pointer, mouse: pointer, frustum: new Frustum() });
|
|
14843
|
-
}
|
|
14844
|
-
const shallowLoose = { objects: "shallow", strict: false };
|
|
14845
|
-
async function resolveRenderer(config, defaultProps, RendererClass) {
|
|
14846
|
-
if (typeof config === "function") return { renderer: await config(defaultProps), owned: true };
|
|
14847
|
-
if (isRenderer(config)) return { renderer: config, owned: false };
|
|
14848
|
-
return { renderer: new RendererClass({ ...defaultProps, ...config }), owned: true };
|
|
14849
|
-
}
|
|
14850
|
-
function computeInitialSize(canvas, size) {
|
|
14851
|
-
if (!size && typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement && canvas.parentElement) {
|
|
14852
|
-
const { width, height, top, left } = canvas.parentElement.getBoundingClientRect();
|
|
14853
|
-
return { width, height, top, left };
|
|
14854
|
-
} else if (!size && typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas) {
|
|
14855
|
-
return {
|
|
14856
|
-
width: canvas.width,
|
|
14857
|
-
height: canvas.height,
|
|
14858
|
-
top: 0,
|
|
14859
|
-
left: 0
|
|
14860
|
-
};
|
|
14861
|
-
}
|
|
14862
|
-
return { width: 0, height: 0, top: 0, left: 0, ...size };
|
|
14863
|
-
}
|
|
14864
|
-
function watchDpr(onChange) {
|
|
14865
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function" || !window.devicePixelRatio) {
|
|
14866
|
-
return () => {
|
|
14867
|
-
};
|
|
14868
|
-
}
|
|
14869
|
-
let query;
|
|
14870
|
-
const listen = () => {
|
|
14871
|
-
try {
|
|
14872
|
-
query = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
14873
|
-
if (typeof query?.addEventListener === "function") query.addEventListener("change", handleChange);
|
|
14874
|
-
else query?.addListener?.(handleChange);
|
|
14875
|
-
} catch {
|
|
14876
|
-
query = void 0;
|
|
15195
|
+
measureClonedInstance: (_instance) => null,
|
|
15196
|
+
// https://github.com/facebook/react/pull/32819
|
|
15197
|
+
maySuspendCommitOnUpdate: (_type, _oldProps, _newProps) => false,
|
|
15198
|
+
maySuspendCommitInSyncRender: (_type, _props) => false,
|
|
15199
|
+
// https://github.com/facebook/react/pull/34486
|
|
15200
|
+
startSuspendingCommit: () => null,
|
|
15201
|
+
// https://github.com/facebook/react/pull/34522
|
|
15202
|
+
getSuspendedCommitReason: (_state, _rootContainer) => null
|
|
15203
|
+
});
|
|
15204
|
+
function flushSync(fn) {
|
|
15205
|
+
return reconciler.flushSyncFromReconciler(fn);
|
|
15206
|
+
}
|
|
15207
|
+
|
|
15208
|
+
const noop = () => {
|
|
15209
|
+
};
|
|
15210
|
+
const _roots = /* @__PURE__ */ new Map();
|
|
15211
|
+
function transitionRoot(root, event) {
|
|
15212
|
+
const state = root.state;
|
|
15213
|
+
switch (event.type) {
|
|
15214
|
+
case "use":
|
|
15215
|
+
if (state.status === "disposed") return false;
|
|
15216
|
+
if (state.status === "closing") {
|
|
15217
|
+
root.store.getState().internal.active = true;
|
|
15218
|
+
state.settle();
|
|
15219
|
+
}
|
|
15220
|
+
root.state = { status: "open" };
|
|
15221
|
+
return true;
|
|
15222
|
+
case "unmount": {
|
|
15223
|
+
if (state.status === "disposed") return false;
|
|
15224
|
+
if (state.status === "closing") state.settle();
|
|
15225
|
+
const { promise, resolve } = deferred();
|
|
15226
|
+
root.state = { status: "closing", token: event.token, settled: promise, settle: resolve };
|
|
15227
|
+
return true;
|
|
14877
15228
|
}
|
|
14878
|
-
|
|
14879
|
-
|
|
14880
|
-
|
|
14881
|
-
|
|
14882
|
-
|
|
14883
|
-
}
|
|
14884
|
-
const handleChange = () => {
|
|
14885
|
-
unlisten();
|
|
14886
|
-
listen();
|
|
14887
|
-
onChange();
|
|
14888
|
-
};
|
|
14889
|
-
listen();
|
|
14890
|
-
return unlisten;
|
|
15229
|
+
case "dispose":
|
|
15230
|
+
if (state.status !== "closing" || state.token !== event.token) return false;
|
|
15231
|
+
root.state = { status: "disposed" };
|
|
15232
|
+
state.settle();
|
|
15233
|
+
return true;
|
|
15234
|
+
}
|
|
14891
15235
|
}
|
|
14892
15236
|
function createRoot(canvas, provider) {
|
|
14893
15237
|
const prevRoot = _roots.get(canvas);
|
|
@@ -14925,585 +15269,670 @@ function createRoot(canvas, provider) {
|
|
|
14925
15269
|
null
|
|
14926
15270
|
// transitionCallbacks
|
|
14927
15271
|
);
|
|
14928
|
-
const root = prevRoot || {
|
|
14929
|
-
|
|
14930
|
-
|
|
14931
|
-
|
|
14932
|
-
|
|
14933
|
-
|
|
14934
|
-
let dprChangedInXR = false;
|
|
14935
|
-
let unwatchDpr;
|
|
14936
|
-
const resolveDpr = () => {
|
|
14937
|
-
if (_roots.get(canvas)?.store !== store) return unwatchDpr?.();
|
|
14938
|
-
const state = store.getState();
|
|
14939
|
-
const xr = state.internal.actualRenderer?.xr;
|
|
14940
|
-
if (xr?.isPresenting || xr?.getSession?.()) {
|
|
14941
|
-
dprChangedInXR = true;
|
|
14942
|
-
return;
|
|
14943
|
-
}
|
|
14944
|
-
dprChangedInXR = false;
|
|
14945
|
-
const dpr = lastConfiguredProps.dpr;
|
|
14946
|
-
if (dpr === void 0 || state.viewport.dpr !== resolvedDpr || calculateDpr(dpr) === resolvedDpr) return;
|
|
14947
|
-
state.setDpr(dpr);
|
|
14948
|
-
resolvedDpr = store.getState().viewport.dpr;
|
|
14949
|
-
};
|
|
14950
|
-
let configured = false;
|
|
14951
|
-
let pending = null;
|
|
14952
|
-
const cancelUnmount = () => {
|
|
14953
|
-
if (!root.unmountClaim) return;
|
|
14954
|
-
root.unmountClaim = null;
|
|
14955
|
-
store.getState().internal.active = true;
|
|
15272
|
+
const root = prevRoot || {
|
|
15273
|
+
fiber,
|
|
15274
|
+
store,
|
|
15275
|
+
state: { status: "open" },
|
|
15276
|
+
ready: fulfilled(void 0),
|
|
15277
|
+
configuration: {}
|
|
14956
15278
|
};
|
|
15279
|
+
if (!prevRoot) _roots.set(canvas, root);
|
|
15280
|
+
if (!prevRoot) root.configuration.apply = createRootConfiguration(store, canvas);
|
|
15281
|
+
let mounted = false;
|
|
14957
15282
|
return {
|
|
14958
|
-
|
|
14959
|
-
|
|
14960
|
-
|
|
14961
|
-
|
|
14962
|
-
|
|
14963
|
-
|
|
14964
|
-
|
|
14965
|
-
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
|
|
14969
|
-
|
|
14970
|
-
|
|
14971
|
-
|
|
14972
|
-
|
|
14973
|
-
|
|
14974
|
-
|
|
14975
|
-
|
|
14976
|
-
|
|
14977
|
-
|
|
14978
|
-
|
|
14979
|
-
|
|
14980
|
-
|
|
14981
|
-
|
|
14982
|
-
|
|
14983
|
-
|
|
14984
|
-
|
|
14985
|
-
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
|
|
14992
|
-
canvas,
|
|
14993
|
-
powerPreference: "high-performance",
|
|
14994
|
-
antialias: true,
|
|
14995
|
-
alpha: true
|
|
15283
|
+
get ready() {
|
|
15284
|
+
return root.ready;
|
|
15285
|
+
},
|
|
15286
|
+
configure(props = {}) {
|
|
15287
|
+
if (!transitionRoot(root, { type: "use" })) {
|
|
15288
|
+
return rejected(new Error("R3F: Cannot configure a root after it has unmounted (disposal has started)."));
|
|
15289
|
+
}
|
|
15290
|
+
const previous = root.ready;
|
|
15291
|
+
const { promise, resolve, reject } = deferred();
|
|
15292
|
+
root.ready = promise;
|
|
15293
|
+
const run = () => {
|
|
15294
|
+
try {
|
|
15295
|
+
const initialized = initializeRenderer(canvas, provider, store, props);
|
|
15296
|
+
const apply = () => {
|
|
15297
|
+
if (props.id) {
|
|
15298
|
+
for (const other of _roots.values()) {
|
|
15299
|
+
if (other !== root && other.state.status === "closing" && other.store.getState().internal.rootId === props.id) {
|
|
15300
|
+
other.state.settled.then(apply).catch(reject);
|
|
15301
|
+
return;
|
|
15302
|
+
}
|
|
15303
|
+
}
|
|
15304
|
+
}
|
|
15305
|
+
const previous2 = root.configuration.previous;
|
|
15306
|
+
root.configuration.apply(props);
|
|
15307
|
+
configureScheduler(store, props.id, props.scheduler, previous2?.scheduler);
|
|
15308
|
+
attachRootExtensions(store);
|
|
15309
|
+
root.configuration.previous = props;
|
|
15310
|
+
resolve(this);
|
|
15311
|
+
};
|
|
15312
|
+
if (isPromiseLike(initialized)) Promise.resolve(initialized).then(apply).catch(reject);
|
|
15313
|
+
else apply();
|
|
15314
|
+
} catch (error) {
|
|
15315
|
+
reject(error);
|
|
15316
|
+
}
|
|
14996
15317
|
};
|
|
14997
|
-
|
|
14998
|
-
|
|
14999
|
-
|
|
15318
|
+
if (previous.status === "pending") previous.then(run, reject);
|
|
15319
|
+
else run();
|
|
15320
|
+
return promise;
|
|
15321
|
+
},
|
|
15322
|
+
render(children) {
|
|
15323
|
+
if (!transitionRoot(root, { type: "use" })) return store;
|
|
15324
|
+
if (!store.getState().internal.actualRenderer && root.ready.status === "fulfilled") this.configure();
|
|
15325
|
+
if (root.ready.status === "rejected") throw root.ready.reason;
|
|
15326
|
+
const commit = () => {
|
|
15327
|
+
if (root.state.status !== "open" || root.ready.status === "rejected") return;
|
|
15328
|
+
if (root.ready.status === "pending") {
|
|
15329
|
+
root.ready.then(commit, logRecoverableError);
|
|
15330
|
+
return;
|
|
15331
|
+
}
|
|
15332
|
+
const onCreated = root.configuration.previous?.onCreated;
|
|
15333
|
+
const element = /* @__PURE__ */ jsx(Provider, { store, children, onCreated, rootElement: canvas });
|
|
15334
|
+
if (mounted) {
|
|
15335
|
+
reconciler.updateContainer(element, fiber, null, noop);
|
|
15336
|
+
return;
|
|
15337
|
+
}
|
|
15338
|
+
mounted = true;
|
|
15339
|
+
reconciler.updateContainerSync(element, fiber, null, noop);
|
|
15340
|
+
reconciler.flushSyncWork();
|
|
15000
15341
|
};
|
|
15001
|
-
|
|
15002
|
-
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
|
|
15007
|
-
|
|
15008
|
-
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15013
|
-
|
|
15014
|
-
|
|
15015
|
-
|
|
15016
|
-
|
|
15017
|
-
|
|
15018
|
-
|
|
15019
|
-
|
|
15020
|
-
|
|
15342
|
+
commit();
|
|
15343
|
+
return store;
|
|
15344
|
+
},
|
|
15345
|
+
unmount() {
|
|
15346
|
+
if (_roots.get(canvas) === root) unmountComponentAtNode(canvas);
|
|
15347
|
+
}
|
|
15348
|
+
};
|
|
15349
|
+
}
|
|
15350
|
+
function Provider({
|
|
15351
|
+
store,
|
|
15352
|
+
children,
|
|
15353
|
+
onCreated,
|
|
15354
|
+
rootElement
|
|
15355
|
+
}) {
|
|
15356
|
+
useIsomorphicLayoutEffect(() => {
|
|
15357
|
+
const state = store.getState();
|
|
15358
|
+
state.set((state2) => ({ internal: { ...state2.internal, active: true } }));
|
|
15359
|
+
if (onCreated) onCreated(state);
|
|
15360
|
+
if (!store.getState().events.connected) state.events.connect?.(rootElement);
|
|
15361
|
+
}, []);
|
|
15362
|
+
return /* @__PURE__ */ jsx(context.Provider, { value: store, children });
|
|
15363
|
+
}
|
|
15364
|
+
function unmountComponentAtNode(canvas, callback) {
|
|
15365
|
+
const claim = Symbol("unmount");
|
|
15366
|
+
const root = _roots.get(canvas);
|
|
15367
|
+
if (!root || !transitionRoot(root, { type: "unmount", token: claim })) return;
|
|
15368
|
+
root.store.getState().internal.active = false;
|
|
15369
|
+
reconciler.updateContainer(null, root.fiber, null, () => {
|
|
15370
|
+
if (root.state.status !== "closing" || root.state.token !== claim) return;
|
|
15371
|
+
reconciler.updateContainer(null, root.fiber, null, () => {
|
|
15372
|
+
if (root.state.status !== "closing" || root.state.token !== claim) return;
|
|
15373
|
+
if (root.ready.status === "pending") root.ready.then(teardown, teardown);
|
|
15374
|
+
else teardown();
|
|
15375
|
+
});
|
|
15376
|
+
});
|
|
15377
|
+
function teardown() {
|
|
15378
|
+
if (root.ready.status === "pending") {
|
|
15379
|
+
root.ready.then(teardown, teardown);
|
|
15380
|
+
return;
|
|
15381
|
+
}
|
|
15382
|
+
if (!transitionRoot(root, { type: "dispose", token: claim })) return;
|
|
15383
|
+
_roots.delete(canvas);
|
|
15384
|
+
const state = root.store.getState();
|
|
15385
|
+
const internal = state.internal;
|
|
15386
|
+
internal.active = false;
|
|
15387
|
+
const attempt = (step) => {
|
|
15388
|
+
try {
|
|
15389
|
+
return step();
|
|
15390
|
+
} catch (error) {
|
|
15391
|
+
console.warn("[R3F] Error while unmounting root; teardown may be incomplete:", error);
|
|
15021
15392
|
}
|
|
15022
|
-
|
|
15023
|
-
|
|
15024
|
-
|
|
15025
|
-
|
|
15026
|
-
|
|
15393
|
+
};
|
|
15394
|
+
attempt(() => internal.unwatchDpr?.());
|
|
15395
|
+
internal.unwatchDpr = void 0;
|
|
15396
|
+
attempt(() => internal.unregisterRoot?.());
|
|
15397
|
+
internal.unregisterRoot = void 0;
|
|
15398
|
+
attempt(() => detachRootExtensions(root.store));
|
|
15399
|
+
attempt(() => internal.unregisterPrimary?.());
|
|
15400
|
+
attempt(() => internal.untrackStandalone?.());
|
|
15401
|
+
attempt(() => state.events.disconnect?.());
|
|
15402
|
+
if (!internal.isSecondary && internal.actualRenderer?.xr && state.xr) attempt(() => state.xr.disconnect());
|
|
15403
|
+
attempt(() => cleanupHelperGroup(root.store));
|
|
15404
|
+
if (state.scene) attempt(() => dispose(state.scene));
|
|
15405
|
+
const canvasTarget = internal.canvasTarget;
|
|
15406
|
+
if (internal.isSecondary && canvasTarget?.dispose) attempt(() => canvasTarget.dispose());
|
|
15407
|
+
const released = attempt(() => internal.releaseRenderer?.());
|
|
15408
|
+
internal.releaseRenderer = void 0;
|
|
15409
|
+
if (callback) {
|
|
15410
|
+
if (released) {
|
|
15411
|
+
released.then(() => callback(canvas)).catch((error) => console.warn("[R3F] Error in unmount callback", error));
|
|
15412
|
+
} else {
|
|
15413
|
+
callback(canvas);
|
|
15027
15414
|
}
|
|
15028
|
-
|
|
15029
|
-
|
|
15030
|
-
|
|
15031
|
-
|
|
15415
|
+
}
|
|
15416
|
+
}
|
|
15417
|
+
}
|
|
15418
|
+
|
|
15419
|
+
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
15420
|
+
const isConstructor = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
15421
|
+
function getLoader(Proto) {
|
|
15422
|
+
if (isConstructor(Proto)) {
|
|
15423
|
+
let loader = memoizedLoaders.get(Proto);
|
|
15424
|
+
if (!loader) {
|
|
15425
|
+
loader = new Proto();
|
|
15426
|
+
memoizedLoaders.set(Proto, loader);
|
|
15427
|
+
}
|
|
15428
|
+
return loader;
|
|
15429
|
+
}
|
|
15430
|
+
return Proto;
|
|
15431
|
+
}
|
|
15432
|
+
function loadingFn(extensions, onProgress) {
|
|
15433
|
+
return function(Proto, input) {
|
|
15434
|
+
const loader = getLoader(Proto);
|
|
15435
|
+
if (extensions) extensions(loader);
|
|
15436
|
+
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
15437
|
+
return loader.loadAsync(input, onProgress).then((data) => {
|
|
15438
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
15439
|
+
return data;
|
|
15440
|
+
});
|
|
15441
|
+
}
|
|
15442
|
+
return new Promise(
|
|
15443
|
+
(res, reject) => loader.load(
|
|
15444
|
+
input,
|
|
15445
|
+
(data) => {
|
|
15446
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
15447
|
+
res(data);
|
|
15448
|
+
},
|
|
15449
|
+
onProgress,
|
|
15450
|
+
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
15451
|
+
)
|
|
15452
|
+
);
|
|
15453
|
+
};
|
|
15454
|
+
}
|
|
15455
|
+
function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
15456
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
15457
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
15458
|
+
const fn = loadingFn(extensions, onProgress);
|
|
15459
|
+
const results = cacheKeys.map(
|
|
15460
|
+
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
15461
|
+
);
|
|
15462
|
+
const stableRef = useRef(null);
|
|
15463
|
+
const previous = stableRef.current;
|
|
15464
|
+
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
15465
|
+
stableRef.current = stable;
|
|
15466
|
+
return Array.isArray(input) ? stable : stable[0];
|
|
15467
|
+
}
|
|
15468
|
+
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
15469
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
15470
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
15471
|
+
cacheKeys.forEach(
|
|
15472
|
+
(key, index) => preload(() => loadingFn(extensions, onProgress)(loader, inputs[index]), [loader, key])
|
|
15473
|
+
);
|
|
15474
|
+
};
|
|
15475
|
+
useLoader.clear = function(loader, input, cacheKey) {
|
|
15476
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
15477
|
+
cacheKeys.forEach((key) => clear([loader, key]));
|
|
15478
|
+
};
|
|
15479
|
+
useLoader.loader = getLoader;
|
|
15480
|
+
|
|
15481
|
+
const IsObject = (url) => url === Object(url) && !Array.isArray(url) && typeof url !== "function";
|
|
15482
|
+
function getUrls(input) {
|
|
15483
|
+
if (typeof input === "string") return [input];
|
|
15484
|
+
if (Array.isArray(input)) return input;
|
|
15485
|
+
return Object.values(input);
|
|
15486
|
+
}
|
|
15487
|
+
function inputSignature(input) {
|
|
15488
|
+
if (typeof input === "string") return input;
|
|
15489
|
+
if (Array.isArray(input)) return input.join("\0");
|
|
15490
|
+
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
15491
|
+
}
|
|
15492
|
+
function allUrlsCached(urls, textureCache) {
|
|
15493
|
+
return urls.every((url) => textureCache.has(url));
|
|
15494
|
+
}
|
|
15495
|
+
function buildFromCache(input, textureCache) {
|
|
15496
|
+
if (typeof input === "string") {
|
|
15497
|
+
return textureCache.get(input);
|
|
15498
|
+
} else if (Array.isArray(input)) {
|
|
15499
|
+
return input.map((url) => textureCache.get(url));
|
|
15500
|
+
} else {
|
|
15501
|
+
const result = {};
|
|
15502
|
+
const objInput = input;
|
|
15503
|
+
for (const key in objInput) {
|
|
15504
|
+
result[key] = textureCache.get(objInput[key]);
|
|
15505
|
+
}
|
|
15506
|
+
return result;
|
|
15507
|
+
}
|
|
15508
|
+
}
|
|
15509
|
+
function useTexture(input, optionsOrOnLoad) {
|
|
15510
|
+
const renderer = useThree((state) => state.internal.actualRenderer);
|
|
15511
|
+
const store = useStore();
|
|
15512
|
+
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
15513
|
+
const { onLoad, cache = true } = options;
|
|
15514
|
+
const onLoadRef = useRef(onLoad);
|
|
15515
|
+
onLoadRef.current = onLoad;
|
|
15516
|
+
const onLoadCalledForRef = useRef(null);
|
|
15517
|
+
const inputKey = useMemo(() => inputSignature(input), [input]);
|
|
15518
|
+
const stableInput = useMemo(() => input, [inputKey]);
|
|
15519
|
+
const urls = useMemo(() => getUrls(stableInput), [stableInput]);
|
|
15520
|
+
const cachedResult = useMemo(() => {
|
|
15521
|
+
if (!cache) return null;
|
|
15522
|
+
const textures = store.getState().textures;
|
|
15523
|
+
if (!allUrlsCached(urls, textures)) return null;
|
|
15524
|
+
return buildFromCache(stableInput, textures);
|
|
15525
|
+
}, [cache, urls, stableInput, store]);
|
|
15526
|
+
const loadedTextures = useLoader(
|
|
15527
|
+
getThree().TextureLoader,
|
|
15528
|
+
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
15529
|
+
);
|
|
15530
|
+
const mappedTextures = useMemo(() => {
|
|
15531
|
+
if (cachedResult) return cachedResult;
|
|
15532
|
+
if (IsObject(stableInput)) {
|
|
15533
|
+
const keyed = {};
|
|
15534
|
+
const textureArray = loadedTextures;
|
|
15535
|
+
let i = 0;
|
|
15536
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
15537
|
+
return keyed;
|
|
15538
|
+
} else {
|
|
15539
|
+
return loadedTextures;
|
|
15540
|
+
}
|
|
15541
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
15542
|
+
useLayoutEffect(() => {
|
|
15543
|
+
if (cachedResult) return;
|
|
15544
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
15545
|
+
onLoadCalledForRef.current = inputKey;
|
|
15546
|
+
onLoadRef.current?.(mappedTextures);
|
|
15547
|
+
}, [cachedResult, mappedTextures, inputKey]);
|
|
15548
|
+
useEffect(() => {
|
|
15549
|
+
if (cachedResult) return;
|
|
15550
|
+
if ("initTexture" in renderer) {
|
|
15551
|
+
let textureArray = [];
|
|
15552
|
+
if (Array.isArray(loadedTextures)) {
|
|
15553
|
+
textureArray = loadedTextures;
|
|
15554
|
+
} else if (loadedTextures.isTexture) {
|
|
15555
|
+
textureArray = [loadedTextures];
|
|
15556
|
+
} else if (IsObject(loadedTextures)) {
|
|
15557
|
+
textureArray = Object.values(loadedTextures);
|
|
15032
15558
|
}
|
|
15033
|
-
|
|
15034
|
-
if (
|
|
15035
|
-
|
|
15036
|
-
|
|
15037
|
-
|
|
15038
|
-
|
|
15039
|
-
|
|
15040
|
-
|
|
15041
|
-
|
|
15042
|
-
|
|
15043
|
-
|
|
15044
|
-
|
|
15045
|
-
|
|
15046
|
-
|
|
15047
|
-
|
|
15048
|
-
|
|
15049
|
-
|
|
15050
|
-
|
|
15051
|
-
|
|
15052
|
-
|
|
15053
|
-
|
|
15054
|
-
}));
|
|
15055
|
-
state.set((prev) => ({
|
|
15056
|
-
webGPUSupported: primary.store.getState().webGPUSupported,
|
|
15057
|
-
renderer,
|
|
15058
|
-
primaryStore: primary.store,
|
|
15059
|
-
internal: {
|
|
15060
|
-
...prev.internal,
|
|
15061
|
-
canvasTarget,
|
|
15062
|
-
isMultiCanvas: true,
|
|
15063
|
-
isSecondary: true,
|
|
15064
|
-
targetId: primaryCanvas
|
|
15065
|
-
}
|
|
15066
|
-
}));
|
|
15067
|
-
} else {
|
|
15068
|
-
const resolved = await resolveRenderer(rendererConfig, defaultGPUProps, support.Renderer);
|
|
15069
|
-
renderer = resolved.renderer;
|
|
15070
|
-
if (!renderer.hasInitialized?.()) {
|
|
15071
|
-
const size2 = computeInitialSize(canvas, propsSize);
|
|
15072
|
-
if (size2.width > 0 && size2.height > 0) {
|
|
15073
|
-
renderer.setPixelRatio(calculateDpr(dpr));
|
|
15074
|
-
renderer.setSize(size2.width, size2.height, false);
|
|
15075
|
-
}
|
|
15076
|
-
await renderer.init();
|
|
15077
|
-
}
|
|
15078
|
-
const backend = renderer.backend;
|
|
15079
|
-
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
15080
|
-
state.internal.actualRenderer = renderer;
|
|
15081
|
-
state.internal.releaseRenderer = leaseRenderer(renderer, resolved.owned);
|
|
15082
|
-
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
15083
|
-
if (canvasId && !state.internal.isSecondary) {
|
|
15084
|
-
const canvasTarget = renderer.getCanvasTarget?.();
|
|
15085
|
-
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
15086
|
-
state.set((prev) => ({
|
|
15087
|
-
internal: {
|
|
15088
|
-
...prev.internal,
|
|
15089
|
-
canvasTarget,
|
|
15090
|
-
unregisterPrimary
|
|
15091
|
-
}
|
|
15092
|
-
}));
|
|
15093
|
-
}
|
|
15094
|
-
}
|
|
15095
|
-
})();
|
|
15096
|
-
root.ready = tracked(setup);
|
|
15559
|
+
textureArray.forEach((texture) => {
|
|
15560
|
+
if (texture?.isTexture) {
|
|
15561
|
+
renderer.initTexture(texture);
|
|
15562
|
+
}
|
|
15563
|
+
});
|
|
15564
|
+
}
|
|
15565
|
+
}, [renderer, loadedTextures, cachedResult]);
|
|
15566
|
+
useEffect(() => {
|
|
15567
|
+
if (!cache) return;
|
|
15568
|
+
const urlTextureMap = urlTextureEntries(stableInput, mappedTextures);
|
|
15569
|
+
store.setState((state) => {
|
|
15570
|
+
const refs = new Map(state._textureRefs);
|
|
15571
|
+
let textures = state.textures;
|
|
15572
|
+
let added = false;
|
|
15573
|
+
for (const [url, texture] of urlTextureMap) {
|
|
15574
|
+
if (!textures.has(url)) {
|
|
15575
|
+
if (!added) {
|
|
15576
|
+
textures = new Map(textures);
|
|
15577
|
+
added = true;
|
|
15578
|
+
}
|
|
15579
|
+
textures.set(url, texture);
|
|
15097
15580
|
}
|
|
15098
|
-
|
|
15099
|
-
state = store.getState();
|
|
15100
|
-
renderer = state.internal.actualRenderer;
|
|
15581
|
+
refs.set(url, (refs.get(url) ?? 0) + 1);
|
|
15101
15582
|
}
|
|
15102
|
-
|
|
15103
|
-
|
|
15104
|
-
|
|
15105
|
-
|
|
15106
|
-
|
|
15107
|
-
|
|
15108
|
-
|
|
15583
|
+
return added ? { textures, _textureRefs: refs } : { _textureRefs: refs };
|
|
15584
|
+
});
|
|
15585
|
+
unstageTextures(
|
|
15586
|
+
store,
|
|
15587
|
+
urlTextureMap.map(([url]) => url)
|
|
15588
|
+
);
|
|
15589
|
+
return () => store.setState((state) => {
|
|
15590
|
+
const refs = new Map(state._textureRefs);
|
|
15591
|
+
for (const [url] of urlTextureMap) {
|
|
15592
|
+
const next = (refs.get(url) ?? 0) - 1;
|
|
15593
|
+
if (next <= 0) refs.delete(url);
|
|
15594
|
+
else refs.set(url, next);
|
|
15109
15595
|
}
|
|
15110
|
-
|
|
15111
|
-
|
|
15112
|
-
|
|
15113
|
-
|
|
15114
|
-
|
|
15115
|
-
|
|
15116
|
-
|
|
15117
|
-
|
|
15118
|
-
|
|
15119
|
-
|
|
15120
|
-
|
|
15121
|
-
|
|
15122
|
-
|
|
15123
|
-
|
|
15124
|
-
|
|
15125
|
-
|
|
15596
|
+
return { _textureRefs: refs };
|
|
15597
|
+
});
|
|
15598
|
+
}, [cache, stableInput, mappedTextures, store]);
|
|
15599
|
+
if (cache && !cachedResult) stageTextures(store, urlTextureEntries(stableInput, mappedTextures));
|
|
15600
|
+
return mappedTextures;
|
|
15601
|
+
}
|
|
15602
|
+
function urlTextureEntries(input, textures) {
|
|
15603
|
+
if (typeof input === "string") return [[input, textures]];
|
|
15604
|
+
if (Array.isArray(input)) return input.map((url, i) => [url, textures[i]]);
|
|
15605
|
+
const record = textures;
|
|
15606
|
+
return Object.keys(input).map((key) => [input[key], record[key]]);
|
|
15607
|
+
}
|
|
15608
|
+
useTexture.preload = (url) => {
|
|
15609
|
+
whenThree().then((three) => useLoader.preload(three.TextureLoader, url));
|
|
15610
|
+
};
|
|
15611
|
+
useTexture.clear = (input) => {
|
|
15612
|
+
if (hasThree()) useLoader.clear(getThree().TextureLoader, input);
|
|
15613
|
+
};
|
|
15614
|
+
const Texture = ({
|
|
15615
|
+
children,
|
|
15616
|
+
input,
|
|
15617
|
+
onLoad,
|
|
15618
|
+
cache
|
|
15619
|
+
}) => {
|
|
15620
|
+
const options = typeof onLoad === "function" ? { onLoad, cache } : { ...onLoad, cache };
|
|
15621
|
+
const ret = useTexture(input, options);
|
|
15622
|
+
return /* @__PURE__ */ jsx(Fragment, { children: children?.(ret) });
|
|
15623
|
+
};
|
|
15624
|
+
|
|
15625
|
+
function useTextures(selector) {
|
|
15626
|
+
const store = useStore();
|
|
15627
|
+
const registry = useMemo(() => {
|
|
15628
|
+
const getState = store.getState;
|
|
15629
|
+
const setState = store.setState;
|
|
15630
|
+
const getOne = (key) => getState().textures.get(key);
|
|
15631
|
+
return {
|
|
15632
|
+
get all() {
|
|
15633
|
+
return getState().textures;
|
|
15634
|
+
},
|
|
15635
|
+
get(input) {
|
|
15636
|
+
if (typeof input === "string") return getOne(input);
|
|
15637
|
+
if (Array.isArray(input)) return input.map(getOne);
|
|
15638
|
+
const out = {};
|
|
15639
|
+
for (const name in input) out[name] = getOne(input[name]);
|
|
15640
|
+
return out;
|
|
15641
|
+
},
|
|
15642
|
+
has: (key) => getState().textures.has(key),
|
|
15643
|
+
add(keyOrRecord, texture) {
|
|
15644
|
+
setState((state) => {
|
|
15645
|
+
const textures = new Map(state.textures);
|
|
15646
|
+
if (typeof keyOrRecord === "string") {
|
|
15647
|
+
textures.set(keyOrRecord, texture);
|
|
15648
|
+
} else {
|
|
15649
|
+
for (const key in keyOrRecord) textures.set(key, keyOrRecord[key]);
|
|
15126
15650
|
}
|
|
15127
|
-
|
|
15651
|
+
return { textures };
|
|
15652
|
+
});
|
|
15653
|
+
},
|
|
15654
|
+
dispose(key, options) {
|
|
15655
|
+
const state = getState();
|
|
15656
|
+
const refs = state._textureRefs.get(key) ?? 0;
|
|
15657
|
+
if (refs > 0 && !options?.force) {
|
|
15658
|
+
console.warn(
|
|
15659
|
+
`[useTextures] "${key}" still has ${refs} active reference(s); skipping dispose. Pass { force: true } to override.`
|
|
15660
|
+
);
|
|
15661
|
+
return false;
|
|
15128
15662
|
}
|
|
15129
|
-
state.
|
|
15130
|
-
|
|
15131
|
-
|
|
15132
|
-
|
|
15133
|
-
|
|
15134
|
-
|
|
15135
|
-
|
|
15136
|
-
scene = sceneOptions;
|
|
15137
|
-
prepare(scene, store, "", {});
|
|
15138
|
-
} else {
|
|
15139
|
-
scene = new three.Scene();
|
|
15140
|
-
prepare(scene, store, "", {});
|
|
15141
|
-
if (sceneOptions) applyProps(scene, sceneOptions);
|
|
15142
|
-
}
|
|
15143
|
-
state.set((prev) => ({
|
|
15144
|
-
scene,
|
|
15145
|
-
rootScene: scene,
|
|
15146
|
-
internal: { ...prev.internal, container: scene }
|
|
15147
|
-
}));
|
|
15148
|
-
const camera = tempCamera;
|
|
15149
|
-
if (camera && !camera.parent) scene.add(camera);
|
|
15150
|
-
}
|
|
15151
|
-
if (events && !state.events.handlers) {
|
|
15152
|
-
state.set({ events: events(store) });
|
|
15153
|
-
let wasEnabled = true;
|
|
15154
|
-
store.subscribe((state2) => {
|
|
15155
|
-
const { enabled } = state2.events;
|
|
15156
|
-
if (enabled && !wasEnabled) {
|
|
15157
|
-
state2.events.update?.();
|
|
15158
|
-
}
|
|
15159
|
-
wasEnabled = enabled;
|
|
15663
|
+
state.textures.get(key)?.dispose();
|
|
15664
|
+
setState((s) => {
|
|
15665
|
+
const textures = new Map(s.textures);
|
|
15666
|
+
textures.delete(key);
|
|
15667
|
+
const nextRefs = new Map(s._textureRefs);
|
|
15668
|
+
nextRefs.delete(key);
|
|
15669
|
+
return { textures, _textureRefs: nextRefs };
|
|
15160
15670
|
});
|
|
15671
|
+
return true;
|
|
15672
|
+
},
|
|
15673
|
+
disposeAll() {
|
|
15674
|
+
for (const texture of getState().textures.values()) texture.dispose();
|
|
15675
|
+
setState({ textures: /* @__PURE__ */ new Map(), _textureRefs: /* @__PURE__ */ new Map() });
|
|
15161
15676
|
}
|
|
15162
|
-
|
|
15163
|
-
|
|
15164
|
-
|
|
15165
|
-
|
|
15166
|
-
|
|
15677
|
+
};
|
|
15678
|
+
}, [store]);
|
|
15679
|
+
const subscribe = selector ? () => selector(registry) : (state) => state.textures;
|
|
15680
|
+
const selected = useThree(subscribe);
|
|
15681
|
+
return selector ? selected : registry;
|
|
15682
|
+
}
|
|
15683
|
+
|
|
15684
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
15685
|
+
const support = useThree((s) => s.internal.support);
|
|
15686
|
+
const size = useThree((s) => s.size);
|
|
15687
|
+
let width;
|
|
15688
|
+
let height;
|
|
15689
|
+
let opts;
|
|
15690
|
+
if (typeof widthOrOptions === "object") {
|
|
15691
|
+
opts = widthOrOptions;
|
|
15692
|
+
} else if (typeof widthOrOptions === "number") {
|
|
15693
|
+
width = widthOrOptions;
|
|
15694
|
+
if (typeof heightOrOptions === "object") {
|
|
15695
|
+
height = widthOrOptions;
|
|
15696
|
+
opts = heightOrOptions;
|
|
15697
|
+
} else if (typeof heightOrOptions === "number") {
|
|
15698
|
+
height = heightOrOptions;
|
|
15699
|
+
opts = options;
|
|
15700
|
+
} else {
|
|
15701
|
+
height = widthOrOptions;
|
|
15702
|
+
}
|
|
15703
|
+
}
|
|
15704
|
+
return useMemo(() => {
|
|
15705
|
+
const w = width ?? size.width;
|
|
15706
|
+
const h = height ?? size.height;
|
|
15707
|
+
const Target = support.RenderTarget;
|
|
15708
|
+
return new Target(w, h, opts);
|
|
15709
|
+
}, [width, height, size.width, size.height, opts, support]);
|
|
15710
|
+
}
|
|
15711
|
+
|
|
15712
|
+
const presetsObj = {
|
|
15713
|
+
apartment: "lebombo_1k.hdr",
|
|
15714
|
+
city: "potsdamer_platz_1k.hdr",
|
|
15715
|
+
dawn: "kiara_1_dawn_1k.hdr",
|
|
15716
|
+
forest: "forest_slope_1k.hdr",
|
|
15717
|
+
lobby: "st_fagans_interior_1k.hdr",
|
|
15718
|
+
night: "dikhololo_night_1k.hdr",
|
|
15719
|
+
park: "rooitou_park_1k.hdr",
|
|
15720
|
+
studio: "studio_small_03_1k.hdr",
|
|
15721
|
+
sunset: "venice_sunset_1k.hdr",
|
|
15722
|
+
warehouse: "empty_warehouse_01_1k.hdr"
|
|
15723
|
+
};
|
|
15724
|
+
|
|
15725
|
+
const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
|
|
15726
|
+
const isArray = (arr) => Array.isArray(arr);
|
|
15727
|
+
const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
|
|
15728
|
+
const loadedLoaders = /* @__PURE__ */ new Map();
|
|
15729
|
+
const pendingLoaders = /* @__PURE__ */ new Map();
|
|
15730
|
+
function loadLoader(format) {
|
|
15731
|
+
let pending = pendingLoaders.get(format);
|
|
15732
|
+
if (!pending) {
|
|
15733
|
+
pending = importLoader(format).then(
|
|
15734
|
+
(loader) => {
|
|
15735
|
+
loadedLoaders.set(format, loader);
|
|
15736
|
+
return loader;
|
|
15737
|
+
},
|
|
15738
|
+
(error) => {
|
|
15739
|
+
pendingLoaders.delete(format);
|
|
15740
|
+
throw error;
|
|
15167
15741
|
}
|
|
15168
|
-
|
|
15169
|
-
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
|
|
15173
|
-
|
|
15174
|
-
|
|
15175
|
-
|
|
15176
|
-
|
|
15177
|
-
|
|
15178
|
-
|
|
15179
|
-
|
|
15180
|
-
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
|
|
15184
|
-
|
|
15185
|
-
|
|
15186
|
-
|
|
15187
|
-
|
|
15188
|
-
|
|
15189
|
-
|
|
15190
|
-
|
|
15191
|
-
|
|
15192
|
-
|
|
15193
|
-
|
|
15194
|
-
|
|
15195
|
-
|
|
15196
|
-
|
|
15197
|
-
|
|
15198
|
-
|
|
15199
|
-
|
|
15200
|
-
|
|
15201
|
-
|
|
15202
|
-
|
|
15203
|
-
|
|
15204
|
-
|
|
15205
|
-
|
|
15206
|
-
|
|
15207
|
-
|
|
15208
|
-
|
|
15209
|
-
|
|
15210
|
-
|
|
15211
|
-
|
|
15212
|
-
|
|
15213
|
-
|
|
15214
|
-
|
|
15215
|
-
|
|
15216
|
-
|
|
15217
|
-
|
|
15218
|
-
|
|
15219
|
-
|
|
15220
|
-
xrManager.addEventListener("sessionstart", handleSessionChange);
|
|
15221
|
-
xrManager.addEventListener("sessionend", handleSessionChange);
|
|
15222
|
-
},
|
|
15223
|
-
disconnect() {
|
|
15224
|
-
const { gl, renderer: renderer2 } = store.getState();
|
|
15225
|
-
const xrManager = (renderer2 || gl).xr;
|
|
15226
|
-
xrManager.removeEventListener("sessionstart", handleSessionChange);
|
|
15227
|
-
xrManager.removeEventListener("sessionend", handleSessionChange);
|
|
15228
|
-
}
|
|
15229
|
-
};
|
|
15230
|
-
if (typeof renderer.xr?.addEventListener === "function") xr.connect();
|
|
15231
|
-
state.set({ xr });
|
|
15232
|
-
}
|
|
15233
|
-
if (renderer.shadowMap && !is.equ(shadows, lastConfiguredProps.shadows, shallowLoose)) {
|
|
15234
|
-
lastConfiguredProps.shadows = shadows;
|
|
15235
|
-
const oldEnabled = renderer.shadowMap.enabled;
|
|
15236
|
-
const oldType = renderer.shadowMap.type;
|
|
15237
|
-
renderer.shadowMap.enabled = !!shadows;
|
|
15238
|
-
if (is.boo(shadows)) {
|
|
15239
|
-
renderer.shadowMap.type = three.PCFShadowMap;
|
|
15240
|
-
} else if (is.str(shadows)) {
|
|
15241
|
-
if (shadows === "soft") {
|
|
15242
|
-
notifyDepreciated({
|
|
15243
|
-
heading: 'shadows="soft" is deprecated',
|
|
15244
|
-
body: "Three has depreciated soft and improved basic PCFShadows, we converted for you.",
|
|
15245
|
-
link: "https://github.com/mrdoob/three.js/wiki/Migration-Guide?utm_source=chatgpt.com#181--182"
|
|
15742
|
+
);
|
|
15743
|
+
pendingLoaders.set(format, pending);
|
|
15744
|
+
}
|
|
15745
|
+
return pending;
|
|
15746
|
+
}
|
|
15747
|
+
async function importLoader(format) {
|
|
15748
|
+
let loader;
|
|
15749
|
+
switch (format) {
|
|
15750
|
+
case "cube":
|
|
15751
|
+
loader = getThree().CubeTextureLoader;
|
|
15752
|
+
break;
|
|
15753
|
+
case "hdr-cube":
|
|
15754
|
+
loader = (await import('three/examples/jsm/loaders/HDRCubeTextureLoader.js')).HDRCubeTextureLoader;
|
|
15755
|
+
break;
|
|
15756
|
+
case "hdr":
|
|
15757
|
+
loader = (await import('three/examples/jsm/loaders/HDRLoader.js')).HDRLoader;
|
|
15758
|
+
break;
|
|
15759
|
+
case "exr":
|
|
15760
|
+
loader = (await import('three/examples/jsm/loaders/EXRLoader.js')).EXRLoader;
|
|
15761
|
+
break;
|
|
15762
|
+
case "jpg":
|
|
15763
|
+
loader = createJpegLoader((await import('three/examples/jsm/loaders/UltraHDRLoader.js')).UltraHDRLoader);
|
|
15764
|
+
break;
|
|
15765
|
+
case "ldr":
|
|
15766
|
+
loader = getThree().TextureLoader;
|
|
15767
|
+
break;
|
|
15768
|
+
}
|
|
15769
|
+
return loader;
|
|
15770
|
+
}
|
|
15771
|
+
function createJpegLoader(UltraHDR) {
|
|
15772
|
+
return class JpegEnvironmentLoader extends UltraHDR {
|
|
15773
|
+
// @ts-expect-error A plain JPEG resolves to a Texture, not the DataTexture UltraHDRLoader declares
|
|
15774
|
+
load(url, onLoad, onProgress, onError) {
|
|
15775
|
+
const three = getThree();
|
|
15776
|
+
const file = new three.FileLoader(this.manager);
|
|
15777
|
+
file.setResponseType("arraybuffer");
|
|
15778
|
+
file.setRequestHeader(this.requestHeader);
|
|
15779
|
+
file.setPath(this.path);
|
|
15780
|
+
file.setWithCredentials(this.withCredentials);
|
|
15781
|
+
file.load(
|
|
15782
|
+
url,
|
|
15783
|
+
(buffer) => {
|
|
15784
|
+
try {
|
|
15785
|
+
this.parse(buffer, (texData) => {
|
|
15786
|
+
const { data } = texData;
|
|
15787
|
+
const texture = new three.DataTexture(data, texData.width, texData.height, three.RGBAFormat, texData.type);
|
|
15788
|
+
texture.minFilter = three.LinearMipMapLinearFilter;
|
|
15789
|
+
texture.magFilter = three.LinearFilter;
|
|
15790
|
+
texture.generateMipmaps = true;
|
|
15791
|
+
texture.flipY = true;
|
|
15792
|
+
texture.needsUpdate = true;
|
|
15793
|
+
onLoad?.(texture);
|
|
15246
15794
|
});
|
|
15247
|
-
}
|
|
15248
|
-
|
|
15249
|
-
|
|
15250
|
-
|
|
15251
|
-
|
|
15252
|
-
|
|
15253
|
-
|
|
15254
|
-
|
|
15255
|
-
|
|
15256
|
-
|
|
15257
|
-
|
|
15258
|
-
|
|
15259
|
-
|
|
15260
|
-
|
|
15261
|
-
|
|
15262
|
-
if (!configured) {
|
|
15263
|
-
renderer.outputColorSpace = three.SRGBColorSpace;
|
|
15264
|
-
renderer.toneMapping = three.ACESFilmicToneMapping;
|
|
15265
|
-
}
|
|
15266
|
-
const textureColorSpace = requestedTextureColorSpace ?? three.SRGBColorSpace;
|
|
15267
|
-
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
15268
|
-
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
15269
|
-
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
15270
|
-
}
|
|
15271
|
-
const r3fProps = ["textureColorSpace"];
|
|
15272
|
-
const constructorOnlyProps = ["samples", "antialias", "alpha", "canvas", "powerPreference"];
|
|
15273
|
-
const nonApplyProps = [...r3fProps, ...constructorOnlyProps];
|
|
15274
|
-
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
|
|
15275
|
-
const glProps = {};
|
|
15276
|
-
for (const key in glConfig) {
|
|
15277
|
-
if (!nonApplyProps.includes(key)) glProps[key] = glConfig[key];
|
|
15278
|
-
}
|
|
15279
|
-
applyProps(renderer, glProps);
|
|
15280
|
-
}
|
|
15281
|
-
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
|
|
15282
|
-
const currentRenderer = state.renderer;
|
|
15283
|
-
if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
|
|
15284
|
-
const rendererProps = {};
|
|
15285
|
-
for (const key in rendererConfig) {
|
|
15286
|
-
if (!nonApplyProps.includes(key)) rendererProps[key] = rendererConfig[key];
|
|
15287
|
-
}
|
|
15288
|
-
applyProps(currentRenderer, rendererProps);
|
|
15289
|
-
}
|
|
15290
|
-
}
|
|
15291
|
-
const scheduler = getScheduler();
|
|
15292
|
-
const rootId = state.internal.rootId;
|
|
15293
|
-
if (!rootId) {
|
|
15294
|
-
const newRootId = canvasId || scheduler.generateRootId();
|
|
15295
|
-
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
15296
|
-
getState: () => store.getState(),
|
|
15297
|
-
onError: (err) => store.getState().setError(err),
|
|
15298
|
-
frameloop: store.getState().frameloop,
|
|
15299
|
-
before: schedulerConfig?.before,
|
|
15300
|
-
after: schedulerConfig?.after,
|
|
15301
|
-
order: schedulerConfig?.order
|
|
15302
|
-
});
|
|
15303
|
-
const unregisterCanvasTarget = scheduler.register(
|
|
15304
|
-
() => {
|
|
15305
|
-
const state2 = store.getState();
|
|
15306
|
-
const canvasTarget = state2.internal.canvasTarget;
|
|
15307
|
-
if (canvasTarget) {
|
|
15308
|
-
const renderer2 = state2.internal.actualRenderer;
|
|
15309
|
-
if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
|
|
15310
|
-
if (state2.internal.canvasTargetSizeDirty) {
|
|
15311
|
-
state2.internal.canvasTargetSizeDirty = false;
|
|
15312
|
-
renderer2.backend?.updateSize?.();
|
|
15795
|
+
} catch {
|
|
15796
|
+
const objectURL = URL.createObjectURL(new Blob([buffer], { type: "image/jpeg" }));
|
|
15797
|
+
const settle = () => URL.revokeObjectURL(objectURL);
|
|
15798
|
+
new three.ImageLoader().load(
|
|
15799
|
+
objectURL,
|
|
15800
|
+
(image) => {
|
|
15801
|
+
settle();
|
|
15802
|
+
const texture = new three.Texture(image);
|
|
15803
|
+
texture.needsUpdate = true;
|
|
15804
|
+
onLoad?.(texture);
|
|
15805
|
+
},
|
|
15806
|
+
void 0,
|
|
15807
|
+
(error) => {
|
|
15808
|
+
settle();
|
|
15809
|
+
onError?.(error);
|
|
15313
15810
|
}
|
|
15314
|
-
|
|
15315
|
-
},
|
|
15316
|
-
{
|
|
15317
|
-
id: `${newRootId}_canvasTarget`,
|
|
15318
|
-
rootId: newRootId,
|
|
15319
|
-
phase: "start",
|
|
15320
|
-
system: true
|
|
15321
|
-
}
|
|
15322
|
-
);
|
|
15323
|
-
const unregisterEventsFlush = scheduler.register(
|
|
15324
|
-
() => {
|
|
15325
|
-
const state2 = store.getState();
|
|
15326
|
-
state2.events.flush?.();
|
|
15327
|
-
},
|
|
15328
|
-
{
|
|
15329
|
-
id: `${newRootId}_events`,
|
|
15330
|
-
rootId: newRootId,
|
|
15331
|
-
phase: "input",
|
|
15332
|
-
system: true
|
|
15333
|
-
}
|
|
15334
|
-
);
|
|
15335
|
-
const unregisterFrustum = scheduler.register(
|
|
15336
|
-
() => {
|
|
15337
|
-
const state2 = store.getState();
|
|
15338
|
-
if (state2.autoUpdateFrustum && state2.camera) {
|
|
15339
|
-
updateFrustum(state2.camera, state2.frustum);
|
|
15340
|
-
}
|
|
15341
|
-
},
|
|
15342
|
-
{
|
|
15343
|
-
id: `${newRootId}_frustum`,
|
|
15344
|
-
rootId: newRootId,
|
|
15345
|
-
before: "render",
|
|
15346
|
-
system: true
|
|
15347
|
-
}
|
|
15348
|
-
);
|
|
15349
|
-
const unregisterVisibility = scheduler.register(
|
|
15350
|
-
() => {
|
|
15351
|
-
const state2 = store.getState();
|
|
15352
|
-
checkVisibility(state2);
|
|
15353
|
-
},
|
|
15354
|
-
{
|
|
15355
|
-
id: `${newRootId}_visibility`,
|
|
15356
|
-
rootId: newRootId,
|
|
15357
|
-
before: "render",
|
|
15358
|
-
system: true,
|
|
15359
|
-
after: `${newRootId}_frustum`
|
|
15360
|
-
}
|
|
15361
|
-
);
|
|
15362
|
-
const unregisterRender = scheduler.register(
|
|
15363
|
-
() => {
|
|
15364
|
-
const state2 = store.getState();
|
|
15365
|
-
const renderer2 = state2.internal.actualRenderer;
|
|
15366
|
-
const userHandlesRender = scheduler.hasUserJobsInPhase("render", newRootId);
|
|
15367
|
-
if (userHandlesRender || state2.internal.priority) return;
|
|
15368
|
-
try {
|
|
15369
|
-
const renderOverride = state2.internal.renderOverride;
|
|
15370
|
-
if (renderOverride) renderOverride();
|
|
15371
|
-
else if (renderer2?.render) renderer2.render(state2.scene, state2.camera);
|
|
15372
|
-
} catch (error) {
|
|
15373
|
-
state2.setError(error instanceof Error ? error : new Error(String(error)));
|
|
15374
|
-
}
|
|
15375
|
-
},
|
|
15376
|
-
{
|
|
15377
|
-
// Use canvas ID directly as job ID if available, otherwise use generated rootId
|
|
15378
|
-
id: canvasId || `${newRootId}_render`,
|
|
15379
|
-
rootId: newRootId,
|
|
15380
|
-
phase: "render",
|
|
15381
|
-
system: true,
|
|
15382
|
-
// Internal flag: this is a system job, not user-controlled
|
|
15383
|
-
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
15384
|
-
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
15385
|
-
}
|
|
15386
|
-
);
|
|
15387
|
-
state.set((state2) => ({
|
|
15388
|
-
internal: {
|
|
15389
|
-
...state2.internal,
|
|
15390
|
-
rootId: newRootId,
|
|
15391
|
-
unregisterRoot: () => {
|
|
15392
|
-
unregisterRoot();
|
|
15393
|
-
unregisterCanvasTarget();
|
|
15394
|
-
unregisterEventsFlush();
|
|
15395
|
-
unregisterFrustum();
|
|
15396
|
-
unregisterVisibility();
|
|
15397
|
-
unregisterRender();
|
|
15398
|
-
},
|
|
15399
|
-
scheduler
|
|
15811
|
+
);
|
|
15400
15812
|
}
|
|
15401
|
-
}
|
|
15402
|
-
|
|
15403
|
-
|
|
15404
|
-
|
|
15405
|
-
scheduler.setRootConstraints(rootId, {
|
|
15406
|
-
before: schedulerConfig?.before,
|
|
15407
|
-
after: schedulerConfig?.after
|
|
15408
|
-
});
|
|
15409
|
-
}
|
|
15410
|
-
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
15411
|
-
scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
15412
|
-
}
|
|
15413
|
-
}
|
|
15414
|
-
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
15415
|
-
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
15416
|
-
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
15417
|
-
attachRootExtensions(store);
|
|
15418
|
-
onCreated = onCreatedCallback;
|
|
15419
|
-
configured = true;
|
|
15420
|
-
resolve();
|
|
15421
|
-
return this;
|
|
15422
|
-
},
|
|
15423
|
-
render(children) {
|
|
15424
|
-
if (_roots.get(canvas) !== root) return store;
|
|
15425
|
-
cancelUnmount();
|
|
15426
|
-
if (!configured && !pending) this.configure();
|
|
15427
|
-
pending.then(() => {
|
|
15428
|
-
if (_roots.get(canvas) !== root || root.unmountClaim) return;
|
|
15429
|
-
reconciler.updateContainer(
|
|
15430
|
-
/* @__PURE__ */ jsx(Provider, { store, children, onCreated, rootElement: canvas }),
|
|
15431
|
-
fiber,
|
|
15432
|
-
null,
|
|
15433
|
-
() => void 0
|
|
15434
|
-
);
|
|
15435
|
-
});
|
|
15436
|
-
return store;
|
|
15437
|
-
},
|
|
15438
|
-
unmount() {
|
|
15439
|
-
if (_roots.get(canvas) === root) unmountComponentAtNode(canvas);
|
|
15813
|
+
},
|
|
15814
|
+
onProgress,
|
|
15815
|
+
onError
|
|
15816
|
+
);
|
|
15440
15817
|
}
|
|
15441
15818
|
};
|
|
15442
15819
|
}
|
|
15443
|
-
|
|
15444
|
-
|
|
15445
|
-
|
|
15446
|
-
onCreated,
|
|
15447
|
-
rootElement
|
|
15448
|
-
}) {
|
|
15449
|
-
useIsomorphicLayoutEffect(() => {
|
|
15450
|
-
const state = store.getState();
|
|
15451
|
-
state.set((state2) => ({ internal: { ...state2.internal, active: true } }));
|
|
15452
|
-
if (onCreated) onCreated(state);
|
|
15453
|
-
if (!store.getState().events.connected) state.events.connect?.(rootElement);
|
|
15454
|
-
}, []);
|
|
15455
|
-
return /* @__PURE__ */ jsx(context.Provider, { value: store, children });
|
|
15820
|
+
const LOADER_KEY = Symbol("r3f-environment-loader");
|
|
15821
|
+
function useEnvironmentLoader(format) {
|
|
15822
|
+
return suspend(() => loadLoader(format), [LOADER_KEY, format]);
|
|
15456
15823
|
}
|
|
15457
|
-
function
|
|
15458
|
-
|
|
15459
|
-
|
|
15460
|
-
|
|
15461
|
-
|
|
15462
|
-
|
|
15463
|
-
|
|
15464
|
-
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15824
|
+
function useEnvironment({
|
|
15825
|
+
files = defaultFiles,
|
|
15826
|
+
path = "",
|
|
15827
|
+
preset = void 0,
|
|
15828
|
+
colorSpace = void 0,
|
|
15829
|
+
extensions
|
|
15830
|
+
} = {}) {
|
|
15831
|
+
if (preset) {
|
|
15832
|
+
validatePreset(preset);
|
|
15833
|
+
files = presetsObj[preset];
|
|
15834
|
+
path = CUBEMAP_ROOT;
|
|
15835
|
+
}
|
|
15836
|
+
const multiFile = isArray(files);
|
|
15837
|
+
const { format, isCubemap } = getFormat(files);
|
|
15838
|
+
if (!format) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
15839
|
+
const loader = useEnvironmentLoader(format);
|
|
15840
|
+
const loaderResult = useLoader(
|
|
15841
|
+
loader,
|
|
15842
|
+
multiFile ? [files] : files,
|
|
15843
|
+
(loader2) => {
|
|
15844
|
+
loader2.setPath?.(path);
|
|
15845
|
+
if (extensions) extensions(loader2);
|
|
15846
|
+
}
|
|
15847
|
+
);
|
|
15848
|
+
const texture = multiFile ? (
|
|
15849
|
+
// @ts-ignore
|
|
15850
|
+
loaderResult[0]
|
|
15851
|
+
) : loaderResult;
|
|
15852
|
+
const three = getThree();
|
|
15853
|
+
texture.mapping = isCubemap ? three.CubeReflectionMapping : three.EquirectangularReflectionMapping;
|
|
15854
|
+
const hdr = format === "hdr-cube" || texture.isDataTexture === true;
|
|
15855
|
+
texture.colorSpace = colorSpace ?? (hdr ? "srgb-linear" : "srgb");
|
|
15856
|
+
return texture;
|
|
15857
|
+
}
|
|
15858
|
+
const preloadDefaultOptions = {
|
|
15859
|
+
files: defaultFiles,
|
|
15860
|
+
path: "",
|
|
15861
|
+
preset: void 0,
|
|
15862
|
+
extensions: void 0
|
|
15863
|
+
};
|
|
15864
|
+
useEnvironment.preload = (preloadOptions) => {
|
|
15865
|
+
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
15866
|
+
let { files, path = "" } = options;
|
|
15867
|
+
const { preset, extensions } = options;
|
|
15868
|
+
if (preset) {
|
|
15869
|
+
validatePreset(preset);
|
|
15870
|
+
files = presetsObj[preset];
|
|
15871
|
+
path = CUBEMAP_ROOT;
|
|
15872
|
+
}
|
|
15873
|
+
const { format } = getFormat(files);
|
|
15874
|
+
if (!format) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
15875
|
+
const input = isArray(files) ? [files] : files;
|
|
15876
|
+
loadLoader(format).then((loader) => {
|
|
15877
|
+
useLoader.preload(loader, input, (loader2) => {
|
|
15878
|
+
loader2.setPath?.(path);
|
|
15879
|
+
if (extensions) extensions(loader2);
|
|
15468
15880
|
});
|
|
15469
15881
|
});
|
|
15470
|
-
|
|
15471
|
-
|
|
15472
|
-
|
|
15473
|
-
|
|
15474
|
-
|
|
15475
|
-
|
|
15476
|
-
|
|
15477
|
-
|
|
15478
|
-
|
|
15479
|
-
|
|
15480
|
-
|
|
15481
|
-
|
|
15482
|
-
}
|
|
15483
|
-
};
|
|
15484
|
-
attempt(() => internal.unwatchDpr?.());
|
|
15485
|
-
internal.unwatchDpr = void 0;
|
|
15486
|
-
attempt(() => internal.unregisterRoot?.());
|
|
15487
|
-
internal.unregisterRoot = void 0;
|
|
15488
|
-
attempt(() => detachRootExtensions(root.store));
|
|
15489
|
-
attempt(() => internal.unregisterPrimary?.());
|
|
15490
|
-
attempt(() => state.events.disconnect?.());
|
|
15491
|
-
if (!internal.isSecondary && internal.actualRenderer?.xr && state.xr) attempt(() => state.xr.disconnect());
|
|
15492
|
-
attempt(() => cleanupHelperGroup(root.store));
|
|
15493
|
-
if (state.scene) attempt(() => dispose(state.scene));
|
|
15494
|
-
const canvasTarget = internal.canvasTarget;
|
|
15495
|
-
if (internal.isSecondary && canvasTarget?.dispose) attempt(() => canvasTarget.dispose());
|
|
15496
|
-
const released = attempt(() => internal.releaseRenderer?.());
|
|
15497
|
-
internal.releaseRenderer = void 0;
|
|
15498
|
-
if (callback) {
|
|
15499
|
-
if (released) {
|
|
15500
|
-
released.then(() => callback(canvas)).catch((error) => console.warn("[R3F] Error in unmount callback", error));
|
|
15501
|
-
} else {
|
|
15502
|
-
callback(canvas);
|
|
15503
|
-
}
|
|
15504
|
-
}
|
|
15882
|
+
};
|
|
15883
|
+
const clearDefaultOptins = {
|
|
15884
|
+
files: defaultFiles,
|
|
15885
|
+
preset: void 0
|
|
15886
|
+
};
|
|
15887
|
+
useEnvironment.clear = (clearOptions) => {
|
|
15888
|
+
const options = { ...clearDefaultOptins, ...clearOptions };
|
|
15889
|
+
let { files } = options;
|
|
15890
|
+
const { preset } = options;
|
|
15891
|
+
if (preset) {
|
|
15892
|
+
validatePreset(preset);
|
|
15893
|
+
files = presetsObj[preset];
|
|
15505
15894
|
}
|
|
15895
|
+
const { format } = getFormat(files);
|
|
15896
|
+
if (!format) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
15897
|
+
const input = isArray(files) ? [files] : files;
|
|
15898
|
+
const clear = (loader2) => useLoader.clear(loader2, input);
|
|
15899
|
+
const loader = loadedLoaders.get(format);
|
|
15900
|
+
if (loader) {
|
|
15901
|
+
clear(loader);
|
|
15902
|
+
} else {
|
|
15903
|
+
const pending = pendingLoaders.get(format);
|
|
15904
|
+
if (pending) void pending.then(clear, () => {
|
|
15905
|
+
});
|
|
15906
|
+
}
|
|
15907
|
+
};
|
|
15908
|
+
function validatePreset(preset) {
|
|
15909
|
+
if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
|
|
15910
|
+
}
|
|
15911
|
+
function getFormat(files) {
|
|
15912
|
+
const isCubemap = isArray(files) && files.length === 6;
|
|
15913
|
+
const firstEntry = isArray(files) ? files[0] : files;
|
|
15914
|
+
const firstExtension = firstEntry.split(/[?#]/)[0].split(".").pop()?.toLowerCase();
|
|
15915
|
+
let format;
|
|
15916
|
+
if (isCubemap) format = firstExtension === "hdr" ? "hdr-cube" : "cube";
|
|
15917
|
+
else if (firstEntry.startsWith("data:application/exr")) format = "exr";
|
|
15918
|
+
else if (firstEntry.startsWith("data:application/hdr")) format = "hdr";
|
|
15919
|
+
else if (firstEntry.startsWith("data:image/jpeg")) format = "jpg";
|
|
15920
|
+
else if (firstExtension === "hdr" || firstExtension === "exr") format = firstExtension;
|
|
15921
|
+
else if (firstExtension === "jpg" || firstExtension === "jpeg") format = "jpg";
|
|
15922
|
+
else if (/^data:image\/(png|webp|avif|gif)[;,]/.test(firstEntry)) format = "ldr";
|
|
15923
|
+
else if (["png", "webp", "avif", "gif"].includes(firstExtension)) format = "ldr";
|
|
15924
|
+
return { format, isCubemap };
|
|
15925
|
+
}
|
|
15926
|
+
|
|
15927
|
+
function useInstanceHandle(ref) {
|
|
15928
|
+
const instance = useRef(null);
|
|
15929
|
+
useImperativeHandle(instance, () => ref.current.__r3f, [ref]);
|
|
15930
|
+
return instance;
|
|
15931
|
+
}
|
|
15932
|
+
function useGraph(object) {
|
|
15933
|
+
return useMemo(() => buildGraph(object), [object]);
|
|
15506
15934
|
}
|
|
15935
|
+
|
|
15507
15936
|
function createPortal(children, container, state) {
|
|
15508
15937
|
return /* @__PURE__ */ jsx(Portal, { children, container, state });
|
|
15509
15938
|
}
|
|
@@ -15540,16 +15969,13 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
15540
15969
|
const [portalScene] = useState(() => {
|
|
15541
15970
|
if ("isScene" in container && container.isScene) return container;
|
|
15542
15971
|
if (!injectScene) return container;
|
|
15543
|
-
|
|
15544
|
-
container.add(scene);
|
|
15545
|
-
return scene;
|
|
15972
|
+
return new (getThree()).Scene();
|
|
15546
15973
|
});
|
|
15547
15974
|
useIsomorphicLayoutEffect(() => {
|
|
15975
|
+
if (portalScene === container || !injectScene) return;
|
|
15976
|
+
container.add(portalScene);
|
|
15548
15977
|
return () => {
|
|
15549
|
-
|
|
15550
|
-
container.remove(portalScene);
|
|
15551
|
-
dispose(portalScene);
|
|
15552
|
-
}
|
|
15978
|
+
container.remove(portalScene);
|
|
15553
15979
|
};
|
|
15554
15980
|
}, [portalScene, container, injectScene]);
|
|
15555
15981
|
const lastRootState = useRef(null);
|
|
@@ -15558,6 +15984,7 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
15558
15984
|
const lastRoot = lastRootState.current;
|
|
15559
15985
|
if (lastRoot) {
|
|
15560
15986
|
for (const key in rootState) {
|
|
15987
|
+
if (isAccessor(rootState, key)) continue;
|
|
15561
15988
|
const field = key;
|
|
15562
15989
|
const changed = rootState[field] !== lastRoot[field];
|
|
15563
15990
|
const inherited = !(key in rest) && injectState[field] === lastRoot[field];
|
|
@@ -15574,11 +16001,7 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
15574
16001
|
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
15575
16002
|
}
|
|
15576
16003
|
const set = injectState.set;
|
|
15577
|
-
return {
|
|
15578
|
-
// The intersect consists of the previous root state
|
|
15579
|
-
...rootState,
|
|
15580
|
-
...injectState,
|
|
15581
|
-
...followed,
|
|
16004
|
+
return Object.assign(cloneState(rootState, injectState, followed), {
|
|
15582
16005
|
// Portals have their own scene - always a real THREE.Scene (injected if needed)
|
|
15583
16006
|
scene: portalScene,
|
|
15584
16007
|
// rootScene always points to the actual THREE.Scene, even inside portals
|
|
@@ -15593,13 +16016,19 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
15593
16016
|
size: resolvedSize,
|
|
15594
16017
|
viewport: { ...rootState.viewport, ...viewport },
|
|
15595
16018
|
// Layers are allowed to override events
|
|
15596
|
-
setEvents: (events2) => set((state2) => ({
|
|
15597
|
-
// Container for child attachment - the portalScene (injected or container itself)
|
|
15598
|
-
|
|
15599
|
-
|
|
16019
|
+
setEvents: (events2) => set((state2) => ({ events: { ...state2.events, ...events2 } })),
|
|
16020
|
+
// Container for child attachment - the portalScene (injected or container itself). A portal
|
|
16021
|
+
// renders with its parent's renderer, which `renderer` / `gl` read from `actualRenderer`
|
|
16022
|
+
internal: {
|
|
16023
|
+
...rootState.internal,
|
|
16024
|
+
...injectState.internal,
|
|
16025
|
+
actualRenderer: rootState.internal.actualRenderer,
|
|
16026
|
+
container: portalScene
|
|
16027
|
+
}
|
|
16028
|
+
});
|
|
15600
16029
|
});
|
|
15601
16030
|
const usePortalStore = useMemo(() => {
|
|
15602
|
-
const store = createWithEqualityFn((set, get) => ({ ...rest, set, get }));
|
|
16031
|
+
const store = createWithEqualityFn(keepAccessors((set, get) => ({ ...rest, set, get })));
|
|
15603
16032
|
const onMutate = (prev) => store.setState((state2) => inject.current(prev, state2));
|
|
15604
16033
|
onMutate(previousRoot.getState());
|
|
15605
16034
|
return store;
|
|
@@ -15618,9 +16047,6 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
15618
16047
|
) })
|
|
15619
16048
|
);
|
|
15620
16049
|
}
|
|
15621
|
-
function flushSync(fn) {
|
|
15622
|
-
return reconciler.flushSyncFromReconciler(fn);
|
|
15623
|
-
}
|
|
15624
16050
|
|
|
15625
16051
|
const isRef = (obj) => obj.current && obj.current.isScene;
|
|
15626
16052
|
const resolveScene = (scene) => isRef(scene) ? scene.current : scene;
|
|
@@ -15812,12 +16238,12 @@ function EnvironmentColor({ color, scene }) {
|
|
|
15812
16238
|
function EnvironmentDualSource(props) {
|
|
15813
16239
|
const { backgroundFiles, ...envProps } = props;
|
|
15814
16240
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15815
|
-
/* @__PURE__ */ jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
15816
|
-
/* @__PURE__ */ jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
|
|
16241
|
+
(envProps.files || envProps.preset) && /* @__PURE__ */ jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
16242
|
+
/* @__PURE__ */ jsx(EnvironmentCube, { ...props, files: backgroundFiles, preset: void 0, background: "only" })
|
|
15817
16243
|
] });
|
|
15818
16244
|
}
|
|
15819
16245
|
function Environment(props) {
|
|
15820
|
-
if (props.color && !props.files && !props.preset && !props.map) {
|
|
16246
|
+
if (props.color !== void 0 && !props.files && !props.preset && !props.map) {
|
|
15821
16247
|
return /* @__PURE__ */ jsx(EnvironmentColor, { ...props });
|
|
15822
16248
|
}
|
|
15823
16249
|
if (props.backgroundFiles && props.backgroundFiles !== props.files) {
|
|
@@ -15827,7 +16253,7 @@ function Environment(props) {
|
|
|
15827
16253
|
}
|
|
15828
16254
|
|
|
15829
16255
|
function parseBackground(background) {
|
|
15830
|
-
if (
|
|
16256
|
+
if (background === void 0 || background === null || background === "") return null;
|
|
15831
16257
|
if (typeof background === "object" && !background.isColor) {
|
|
15832
16258
|
const { backgroundMap, envMap, files, preset, ...rest } = background;
|
|
15833
16259
|
return {
|
|
@@ -15845,7 +16271,7 @@ function parseBackground(background) {
|
|
|
15845
16271
|
if (background in presetsObj) {
|
|
15846
16272
|
return { preset: background, background: true };
|
|
15847
16273
|
}
|
|
15848
|
-
if (/^(https
|
|
16274
|
+
if (/^(https?:\/\/|\/|\.\/|\.\.\/|data:)|\.(hdr|exr|jpg|jpeg|png|webp|avif|gif)([?#].*)?$/i.test(background)) {
|
|
15849
16275
|
return { files: background, background: true };
|
|
15850
16276
|
}
|
|
15851
16277
|
return { color: background, background: true };
|
|
@@ -15856,19 +16282,6 @@ function parseBackground(background) {
|
|
|
15856
16282
|
return null;
|
|
15857
16283
|
}
|
|
15858
16284
|
|
|
15859
|
-
function parseRendererConfig(rendererProp) {
|
|
15860
|
-
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
15861
|
-
if (isRendererConfig) {
|
|
15862
|
-
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
15863
|
-
return {
|
|
15864
|
-
primaryCanvas: pc,
|
|
15865
|
-
scheduler: sc,
|
|
15866
|
-
renderer: Object.keys(rest).length > 0 ? rest : rendererProp
|
|
15867
|
-
};
|
|
15868
|
-
}
|
|
15869
|
-
return { primaryCanvas: void 0, scheduler: void 0, renderer: rendererProp };
|
|
15870
|
-
}
|
|
15871
|
-
|
|
15872
16285
|
function CanvasImpl({
|
|
15873
16286
|
ref,
|
|
15874
16287
|
children,
|
|
@@ -15877,11 +16290,13 @@ function CanvasImpl({
|
|
|
15877
16290
|
style,
|
|
15878
16291
|
id,
|
|
15879
16292
|
gl,
|
|
15880
|
-
renderer
|
|
16293
|
+
renderer,
|
|
16294
|
+
primary,
|
|
16295
|
+
share,
|
|
16296
|
+
scheduler,
|
|
15881
16297
|
events = createPointerEvents,
|
|
15882
16298
|
eventSource,
|
|
15883
16299
|
eventPrefix,
|
|
15884
|
-
shadows,
|
|
15885
16300
|
orthographic,
|
|
15886
16301
|
frameloop,
|
|
15887
16302
|
dpr,
|
|
@@ -15903,7 +16318,11 @@ function CanvasImpl({
|
|
|
15903
16318
|
provider,
|
|
15904
16319
|
...props
|
|
15905
16320
|
}) {
|
|
15906
|
-
const {
|
|
16321
|
+
const {
|
|
16322
|
+
shadows: removedShadows,
|
|
16323
|
+
primaryCanvas: removedPrimaryCanvas,
|
|
16324
|
+
...divProps
|
|
16325
|
+
} = props;
|
|
15907
16326
|
const Bridge = useBridge();
|
|
15908
16327
|
const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
|
|
15909
16328
|
const [hasInitialSize, setHasInitialSize] = React.useState(false);
|
|
@@ -15949,10 +16368,22 @@ function CanvasImpl({
|
|
|
15949
16368
|
if (block) throw block;
|
|
15950
16369
|
if (error) throw error;
|
|
15951
16370
|
const root = React.useRef(null);
|
|
15952
|
-
const
|
|
15953
|
-
const
|
|
16371
|
+
const [gate, waitFor] = useGate();
|
|
16372
|
+
const rootState = React.useRef(null);
|
|
16373
|
+
const eventTarget = () => eventSource ? isRef$1(eventSource) ? eventSource.current : eventSource : divRef.current;
|
|
16374
|
+
const pointerMissed = React.useCallback(
|
|
16375
|
+
(...args) => handlePointerMissed.current?.(...args),
|
|
16376
|
+
[handlePointerMissed]
|
|
16377
|
+
);
|
|
16378
|
+
const dragOverMissed = React.useCallback(
|
|
16379
|
+
(...args) => handleDragOverMissed.current?.(...args),
|
|
16380
|
+
[handleDragOverMissed]
|
|
16381
|
+
);
|
|
16382
|
+
const dropMissed = React.useCallback(
|
|
16383
|
+
(...args) => handleDropMissed.current?.(...args),
|
|
16384
|
+
[handleDropMissed]
|
|
16385
|
+
);
|
|
15954
16386
|
useIsomorphicLayoutEffect(() => {
|
|
15955
|
-
effectActiveRef.current = true;
|
|
15956
16387
|
if (fallbackVisible) return;
|
|
15957
16388
|
const canvas = canvasRef.current;
|
|
15958
16389
|
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
@@ -15962,97 +16393,97 @@ function CanvasImpl({
|
|
|
15962
16393
|
message: "React Three Fiber v10 is in ALPHA - expect breaking changes",
|
|
15963
16394
|
link: "https://github.com/pmndrs/react-three-fiber/discussions"
|
|
15964
16395
|
});
|
|
15965
|
-
const rootEntry = _roots.get(canvas);
|
|
15966
|
-
if (rootEntry?.store) {
|
|
15967
|
-
if (unsubscribeErrorRef.current) unsubscribeErrorRef.current();
|
|
15968
|
-
unsubscribeErrorRef.current = rootEntry.store.subscribe((state) => {
|
|
15969
|
-
if (state.error && effectActiveRef.current) {
|
|
15970
|
-
setError(state.error);
|
|
15971
|
-
}
|
|
15972
|
-
});
|
|
15973
|
-
}
|
|
15974
16396
|
}
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
15982
|
-
|
|
15983
|
-
|
|
15984
|
-
|
|
15985
|
-
|
|
15986
|
-
|
|
15987
|
-
|
|
15988
|
-
|
|
15989
|
-
|
|
15990
|
-
|
|
15991
|
-
|
|
15992
|
-
|
|
15993
|
-
|
|
15994
|
-
|
|
15995
|
-
|
|
15996
|
-
|
|
15997
|
-
|
|
15998
|
-
|
|
15999
|
-
|
|
16000
|
-
|
|
16001
|
-
|
|
16002
|
-
|
|
16003
|
-
|
|
16004
|
-
|
|
16005
|
-
|
|
16006
|
-
|
|
16007
|
-
|
|
16008
|
-
|
|
16009
|
-
|
|
16010
|
-
|
|
16011
|
-
|
|
16012
|
-
|
|
16013
|
-
|
|
16014
|
-
|
|
16015
|
-
}
|
|
16016
|
-
onCreated?.(state);
|
|
16017
|
-
}
|
|
16018
|
-
}).then(
|
|
16019
|
-
() => true,
|
|
16020
|
-
// Renderer setup failed (e.g. no WebGL/WebGPU support). The `fallback` prop lives
|
|
16021
|
-
// inside <canvas>, which browsers don't display, so surface it as visible DOM
|
|
16022
|
-
// instead; with no fallback, rethrow to an external error boundary. (#3757)
|
|
16023
|
-
(setupError) => {
|
|
16024
|
-
if (effectActiveRef.current) {
|
|
16025
|
-
if (fallback != null) setFallbackVisible(true);
|
|
16026
|
-
else setError(setupError);
|
|
16027
|
-
}
|
|
16028
|
-
return false;
|
|
16397
|
+
const current = root.current;
|
|
16398
|
+
current.configure({
|
|
16399
|
+
id,
|
|
16400
|
+
primary,
|
|
16401
|
+
share,
|
|
16402
|
+
scheduler,
|
|
16403
|
+
gl,
|
|
16404
|
+
renderer,
|
|
16405
|
+
scene,
|
|
16406
|
+
events,
|
|
16407
|
+
_primaryToken: primaryToken,
|
|
16408
|
+
...{ shadows: removedShadows, primaryCanvas: removedPrimaryCanvas },
|
|
16409
|
+
orthographic,
|
|
16410
|
+
frameloop,
|
|
16411
|
+
dpr,
|
|
16412
|
+
performance,
|
|
16413
|
+
raycaster,
|
|
16414
|
+
camera,
|
|
16415
|
+
autoUpdateFrustum,
|
|
16416
|
+
occlusion,
|
|
16417
|
+
size: effectiveSize,
|
|
16418
|
+
// Store size props for reset functionality
|
|
16419
|
+
_sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
|
|
16420
|
+
forceEven,
|
|
16421
|
+
// Pass mutable reference to onPointerMissed so it's free to update
|
|
16422
|
+
onPointerMissed: pointerMissed,
|
|
16423
|
+
onDragOverMissed: dragOverMissed,
|
|
16424
|
+
onDropMissed: dropMissed,
|
|
16425
|
+
onCreated: (state) => {
|
|
16426
|
+
rootState.current = state;
|
|
16427
|
+
state.events.connect?.(eventTarget() ?? divRef.current);
|
|
16428
|
+
if (eventPrefix) {
|
|
16429
|
+
state.setEvents({
|
|
16430
|
+
compute: (event, state2) => {
|
|
16431
|
+
const x = event[eventPrefix + "X"];
|
|
16432
|
+
const y = event[eventPrefix + "Y"];
|
|
16433
|
+
state2.pointer.set(x / state2.size.width * 2 - 1, -(y / state2.size.height) * 2 + 1);
|
|
16434
|
+
state2.raycaster.setFromCamera(state2.pointer, state2.camera);
|
|
16435
|
+
}
|
|
16436
|
+
});
|
|
16029
16437
|
}
|
|
16030
|
-
|
|
16031
|
-
|
|
16032
|
-
|
|
16438
|
+
onCreated?.(state);
|
|
16439
|
+
}
|
|
16440
|
+
}).catch((setupError) => {
|
|
16441
|
+
if (root.current !== current) return;
|
|
16442
|
+
if (fallback != null) setFallbackVisible(true);
|
|
16443
|
+
else setError(setupError);
|
|
16444
|
+
});
|
|
16445
|
+
if (current.ready.status === "fulfilled") {
|
|
16446
|
+
current.render(
|
|
16033
16447
|
/* @__PURE__ */ jsx(Bridge, { children: /* @__PURE__ */ jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxs(React.Suspense, { fallback: /* @__PURE__ */ jsx(Block, { set: setBlock }), children: [
|
|
16034
16448
|
backgroundProps && /* @__PURE__ */ jsx(Environment, { ...backgroundProps }),
|
|
16035
16449
|
children ?? null
|
|
16036
16450
|
] }) }) })
|
|
16037
16451
|
);
|
|
16452
|
+
} else if (current.ready.status === "pending") {
|
|
16453
|
+
waitFor(current.ready);
|
|
16038
16454
|
}
|
|
16039
|
-
run();
|
|
16040
16455
|
}
|
|
16041
|
-
|
|
16042
|
-
|
|
16043
|
-
|
|
16044
|
-
|
|
16045
|
-
|
|
16046
|
-
|
|
16456
|
+
});
|
|
16457
|
+
useIsomorphicLayoutEffect(() => {
|
|
16458
|
+
const store = canvasRef.current && _roots.get(canvasRef.current)?.store;
|
|
16459
|
+
if (!store) return;
|
|
16460
|
+
const report = () => {
|
|
16461
|
+
const error2 = store.getState().error;
|
|
16462
|
+
if (error2) setError(error2);
|
|
16047
16463
|
};
|
|
16464
|
+
report();
|
|
16465
|
+
return store.subscribe(report);
|
|
16466
|
+
});
|
|
16467
|
+
React.useEffect(() => {
|
|
16468
|
+
const state = rootState.current?.get();
|
|
16469
|
+
const target = eventTarget();
|
|
16470
|
+
if (state && target && state.events.connected !== target) state.events.connect?.(target);
|
|
16048
16471
|
});
|
|
16049
16472
|
const insertionMounted = React.useRef(false);
|
|
16473
|
+
const [primaryToken] = React.useState(() => ({}));
|
|
16474
|
+
const primaryKey = React.useRef(null);
|
|
16050
16475
|
React.useInsertionEffect(() => {
|
|
16051
16476
|
insertionMounted.current = true;
|
|
16477
|
+
if (primary && provider.webgpu) {
|
|
16478
|
+
primaryKey.current ?? (primaryKey.current = id || DEFAULT_PRIMARY);
|
|
16479
|
+
announcePrimary(primaryKey.current, primaryToken);
|
|
16480
|
+
}
|
|
16052
16481
|
return () => {
|
|
16053
16482
|
insertionMounted.current = false;
|
|
16483
|
+
if (primaryKey.current) markWithdrawing(primaryToken);
|
|
16054
16484
|
queueMicrotask(() => {
|
|
16055
16485
|
if (insertionMounted.current) return;
|
|
16486
|
+
if (primaryKey.current) withdrawPrimary(primaryKey.current, primaryToken);
|
|
16056
16487
|
const current = root.current;
|
|
16057
16488
|
root.current = null;
|
|
16058
16489
|
current?.unmount();
|
|
@@ -16093,7 +16524,7 @@ function CanvasImpl({
|
|
|
16093
16524
|
}
|
|
16094
16525
|
}, [hmr]);
|
|
16095
16526
|
const pointerEvents = eventSource ? "none" : "auto";
|
|
16096
|
-
return /* @__PURE__ */
|
|
16527
|
+
return /* @__PURE__ */ jsxs(
|
|
16097
16528
|
"div",
|
|
16098
16529
|
{
|
|
16099
16530
|
ref: divRef,
|
|
@@ -16105,21 +16536,24 @@ function CanvasImpl({
|
|
|
16105
16536
|
pointerEvents,
|
|
16106
16537
|
...style
|
|
16107
16538
|
},
|
|
16108
|
-
...
|
|
16109
|
-
children:
|
|
16110
|
-
|
|
16111
|
-
|
|
16112
|
-
|
|
16113
|
-
|
|
16114
|
-
"canvas",
|
|
16115
|
-
|
|
16116
|
-
|
|
16117
|
-
|
|
16118
|
-
|
|
16119
|
-
|
|
16120
|
-
|
|
16121
|
-
|
|
16122
|
-
|
|
16539
|
+
...divProps,
|
|
16540
|
+
children: [
|
|
16541
|
+
fallbackVisible ? (
|
|
16542
|
+
// Renderer setup failed: render the fallback as visible DOM. Inside <canvas> (below)
|
|
16543
|
+
// it exists in the tree but browsers never paint it, which is the whole bug (#3757).
|
|
16544
|
+
fallback
|
|
16545
|
+
) : /* @__PURE__ */ jsx("div", { ref: containerRef, className: "r3f-canvas-container", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx(
|
|
16546
|
+
"canvas",
|
|
16547
|
+
{
|
|
16548
|
+
ref: canvasRef,
|
|
16549
|
+
id,
|
|
16550
|
+
className: "r3f-canvas",
|
|
16551
|
+
style: { display: "block", width: "100%", height: "100%" },
|
|
16552
|
+
children: fallback
|
|
16553
|
+
}
|
|
16554
|
+
) }),
|
|
16555
|
+
gate
|
|
16556
|
+
]
|
|
16123
16557
|
}
|
|
16124
16558
|
);
|
|
16125
16559
|
}
|
|
@@ -16127,4 +16561,4 @@ function Canvas(props) {
|
|
|
16127
16561
|
return /* @__PURE__ */ jsx(FiberProvider, { children: /* @__PURE__ */ jsx(CanvasImpl, { ...props }) });
|
|
16128
16562
|
}
|
|
16129
16563
|
|
|
16130
|
-
export {
|
|
16564
|
+
export { invalidateInstance as $, useGraph as A, useLoader as B, Canvas as C, useTexture as D, EnvironmentMap as E, useTextures as F, useEnvironment as G, extend as H, IsObject as I, reconciler as J, flushSync as K, unmountComponentAtNode as L, createPortal as M, calculateDpr as N, getUuidPrefix as O, Portal as P, updateCamera as Q, updateFrustum as R, REACT_INTERNAL_PROPS as S, Texture as T, findInitialRoot as U, getRootState as V, buildGraph as W, dispose as X, getInstanceProps as Y, prepare as Z, _roots as _, createPointerEvents as a, RESERVED_PROPS as a0, resolve as a1, attach as a2, detach as a3, diffProps as a4, applyProps as a5, is as a6, isOrthographicCamera as a7, isRef$1 as a8, isColorRepresentation as a9, isObject3D as aa, isTexture as ab, isLayers as ac, isUniform as ad, isVectorLike as ae, isCopyable as af, hasConstructor as ag, FROM_REF as ah, fromRef as ai, isFromRef as aj, ONCE as ak, once as al, isOnce as am, useRenderTarget as an, addEffect as b, createRoot as c, addAfterEffect as d, addTail as e, advance as f, isRenderer as g, getPrimary as h, invalidate as i, hasPrimary as j, getPrimaryIds as k, createStore as l, getThree as m, hasThree as n, whenThree as o, EnvironmentCube as p, EnvironmentPortal as q, registerPrimary as r, Environment as s, presetsObj as t, unregisterPrimary as u, swapInteractivity as v, waitForPrimary as w, removeInteractivity as x, createEvents as y, useInstanceHandle as z };
|