@react-three/fiber 10.0.0-canary.da7a768 → 10.0.0-canary.dc0ec15
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 +278 -0
- package/dist/extension.d.cts +1675 -0
- package/dist/extension.d.mts +1675 -0
- package/dist/extension.d.ts +1647 -0
- package/dist/extension.mjs +258 -0
- package/dist/index.cjs +994 -898
- package/dist/index.d.cts +331 -155
- package/dist/index.d.mts +331 -155
- package/dist/index.d.ts +331 -183
- package/dist/index.mjs +995 -901
- package/dist/legacy.cjs +1345 -1245
- package/dist/legacy.d.cts +353 -205
- package/dist/legacy.d.mts +353 -205
- package/dist/legacy.d.ts +353 -231
- package/dist/legacy.mjs +1346 -1248
- package/dist/webgpu/index.cjs +908 -713
- package/dist/webgpu/index.d.cts +389 -212
- package/dist/webgpu/index.d.mts +389 -212
- package/dist/webgpu/index.d.ts +389 -240
- package/dist/webgpu/index.mjs +910 -717
- package/package.json +7 -2
package/dist/legacy.cjs
CHANGED
|
@@ -10,6 +10,7 @@ const scheduler = require('@pmndrs/scheduler');
|
|
|
10
10
|
const Tb = require('scheduler');
|
|
11
11
|
const GroundedSkybox_js = require('three/examples/jsm/objects/GroundedSkybox.js');
|
|
12
12
|
const HDRLoader_js = require('three/examples/jsm/loaders/HDRLoader.js');
|
|
13
|
+
const HDRCubeTextureLoader_js = require('three/examples/jsm/loaders/HDRCubeTextureLoader.js');
|
|
13
14
|
const EXRLoader_js = require('three/examples/jsm/loaders/EXRLoader.js');
|
|
14
15
|
const UltraHDRLoader_js = require('three/examples/jsm/loaders/UltraHDRLoader.js');
|
|
15
16
|
const gainmapJs = require('@monogrid/gainmap-js');
|
|
@@ -53,11 +54,11 @@ const R3F_BUILD_WEBGPU = false;
|
|
|
53
54
|
async function loadInspector() {
|
|
54
55
|
throw new Error("Inspector is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
55
56
|
}
|
|
56
|
-
|
|
57
|
+
class WebGPURenderer {
|
|
57
58
|
constructor() {
|
|
58
59
|
throw new Error("WebGPURenderer is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
|
|
59
60
|
}
|
|
60
|
-
}
|
|
61
|
+
}
|
|
61
62
|
const RenderTarget = null;
|
|
62
63
|
const CubeRenderTarget = null;
|
|
63
64
|
|
|
@@ -317,7 +318,6 @@ function prepare(target, root, type, props) {
|
|
|
317
318
|
}
|
|
318
319
|
function invalidateInstance(instance) {
|
|
319
320
|
if (!instance.parent) return;
|
|
320
|
-
instance.props.onUpdate?.(instance.object);
|
|
321
321
|
const state = instance.root?.getState?.();
|
|
322
322
|
if (state && state.internal.frames === 0) state.invalidate();
|
|
323
323
|
}
|
|
@@ -533,8 +533,10 @@ function hasVisibilityHandlers(handlers) {
|
|
|
533
533
|
}
|
|
534
534
|
|
|
535
535
|
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
536
|
-
function fromRef(ref) {
|
|
537
|
-
|
|
536
|
+
function fromRef(ref, transform) {
|
|
537
|
+
const marker = { [FROM_REF]: ref };
|
|
538
|
+
if (transform) marker.transform = transform;
|
|
539
|
+
return marker;
|
|
538
540
|
}
|
|
539
541
|
function isFromRef(value) {
|
|
540
542
|
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
@@ -548,6 +550,63 @@ function isOnce(value) {
|
|
|
548
550
|
return value !== null && typeof value === "object" && ONCE in value;
|
|
549
551
|
}
|
|
550
552
|
|
|
553
|
+
const shownNotices = /* @__PURE__ */ new Set();
|
|
554
|
+
function notifyDepreciated({ heading, body, link }) {
|
|
555
|
+
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
if (shownNotices.has(heading)) return;
|
|
559
|
+
shownNotices.add(heading);
|
|
560
|
+
const caller = getCallerFrame();
|
|
561
|
+
if (caller) {
|
|
562
|
+
console.log();
|
|
563
|
+
}
|
|
564
|
+
const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
|
|
565
|
+
if (caller) {
|
|
566
|
+
console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
|
|
567
|
+
}
|
|
568
|
+
if (body || link) {
|
|
569
|
+
let message = "";
|
|
570
|
+
if (body) message += body;
|
|
571
|
+
if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
|
|
572
|
+
console.warn(`%c${message}`, "font-weight: bold;");
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
function getCallerFrame(depth = 3) {
|
|
576
|
+
const stack = new Error().stack;
|
|
577
|
+
if (!stack) return null;
|
|
578
|
+
const lines = stack.split("\n");
|
|
579
|
+
const frame = lines[depth];
|
|
580
|
+
if (!frame) return null;
|
|
581
|
+
let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
|
|
582
|
+
if (!match) {
|
|
583
|
+
match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
|
|
584
|
+
}
|
|
585
|
+
if (!match) return null;
|
|
586
|
+
const [, fn, url, line] = match;
|
|
587
|
+
return {
|
|
588
|
+
functionName: fn ?? "<anonymous>",
|
|
589
|
+
location: formatLocation(url, Number(line))
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
function formatLocation(url, line) {
|
|
593
|
+
const clean = url.split("?")[0];
|
|
594
|
+
const file = clean.split("/").pop() ?? clean;
|
|
595
|
+
return `${file}:${line}`;
|
|
596
|
+
}
|
|
597
|
+
function notifyAlpha({ message, link }) {
|
|
598
|
+
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
if (shownNotices.has(message)) return;
|
|
602
|
+
shownNotices.add(message);
|
|
603
|
+
const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
|
|
604
|
+
console.log(`%c\u{1F52C} ${message}`, boxStyle);
|
|
605
|
+
{
|
|
606
|
+
console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
551
610
|
const RESERVED_PROPS = [
|
|
552
611
|
"children",
|
|
553
612
|
"key",
|
|
@@ -557,7 +616,6 @@ const RESERVED_PROPS = [
|
|
|
557
616
|
"dispose",
|
|
558
617
|
"attach",
|
|
559
618
|
"object",
|
|
560
|
-
"onUpdate",
|
|
561
619
|
// Behavior flags
|
|
562
620
|
"dispose"
|
|
563
621
|
];
|
|
@@ -635,11 +693,9 @@ function diffProps(instance, newProps) {
|
|
|
635
693
|
for (const prop in instance.props) {
|
|
636
694
|
if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
|
|
637
695
|
const { root, key } = resolve(instance.object, prop);
|
|
638
|
-
if (
|
|
696
|
+
if (typeof root?.constructor === "function") {
|
|
639
697
|
const ctor = getMemoizedPrototype(root);
|
|
640
698
|
if (!is.und(ctor)) changedProps[prop] = ctor[key];
|
|
641
|
-
} else {
|
|
642
|
-
changedProps[prop] = 0;
|
|
643
699
|
}
|
|
644
700
|
}
|
|
645
701
|
return changedProps;
|
|
@@ -651,6 +707,13 @@ function applyProps(object, props) {
|
|
|
651
707
|
for (const prop in props) {
|
|
652
708
|
const value = props[prop];
|
|
653
709
|
if (RESERVED_PROPS.includes(prop)) continue;
|
|
710
|
+
if (prop === "onUpdate") {
|
|
711
|
+
notifyDepreciated({
|
|
712
|
+
heading: "onUpdate is no longer an R3F prop",
|
|
713
|
+
body: "v10 removed the onUpdate hook: R3F no longer calls it after prop updates. The value is assigned to the object by name. On a Texture that sets three's Texture.onUpdate, which the renderer calls after a GPU upload, not after prop changes. On a node it replaces the Node.onUpdate() method. On other objects it is never called.\n\nUse an effect keyed on the props that change, read the object in useFrame, or use a ref callback.",
|
|
714
|
+
link: "https://docs.pmnd.rs/react-three-fiber/migration/v10#onupdate-removed"
|
|
715
|
+
});
|
|
716
|
+
}
|
|
654
717
|
if (instance && EVENT_REGEX.test(prop)) {
|
|
655
718
|
if (typeof value === "function") instance.handlers[prop] = value;
|
|
656
719
|
else delete instance.handlers[prop];
|
|
@@ -756,1059 +819,754 @@ function applyProps(object, props) {
|
|
|
756
819
|
return object;
|
|
757
820
|
}
|
|
758
821
|
|
|
759
|
-
const
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
if (
|
|
765
|
-
|
|
766
|
-
const caller = getCallerFrame();
|
|
767
|
-
if (caller) {
|
|
768
|
-
console.log();
|
|
769
|
-
}
|
|
770
|
-
const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
|
|
771
|
-
if (caller) {
|
|
772
|
-
console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
|
|
773
|
-
}
|
|
774
|
-
if (body || link) {
|
|
775
|
-
let message = "";
|
|
776
|
-
if (body) message += body;
|
|
777
|
-
if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
|
|
778
|
-
console.warn(`%c${message}`, "font-weight: bold;");
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
function getCallerFrame(depth = 3) {
|
|
782
|
-
const stack = new Error().stack;
|
|
783
|
-
if (!stack) return null;
|
|
784
|
-
const lines = stack.split("\n");
|
|
785
|
-
const frame = lines[depth];
|
|
786
|
-
if (!frame) return null;
|
|
787
|
-
let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
|
|
788
|
-
if (!match) {
|
|
789
|
-
match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
|
|
790
|
-
}
|
|
791
|
-
if (!match) return null;
|
|
792
|
-
const [, fn, url, line] = match;
|
|
793
|
-
return {
|
|
794
|
-
functionName: fn ?? "<anonymous>",
|
|
795
|
-
location: formatLocation(url, Number(line))
|
|
796
|
-
};
|
|
822
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
823
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React__namespace.createContext(null));
|
|
824
|
+
|
|
825
|
+
function useStore() {
|
|
826
|
+
const store = React.useContext(context);
|
|
827
|
+
if (!store) throw new Error("R3F: Hooks can only be used within the Canvas component!");
|
|
828
|
+
return store;
|
|
797
829
|
}
|
|
798
|
-
function
|
|
799
|
-
|
|
800
|
-
const file = clean.split("/").pop() ?? clean;
|
|
801
|
-
return `${file}:${line}`;
|
|
830
|
+
function useThree$1(selector = (state) => state, equalityFn) {
|
|
831
|
+
return useStore()(selector, equalityFn);
|
|
802
832
|
}
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
if (
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
833
|
+
|
|
834
|
+
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
835
|
+
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
836
|
+
function getLoader$1(Proto) {
|
|
837
|
+
if (isConstructor$1(Proto)) {
|
|
838
|
+
let loader = memoizedLoaders.get(Proto);
|
|
839
|
+
if (!loader) {
|
|
840
|
+
loader = new Proto();
|
|
841
|
+
memoizedLoaders.set(Proto, loader);
|
|
842
|
+
}
|
|
843
|
+
return loader;
|
|
813
844
|
}
|
|
845
|
+
return Proto;
|
|
814
846
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
847
|
+
function loadingFn(extensions, onProgress) {
|
|
848
|
+
return function(Proto, input) {
|
|
849
|
+
const loader = getLoader$1(Proto);
|
|
850
|
+
if (extensions) extensions(loader);
|
|
851
|
+
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
852
|
+
return loader.loadAsync(input, onProgress).then((data) => {
|
|
853
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
854
|
+
return data;
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
return new Promise(
|
|
858
|
+
(res, reject) => loader.load(
|
|
859
|
+
input,
|
|
860
|
+
(data) => {
|
|
861
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
862
|
+
res(data);
|
|
863
|
+
},
|
|
864
|
+
onProgress,
|
|
865
|
+
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
866
|
+
)
|
|
867
|
+
);
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
871
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
872
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
873
|
+
const fn = loadingFn(extensions, onProgress);
|
|
874
|
+
const results = cacheKeys.map(
|
|
875
|
+
(key, index) => suspendReact.suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
876
|
+
);
|
|
877
|
+
const stableRef = React.useRef(null);
|
|
878
|
+
const previous = stableRef.current;
|
|
879
|
+
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
880
|
+
stableRef.current = stable;
|
|
881
|
+
return Array.isArray(input) ? stable : stable[0];
|
|
821
882
|
}
|
|
883
|
+
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
884
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
885
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
886
|
+
cacheKeys.forEach(
|
|
887
|
+
(key, index) => suspendReact.preload(() => loadingFn(extensions, onProgress)(loader, inputs[index]), [loader, key])
|
|
888
|
+
);
|
|
889
|
+
};
|
|
890
|
+
useLoader.clear = function(loader, input, cacheKey) {
|
|
891
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
892
|
+
cacheKeys.forEach((key) => suspendReact.clear([loader, key]));
|
|
893
|
+
};
|
|
894
|
+
useLoader.loader = getLoader$1;
|
|
822
895
|
|
|
823
|
-
|
|
824
|
-
const
|
|
825
|
-
const
|
|
826
|
-
const
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
896
|
+
function useFrame$1(callback, priorityOrOptions) {
|
|
897
|
+
const store = React__namespace.useContext(context);
|
|
898
|
+
const isInsideCanvas = store !== null;
|
|
899
|
+
const scheduler$1 = scheduler.getScheduler();
|
|
900
|
+
const optionsKey = typeof priorityOrOptions === "number" ? `p:${priorityOrOptions}` : priorityOrOptions ? JSON.stringify({
|
|
901
|
+
id: priorityOrOptions.id,
|
|
902
|
+
phase: priorityOrOptions.phase,
|
|
903
|
+
priority: priorityOrOptions.priority,
|
|
904
|
+
fps: priorityOrOptions.fps,
|
|
905
|
+
drop: priorityOrOptions.drop,
|
|
906
|
+
enabled: priorityOrOptions.enabled,
|
|
907
|
+
before: priorityOrOptions.before,
|
|
908
|
+
after: priorityOrOptions.after
|
|
909
|
+
}) : "";
|
|
910
|
+
const options = React__namespace.useMemo(() => {
|
|
911
|
+
return typeof priorityOrOptions === "number" ? { priority: priorityOrOptions } : priorityOrOptions ?? {};
|
|
912
|
+
}, [optionsKey]);
|
|
913
|
+
const reactId = React__namespace.useId();
|
|
914
|
+
const id = options.id ?? reactId;
|
|
915
|
+
const callbackRef = useMutableCallback(callback);
|
|
916
|
+
const isLegacyPriority = typeof priorityOrOptions === "number" && priorityOrOptions > 0;
|
|
917
|
+
useIsomorphicLayoutEffect(() => {
|
|
918
|
+
if (!callback) return;
|
|
919
|
+
if (isInsideCanvas) {
|
|
920
|
+
const state = store.getState();
|
|
921
|
+
const rootId = state.internal.rootId;
|
|
922
|
+
if (isLegacyPriority) {
|
|
923
|
+
state.internal.priority++;
|
|
924
|
+
let parentRoot = state.previousRoot;
|
|
925
|
+
while (parentRoot) {
|
|
926
|
+
const parentState = parentRoot.getState();
|
|
927
|
+
if (parentState?.internal) parentState.internal.priority++;
|
|
928
|
+
parentRoot = parentState?.previousRoot;
|
|
929
|
+
}
|
|
930
|
+
notifyDepreciated({
|
|
931
|
+
heading: "useFrame with numeric priority is deprecated",
|
|
932
|
+
body: 'Using useFrame(callback, number) to control render order is deprecated.\n\nFor custom rendering, use: useFrame(callback, { phase: "render" })\nFor execution order within update phase, use: useFrame(callback, { priority: number })',
|
|
933
|
+
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
934
|
+
});
|
|
843
935
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
inspector: null,
|
|
872
|
-
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
873
|
-
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
874
|
-
textureColorSpace: three.SRGBColorSpace,
|
|
875
|
-
isLegacy: false,
|
|
876
|
-
webGPUSupported: false,
|
|
877
|
-
isNative: false,
|
|
878
|
-
controls: null,
|
|
879
|
-
pointer,
|
|
880
|
-
mouse: pointer,
|
|
881
|
-
frameloop: "always",
|
|
882
|
-
onPointerMissed: void 0,
|
|
883
|
-
onDragOverMissed: void 0,
|
|
884
|
-
onDropMissed: void 0,
|
|
885
|
-
performance: {
|
|
886
|
-
current: 1,
|
|
887
|
-
min: 0.5,
|
|
888
|
-
max: 1,
|
|
889
|
-
debounce: 200,
|
|
890
|
-
regress: () => {
|
|
891
|
-
const state2 = get();
|
|
892
|
-
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
893
|
-
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
894
|
-
performanceTimeout = setTimeout(
|
|
895
|
-
() => setPerformanceCurrent(get().performance.max),
|
|
896
|
-
state2.performance.debounce
|
|
897
|
-
);
|
|
898
|
-
}
|
|
899
|
-
},
|
|
900
|
-
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
901
|
-
viewport: {
|
|
902
|
-
initialDpr: 0,
|
|
903
|
-
dpr: 0,
|
|
904
|
-
width: 0,
|
|
905
|
-
height: 0,
|
|
906
|
-
top: 0,
|
|
907
|
-
left: 0,
|
|
908
|
-
aspect: 0,
|
|
909
|
-
distance: 0,
|
|
910
|
-
factor: 0,
|
|
911
|
-
getCurrentViewport
|
|
912
|
-
},
|
|
913
|
-
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
914
|
-
setSize: (width, height, top, left) => {
|
|
915
|
-
const state2 = get();
|
|
916
|
-
if (width === void 0) {
|
|
917
|
-
set({ _sizeImperative: false });
|
|
918
|
-
if (state2._sizeProps) {
|
|
919
|
-
const { width: propW, height: propH } = state2._sizeProps;
|
|
920
|
-
if (propW !== void 0 || propH !== void 0) {
|
|
921
|
-
const currentSize = state2.size;
|
|
922
|
-
const newSize = {
|
|
923
|
-
width: propW ?? currentSize.width,
|
|
924
|
-
height: propH ?? currentSize.height,
|
|
925
|
-
top: currentSize.top,
|
|
926
|
-
left: currentSize.left
|
|
927
|
-
};
|
|
928
|
-
set((s) => ({
|
|
929
|
-
size: newSize,
|
|
930
|
-
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
931
|
-
}));
|
|
932
|
-
scheduler.getScheduler().invalidate();
|
|
936
|
+
const wrappedCallback = (frameState, delta) => {
|
|
937
|
+
const localState = store.getState();
|
|
938
|
+
const mergedState = {
|
|
939
|
+
...localState,
|
|
940
|
+
time: frameState.time,
|
|
941
|
+
delta: frameState.delta,
|
|
942
|
+
elapsed: frameState.elapsed,
|
|
943
|
+
frame: frameState.frame
|
|
944
|
+
};
|
|
945
|
+
callbackRef.current?.(mergedState, delta);
|
|
946
|
+
};
|
|
947
|
+
const unregister = scheduler$1.register(wrappedCallback, {
|
|
948
|
+
id,
|
|
949
|
+
rootId,
|
|
950
|
+
...options
|
|
951
|
+
});
|
|
952
|
+
return () => {
|
|
953
|
+
unregister();
|
|
954
|
+
if (isLegacyPriority) {
|
|
955
|
+
const currentState = store.getState();
|
|
956
|
+
if (currentState.internal) {
|
|
957
|
+
currentState.internal.priority--;
|
|
958
|
+
let parentRoot = currentState.previousRoot;
|
|
959
|
+
while (parentRoot) {
|
|
960
|
+
const parentState = parentRoot.getState();
|
|
961
|
+
if (parentState?.internal) parentState.internal.priority--;
|
|
962
|
+
parentRoot = parentState?.previousRoot;
|
|
933
963
|
}
|
|
934
964
|
}
|
|
935
|
-
return;
|
|
936
965
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
966
|
+
};
|
|
967
|
+
} else {
|
|
968
|
+
return scheduler$1.register(
|
|
969
|
+
(state, delta) => {
|
|
970
|
+
const frameState = state;
|
|
971
|
+
if (!frameState.renderer) return;
|
|
972
|
+
callbackRef.current?.(frameState, delta);
|
|
973
|
+
},
|
|
974
|
+
{ id, ...options }
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
}, [store, scheduler$1, id, optionsKey, isLegacyPriority, isInsideCanvas]);
|
|
978
|
+
const isPaused = React__namespace.useSyncExternalStore(
|
|
979
|
+
// Subscribe function
|
|
980
|
+
React__namespace.useCallback(
|
|
981
|
+
(onStoreChange) => {
|
|
982
|
+
return scheduler.getScheduler().subscribeJobState(id, onStoreChange);
|
|
948
983
|
},
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
984
|
+
[id]
|
|
985
|
+
),
|
|
986
|
+
// getSnapshot function
|
|
987
|
+
React__namespace.useCallback(() => scheduler.getScheduler().isJobPaused(id), [id]),
|
|
988
|
+
// getServerSnapshot function (SSR)
|
|
989
|
+
React__namespace.useCallback(() => false, [])
|
|
990
|
+
);
|
|
991
|
+
const controls = React__namespace.useMemo(() => {
|
|
992
|
+
const scheduler2 = scheduler.getScheduler();
|
|
993
|
+
return {
|
|
994
|
+
/** The job's unique ID */
|
|
995
|
+
id,
|
|
996
|
+
/**
|
|
997
|
+
* Access to the global scheduler for frame loop control.
|
|
998
|
+
* Use for controlling the entire frame loop, adding phases, etc.
|
|
999
|
+
*/
|
|
1000
|
+
scheduler: scheduler2,
|
|
1001
|
+
/**
|
|
1002
|
+
* The root that currently owns this job. Resolve on access because ambient
|
|
1003
|
+
* jobs can be adopted by a Canvas after the controls object is created.
|
|
1004
|
+
*/
|
|
1005
|
+
get rootId() {
|
|
1006
|
+
return scheduler.getScheduler().getJobRootId(id);
|
|
956
1007
|
},
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
internal.subscribers.push({ ref, priority, store });
|
|
1000
|
-
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
1001
|
-
return () => {
|
|
1002
|
-
const internal2 = get().internal;
|
|
1003
|
-
if (internal2?.subscribers) {
|
|
1004
|
-
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
1005
|
-
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
1006
|
-
}
|
|
1007
|
-
};
|
|
1008
|
-
},
|
|
1009
|
-
// Renderer Storage (single source of truth)
|
|
1010
|
-
actualRenderer: null,
|
|
1011
|
-
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
1012
|
-
scheduler: null
|
|
1013
|
-
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Manually step this job only.
|
|
1010
|
+
* Bypasses FPS limiting - always runs.
|
|
1011
|
+
* @param timestamp Optional timestamp (defaults to performance.now())
|
|
1012
|
+
*/
|
|
1013
|
+
step: (timestamp) => {
|
|
1014
|
+
scheduler.getScheduler().stepJob(id, timestamp);
|
|
1015
|
+
},
|
|
1016
|
+
/**
|
|
1017
|
+
* Manually step ALL jobs in the scheduler.
|
|
1018
|
+
* Useful for frameloop='never' mode.
|
|
1019
|
+
* @param timestamp Optional timestamp (defaults to performance.now())
|
|
1020
|
+
*/
|
|
1021
|
+
stepAll: (timestamp) => {
|
|
1022
|
+
scheduler.getScheduler().step(timestamp);
|
|
1023
|
+
},
|
|
1024
|
+
/**
|
|
1025
|
+
* Request frames for this job's owning root without waking sibling roots.
|
|
1026
|
+
*/
|
|
1027
|
+
invalidate: (frames, stackFrames) => {
|
|
1028
|
+
const scheduler3 = scheduler.getScheduler();
|
|
1029
|
+
const rootId = scheduler3.getJobRootId(id);
|
|
1030
|
+
if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
|
|
1031
|
+
},
|
|
1032
|
+
/**
|
|
1033
|
+
* Pause this job (set enabled=false).
|
|
1034
|
+
* Job remains registered but won't run.
|
|
1035
|
+
*/
|
|
1036
|
+
pause: () => {
|
|
1037
|
+
scheduler.getScheduler().pauseJob(id);
|
|
1038
|
+
},
|
|
1039
|
+
/**
|
|
1040
|
+
* Resume this job (set enabled=true).
|
|
1041
|
+
*/
|
|
1042
|
+
resume: () => {
|
|
1043
|
+
scheduler.getScheduler().resumeJob(id);
|
|
1044
|
+
},
|
|
1045
|
+
/**
|
|
1046
|
+
* Reactive paused state - automatically updates when pause/resume is called.
|
|
1047
|
+
* No need for forceUpdate() in your components.
|
|
1048
|
+
*/
|
|
1049
|
+
isPaused
|
|
1014
1050
|
};
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
set(value) {
|
|
1044
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1045
|
-
},
|
|
1046
|
-
enumerable: true,
|
|
1047
|
-
configurable: true
|
|
1048
|
-
});
|
|
1049
|
-
let oldScene = state.scene;
|
|
1050
|
-
rootStore.subscribe(() => {
|
|
1051
|
-
const currentState = rootStore.getState();
|
|
1052
|
-
const { scene, rootScene, set } = currentState;
|
|
1053
|
-
if (scene !== oldScene) {
|
|
1054
|
-
oldScene = scene;
|
|
1055
|
-
if (scene?.isScene && scene !== rootScene) {
|
|
1056
|
-
set({ rootScene: scene });
|
|
1057
|
-
}
|
|
1051
|
+
}, [id, isPaused]);
|
|
1052
|
+
return controls;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
const IsObject = (url) => url === Object(url) && !Array.isArray(url) && typeof url !== "function";
|
|
1056
|
+
function getUrls(input) {
|
|
1057
|
+
if (typeof input === "string") return [input];
|
|
1058
|
+
if (Array.isArray(input)) return input;
|
|
1059
|
+
return Object.values(input);
|
|
1060
|
+
}
|
|
1061
|
+
function inputSignature(input) {
|
|
1062
|
+
if (typeof input === "string") return input;
|
|
1063
|
+
if (Array.isArray(input)) return input.join("\0");
|
|
1064
|
+
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
1065
|
+
}
|
|
1066
|
+
function allUrlsCached(urls, textureCache) {
|
|
1067
|
+
return urls.every((url) => textureCache.has(url));
|
|
1068
|
+
}
|
|
1069
|
+
function buildFromCache(input, textureCache) {
|
|
1070
|
+
if (typeof input === "string") {
|
|
1071
|
+
return textureCache.get(input);
|
|
1072
|
+
} else if (Array.isArray(input)) {
|
|
1073
|
+
return input.map((url) => textureCache.get(url));
|
|
1074
|
+
} else {
|
|
1075
|
+
const result = {};
|
|
1076
|
+
const objInput = input;
|
|
1077
|
+
for (const key in objInput) {
|
|
1078
|
+
result[key] = textureCache.get(objInput[key]);
|
|
1058
1079
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
+
return result;
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
function useTexture(input, optionsOrOnLoad) {
|
|
1084
|
+
const renderer = useThree$1((state) => state.internal.actualRenderer);
|
|
1085
|
+
const store = useStore();
|
|
1086
|
+
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
1087
|
+
const { onLoad, cache = true } = options;
|
|
1088
|
+
const onLoadRef = React.useRef(onLoad);
|
|
1089
|
+
onLoadRef.current = onLoad;
|
|
1090
|
+
const onLoadCalledForRef = React.useRef(null);
|
|
1091
|
+
const inputKey = React.useMemo(() => inputSignature(input), [input]);
|
|
1092
|
+
const stableInput = React.useMemo(() => input, [inputKey]);
|
|
1093
|
+
const urls = React.useMemo(() => getUrls(stableInput), [stableInput]);
|
|
1094
|
+
const cachedResult = React.useMemo(() => {
|
|
1095
|
+
if (!cache) return null;
|
|
1096
|
+
const textures = store.getState().textures;
|
|
1097
|
+
if (!allUrlsCached(urls, textures)) return null;
|
|
1098
|
+
return buildFromCache(stableInput, textures);
|
|
1099
|
+
}, [cache, urls, stableInput, store]);
|
|
1100
|
+
const loadedTextures = useLoader(
|
|
1101
|
+
three.TextureLoader,
|
|
1102
|
+
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
1103
|
+
);
|
|
1104
|
+
const mappedTextures = React.useMemo(() => {
|
|
1105
|
+
if (cachedResult) return cachedResult;
|
|
1106
|
+
if (IsObject(stableInput)) {
|
|
1107
|
+
const keyed = {};
|
|
1108
|
+
const textureArray = loadedTextures;
|
|
1109
|
+
let i = 0;
|
|
1110
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1111
|
+
return keyed;
|
|
1112
|
+
} else {
|
|
1113
|
+
return loadedTextures;
|
|
1114
|
+
}
|
|
1115
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
1116
|
+
React.useLayoutEffect(() => {
|
|
1117
|
+
if (cachedResult) return;
|
|
1118
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
1119
|
+
onLoadCalledForRef.current = inputKey;
|
|
1120
|
+
onLoadRef.current?.(mappedTextures);
|
|
1121
|
+
}, [cachedResult, mappedTextures, inputKey]);
|
|
1122
|
+
React.useEffect(() => {
|
|
1123
|
+
if (cachedResult) return;
|
|
1124
|
+
if ("initTexture" in renderer) {
|
|
1125
|
+
let textureArray = [];
|
|
1126
|
+
if (Array.isArray(loadedTextures)) {
|
|
1127
|
+
textureArray = loadedTextures;
|
|
1128
|
+
} else if (loadedTextures instanceof three.Texture) {
|
|
1129
|
+
textureArray = [loadedTextures];
|
|
1130
|
+
} else if (IsObject(loadedTextures)) {
|
|
1131
|
+
textureArray = Object.values(loadedTextures);
|
|
1132
|
+
}
|
|
1133
|
+
textureArray.forEach((texture) => {
|
|
1134
|
+
if (texture instanceof three.Texture) {
|
|
1135
|
+
renderer.initTexture(texture);
|
|
1080
1136
|
}
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
}, [renderer, loadedTextures, cachedResult]);
|
|
1140
|
+
React.useEffect(() => {
|
|
1141
|
+
if (!cache) return;
|
|
1142
|
+
const urlTextureMap = [];
|
|
1143
|
+
if (typeof stableInput === "string") {
|
|
1144
|
+
urlTextureMap.push([stableInput, mappedTextures]);
|
|
1145
|
+
} else if (Array.isArray(stableInput)) {
|
|
1146
|
+
const textureArray = mappedTextures;
|
|
1147
|
+
stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1148
|
+
} else if (IsObject(stableInput)) {
|
|
1149
|
+
const textureRecord = mappedTextures;
|
|
1150
|
+
for (const key in stableInput) {
|
|
1151
|
+
const url = stableInput[key];
|
|
1152
|
+
urlTextureMap.push([url, textureRecord[key]]);
|
|
1081
1153
|
}
|
|
1082
1154
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1155
|
+
store.setState((state) => {
|
|
1156
|
+
const refs = new Map(state._textureRefs);
|
|
1157
|
+
let textures = state.textures;
|
|
1158
|
+
let added = false;
|
|
1159
|
+
for (const [url, texture] of urlTextureMap) {
|
|
1160
|
+
if (!textures.has(url)) {
|
|
1161
|
+
if (!added) {
|
|
1162
|
+
textures = new Map(textures);
|
|
1163
|
+
added = true;
|
|
1164
|
+
}
|
|
1165
|
+
textures.set(url, texture);
|
|
1166
|
+
}
|
|
1167
|
+
refs.set(url, (refs.get(url) ?? 0) + 1);
|
|
1088
1168
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1169
|
+
return added ? { textures, _textureRefs: refs } : { _textureRefs: refs };
|
|
1170
|
+
});
|
|
1171
|
+
return () => store.setState((state) => {
|
|
1172
|
+
const refs = new Map(state._textureRefs);
|
|
1173
|
+
for (const [url] of urlTextureMap) {
|
|
1174
|
+
const next = (refs.get(url) ?? 0) - 1;
|
|
1175
|
+
if (next <= 0) refs.delete(url);
|
|
1176
|
+
else refs.set(url, next);
|
|
1093
1177
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
return
|
|
1178
|
+
return { _textureRefs: refs };
|
|
1179
|
+
});
|
|
1180
|
+
}, [cache, stableInput, mappedTextures, store]);
|
|
1181
|
+
return mappedTextures;
|
|
1182
|
+
}
|
|
1183
|
+
useTexture.preload = (url) => useLoader.preload(three.TextureLoader, url);
|
|
1184
|
+
useTexture.clear = (input) => useLoader.clear(three.TextureLoader, input);
|
|
1185
|
+
const Texture = ({
|
|
1186
|
+
children,
|
|
1187
|
+
input,
|
|
1188
|
+
onLoad,
|
|
1189
|
+
cache
|
|
1190
|
+
}) => {
|
|
1191
|
+
const options = typeof onLoad === "function" ? { onLoad, cache } : { ...onLoad, cache };
|
|
1192
|
+
const ret = useTexture(input, options);
|
|
1193
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: children?.(ret) });
|
|
1098
1194
|
};
|
|
1099
1195
|
|
|
1100
|
-
|
|
1101
|
-
const
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1196
|
+
function useTextures(selector) {
|
|
1197
|
+
const store = useStore();
|
|
1198
|
+
const registry = React.useMemo(() => {
|
|
1199
|
+
const getState = store.getState;
|
|
1200
|
+
const setState = store.setState;
|
|
1201
|
+
const getOne = (key) => getState().textures.get(key);
|
|
1202
|
+
return {
|
|
1203
|
+
get all() {
|
|
1204
|
+
return getState().textures;
|
|
1205
|
+
},
|
|
1206
|
+
get(input) {
|
|
1207
|
+
if (typeof input === "string") return getOne(input);
|
|
1208
|
+
if (Array.isArray(input)) return input.map(getOne);
|
|
1209
|
+
const out = {};
|
|
1210
|
+
for (const name in input) out[name] = getOne(input[name]);
|
|
1211
|
+
return out;
|
|
1212
|
+
},
|
|
1213
|
+
has: (key) => getState().textures.has(key),
|
|
1214
|
+
add(keyOrRecord, texture) {
|
|
1215
|
+
setState((state) => {
|
|
1216
|
+
const textures = new Map(state.textures);
|
|
1217
|
+
if (typeof keyOrRecord === "string") {
|
|
1218
|
+
textures.set(keyOrRecord, texture);
|
|
1219
|
+
} else {
|
|
1220
|
+
for (const key in keyOrRecord) textures.set(key, keyOrRecord[key]);
|
|
1221
|
+
}
|
|
1222
|
+
return { textures };
|
|
1223
|
+
});
|
|
1224
|
+
},
|
|
1225
|
+
dispose(key, options) {
|
|
1226
|
+
const state = getState();
|
|
1227
|
+
const refs = state._textureRefs.get(key) ?? 0;
|
|
1228
|
+
if (refs > 0 && !options?.force) {
|
|
1229
|
+
console.warn(
|
|
1230
|
+
`[useTextures] "${key}" still has ${refs} active reference(s); skipping dispose. Pass { force: true } to override.`
|
|
1231
|
+
);
|
|
1232
|
+
return false;
|
|
1233
|
+
}
|
|
1234
|
+
state.textures.get(key)?.dispose();
|
|
1235
|
+
setState((s) => {
|
|
1236
|
+
const textures = new Map(s.textures);
|
|
1237
|
+
textures.delete(key);
|
|
1238
|
+
const nextRefs = new Map(s._textureRefs);
|
|
1239
|
+
nextRefs.delete(key);
|
|
1240
|
+
return { textures, _textureRefs: nextRefs };
|
|
1241
|
+
});
|
|
1242
|
+
return true;
|
|
1243
|
+
},
|
|
1244
|
+
disposeAll() {
|
|
1245
|
+
for (const texture of getState().textures.values()) texture.dispose();
|
|
1246
|
+
setState({ textures: /* @__PURE__ */ new Map(), _textureRefs: /* @__PURE__ */ new Map() });
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
}, [store]);
|
|
1250
|
+
const subscribe = selector ? () => selector(registry) : (state) => state.textures;
|
|
1251
|
+
const selected = useThree$1(subscribe);
|
|
1252
|
+
return selector ? selected : registry;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
1256
|
+
const isLegacy = useThree$1((s) => s.isLegacy);
|
|
1257
|
+
const size = useThree$1((s) => s.size);
|
|
1258
|
+
let width;
|
|
1259
|
+
let height;
|
|
1260
|
+
let opts;
|
|
1261
|
+
if (typeof widthOrOptions === "object") {
|
|
1262
|
+
opts = widthOrOptions;
|
|
1263
|
+
} else if (typeof widthOrOptions === "number") {
|
|
1264
|
+
width = widthOrOptions;
|
|
1265
|
+
if (typeof heightOrOptions === "object") {
|
|
1266
|
+
height = widthOrOptions;
|
|
1267
|
+
opts = heightOrOptions;
|
|
1268
|
+
} else if (typeof heightOrOptions === "number") {
|
|
1269
|
+
height = heightOrOptions;
|
|
1270
|
+
opts = options;
|
|
1271
|
+
} else {
|
|
1272
|
+
height = widthOrOptions;
|
|
1108
1273
|
}
|
|
1109
|
-
return loader;
|
|
1110
1274
|
}
|
|
1111
|
-
return
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
if (extensions) extensions(loader);
|
|
1117
|
-
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
1118
|
-
return loader.loadAsync(input, onProgress).then((data) => {
|
|
1119
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1120
|
-
return data;
|
|
1121
|
-
});
|
|
1122
|
-
}
|
|
1123
|
-
return new Promise(
|
|
1124
|
-
(res, reject) => loader.load(
|
|
1125
|
-
input,
|
|
1126
|
-
(data) => {
|
|
1127
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1128
|
-
res(data);
|
|
1129
|
-
},
|
|
1130
|
-
onProgress,
|
|
1131
|
-
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
1132
|
-
)
|
|
1133
|
-
);
|
|
1134
|
-
};
|
|
1275
|
+
return React.useMemo(() => {
|
|
1276
|
+
const w = width ?? size.width;
|
|
1277
|
+
const h = height ?? size.height;
|
|
1278
|
+
return new three.WebGLRenderTarget(w, h, opts);
|
|
1279
|
+
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
1135
1280
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1281
|
+
|
|
1282
|
+
const presetsObj = {
|
|
1283
|
+
apartment: "lebombo_1k.hdr",
|
|
1284
|
+
city: "potsdamer_platz_1k.hdr",
|
|
1285
|
+
dawn: "kiara_1_dawn_1k.hdr",
|
|
1286
|
+
forest: "forest_slope_1k.hdr",
|
|
1287
|
+
lobby: "st_fagans_interior_1k.hdr",
|
|
1288
|
+
night: "dikhololo_night_1k.hdr",
|
|
1289
|
+
park: "rooitou_park_1k.hdr",
|
|
1290
|
+
studio: "studio_small_03_1k.hdr",
|
|
1291
|
+
sunset: "venice_sunset_1k.hdr",
|
|
1292
|
+
warehouse: "empty_warehouse_01_1k.hdr"
|
|
1293
|
+
};
|
|
1294
|
+
|
|
1295
|
+
const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
|
|
1296
|
+
const isArray = (arr) => Array.isArray(arr);
|
|
1297
|
+
const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
|
|
1298
|
+
function useEnvironment({
|
|
1299
|
+
files = defaultFiles,
|
|
1300
|
+
path = "",
|
|
1301
|
+
preset = void 0,
|
|
1302
|
+
colorSpace = void 0,
|
|
1303
|
+
extensions
|
|
1304
|
+
} = {}) {
|
|
1305
|
+
if (preset) {
|
|
1306
|
+
validatePreset(preset);
|
|
1307
|
+
files = presetsObj[preset];
|
|
1308
|
+
path = CUBEMAP_ROOT;
|
|
1309
|
+
}
|
|
1310
|
+
const multiFile = isArray(files);
|
|
1311
|
+
const { extension, isCubemap } = getExtension(files);
|
|
1312
|
+
const loader = getLoader(extension);
|
|
1313
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1314
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
1315
|
+
React.useLayoutEffect(() => {
|
|
1316
|
+
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
1317
|
+
function clearGainmapTexture() {
|
|
1318
|
+
useLoader.clear(loader, multiFile ? [files] : files);
|
|
1319
|
+
}
|
|
1320
|
+
renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
|
|
1321
|
+
}, [extension, files, loader, multiFile, renderer.domElement]);
|
|
1322
|
+
const loaderResult = useLoader(
|
|
1323
|
+
loader,
|
|
1324
|
+
multiFile ? [files] : files,
|
|
1325
|
+
(loader2) => {
|
|
1326
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
1327
|
+
loader2.setRenderer?.(renderer);
|
|
1328
|
+
}
|
|
1329
|
+
loader2.setPath?.(path);
|
|
1330
|
+
if (extensions) extensions(loader2);
|
|
1331
|
+
}
|
|
1142
1332
|
);
|
|
1143
|
-
|
|
1333
|
+
let texture = multiFile ? (
|
|
1334
|
+
// @ts-ignore
|
|
1335
|
+
loaderResult[0]
|
|
1336
|
+
) : loaderResult;
|
|
1337
|
+
if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
|
|
1338
|
+
texture = texture.renderTarget?.texture;
|
|
1339
|
+
}
|
|
1340
|
+
texture.mapping = isCubemap ? three.CubeReflectionMapping : three.EquirectangularReflectionMapping;
|
|
1341
|
+
texture.colorSpace = colorSpace ?? (isCubemap && extension !== "hdr-cube" ? "srgb" : "srgb-linear");
|
|
1342
|
+
return texture;
|
|
1144
1343
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
);
|
|
1344
|
+
const preloadDefaultOptions = {
|
|
1345
|
+
files: defaultFiles,
|
|
1346
|
+
path: "",
|
|
1347
|
+
preset: void 0,
|
|
1348
|
+
extensions: void 0
|
|
1151
1349
|
};
|
|
1152
|
-
|
|
1153
|
-
const
|
|
1154
|
-
|
|
1350
|
+
useEnvironment.preload = (preloadOptions) => {
|
|
1351
|
+
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
1352
|
+
let { files, path = "" } = options;
|
|
1353
|
+
const { preset, extensions } = options;
|
|
1354
|
+
if (preset) {
|
|
1355
|
+
validatePreset(preset);
|
|
1356
|
+
files = presetsObj[preset];
|
|
1357
|
+
path = CUBEMAP_ROOT;
|
|
1358
|
+
}
|
|
1359
|
+
const { extension } = getExtension(files);
|
|
1360
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
1361
|
+
throw new Error("useEnvironment: Preloading gainmaps is not supported");
|
|
1362
|
+
}
|
|
1363
|
+
const loader = getLoader(extension);
|
|
1364
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1365
|
+
useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
|
|
1366
|
+
loader2.setPath?.(path);
|
|
1367
|
+
if (extensions) extensions(loader2);
|
|
1368
|
+
});
|
|
1155
1369
|
};
|
|
1156
|
-
|
|
1370
|
+
const clearDefaultOptins = {
|
|
1371
|
+
files: defaultFiles,
|
|
1372
|
+
preset: void 0
|
|
1373
|
+
};
|
|
1374
|
+
useEnvironment.clear = (clearOptions) => {
|
|
1375
|
+
const options = { ...clearDefaultOptins, ...clearOptions };
|
|
1376
|
+
let { files } = options;
|
|
1377
|
+
const { preset } = options;
|
|
1378
|
+
if (preset) {
|
|
1379
|
+
validatePreset(preset);
|
|
1380
|
+
files = presetsObj[preset];
|
|
1381
|
+
}
|
|
1382
|
+
const { extension } = getExtension(files);
|
|
1383
|
+
const loader = getLoader(extension);
|
|
1384
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1385
|
+
useLoader.clear(loader, isArray(files) ? [files] : files);
|
|
1386
|
+
};
|
|
1387
|
+
function validatePreset(preset) {
|
|
1388
|
+
if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
|
|
1389
|
+
}
|
|
1390
|
+
function getExtension(files) {
|
|
1391
|
+
const isCubemap = isArray(files) && files.length === 6;
|
|
1392
|
+
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
1393
|
+
const firstEntry = isArray(files) ? files[0] : files;
|
|
1394
|
+
const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
1395
|
+
const extension = isCubemap ? firstExtension === "hdr" ? "hdr-cube" : "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstExtension;
|
|
1396
|
+
return { extension, isCubemap, isGainmap };
|
|
1397
|
+
}
|
|
1398
|
+
function getLoader(extension) {
|
|
1399
|
+
const loader = extension === "cube" ? three.CubeTextureLoader : extension === "hdr-cube" ? HDRCubeTextureLoader_js.HDRCubeTextureLoader : extension === "hdr" ? HDRLoader_js.HDRLoader : extension === "exr" ? EXRLoader_js.EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader_js.UltraHDRLoader : extension === "webp" ? gainmapJs.GainMapLoader : null;
|
|
1400
|
+
return loader;
|
|
1401
|
+
}
|
|
1157
1402
|
|
|
1158
|
-
function
|
|
1159
|
-
const
|
|
1160
|
-
|
|
1403
|
+
function useInstanceHandle(ref) {
|
|
1404
|
+
const instance = React.useRef(null);
|
|
1405
|
+
React.useImperativeHandle(instance, () => ref.current.__r3f, [ref]);
|
|
1406
|
+
return instance;
|
|
1407
|
+
}
|
|
1408
|
+
function useGraph(object) {
|
|
1409
|
+
return React.useMemo(() => buildGraph(object), [object]);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
const t = 1, o = 8, r = 32, e = 2, i$1 = 268435456;
|
|
1413
|
+
|
|
1414
|
+
let effectId = 0;
|
|
1415
|
+
function addEffect(callback) {
|
|
1416
|
+
notifyDepreciated({
|
|
1417
|
+
heading: "addEffect is deprecated",
|
|
1418
|
+
body: 'Use useFrame(callback, { phase: "start" }) instead.\naddEffect will be removed in a future version.',
|
|
1419
|
+
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
1420
|
+
});
|
|
1421
|
+
const id = `legacy_effect_${effectId++}`;
|
|
1422
|
+
return scheduler.getScheduler().registerGlobal("before", id, callback);
|
|
1423
|
+
}
|
|
1424
|
+
function addAfterEffect(callback) {
|
|
1425
|
+
notifyDepreciated({
|
|
1426
|
+
heading: "addAfterEffect is deprecated",
|
|
1427
|
+
body: 'Use useFrame(callback, { phase: "finish" }) instead.\naddAfterEffect will be removed in a future version.',
|
|
1428
|
+
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
1429
|
+
});
|
|
1430
|
+
const id = `legacy_afterEffect_${effectId++}`;
|
|
1431
|
+
return scheduler.getScheduler().registerGlobal("after", id, callback);
|
|
1432
|
+
}
|
|
1433
|
+
function addTail(callback) {
|
|
1434
|
+
notifyDepreciated({
|
|
1435
|
+
heading: "addTail is deprecated",
|
|
1436
|
+
body: "Use scheduler.onIdle(callback) instead.\naddTail will be removed in a future version.",
|
|
1437
|
+
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
1438
|
+
});
|
|
1439
|
+
return scheduler.getScheduler().onIdle(callback);
|
|
1440
|
+
}
|
|
1441
|
+
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1442
|
+
const rootId = state?.internal?.rootId;
|
|
1161
1443
|
const scheduler$1 = scheduler.getScheduler();
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1444
|
+
if (rootId) scheduler$1.invalidateRoot(rootId, frames, stackFrames);
|
|
1445
|
+
else scheduler$1.invalidate(frames, stackFrames);
|
|
1446
|
+
}
|
|
1447
|
+
function advance(timestamp, runGlobalEffects, state) {
|
|
1448
|
+
const rootId = state?.internal?.rootId;
|
|
1449
|
+
const scheduler$1 = scheduler.getScheduler();
|
|
1450
|
+
if (rootId) scheduler$1.stepRoot(rootId, timestamp);
|
|
1451
|
+
else scheduler$1.step(timestamp);
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
const version = "10.0.0-alpha.5";
|
|
1455
|
+
const packageData = {
|
|
1456
|
+
version: version};
|
|
1457
|
+
|
|
1458
|
+
function Xb(Tt) {
|
|
1459
|
+
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
1460
|
+
}
|
|
1461
|
+
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
1462
|
+
function Kb() {
|
|
1463
|
+
return _b || (_b = 1, (function(Tt) {
|
|
1464
|
+
Tt.exports = function(m) {
|
|
1465
|
+
function Yn(t, r, a, l) {
|
|
1466
|
+
return new uc(t, r, a, l);
|
|
1467
|
+
}
|
|
1468
|
+
function _d() {
|
|
1469
|
+
}
|
|
1470
|
+
function F(t) {
|
|
1471
|
+
var r = "https://react.dev/errors/" + t;
|
|
1472
|
+
if (1 < arguments.length) {
|
|
1473
|
+
r += "?args[]=" + encodeURIComponent(arguments[1]);
|
|
1474
|
+
for (var a = 2; a < arguments.length; a++) r += "&args[]=" + encodeURIComponent(arguments[a]);
|
|
1191
1475
|
}
|
|
1192
|
-
|
|
1193
|
-
heading: "useFrame with numeric priority is deprecated",
|
|
1194
|
-
body: 'Using useFrame(callback, number) to control render order is deprecated.\n\nFor custom rendering, use: useFrame(callback, { phase: "render" })\nFor execution order within update phase, use: useFrame(callback, { priority: number })',
|
|
1195
|
-
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
1196
|
-
});
|
|
1476
|
+
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.";
|
|
1197
1477
|
}
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
};
|
|
1207
|
-
callbackRef.current?.(mergedState, delta);
|
|
1208
|
-
};
|
|
1209
|
-
const unregister = scheduler$1.register(wrappedCallback, {
|
|
1210
|
-
id,
|
|
1211
|
-
rootId,
|
|
1212
|
-
...options
|
|
1213
|
-
});
|
|
1214
|
-
return () => {
|
|
1215
|
-
unregister();
|
|
1216
|
-
if (isLegacyPriority) {
|
|
1217
|
-
const currentState = store.getState();
|
|
1218
|
-
if (currentState.internal) {
|
|
1219
|
-
currentState.internal.priority--;
|
|
1220
|
-
let parentRoot = currentState.previousRoot;
|
|
1221
|
-
while (parentRoot) {
|
|
1222
|
-
const parentState = parentRoot.getState();
|
|
1223
|
-
if (parentState?.internal) parentState.internal.priority--;
|
|
1224
|
-
parentRoot = parentState?.previousRoot;
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1478
|
+
function Rd(t) {
|
|
1479
|
+
var r = t, a = t;
|
|
1480
|
+
if (t.alternate) for (; r.return; ) r = r.return;
|
|
1481
|
+
else {
|
|
1482
|
+
t = r;
|
|
1483
|
+
do
|
|
1484
|
+
r = t, (r.flags & 4098) !== 0 && (a = r.return), t = r.return;
|
|
1485
|
+
while (t);
|
|
1227
1486
|
}
|
|
1228
|
-
|
|
1229
|
-
} else {
|
|
1230
|
-
return scheduler$1.register(
|
|
1231
|
-
(state, delta) => {
|
|
1232
|
-
const frameState = state;
|
|
1233
|
-
if (!frameState.renderer) return;
|
|
1234
|
-
callbackRef.current?.(frameState, delta);
|
|
1235
|
-
},
|
|
1236
|
-
{ id, ...options }
|
|
1237
|
-
);
|
|
1238
|
-
}
|
|
1239
|
-
}, [store, scheduler$1, id, optionsKey, isLegacyPriority, isInsideCanvas]);
|
|
1240
|
-
const isPaused = React__namespace.useSyncExternalStore(
|
|
1241
|
-
// Subscribe function
|
|
1242
|
-
React__namespace.useCallback(
|
|
1243
|
-
(onStoreChange) => {
|
|
1244
|
-
return scheduler.getScheduler().subscribeJobState(id, onStoreChange);
|
|
1245
|
-
},
|
|
1246
|
-
[id]
|
|
1247
|
-
),
|
|
1248
|
-
// getSnapshot function
|
|
1249
|
-
React__namespace.useCallback(() => scheduler.getScheduler().isJobPaused(id), [id]),
|
|
1250
|
-
// getServerSnapshot function (SSR)
|
|
1251
|
-
React__namespace.useCallback(() => false, [])
|
|
1252
|
-
);
|
|
1253
|
-
const controls = React__namespace.useMemo(() => {
|
|
1254
|
-
const scheduler2 = scheduler.getScheduler();
|
|
1255
|
-
return {
|
|
1256
|
-
/** The job's unique ID */
|
|
1257
|
-
id,
|
|
1258
|
-
/**
|
|
1259
|
-
* Access to the global scheduler for frame loop control.
|
|
1260
|
-
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1261
|
-
*/
|
|
1262
|
-
scheduler: scheduler2,
|
|
1263
|
-
/**
|
|
1264
|
-
* Manually step this job only.
|
|
1265
|
-
* Bypasses FPS limiting - always runs.
|
|
1266
|
-
* @param timestamp Optional timestamp (defaults to performance.now())
|
|
1267
|
-
*/
|
|
1268
|
-
step: (timestamp) => {
|
|
1269
|
-
scheduler.getScheduler().stepJob(id, timestamp);
|
|
1270
|
-
},
|
|
1271
|
-
/**
|
|
1272
|
-
* Manually step ALL jobs in the scheduler.
|
|
1273
|
-
* Useful for frameloop='never' mode.
|
|
1274
|
-
* @param timestamp Optional timestamp (defaults to performance.now())
|
|
1275
|
-
*/
|
|
1276
|
-
stepAll: (timestamp) => {
|
|
1277
|
-
scheduler.getScheduler().step(timestamp);
|
|
1278
|
-
},
|
|
1279
|
-
/**
|
|
1280
|
-
* Pause this job (set enabled=false).
|
|
1281
|
-
* Job remains registered but won't run.
|
|
1282
|
-
*/
|
|
1283
|
-
pause: () => {
|
|
1284
|
-
scheduler.getScheduler().pauseJob(id);
|
|
1285
|
-
},
|
|
1286
|
-
/**
|
|
1287
|
-
* Resume this job (set enabled=true).
|
|
1288
|
-
*/
|
|
1289
|
-
resume: () => {
|
|
1290
|
-
scheduler.getScheduler().resumeJob(id);
|
|
1291
|
-
},
|
|
1292
|
-
/**
|
|
1293
|
-
* Reactive paused state - automatically updates when pause/resume is called.
|
|
1294
|
-
* No need for forceUpdate() in your components.
|
|
1295
|
-
*/
|
|
1296
|
-
isPaused
|
|
1297
|
-
};
|
|
1298
|
-
}, [id, isPaused]);
|
|
1299
|
-
return controls;
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
const IsObject = (url) => url === Object(url) && !Array.isArray(url) && typeof url !== "function";
|
|
1303
|
-
function getUrls(input) {
|
|
1304
|
-
if (typeof input === "string") return [input];
|
|
1305
|
-
if (Array.isArray(input)) return input;
|
|
1306
|
-
return Object.values(input);
|
|
1307
|
-
}
|
|
1308
|
-
function allUrlsCached(urls, textureCache) {
|
|
1309
|
-
return urls.every((url) => textureCache.has(url));
|
|
1310
|
-
}
|
|
1311
|
-
function buildFromCache(input, textureCache) {
|
|
1312
|
-
if (typeof input === "string") {
|
|
1313
|
-
return textureCache.get(input);
|
|
1314
|
-
} else if (Array.isArray(input)) {
|
|
1315
|
-
return input.map((url) => textureCache.get(url));
|
|
1316
|
-
} else {
|
|
1317
|
-
const result = {};
|
|
1318
|
-
const objInput = input;
|
|
1319
|
-
for (const key in objInput) {
|
|
1320
|
-
result[key] = textureCache.get(objInput[key]);
|
|
1321
|
-
}
|
|
1322
|
-
return result;
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
function useTexture(input, optionsOrOnLoad) {
|
|
1326
|
-
const renderer = useThree((state) => state.internal.actualRenderer);
|
|
1327
|
-
const store = useStore();
|
|
1328
|
-
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
1329
|
-
const { onLoad, cache = true } = options;
|
|
1330
|
-
const onLoadRef = React.useRef(onLoad);
|
|
1331
|
-
onLoadRef.current = onLoad;
|
|
1332
|
-
const onLoadCalledForRef = React.useRef(null);
|
|
1333
|
-
const urls = React.useMemo(() => getUrls(input), [input]);
|
|
1334
|
-
const cachedResult = React.useMemo(() => {
|
|
1335
|
-
if (!cache) return null;
|
|
1336
|
-
const textures = store.getState().textures;
|
|
1337
|
-
if (!allUrlsCached(urls, textures)) return null;
|
|
1338
|
-
return buildFromCache(input, textures);
|
|
1339
|
-
}, [cache, urls, input, store]);
|
|
1340
|
-
const loadedTextures = useLoader(
|
|
1341
|
-
three.TextureLoader,
|
|
1342
|
-
IsObject(input) ? Object.values(input) : input
|
|
1343
|
-
);
|
|
1344
|
-
const inputKey = urls.join("\0");
|
|
1345
|
-
React.useLayoutEffect(() => {
|
|
1346
|
-
if (cachedResult) return;
|
|
1347
|
-
if (onLoadCalledForRef.current === inputKey) return;
|
|
1348
|
-
onLoadCalledForRef.current = inputKey;
|
|
1349
|
-
onLoadRef.current?.(loadedTextures);
|
|
1350
|
-
}, [cachedResult, loadedTextures, inputKey]);
|
|
1351
|
-
React.useEffect(() => {
|
|
1352
|
-
if (cachedResult) return;
|
|
1353
|
-
if ("initTexture" in renderer) {
|
|
1354
|
-
let textureArray = [];
|
|
1355
|
-
if (Array.isArray(loadedTextures)) {
|
|
1356
|
-
textureArray = loadedTextures;
|
|
1357
|
-
} else if (loadedTextures instanceof three.Texture) {
|
|
1358
|
-
textureArray = [loadedTextures];
|
|
1359
|
-
} else if (IsObject(loadedTextures)) {
|
|
1360
|
-
textureArray = Object.values(loadedTextures);
|
|
1487
|
+
return r.tag === 3 ? a : null;
|
|
1361
1488
|
}
|
|
1362
|
-
|
|
1363
|
-
if (
|
|
1364
|
-
renderer.initTexture(texture);
|
|
1365
|
-
}
|
|
1366
|
-
});
|
|
1367
|
-
}
|
|
1368
|
-
}, [renderer, loadedTextures, cachedResult]);
|
|
1369
|
-
const mappedTextures = React.useMemo(() => {
|
|
1370
|
-
if (cachedResult) return cachedResult;
|
|
1371
|
-
if (IsObject(input)) {
|
|
1372
|
-
const keyed = {};
|
|
1373
|
-
const textureArray = loadedTextures;
|
|
1374
|
-
let i = 0;
|
|
1375
|
-
for (const key in input) keyed[key] = textureArray[i++];
|
|
1376
|
-
return keyed;
|
|
1377
|
-
} else {
|
|
1378
|
-
return loadedTextures;
|
|
1379
|
-
}
|
|
1380
|
-
}, [input, loadedTextures, cachedResult]);
|
|
1381
|
-
React.useEffect(() => {
|
|
1382
|
-
if (!cache) return;
|
|
1383
|
-
const urlTextureMap = [];
|
|
1384
|
-
if (typeof input === "string") {
|
|
1385
|
-
urlTextureMap.push([input, mappedTextures]);
|
|
1386
|
-
} else if (Array.isArray(input)) {
|
|
1387
|
-
const textureArray = mappedTextures;
|
|
1388
|
-
input.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1389
|
-
} else if (IsObject(input)) {
|
|
1390
|
-
const textureRecord = mappedTextures;
|
|
1391
|
-
for (const key in input) {
|
|
1392
|
-
const url = input[key];
|
|
1393
|
-
urlTextureMap.push([url, textureRecord[key]]);
|
|
1489
|
+
function du(t) {
|
|
1490
|
+
if (Rd(t) !== t) throw Error(F(188));
|
|
1394
1491
|
}
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1492
|
+
function fu(t) {
|
|
1493
|
+
var r = t.alternate;
|
|
1494
|
+
if (!r) {
|
|
1495
|
+
if (r = Rd(t), r === null) throw Error(F(188));
|
|
1496
|
+
return r !== t ? null : t;
|
|
1497
|
+
}
|
|
1498
|
+
for (var a = t, l = r; ; ) {
|
|
1499
|
+
var c = a.return;
|
|
1500
|
+
if (c === null) break;
|
|
1501
|
+
var d = c.alternate;
|
|
1502
|
+
if (d === null) {
|
|
1503
|
+
if (l = c.return, l !== null) {
|
|
1504
|
+
a = l;
|
|
1505
|
+
continue;
|
|
1506
|
+
}
|
|
1507
|
+
break;
|
|
1405
1508
|
}
|
|
1406
|
-
|
|
1509
|
+
if (c.child === d.child) {
|
|
1510
|
+
for (d = c.child; d; ) {
|
|
1511
|
+
if (d === a) return du(c), t;
|
|
1512
|
+
if (d === l) return du(c), r;
|
|
1513
|
+
d = d.sibling;
|
|
1514
|
+
}
|
|
1515
|
+
throw Error(F(188));
|
|
1516
|
+
}
|
|
1517
|
+
if (a.return !== l.return) a = c, l = d;
|
|
1518
|
+
else {
|
|
1519
|
+
for (var h = false, y = c.child; y; ) {
|
|
1520
|
+
if (y === a) {
|
|
1521
|
+
h = true, a = c, l = d;
|
|
1522
|
+
break;
|
|
1523
|
+
}
|
|
1524
|
+
if (y === l) {
|
|
1525
|
+
h = true, l = c, a = d;
|
|
1526
|
+
break;
|
|
1527
|
+
}
|
|
1528
|
+
y = y.sibling;
|
|
1529
|
+
}
|
|
1530
|
+
if (!h) {
|
|
1531
|
+
for (y = d.child; y; ) {
|
|
1532
|
+
if (y === a) {
|
|
1533
|
+
h = true, a = d, l = c;
|
|
1534
|
+
break;
|
|
1535
|
+
}
|
|
1536
|
+
if (y === l) {
|
|
1537
|
+
h = true, l = d, a = c;
|
|
1538
|
+
break;
|
|
1539
|
+
}
|
|
1540
|
+
y = y.sibling;
|
|
1541
|
+
}
|
|
1542
|
+
if (!h) throw Error(F(189));
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
if (a.alternate !== l) throw Error(F(190));
|
|
1407
1546
|
}
|
|
1408
|
-
|
|
1547
|
+
if (a.tag !== 3) throw Error(F(188));
|
|
1548
|
+
return a.stateNode.current === a ? t : r;
|
|
1409
1549
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1550
|
+
function pu(t) {
|
|
1551
|
+
var r = t.tag;
|
|
1552
|
+
if (r === 5 || r === 26 || r === 27 || r === 6) return t;
|
|
1553
|
+
for (t = t.child; t !== null; ) {
|
|
1554
|
+
if (r = pu(t), r !== null) return r;
|
|
1555
|
+
t = t.sibling;
|
|
1556
|
+
}
|
|
1557
|
+
return null;
|
|
1418
1558
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
useTexture.clear = (input) => useLoader.clear(three.TextureLoader, input);
|
|
1426
|
-
const Texture = ({
|
|
1427
|
-
children,
|
|
1428
|
-
input,
|
|
1429
|
-
onLoad,
|
|
1430
|
-
cache
|
|
1431
|
-
}) => {
|
|
1432
|
-
const options = typeof onLoad === "function" ? { onLoad, cache } : { ...onLoad, cache };
|
|
1433
|
-
const ret = useTexture(input, options);
|
|
1434
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: children?.(ret) });
|
|
1435
|
-
};
|
|
1436
|
-
|
|
1437
|
-
function useTextures(selector) {
|
|
1438
|
-
const store = useStore();
|
|
1439
|
-
const registry = React.useMemo(() => {
|
|
1440
|
-
const getState = store.getState;
|
|
1441
|
-
const setState = store.setState;
|
|
1442
|
-
const getOne = (key) => getState().textures.get(key);
|
|
1443
|
-
return {
|
|
1444
|
-
get all() {
|
|
1445
|
-
return getState().textures;
|
|
1446
|
-
},
|
|
1447
|
-
get(input) {
|
|
1448
|
-
if (typeof input === "string") return getOne(input);
|
|
1449
|
-
if (Array.isArray(input)) return input.map(getOne);
|
|
1450
|
-
const out = {};
|
|
1451
|
-
for (const name in input) out[name] = getOne(input[name]);
|
|
1452
|
-
return out;
|
|
1453
|
-
},
|
|
1454
|
-
has: (key) => getState().textures.has(key),
|
|
1455
|
-
add(keyOrRecord, texture) {
|
|
1456
|
-
setState((state) => {
|
|
1457
|
-
const textures = new Map(state.textures);
|
|
1458
|
-
if (typeof keyOrRecord === "string") {
|
|
1459
|
-
textures.set(keyOrRecord, texture);
|
|
1460
|
-
} else {
|
|
1461
|
-
for (const key in keyOrRecord) textures.set(key, keyOrRecord[key]);
|
|
1462
|
-
}
|
|
1463
|
-
return { textures };
|
|
1464
|
-
});
|
|
1465
|
-
},
|
|
1466
|
-
dispose(key, options) {
|
|
1467
|
-
const state = getState();
|
|
1468
|
-
const refs = state._textureRefs.get(key) ?? 0;
|
|
1469
|
-
if (refs > 0 && !options?.force) {
|
|
1470
|
-
console.warn(
|
|
1471
|
-
`[useTextures] "${key}" still has ${refs} active reference(s); skipping dispose. Pass { force: true } to override.`
|
|
1472
|
-
);
|
|
1473
|
-
return false;
|
|
1559
|
+
function lt(t) {
|
|
1560
|
+
var r = t.tag;
|
|
1561
|
+
if (r === 5 || r === 26 || r === 27 || r === 6) return t;
|
|
1562
|
+
for (t = t.child; t !== null; ) {
|
|
1563
|
+
if (t.tag !== 4 && (r = lt(t), r !== null)) return r;
|
|
1564
|
+
t = t.sibling;
|
|
1474
1565
|
}
|
|
1475
|
-
|
|
1476
|
-
setState((s) => {
|
|
1477
|
-
const textures = new Map(s.textures);
|
|
1478
|
-
textures.delete(key);
|
|
1479
|
-
const nextRefs = new Map(s._textureRefs);
|
|
1480
|
-
nextRefs.delete(key);
|
|
1481
|
-
return { textures, _textureRefs: nextRefs };
|
|
1482
|
-
});
|
|
1483
|
-
return true;
|
|
1484
|
-
},
|
|
1485
|
-
disposeAll() {
|
|
1486
|
-
for (const texture of getState().textures.values()) texture.dispose();
|
|
1487
|
-
setState({ textures: /* @__PURE__ */ new Map(), _textureRefs: /* @__PURE__ */ new Map() });
|
|
1566
|
+
return null;
|
|
1488
1567
|
}
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
const subscribe = selector ? () => selector(registry) : (state) => state.textures;
|
|
1492
|
-
const selected = useThree(subscribe);
|
|
1493
|
-
return selector ? selected : registry;
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1496
|
-
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
1497
|
-
const isLegacy = useThree((s) => s.isLegacy);
|
|
1498
|
-
const size = useThree((s) => s.size);
|
|
1499
|
-
let width;
|
|
1500
|
-
let height;
|
|
1501
|
-
let opts;
|
|
1502
|
-
if (typeof widthOrOptions === "object") {
|
|
1503
|
-
opts = widthOrOptions;
|
|
1504
|
-
} else if (typeof widthOrOptions === "number") {
|
|
1505
|
-
width = widthOrOptions;
|
|
1506
|
-
if (typeof heightOrOptions === "object") {
|
|
1507
|
-
height = widthOrOptions;
|
|
1508
|
-
opts = heightOrOptions;
|
|
1509
|
-
} else if (typeof heightOrOptions === "number") {
|
|
1510
|
-
height = heightOrOptions;
|
|
1511
|
-
opts = options;
|
|
1512
|
-
} else {
|
|
1513
|
-
height = widthOrOptions;
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
return React.useMemo(() => {
|
|
1517
|
-
const w = width ?? size.width;
|
|
1518
|
-
const h = height ?? size.height;
|
|
1519
|
-
return new three.WebGLRenderTarget(w, h, opts);
|
|
1520
|
-
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
const presetsObj = {
|
|
1524
|
-
apartment: "lebombo_1k.hdr",
|
|
1525
|
-
city: "potsdamer_platz_1k.hdr",
|
|
1526
|
-
dawn: "kiara_1_dawn_1k.hdr",
|
|
1527
|
-
forest: "forest_slope_1k.hdr",
|
|
1528
|
-
lobby: "st_fagans_interior_1k.hdr",
|
|
1529
|
-
night: "dikhololo_night_1k.hdr",
|
|
1530
|
-
park: "rooitou_park_1k.hdr",
|
|
1531
|
-
studio: "studio_small_03_1k.hdr",
|
|
1532
|
-
sunset: "venice_sunset_1k.hdr",
|
|
1533
|
-
warehouse: "empty_warehouse_01_1k.hdr"
|
|
1534
|
-
};
|
|
1535
|
-
|
|
1536
|
-
const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
|
|
1537
|
-
const isArray = (arr) => Array.isArray(arr);
|
|
1538
|
-
const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
|
|
1539
|
-
function useEnvironment({
|
|
1540
|
-
files = defaultFiles,
|
|
1541
|
-
path = "",
|
|
1542
|
-
preset = void 0,
|
|
1543
|
-
colorSpace = void 0,
|
|
1544
|
-
extensions
|
|
1545
|
-
} = {}) {
|
|
1546
|
-
if (preset) {
|
|
1547
|
-
validatePreset(preset);
|
|
1548
|
-
files = presetsObj[preset];
|
|
1549
|
-
path = CUBEMAP_ROOT;
|
|
1550
|
-
}
|
|
1551
|
-
const multiFile = isArray(files);
|
|
1552
|
-
const { extension, isCubemap } = getExtension(files);
|
|
1553
|
-
const loader = getLoader(extension);
|
|
1554
|
-
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1555
|
-
const renderer = useThree((state) => state.renderer);
|
|
1556
|
-
React.useLayoutEffect(() => {
|
|
1557
|
-
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
1558
|
-
function clearGainmapTexture() {
|
|
1559
|
-
useLoader.clear(loader, multiFile ? [files] : files);
|
|
1560
|
-
}
|
|
1561
|
-
renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
|
|
1562
|
-
}, [extension, files, loader, multiFile, renderer.domElement]);
|
|
1563
|
-
const loaderResult = useLoader(
|
|
1564
|
-
loader,
|
|
1565
|
-
multiFile ? [files] : files,
|
|
1566
|
-
(loader2) => {
|
|
1567
|
-
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
1568
|
-
loader2.setRenderer?.(renderer);
|
|
1569
|
-
}
|
|
1570
|
-
loader2.setPath?.(path);
|
|
1571
|
-
if (extensions) extensions(loader2);
|
|
1572
|
-
}
|
|
1573
|
-
);
|
|
1574
|
-
let texture = multiFile ? (
|
|
1575
|
-
// @ts-ignore
|
|
1576
|
-
loaderResult[0]
|
|
1577
|
-
) : loaderResult;
|
|
1578
|
-
if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
|
|
1579
|
-
texture = texture.renderTarget?.texture;
|
|
1580
|
-
}
|
|
1581
|
-
texture.mapping = isCubemap ? three.CubeReflectionMapping : three.EquirectangularReflectionMapping;
|
|
1582
|
-
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
1583
|
-
return texture;
|
|
1584
|
-
}
|
|
1585
|
-
const preloadDefaultOptions = {
|
|
1586
|
-
files: defaultFiles,
|
|
1587
|
-
path: "",
|
|
1588
|
-
preset: void 0,
|
|
1589
|
-
extensions: void 0
|
|
1590
|
-
};
|
|
1591
|
-
useEnvironment.preload = (preloadOptions) => {
|
|
1592
|
-
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
1593
|
-
let { files, path = "" } = options;
|
|
1594
|
-
const { preset, extensions } = options;
|
|
1595
|
-
if (preset) {
|
|
1596
|
-
validatePreset(preset);
|
|
1597
|
-
files = presetsObj[preset];
|
|
1598
|
-
path = CUBEMAP_ROOT;
|
|
1599
|
-
}
|
|
1600
|
-
const { extension } = getExtension(files);
|
|
1601
|
-
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
1602
|
-
throw new Error("useEnvironment: Preloading gainmaps is not supported");
|
|
1603
|
-
}
|
|
1604
|
-
const loader = getLoader(extension);
|
|
1605
|
-
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1606
|
-
useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
|
|
1607
|
-
loader2.setPath?.(path);
|
|
1608
|
-
if (extensions) extensions(loader2);
|
|
1609
|
-
});
|
|
1610
|
-
};
|
|
1611
|
-
const clearDefaultOptins = {
|
|
1612
|
-
files: defaultFiles,
|
|
1613
|
-
preset: void 0
|
|
1614
|
-
};
|
|
1615
|
-
useEnvironment.clear = (clearOptions) => {
|
|
1616
|
-
const options = { ...clearDefaultOptins, ...clearOptions };
|
|
1617
|
-
let { files } = options;
|
|
1618
|
-
const { preset } = options;
|
|
1619
|
-
if (preset) {
|
|
1620
|
-
validatePreset(preset);
|
|
1621
|
-
files = presetsObj[preset];
|
|
1622
|
-
}
|
|
1623
|
-
const { extension } = getExtension(files);
|
|
1624
|
-
const loader = getLoader(extension);
|
|
1625
|
-
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1626
|
-
useLoader.clear(loader, isArray(files) ? [files] : files);
|
|
1627
|
-
};
|
|
1628
|
-
function validatePreset(preset) {
|
|
1629
|
-
if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
|
|
1630
|
-
}
|
|
1631
|
-
function getExtension(files) {
|
|
1632
|
-
const isCubemap = isArray(files) && files.length === 6;
|
|
1633
|
-
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
1634
|
-
const firstEntry = isArray(files) ? files[0] : files;
|
|
1635
|
-
const extension = isCubemap ? "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
1636
|
-
return { extension, isCubemap, isGainmap };
|
|
1637
|
-
}
|
|
1638
|
-
function getLoader(extension) {
|
|
1639
|
-
const loader = extension === "cube" ? three.CubeTextureLoader : extension === "hdr" ? HDRLoader_js.HDRLoader : extension === "exr" ? EXRLoader_js.EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader_js.UltraHDRLoader : extension === "webp" ? gainmapJs.GainMapLoader : null;
|
|
1640
|
-
return loader;
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
|
-
function useStore() {
|
|
1644
|
-
const store = React.useContext(context);
|
|
1645
|
-
if (!store) throw new Error("R3F: Hooks can only be used within the Canvas component!");
|
|
1646
|
-
return store;
|
|
1647
|
-
}
|
|
1648
|
-
function useThree(selector = (state) => state, equalityFn) {
|
|
1649
|
-
return useStore()(selector, equalityFn);
|
|
1650
|
-
}
|
|
1651
|
-
function useInstanceHandle(ref) {
|
|
1652
|
-
const instance = React.useRef(null);
|
|
1653
|
-
React.useImperativeHandle(instance, () => ref.current.__r3f, [ref]);
|
|
1654
|
-
return instance;
|
|
1655
|
-
}
|
|
1656
|
-
function useGraph(object) {
|
|
1657
|
-
return React.useMemo(() => buildGraph(object), [object]);
|
|
1658
|
-
}
|
|
1659
|
-
|
|
1660
|
-
const t = 1, o = 8, r = 32, e = 2, i$1 = 268435456;
|
|
1661
|
-
|
|
1662
|
-
let effectId = 0;
|
|
1663
|
-
function addEffect(callback) {
|
|
1664
|
-
notifyDepreciated({
|
|
1665
|
-
heading: "addEffect is deprecated",
|
|
1666
|
-
body: 'Use useFrame(callback, { phase: "start" }) instead.\naddEffect will be removed in a future version.',
|
|
1667
|
-
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
1668
|
-
});
|
|
1669
|
-
const id = `legacy_effect_${effectId++}`;
|
|
1670
|
-
return scheduler.getScheduler().registerGlobal("before", id, callback);
|
|
1671
|
-
}
|
|
1672
|
-
function addAfterEffect(callback) {
|
|
1673
|
-
notifyDepreciated({
|
|
1674
|
-
heading: "addAfterEffect is deprecated",
|
|
1675
|
-
body: 'Use useFrame(callback, { phase: "finish" }) instead.\naddAfterEffect will be removed in a future version.',
|
|
1676
|
-
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
1677
|
-
});
|
|
1678
|
-
const id = `legacy_afterEffect_${effectId++}`;
|
|
1679
|
-
return scheduler.getScheduler().registerGlobal("after", id, callback);
|
|
1680
|
-
}
|
|
1681
|
-
function addTail(callback) {
|
|
1682
|
-
notifyDepreciated({
|
|
1683
|
-
heading: "addTail is deprecated",
|
|
1684
|
-
body: "Use scheduler.onIdle(callback) instead.\naddTail will be removed in a future version.",
|
|
1685
|
-
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
1686
|
-
});
|
|
1687
|
-
return scheduler.getScheduler().onIdle(callback);
|
|
1688
|
-
}
|
|
1689
|
-
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1690
|
-
scheduler.getScheduler().invalidate(frames, stackFrames);
|
|
1691
|
-
}
|
|
1692
|
-
function advance(timestamp) {
|
|
1693
|
-
scheduler.getScheduler().step(timestamp);
|
|
1694
|
-
}
|
|
1695
|
-
|
|
1696
|
-
const version = "10.0.0-alpha.3";
|
|
1697
|
-
const packageData = {
|
|
1698
|
-
version: version};
|
|
1699
|
-
|
|
1700
|
-
function Xb(Tt) {
|
|
1701
|
-
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
1702
|
-
}
|
|
1703
|
-
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
1704
|
-
function Kb() {
|
|
1705
|
-
return _b || (_b = 1, (function(Tt) {
|
|
1706
|
-
Tt.exports = function(m) {
|
|
1707
|
-
function Yn(t, r, a, l) {
|
|
1708
|
-
return new uc(t, r, a, l);
|
|
1709
|
-
}
|
|
1710
|
-
function _d() {
|
|
1711
|
-
}
|
|
1712
|
-
function F(t) {
|
|
1713
|
-
var r = "https://react.dev/errors/" + t;
|
|
1714
|
-
if (1 < arguments.length) {
|
|
1715
|
-
r += "?args[]=" + encodeURIComponent(arguments[1]);
|
|
1716
|
-
for (var a = 2; a < arguments.length; a++) r += "&args[]=" + encodeURIComponent(arguments[a]);
|
|
1717
|
-
}
|
|
1718
|
-
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.";
|
|
1719
|
-
}
|
|
1720
|
-
function Rd(t) {
|
|
1721
|
-
var r = t, a = t;
|
|
1722
|
-
if (t.alternate) for (; r.return; ) r = r.return;
|
|
1723
|
-
else {
|
|
1724
|
-
t = r;
|
|
1725
|
-
do
|
|
1726
|
-
r = t, (r.flags & 4098) !== 0 && (a = r.return), t = r.return;
|
|
1727
|
-
while (t);
|
|
1728
|
-
}
|
|
1729
|
-
return r.tag === 3 ? a : null;
|
|
1730
|
-
}
|
|
1731
|
-
function du(t) {
|
|
1732
|
-
if (Rd(t) !== t) throw Error(F(188));
|
|
1733
|
-
}
|
|
1734
|
-
function fu(t) {
|
|
1735
|
-
var r = t.alternate;
|
|
1736
|
-
if (!r) {
|
|
1737
|
-
if (r = Rd(t), r === null) throw Error(F(188));
|
|
1738
|
-
return r !== t ? null : t;
|
|
1739
|
-
}
|
|
1740
|
-
for (var a = t, l = r; ; ) {
|
|
1741
|
-
var c = a.return;
|
|
1742
|
-
if (c === null) break;
|
|
1743
|
-
var d = c.alternate;
|
|
1744
|
-
if (d === null) {
|
|
1745
|
-
if (l = c.return, l !== null) {
|
|
1746
|
-
a = l;
|
|
1747
|
-
continue;
|
|
1748
|
-
}
|
|
1749
|
-
break;
|
|
1750
|
-
}
|
|
1751
|
-
if (c.child === d.child) {
|
|
1752
|
-
for (d = c.child; d; ) {
|
|
1753
|
-
if (d === a) return du(c), t;
|
|
1754
|
-
if (d === l) return du(c), r;
|
|
1755
|
-
d = d.sibling;
|
|
1756
|
-
}
|
|
1757
|
-
throw Error(F(188));
|
|
1758
|
-
}
|
|
1759
|
-
if (a.return !== l.return) a = c, l = d;
|
|
1760
|
-
else {
|
|
1761
|
-
for (var h = false, y = c.child; y; ) {
|
|
1762
|
-
if (y === a) {
|
|
1763
|
-
h = true, a = c, l = d;
|
|
1764
|
-
break;
|
|
1765
|
-
}
|
|
1766
|
-
if (y === l) {
|
|
1767
|
-
h = true, l = c, a = d;
|
|
1768
|
-
break;
|
|
1769
|
-
}
|
|
1770
|
-
y = y.sibling;
|
|
1771
|
-
}
|
|
1772
|
-
if (!h) {
|
|
1773
|
-
for (y = d.child; y; ) {
|
|
1774
|
-
if (y === a) {
|
|
1775
|
-
h = true, a = d, l = c;
|
|
1776
|
-
break;
|
|
1777
|
-
}
|
|
1778
|
-
if (y === l) {
|
|
1779
|
-
h = true, l = d, a = c;
|
|
1780
|
-
break;
|
|
1781
|
-
}
|
|
1782
|
-
y = y.sibling;
|
|
1783
|
-
}
|
|
1784
|
-
if (!h) throw Error(F(189));
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1787
|
-
if (a.alternate !== l) throw Error(F(190));
|
|
1788
|
-
}
|
|
1789
|
-
if (a.tag !== 3) throw Error(F(188));
|
|
1790
|
-
return a.stateNode.current === a ? t : r;
|
|
1791
|
-
}
|
|
1792
|
-
function pu(t) {
|
|
1793
|
-
var r = t.tag;
|
|
1794
|
-
if (r === 5 || r === 26 || r === 27 || r === 6) return t;
|
|
1795
|
-
for (t = t.child; t !== null; ) {
|
|
1796
|
-
if (r = pu(t), r !== null) return r;
|
|
1797
|
-
t = t.sibling;
|
|
1798
|
-
}
|
|
1799
|
-
return null;
|
|
1800
|
-
}
|
|
1801
|
-
function lt(t) {
|
|
1802
|
-
var r = t.tag;
|
|
1803
|
-
if (r === 5 || r === 26 || r === 27 || r === 6) return t;
|
|
1804
|
-
for (t = t.child; t !== null; ) {
|
|
1805
|
-
if (t.tag !== 4 && (r = lt(t), r !== null)) return r;
|
|
1806
|
-
t = t.sibling;
|
|
1807
|
-
}
|
|
1808
|
-
return null;
|
|
1809
|
-
}
|
|
1810
|
-
function Fl(t) {
|
|
1811
|
-
return t === null || typeof t != "object" ? null : (t = Pf && t[Pf] || t["@@iterator"], typeof t == "function" ? t : null);
|
|
1568
|
+
function Fl(t) {
|
|
1569
|
+
return t === null || typeof t != "object" ? null : (t = Pf && t[Pf] || t["@@iterator"], typeof t == "function" ? t : null);
|
|
1812
1570
|
}
|
|
1813
1571
|
function hu(t) {
|
|
1814
1572
|
if (t == null) return null;
|
|
@@ -13552,7 +13310,10 @@ function extend(objects) {
|
|
|
13552
13310
|
catalogue[Component] = objects;
|
|
13553
13311
|
return Component;
|
|
13554
13312
|
} else {
|
|
13555
|
-
|
|
13313
|
+
for (const name in objects) {
|
|
13314
|
+
const object = objects[name];
|
|
13315
|
+
if (isConstructor(object)) catalogue[name] = object;
|
|
13316
|
+
}
|
|
13556
13317
|
}
|
|
13557
13318
|
}
|
|
13558
13319
|
function validateInstance(type, props) {
|
|
@@ -13900,7 +13661,7 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13900
13661
|
getRootHostContext: () => NO_CONTEXT,
|
|
13901
13662
|
getChildHostContext: () => NO_CONTEXT,
|
|
13902
13663
|
commitUpdate(instance, type, oldProps, newProps, fiber) {
|
|
13903
|
-
validateInstance(type, newProps);
|
|
13664
|
+
validateInstance(instance.type, newProps);
|
|
13904
13665
|
let reconstruct = false;
|
|
13905
13666
|
if (instance.type === "primitive" && oldProps.object !== newProps.object) reconstruct = true;
|
|
13906
13667
|
else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
|
|
@@ -13915,162 +13676,491 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13915
13676
|
else delete instance.props.attach;
|
|
13916
13677
|
if (Object.keys(changedProps).length) applyProps(instance.object, changedProps);
|
|
13917
13678
|
}
|
|
13918
|
-
},
|
|
13919
|
-
finalizeInitialChildren: (instance) => {
|
|
13920
|
-
for (const prop in instance.props) {
|
|
13921
|
-
if (isFromRef(instance.props[prop])) return true;
|
|
13679
|
+
},
|
|
13680
|
+
finalizeInitialChildren: (instance) => {
|
|
13681
|
+
for (const prop in instance.props) {
|
|
13682
|
+
if (isFromRef(instance.props[prop])) return true;
|
|
13683
|
+
}
|
|
13684
|
+
return false;
|
|
13685
|
+
},
|
|
13686
|
+
commitMount(instance) {
|
|
13687
|
+
const resolved = {};
|
|
13688
|
+
for (const prop in instance.props) {
|
|
13689
|
+
const value = instance.props[prop];
|
|
13690
|
+
if (isFromRef(value)) {
|
|
13691
|
+
const { [FROM_REF]: ref, transform } = value;
|
|
13692
|
+
if (ref.current != null) resolved[prop] = transform ? transform(ref.current) : ref.current;
|
|
13693
|
+
}
|
|
13694
|
+
}
|
|
13695
|
+
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
13696
|
+
},
|
|
13697
|
+
getPublicInstance: (instance) => instance?.object,
|
|
13698
|
+
prepareForCommit: () => null,
|
|
13699
|
+
preparePortalMount: (container) => {
|
|
13700
|
+
const target = container.getState().internal.container ?? container.getState().scene;
|
|
13701
|
+
return prepare(target, container, "", {});
|
|
13702
|
+
},
|
|
13703
|
+
// Reconstructed instances are swapped once all mutations are committed,
|
|
13704
|
+
// before layout effects run so refs point to the new objects
|
|
13705
|
+
resetAfterCommit: flushReconstructedInstances,
|
|
13706
|
+
shouldSetTextContent: () => false,
|
|
13707
|
+
clearContainer: () => false,
|
|
13708
|
+
hideInstance,
|
|
13709
|
+
unhideInstance,
|
|
13710
|
+
createTextInstance: handleTextInstance,
|
|
13711
|
+
hideTextInstance: handleTextInstance,
|
|
13712
|
+
unhideTextInstance: handleTextInstance,
|
|
13713
|
+
// Mirrors react-dom, which flushes discrete work in microtasks
|
|
13714
|
+
supportsMicrotasks: true,
|
|
13715
|
+
scheduleMicrotask,
|
|
13716
|
+
scheduleTimeout: typeof setTimeout === "function" ? setTimeout : void 0,
|
|
13717
|
+
cancelTimeout: typeof clearTimeout === "function" ? clearTimeout : void 0,
|
|
13718
|
+
noTimeout: -1,
|
|
13719
|
+
getInstanceFromNode: () => null,
|
|
13720
|
+
beforeActiveInstanceBlur() {
|
|
13721
|
+
},
|
|
13722
|
+
afterActiveInstanceBlur() {
|
|
13723
|
+
},
|
|
13724
|
+
detachDeletedInstance() {
|
|
13725
|
+
},
|
|
13726
|
+
prepareScopeUpdate() {
|
|
13727
|
+
},
|
|
13728
|
+
getInstanceFromScope: () => null,
|
|
13729
|
+
shouldAttemptEagerTransition: () => false,
|
|
13730
|
+
trackSchedulerEvent: () => {
|
|
13731
|
+
},
|
|
13732
|
+
resolveEventType: () => null,
|
|
13733
|
+
resolveEventTimeStamp: () => -1.1,
|
|
13734
|
+
requestPostPaintCallback() {
|
|
13735
|
+
},
|
|
13736
|
+
maySuspendCommit: () => false,
|
|
13737
|
+
preloadInstance: () => true,
|
|
13738
|
+
// true indicates already loaded
|
|
13739
|
+
suspendInstance() {
|
|
13740
|
+
},
|
|
13741
|
+
waitForCommitToBeReady: () => null,
|
|
13742
|
+
NotPendingTransition: null,
|
|
13743
|
+
// The reconciler types use the internal ReactContext with all the hidden properties
|
|
13744
|
+
// so we have to cast from the public React.Context type
|
|
13745
|
+
HostTransitionContext: /* @__PURE__ */ React__namespace.createContext(
|
|
13746
|
+
null
|
|
13747
|
+
),
|
|
13748
|
+
setCurrentUpdatePriority(newPriority) {
|
|
13749
|
+
currentUpdatePriority = newPriority;
|
|
13750
|
+
},
|
|
13751
|
+
getCurrentUpdatePriority() {
|
|
13752
|
+
return currentUpdatePriority;
|
|
13753
|
+
},
|
|
13754
|
+
resolveUpdatePriority() {
|
|
13755
|
+
if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
|
|
13756
|
+
const eventType = typeof window !== "undefined" ? window.event?.type : void 0;
|
|
13757
|
+
if (eventType === void 0) return r;
|
|
13758
|
+
return getEventPriority(eventType);
|
|
13759
|
+
},
|
|
13760
|
+
resetFormInstance() {
|
|
13761
|
+
},
|
|
13762
|
+
// @ts-ignore DefinitelyTyped is not up to date
|
|
13763
|
+
rendererPackageName: "@react-three/fiber",
|
|
13764
|
+
rendererVersion: packageData.version,
|
|
13765
|
+
// 19.2 Reconciler
|
|
13766
|
+
// https://github.com/facebook/react/pull/31975
|
|
13767
|
+
// https://github.com/facebook/react/pull/31999
|
|
13768
|
+
applyViewTransitionName(_instance, _name, _className) {
|
|
13769
|
+
},
|
|
13770
|
+
restoreViewTransitionName(_instance, _props) {
|
|
13771
|
+
},
|
|
13772
|
+
cancelViewTransitionName(_instance, _name, _props) {
|
|
13773
|
+
},
|
|
13774
|
+
cancelRootViewTransitionName(_rootContainer) {
|
|
13775
|
+
},
|
|
13776
|
+
restoreRootViewTransitionName(_rootContainer) {
|
|
13777
|
+
},
|
|
13778
|
+
InstanceMeasurement: null,
|
|
13779
|
+
measureInstance: (_instance) => null,
|
|
13780
|
+
wasInstanceInViewport: (_measurement) => true,
|
|
13781
|
+
hasInstanceChanged: (_oldMeasurement, _newMeasurement) => false,
|
|
13782
|
+
hasInstanceAffectedParent: (_oldMeasurement, _newMeasurement) => false,
|
|
13783
|
+
// https://github.com/facebook/react/pull/32002
|
|
13784
|
+
// https://github.com/facebook/react/pull/34486
|
|
13785
|
+
suspendOnActiveViewTransition(_state, _container) {
|
|
13786
|
+
},
|
|
13787
|
+
// https://github.com/facebook/react/pull/32451
|
|
13788
|
+
// https://github.com/facebook/react/pull/32760
|
|
13789
|
+
startGestureTransition: () => null,
|
|
13790
|
+
startViewTransition: () => null,
|
|
13791
|
+
stopViewTransition(_transition) {
|
|
13792
|
+
},
|
|
13793
|
+
// https://github.com/facebook/react/pull/32038
|
|
13794
|
+
createViewTransitionInstance: (_name) => null,
|
|
13795
|
+
// https://github.com/facebook/react/pull/32379
|
|
13796
|
+
// https://github.com/facebook/react/pull/32786
|
|
13797
|
+
getCurrentGestureOffset(_provider) {
|
|
13798
|
+
throw new Error("startGestureTransition is not yet supported in react-three-fiber.");
|
|
13799
|
+
},
|
|
13800
|
+
// https://github.com/facebook/react/pull/32500
|
|
13801
|
+
cloneMutableInstance(instance, _keepChildren) {
|
|
13802
|
+
return instance;
|
|
13803
|
+
},
|
|
13804
|
+
cloneMutableTextInstance(textInstance) {
|
|
13805
|
+
return textInstance;
|
|
13806
|
+
},
|
|
13807
|
+
// React 19.2 added these for root-level view transitions. They only run for hosts that opt into
|
|
13808
|
+
// view transitions by returning a container from cloneRootViewTransitionContainer; R3F renders
|
|
13809
|
+
// into a WebGL/WebGPU canvas, where cloning the root has no meaning, so we never opt in and
|
|
13810
|
+
// React never calls them. They stay as no-ops rather than throws: the host config is shared by
|
|
13811
|
+
// every root, and a throw here would turn a React-internal probe into a hard crash for users.
|
|
13812
|
+
// Guarded by a test asserting a full render + unmount never reaches them.
|
|
13813
|
+
cloneRootViewTransitionContainer(_rootContainer) {
|
|
13814
|
+
},
|
|
13815
|
+
removeRootViewTransitionClone(_rootContainer, _clone) {
|
|
13816
|
+
},
|
|
13817
|
+
// https://github.com/facebook/react/pull/32465
|
|
13818
|
+
createFragmentInstance: (_fiber) => null,
|
|
13819
|
+
updateFragmentInstanceFiber(_fiber, _instance) {
|
|
13820
|
+
},
|
|
13821
|
+
commitNewChildToFragmentInstance(_child, _fragmentInstance) {
|
|
13822
|
+
},
|
|
13823
|
+
deleteChildFromFragmentInstance(_child, _fragmentInstance) {
|
|
13824
|
+
},
|
|
13825
|
+
// https://github.com/facebook/react/pull/32653
|
|
13826
|
+
measureClonedInstance: (_instance) => null,
|
|
13827
|
+
// https://github.com/facebook/react/pull/32819
|
|
13828
|
+
maySuspendCommitOnUpdate: (_type, _oldProps, _newProps) => false,
|
|
13829
|
+
maySuspendCommitInSyncRender: (_type, _props) => false,
|
|
13830
|
+
// https://github.com/facebook/react/pull/34486
|
|
13831
|
+
startSuspendingCommit: () => null,
|
|
13832
|
+
// https://github.com/facebook/react/pull/34522
|
|
13833
|
+
getSuspendedCommitReason: (_state, _rootContainer) => null
|
|
13834
|
+
});
|
|
13835
|
+
|
|
13836
|
+
const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
|
|
13837
|
+
function isInternalRendererAccess(stack, callerDepth = 2) {
|
|
13838
|
+
if (!stack) return false;
|
|
13839
|
+
const caller = stack.split("\n")[callerDepth] ?? "";
|
|
13840
|
+
return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
|
|
13841
|
+
}
|
|
13842
|
+
|
|
13843
|
+
const createStore = (invalidate, advance) => {
|
|
13844
|
+
const rootStore = traditional.createWithEqualityFn((set, get) => {
|
|
13845
|
+
const position = new three.Vector3();
|
|
13846
|
+
const defaultTarget = new three.Vector3();
|
|
13847
|
+
const tempTarget = new three.Vector3();
|
|
13848
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
13849
|
+
const { width, height, top, left } = size;
|
|
13850
|
+
const aspect = width / height;
|
|
13851
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
13852
|
+
else tempTarget.set(...target);
|
|
13853
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
13854
|
+
if (isOrthographicCamera(camera)) {
|
|
13855
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
13856
|
+
} else {
|
|
13857
|
+
const fov = camera.fov * Math.PI / 180;
|
|
13858
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
13859
|
+
const w = h * (width / height);
|
|
13860
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
13861
|
+
}
|
|
13862
|
+
}
|
|
13863
|
+
let performanceTimeout = void 0;
|
|
13864
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
13865
|
+
const pointer = new three.Vector2();
|
|
13866
|
+
const rootState = {
|
|
13867
|
+
set,
|
|
13868
|
+
get,
|
|
13869
|
+
// Mock objects that have to be configured
|
|
13870
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
13871
|
+
primaryStore: null,
|
|
13872
|
+
gl: null,
|
|
13873
|
+
renderer: null,
|
|
13874
|
+
camera: null,
|
|
13875
|
+
frustum: new three.Frustum(),
|
|
13876
|
+
autoUpdateFrustum: true,
|
|
13877
|
+
raycaster: null,
|
|
13878
|
+
events: {
|
|
13879
|
+
priority: 1,
|
|
13880
|
+
enabled: true,
|
|
13881
|
+
connected: false,
|
|
13882
|
+
frameTimedRaycasts: true,
|
|
13883
|
+
alwaysFireOnScroll: true,
|
|
13884
|
+
updateOnFrame: false
|
|
13885
|
+
},
|
|
13886
|
+
scene: null,
|
|
13887
|
+
rootScene: null,
|
|
13888
|
+
xr: null,
|
|
13889
|
+
inspector: null,
|
|
13890
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
13891
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
13892
|
+
textureColorSpace: three.SRGBColorSpace,
|
|
13893
|
+
isLegacy: false,
|
|
13894
|
+
webGPUSupported: false,
|
|
13895
|
+
isNative: false,
|
|
13896
|
+
controls: null,
|
|
13897
|
+
pointer,
|
|
13898
|
+
mouse: pointer,
|
|
13899
|
+
frameloop: "always",
|
|
13900
|
+
onPointerMissed: void 0,
|
|
13901
|
+
onDragOverMissed: void 0,
|
|
13902
|
+
onDropMissed: void 0,
|
|
13903
|
+
performance: {
|
|
13904
|
+
current: 1,
|
|
13905
|
+
min: 0.5,
|
|
13906
|
+
max: 1,
|
|
13907
|
+
debounce: 200,
|
|
13908
|
+
regress: () => {
|
|
13909
|
+
const state2 = get();
|
|
13910
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
13911
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
13912
|
+
performanceTimeout = setTimeout(
|
|
13913
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
13914
|
+
state2.performance.debounce
|
|
13915
|
+
);
|
|
13916
|
+
}
|
|
13917
|
+
},
|
|
13918
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
13919
|
+
viewport: {
|
|
13920
|
+
initialDpr: 0,
|
|
13921
|
+
dpr: 0,
|
|
13922
|
+
width: 0,
|
|
13923
|
+
height: 0,
|
|
13924
|
+
top: 0,
|
|
13925
|
+
left: 0,
|
|
13926
|
+
aspect: 0,
|
|
13927
|
+
distance: 0,
|
|
13928
|
+
factor: 0,
|
|
13929
|
+
getCurrentViewport
|
|
13930
|
+
},
|
|
13931
|
+
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
13932
|
+
setSize: (width, height, top, left) => {
|
|
13933
|
+
const state2 = get();
|
|
13934
|
+
if (width === void 0) {
|
|
13935
|
+
set({ _sizeImperative: false });
|
|
13936
|
+
if (state2._sizeProps) {
|
|
13937
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
13938
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
13939
|
+
const currentSize = state2.size;
|
|
13940
|
+
const newSize = {
|
|
13941
|
+
width: propW ?? currentSize.width,
|
|
13942
|
+
height: propH ?? currentSize.height,
|
|
13943
|
+
top: currentSize.top,
|
|
13944
|
+
left: currentSize.left
|
|
13945
|
+
};
|
|
13946
|
+
set((s) => ({
|
|
13947
|
+
size: newSize,
|
|
13948
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
13949
|
+
}));
|
|
13950
|
+
get().invalidate();
|
|
13951
|
+
}
|
|
13952
|
+
}
|
|
13953
|
+
return;
|
|
13954
|
+
}
|
|
13955
|
+
const w = width;
|
|
13956
|
+
const h = height ?? width;
|
|
13957
|
+
const t = top ?? state2.size.top;
|
|
13958
|
+
const l = left ?? state2.size.left;
|
|
13959
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
13960
|
+
set((s) => ({
|
|
13961
|
+
size,
|
|
13962
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
13963
|
+
_sizeImperative: true
|
|
13964
|
+
}));
|
|
13965
|
+
get().invalidate();
|
|
13966
|
+
},
|
|
13967
|
+
setDpr: (dpr) => set((state2) => {
|
|
13968
|
+
const resolved = calculateDpr(dpr);
|
|
13969
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
13970
|
+
}),
|
|
13971
|
+
setFrameloop: (frameloop = "always") => {
|
|
13972
|
+
const rootId = get().internal.rootId;
|
|
13973
|
+
if (rootId) scheduler.getScheduler().setRootFrameloop(rootId, frameloop);
|
|
13974
|
+
set(() => ({ frameloop }));
|
|
13975
|
+
},
|
|
13976
|
+
setError: (error) => set(() => ({ error })),
|
|
13977
|
+
error: null,
|
|
13978
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useBuffers, useGPUStorage, useTextures, useRenderPipeline) ==============================
|
|
13979
|
+
uniforms: {},
|
|
13980
|
+
nodes: {},
|
|
13981
|
+
buffers: {},
|
|
13982
|
+
gpuStorage: {},
|
|
13983
|
+
textures: /* @__PURE__ */ new Map(),
|
|
13984
|
+
_textureRefs: /* @__PURE__ */ new Map(),
|
|
13985
|
+
renderPipeline: null,
|
|
13986
|
+
passes: {},
|
|
13987
|
+
_hmrVersion: 0,
|
|
13988
|
+
_sizeImperative: false,
|
|
13989
|
+
_sizeProps: null,
|
|
13990
|
+
previousRoot: void 0,
|
|
13991
|
+
internal: {
|
|
13992
|
+
// Events
|
|
13993
|
+
interaction: [],
|
|
13994
|
+
subscribers: [],
|
|
13995
|
+
// Per-pointer state (new unified structure)
|
|
13996
|
+
pointerMap: /* @__PURE__ */ new Map(),
|
|
13997
|
+
pointerDirty: /* @__PURE__ */ new Map(),
|
|
13998
|
+
lastEvent: React__namespace.createRef(),
|
|
13999
|
+
// Deprecated but kept for backwards compatibility
|
|
14000
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
14001
|
+
initialClick: [0, 0],
|
|
14002
|
+
initialHits: [],
|
|
14003
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
14004
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
14005
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
14006
|
+
// Occlusion system (WebGPU only)
|
|
14007
|
+
occlusionEnabled: false,
|
|
14008
|
+
occlusionObserver: null,
|
|
14009
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
14010
|
+
helperGroup: null,
|
|
14011
|
+
// Updates
|
|
14012
|
+
active: false,
|
|
14013
|
+
frames: 0,
|
|
14014
|
+
priority: 0,
|
|
14015
|
+
subscribe: (ref, priority, store) => {
|
|
14016
|
+
const internal = get().internal;
|
|
14017
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
14018
|
+
internal.subscribers.push({ ref, priority, store });
|
|
14019
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
14020
|
+
return () => {
|
|
14021
|
+
const internal2 = get().internal;
|
|
14022
|
+
if (internal2?.subscribers) {
|
|
14023
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
14024
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
14025
|
+
}
|
|
14026
|
+
};
|
|
14027
|
+
},
|
|
14028
|
+
// Renderer Storage (single source of truth)
|
|
14029
|
+
actualRenderer: null,
|
|
14030
|
+
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
14031
|
+
scheduler: null,
|
|
14032
|
+
// Replaces the default render call when set (see setRenderOverride)
|
|
14033
|
+
renderOverride: null
|
|
14034
|
+
}
|
|
14035
|
+
};
|
|
14036
|
+
return rootState;
|
|
14037
|
+
});
|
|
14038
|
+
const state = rootStore.getState();
|
|
14039
|
+
Object.defineProperty(state, "gl", {
|
|
14040
|
+
get() {
|
|
14041
|
+
const currentState = rootStore.getState();
|
|
14042
|
+
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
14043
|
+
const stack = new Error().stack || "";
|
|
14044
|
+
if (!isInternalRendererAccess(stack)) {
|
|
14045
|
+
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
14046
|
+
notifyDepreciated({
|
|
14047
|
+
heading: "Accessing state.gl in WebGPU mode",
|
|
14048
|
+
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
|
|
14049
|
+
});
|
|
14050
|
+
}
|
|
14051
|
+
}
|
|
14052
|
+
return currentState.internal.actualRenderer;
|
|
14053
|
+
},
|
|
14054
|
+
set(value) {
|
|
14055
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
14056
|
+
},
|
|
14057
|
+
enumerable: true,
|
|
14058
|
+
configurable: true
|
|
14059
|
+
});
|
|
14060
|
+
Object.defineProperty(state, "renderer", {
|
|
14061
|
+
get() {
|
|
14062
|
+
return rootStore.getState().internal.actualRenderer;
|
|
14063
|
+
},
|
|
14064
|
+
set(value) {
|
|
14065
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
14066
|
+
},
|
|
14067
|
+
enumerable: true,
|
|
14068
|
+
configurable: true
|
|
14069
|
+
});
|
|
14070
|
+
let oldScene = state.scene;
|
|
14071
|
+
rootStore.subscribe(() => {
|
|
14072
|
+
const currentState = rootStore.getState();
|
|
14073
|
+
const { scene, rootScene, set } = currentState;
|
|
14074
|
+
if (scene !== oldScene) {
|
|
14075
|
+
oldScene = scene;
|
|
14076
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
14077
|
+
set({ rootScene: scene });
|
|
14078
|
+
}
|
|
14079
|
+
}
|
|
14080
|
+
});
|
|
14081
|
+
let oldSize = state.size;
|
|
14082
|
+
let oldDpr = state.viewport.dpr;
|
|
14083
|
+
let oldCamera = state.camera;
|
|
14084
|
+
rootStore.subscribe(() => {
|
|
14085
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
14086
|
+
const actualRenderer = internal.actualRenderer;
|
|
14087
|
+
const canvasTarget = internal.canvasTarget;
|
|
14088
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
14089
|
+
oldSize = size;
|
|
14090
|
+
oldDpr = viewport.dpr;
|
|
14091
|
+
updateCamera(camera, size);
|
|
14092
|
+
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
14093
|
+
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
14094
|
+
resizeTarget.setSize(size.width, size.height, false);
|
|
14095
|
+
const activeTarget = actualRenderer.getCanvasTarget?.();
|
|
14096
|
+
if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
|
|
13922
14097
|
}
|
|
13923
|
-
|
|
13924
|
-
|
|
13925
|
-
|
|
13926
|
-
|
|
13927
|
-
|
|
13928
|
-
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
|
|
14098
|
+
if (camera !== oldCamera) {
|
|
14099
|
+
oldCamera = camera;
|
|
14100
|
+
const { rootScene } = rootStore.getState();
|
|
14101
|
+
if (camera && rootScene && !camera.parent) {
|
|
14102
|
+
rootScene.add(camera);
|
|
14103
|
+
}
|
|
14104
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
14105
|
+
const currentState = rootStore.getState();
|
|
14106
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
14107
|
+
updateFrustum(camera, currentState.frustum);
|
|
13932
14108
|
}
|
|
13933
14109
|
}
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
|
|
13945
|
-
|
|
13946
|
-
|
|
13947
|
-
|
|
13948
|
-
|
|
13949
|
-
|
|
13950
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13958
|
-
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
|
|
13980
|
-
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
13986
|
-
),
|
|
13987
|
-
|
|
13988
|
-
currentUpdatePriority = newPriority;
|
|
13989
|
-
},
|
|
13990
|
-
getCurrentUpdatePriority() {
|
|
13991
|
-
return currentUpdatePriority;
|
|
13992
|
-
},
|
|
13993
|
-
resolveUpdatePriority() {
|
|
13994
|
-
if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
|
|
13995
|
-
const eventType = typeof window !== "undefined" ? window.event?.type : void 0;
|
|
13996
|
-
if (eventType === void 0) return r;
|
|
13997
|
-
return getEventPriority(eventType);
|
|
13998
|
-
},
|
|
13999
|
-
resetFormInstance() {
|
|
14000
|
-
},
|
|
14001
|
-
// @ts-ignore DefinitelyTyped is not up to date
|
|
14002
|
-
rendererPackageName: "@react-three/fiber",
|
|
14003
|
-
rendererVersion: packageData.version,
|
|
14004
|
-
// 19.2 Reconciler
|
|
14005
|
-
// https://github.com/facebook/react/pull/31975
|
|
14006
|
-
// https://github.com/facebook/react/pull/31999
|
|
14007
|
-
applyViewTransitionName(_instance, _name, _className) {
|
|
14008
|
-
},
|
|
14009
|
-
restoreViewTransitionName(_instance, _props) {
|
|
14010
|
-
},
|
|
14011
|
-
cancelViewTransitionName(_instance, _name, _props) {
|
|
14012
|
-
},
|
|
14013
|
-
cancelRootViewTransitionName(_rootContainer) {
|
|
14014
|
-
},
|
|
14015
|
-
restoreRootViewTransitionName(_rootContainer) {
|
|
14016
|
-
},
|
|
14017
|
-
InstanceMeasurement: null,
|
|
14018
|
-
measureInstance: (_instance) => null,
|
|
14019
|
-
wasInstanceInViewport: (_measurement) => true,
|
|
14020
|
-
hasInstanceChanged: (_oldMeasurement, _newMeasurement) => false,
|
|
14021
|
-
hasInstanceAffectedParent: (_oldMeasurement, _newMeasurement) => false,
|
|
14022
|
-
// https://github.com/facebook/react/pull/32002
|
|
14023
|
-
// https://github.com/facebook/react/pull/34486
|
|
14024
|
-
suspendOnActiveViewTransition(_state, _container) {
|
|
14025
|
-
},
|
|
14026
|
-
// https://github.com/facebook/react/pull/32451
|
|
14027
|
-
// https://github.com/facebook/react/pull/32760
|
|
14028
|
-
startGestureTransition: () => null,
|
|
14029
|
-
startViewTransition: () => null,
|
|
14030
|
-
stopViewTransition(_transition) {
|
|
14031
|
-
},
|
|
14032
|
-
// https://github.com/facebook/react/pull/32038
|
|
14033
|
-
createViewTransitionInstance: (_name) => null,
|
|
14034
|
-
// https://github.com/facebook/react/pull/32379
|
|
14035
|
-
// https://github.com/facebook/react/pull/32786
|
|
14036
|
-
getCurrentGestureOffset(_provider) {
|
|
14037
|
-
throw new Error("startGestureTransition is not yet supported in react-three-fiber.");
|
|
14038
|
-
},
|
|
14039
|
-
// https://github.com/facebook/react/pull/32500
|
|
14040
|
-
cloneMutableInstance(instance, _keepChildren) {
|
|
14041
|
-
return instance;
|
|
14042
|
-
},
|
|
14043
|
-
cloneMutableTextInstance(textInstance) {
|
|
14044
|
-
return textInstance;
|
|
14045
|
-
},
|
|
14046
|
-
// React 19.2 added these for root-level view transitions. They only run for hosts that opt into
|
|
14047
|
-
// view transitions by returning a container from cloneRootViewTransitionContainer; R3F renders
|
|
14048
|
-
// into a WebGL/WebGPU canvas, where cloning the root has no meaning, so we never opt in and
|
|
14049
|
-
// React never calls them. They stay as no-ops rather than throws: the host config is shared by
|
|
14050
|
-
// every root, and a throw here would turn a React-internal probe into a hard crash for users.
|
|
14051
|
-
// Guarded by a test asserting a full render + unmount never reaches them.
|
|
14052
|
-
cloneRootViewTransitionContainer(_rootContainer) {
|
|
14053
|
-
},
|
|
14054
|
-
removeRootViewTransitionClone(_rootContainer, _clone) {
|
|
14055
|
-
},
|
|
14056
|
-
// https://github.com/facebook/react/pull/32465
|
|
14057
|
-
createFragmentInstance: (_fiber) => null,
|
|
14058
|
-
updateFragmentInstanceFiber(_fiber, _instance) {
|
|
14059
|
-
},
|
|
14060
|
-
commitNewChildToFragmentInstance(_child, _fragmentInstance) {
|
|
14061
|
-
},
|
|
14062
|
-
deleteChildFromFragmentInstance(_child, _fragmentInstance) {
|
|
14063
|
-
},
|
|
14064
|
-
// https://github.com/facebook/react/pull/32653
|
|
14065
|
-
measureClonedInstance: (_instance) => null,
|
|
14066
|
-
// https://github.com/facebook/react/pull/32819
|
|
14067
|
-
maySuspendCommitOnUpdate: (_type, _oldProps, _newProps) => false,
|
|
14068
|
-
maySuspendCommitInSyncRender: (_type, _props) => false,
|
|
14069
|
-
// https://github.com/facebook/react/pull/34486
|
|
14070
|
-
startSuspendingCommit: () => null,
|
|
14071
|
-
// https://github.com/facebook/react/pull/34522
|
|
14072
|
-
getSuspendedCommitReason: (_state, _rootContainer) => null
|
|
14073
|
-
});
|
|
14110
|
+
});
|
|
14111
|
+
rootStore.subscribe((state2) => invalidate(state2));
|
|
14112
|
+
return rootStore;
|
|
14113
|
+
};
|
|
14114
|
+
|
|
14115
|
+
const R3F_EXTENSIONS = Symbol.for("@react-three/fiber.extensions");
|
|
14116
|
+
function getRegistry() {
|
|
14117
|
+
return globalThis[R3F_EXTENSIONS] ?? (globalThis[R3F_EXTENSIONS] = {
|
|
14118
|
+
extensions: /* @__PURE__ */ new Map(),
|
|
14119
|
+
roots: /* @__PURE__ */ new Set(),
|
|
14120
|
+
applied: /* @__PURE__ */ new WeakMap()
|
|
14121
|
+
});
|
|
14122
|
+
}
|
|
14123
|
+
function setupRoot(registry, store, extension) {
|
|
14124
|
+
let applied = registry.applied.get(store);
|
|
14125
|
+
if (!applied) registry.applied.set(store, applied = /* @__PURE__ */ new Map());
|
|
14126
|
+
if (applied.has(extension.name)) return;
|
|
14127
|
+
applied.set(extension.name, extension);
|
|
14128
|
+
const patch = extension.setup?.(store);
|
|
14129
|
+
if (patch) store.setState(patch);
|
|
14130
|
+
}
|
|
14131
|
+
function registerRootExtension(extension) {
|
|
14132
|
+
const registry = getRegistry();
|
|
14133
|
+
registry.extensions.set(extension.name, extension);
|
|
14134
|
+
for (const store of registry.roots) setupRoot(registry, store, extension);
|
|
14135
|
+
return () => {
|
|
14136
|
+
if (registry.extensions.get(extension.name) === extension) registry.extensions.delete(extension.name);
|
|
14137
|
+
};
|
|
14138
|
+
}
|
|
14139
|
+
function setRenderOverride(store, render) {
|
|
14140
|
+
store.getState().internal.renderOverride = render;
|
|
14141
|
+
}
|
|
14142
|
+
function attachRootExtensions(store) {
|
|
14143
|
+
const registry = getRegistry();
|
|
14144
|
+
registry.roots.add(store);
|
|
14145
|
+
for (const extension of registry.extensions.values()) setupRoot(registry, store, extension);
|
|
14146
|
+
}
|
|
14147
|
+
function current(registry, setUpBy) {
|
|
14148
|
+
return registry.extensions.get(setUpBy.name) ?? setUpBy;
|
|
14149
|
+
}
|
|
14150
|
+
function detachRootExtensions(store) {
|
|
14151
|
+
const registry = getRegistry();
|
|
14152
|
+
if (!registry.roots.delete(store)) return;
|
|
14153
|
+
const applied = registry.applied.get(store);
|
|
14154
|
+
registry.applied.delete(store);
|
|
14155
|
+
if (!applied) return;
|
|
14156
|
+
for (const setUpBy of applied.values()) current(registry, setUpBy).dispose?.(store);
|
|
14157
|
+
}
|
|
14158
|
+
function notifyRootExtensionsHmr(store) {
|
|
14159
|
+
const registry = getRegistry();
|
|
14160
|
+
const applied = registry.applied.get(store);
|
|
14161
|
+
if (!applied) return;
|
|
14162
|
+
for (const setUpBy of applied.values()) current(registry, setUpBy).hmr?.(store);
|
|
14163
|
+
}
|
|
14074
14164
|
|
|
14075
14165
|
const isRenderer = (def) => !!def?.render;
|
|
14076
14166
|
const _roots = /* @__PURE__ */ new Map();
|
|
@@ -14305,7 +14395,7 @@ function createRoot(canvas) {
|
|
|
14305
14395
|
const handleXRFrame = (timestamp, _frame) => {
|
|
14306
14396
|
const state2 = store.getState();
|
|
14307
14397
|
if (state2.frameloop === "never") return;
|
|
14308
|
-
advance(timestamp);
|
|
14398
|
+
advance(timestamp, true, state2);
|
|
14309
14399
|
};
|
|
14310
14400
|
const actualRenderer = state.internal.actualRenderer;
|
|
14311
14401
|
const handleSessionChange = () => {
|
|
@@ -14313,7 +14403,7 @@ function createRoot(canvas) {
|
|
|
14313
14403
|
const renderer2 = state2.internal.actualRenderer;
|
|
14314
14404
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
14315
14405
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
14316
|
-
if (!renderer2.xr.isPresenting) invalidate();
|
|
14406
|
+
if (!renderer2.xr.isPresenting) invalidate(state2);
|
|
14317
14407
|
};
|
|
14318
14408
|
const xr = {
|
|
14319
14409
|
connect() {
|
|
@@ -14395,14 +14485,23 @@ function createRoot(canvas) {
|
|
|
14395
14485
|
const newRootId = canvasId || scheduler$1.generateRootId();
|
|
14396
14486
|
const unregisterRoot = scheduler$1.registerRoot(newRootId, {
|
|
14397
14487
|
getState: () => store.getState(),
|
|
14398
|
-
onError: (err) => store.getState().setError(err)
|
|
14488
|
+
onError: (err) => store.getState().setError(err),
|
|
14489
|
+
frameloop: store.getState().frameloop,
|
|
14490
|
+
before: schedulerConfig?.before,
|
|
14491
|
+
after: schedulerConfig?.after,
|
|
14492
|
+
order: schedulerConfig?.order
|
|
14399
14493
|
});
|
|
14400
14494
|
const unregisterCanvasTarget = scheduler$1.register(
|
|
14401
14495
|
() => {
|
|
14402
14496
|
const state2 = store.getState();
|
|
14403
|
-
|
|
14497
|
+
const canvasTarget = state2.internal.canvasTarget;
|
|
14498
|
+
if (canvasTarget) {
|
|
14404
14499
|
const renderer2 = state2.internal.actualRenderer;
|
|
14405
|
-
renderer2.setCanvasTarget(
|
|
14500
|
+
if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
|
|
14501
|
+
if (state2.internal.canvasTargetSizeDirty) {
|
|
14502
|
+
state2.internal.canvasTargetSizeDirty = false;
|
|
14503
|
+
renderer2.backend?.updateSize?.();
|
|
14504
|
+
}
|
|
14406
14505
|
}
|
|
14407
14506
|
},
|
|
14408
14507
|
{
|
|
@@ -14458,7 +14557,8 @@ function createRoot(canvas) {
|
|
|
14458
14557
|
const userHandlesRender = scheduler$1.hasUserJobsInPhase("render", newRootId);
|
|
14459
14558
|
if (userHandlesRender || state2.internal.priority) return;
|
|
14460
14559
|
try {
|
|
14461
|
-
|
|
14560
|
+
const renderOverride = state2.internal.renderOverride;
|
|
14561
|
+
if (renderOverride) renderOverride();
|
|
14462
14562
|
else if (renderer2?.render) renderer2.render(state2.scene, state2.camera);
|
|
14463
14563
|
} catch (error) {
|
|
14464
14564
|
state2.setError(error instanceof Error ? error : new Error(String(error)));
|
|
@@ -14471,8 +14571,7 @@ function createRoot(canvas) {
|
|
|
14471
14571
|
phase: "render",
|
|
14472
14572
|
system: true,
|
|
14473
14573
|
// Internal flag: this is a system job, not user-controlled
|
|
14474
|
-
//
|
|
14475
|
-
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
14574
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
14476
14575
|
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14477
14576
|
}
|
|
14478
14577
|
);
|
|
@@ -14491,8 +14590,22 @@ function createRoot(canvas) {
|
|
|
14491
14590
|
scheduler: scheduler$1
|
|
14492
14591
|
}
|
|
14493
14592
|
}));
|
|
14593
|
+
} else {
|
|
14594
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
|
|
14595
|
+
if (constraintsChanged) {
|
|
14596
|
+
scheduler$1.setRootConstraints(rootId, {
|
|
14597
|
+
before: schedulerConfig?.before,
|
|
14598
|
+
after: schedulerConfig?.after
|
|
14599
|
+
});
|
|
14600
|
+
}
|
|
14601
|
+
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
14602
|
+
scheduler$1.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
14603
|
+
}
|
|
14494
14604
|
}
|
|
14495
|
-
|
|
14605
|
+
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
14606
|
+
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
14607
|
+
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
14608
|
+
attachRootExtensions(store);
|
|
14496
14609
|
onCreated = onCreatedCallback;
|
|
14497
14610
|
configured = true;
|
|
14498
14611
|
resolve();
|
|
@@ -14534,18 +14647,24 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14534
14647
|
const fiber = root?.fiber;
|
|
14535
14648
|
if (fiber) {
|
|
14536
14649
|
const state = root?.store.getState();
|
|
14537
|
-
if (state)
|
|
14650
|
+
if (state) {
|
|
14651
|
+
state.internal.active = false;
|
|
14652
|
+
const unregisterRoot = state.internal.unregisterRoot;
|
|
14653
|
+
if (unregisterRoot) {
|
|
14654
|
+
unregisterRoot();
|
|
14655
|
+
state.internal.unregisterRoot = void 0;
|
|
14656
|
+
}
|
|
14657
|
+
}
|
|
14538
14658
|
reconciler.updateContainer(null, fiber, null, () => {
|
|
14659
|
+
if (root?.store) detachRootExtensions(root.store);
|
|
14539
14660
|
if (state) {
|
|
14540
14661
|
setTimeout(() => {
|
|
14541
14662
|
try {
|
|
14542
14663
|
const renderer = state.internal.actualRenderer;
|
|
14543
|
-
const unregisterRoot = state.internal.unregisterRoot;
|
|
14544
|
-
if (unregisterRoot) unregisterRoot();
|
|
14545
14664
|
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
14546
14665
|
if (unregisterPrimary) unregisterPrimary();
|
|
14547
14666
|
const canvasTarget = state.internal.canvasTarget;
|
|
14548
|
-
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14667
|
+
if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
|
|
14549
14668
|
state.events.disconnect?.();
|
|
14550
14669
|
cleanupHelperGroup(root.store);
|
|
14551
14670
|
if (state.isLegacy && renderer) {
|
|
@@ -14615,11 +14734,24 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
14615
14734
|
}
|
|
14616
14735
|
};
|
|
14617
14736
|
}, [portalScene, container, injectScene]);
|
|
14737
|
+
const lastRootState = React.useRef(null);
|
|
14618
14738
|
const inject = useMutableCallback((rootState, injectState) => {
|
|
14739
|
+
const followed = {};
|
|
14740
|
+
const lastRoot = lastRootState.current;
|
|
14741
|
+
if (lastRoot) {
|
|
14742
|
+
for (const key in rootState) {
|
|
14743
|
+
const field = key;
|
|
14744
|
+
const changed = rootState[field] !== lastRoot[field];
|
|
14745
|
+
const inherited = !(key in rest) && injectState[field] === lastRoot[field];
|
|
14746
|
+
if (changed && inherited) followed[field] = rootState[field];
|
|
14747
|
+
}
|
|
14748
|
+
}
|
|
14749
|
+
lastRootState.current = rootState;
|
|
14619
14750
|
const resolvedSize = { ...rootState.size, ...injectState.size, ...size };
|
|
14620
14751
|
let viewport = void 0;
|
|
14621
|
-
|
|
14622
|
-
|
|
14752
|
+
const portalCamera = followed.camera ?? injectState.camera;
|
|
14753
|
+
if (portalCamera && (size || injectState.size)) {
|
|
14754
|
+
const camera = portalCamera;
|
|
14623
14755
|
viewport = rootState.viewport.getCurrentViewport(camera, new three.Vector3(), resolvedSize);
|
|
14624
14756
|
if (camera !== rootState.camera) updateCamera(camera, resolvedSize);
|
|
14625
14757
|
}
|
|
@@ -14628,6 +14760,7 @@ function PortalInner({ state = {}, children, container }) {
|
|
|
14628
14760
|
// The intersect consists of the previous root state
|
|
14629
14761
|
...rootState,
|
|
14630
14762
|
...injectState,
|
|
14763
|
+
...followed,
|
|
14631
14764
|
// Portals have their own scene - always a real THREE.Scene (injected if needed)
|
|
14632
14765
|
scene: portalScene,
|
|
14633
14766
|
// rootScene always points to the actual THREE.Scene, even inside portals
|
|
@@ -14686,16 +14819,11 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
|
|
|
14686
14819
|
const oldbg = target.background;
|
|
14687
14820
|
const oldenv = target.environment;
|
|
14688
14821
|
const oldSceneProps = {
|
|
14689
|
-
// @ts-ignore
|
|
14690
14822
|
backgroundBlurriness: target.backgroundBlurriness,
|
|
14691
|
-
// @ts-ignore
|
|
14692
14823
|
backgroundIntensity: target.backgroundIntensity,
|
|
14693
|
-
|
|
14694
|
-
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
14695
|
-
// @ts-ignore
|
|
14824
|
+
backgroundRotation: target.backgroundRotation.clone(),
|
|
14696
14825
|
environmentIntensity: target.environmentIntensity,
|
|
14697
|
-
|
|
14698
|
-
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
14826
|
+
environmentRotation: target.environmentRotation.clone()
|
|
14699
14827
|
};
|
|
14700
14828
|
if (background !== "only") target.environment = texture;
|
|
14701
14829
|
if (background) target.background = texture;
|
|
@@ -14707,7 +14835,7 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
|
|
|
14707
14835
|
};
|
|
14708
14836
|
}
|
|
14709
14837
|
function EnvironmentMap({ scene, background = false, map, ...config }) {
|
|
14710
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14838
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14711
14839
|
React__namespace.useLayoutEffect(() => {
|
|
14712
14840
|
if (map) return setEnvProps(background, scene, defaultScene, map, config);
|
|
14713
14841
|
});
|
|
@@ -14725,7 +14853,7 @@ function EnvironmentCube({
|
|
|
14725
14853
|
...rest
|
|
14726
14854
|
}) {
|
|
14727
14855
|
const texture = useEnvironment(rest);
|
|
14728
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14856
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14729
14857
|
React__namespace.useLayoutEffect(() => {
|
|
14730
14858
|
return setEnvProps(background, scene, defaultScene, texture, {
|
|
14731
14859
|
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
@@ -14762,9 +14890,9 @@ function EnvironmentPortal({
|
|
|
14762
14890
|
preset = void 0,
|
|
14763
14891
|
extensions
|
|
14764
14892
|
}) {
|
|
14765
|
-
const renderer = useThree((state) => state.renderer);
|
|
14766
|
-
const isLegacy = useThree((state) => state.isLegacy);
|
|
14767
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14893
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
14894
|
+
const isLegacy = useThree$1((state) => state.isLegacy);
|
|
14895
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14768
14896
|
const camera = React__namespace.useRef(null);
|
|
14769
14897
|
const [virtualScene] = React__namespace.useState(() => new three.Scene());
|
|
14770
14898
|
const fbo = React__namespace.useMemo(() => {
|
|
@@ -14808,7 +14936,7 @@ function EnvironmentPortal({
|
|
|
14808
14936
|
environmentRotation
|
|
14809
14937
|
]);
|
|
14810
14938
|
let count = 1;
|
|
14811
|
-
useFrame(() => {
|
|
14939
|
+
useFrame$1(() => {
|
|
14812
14940
|
if (frames === Infinity || count < frames) {
|
|
14813
14941
|
const autoClear = renderer.autoClear;
|
|
14814
14942
|
renderer.autoClear = true;
|
|
@@ -14848,7 +14976,7 @@ function EnvironmentGround(props) {
|
|
|
14848
14976
|
] });
|
|
14849
14977
|
}
|
|
14850
14978
|
function EnvironmentColor({ color, scene }) {
|
|
14851
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14979
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14852
14980
|
React__namespace.useLayoutEffect(() => {
|
|
14853
14981
|
if (color === void 0) return;
|
|
14854
14982
|
const target = resolveScene(scene || defaultScene);
|
|
@@ -14920,38 +15048,6 @@ function parseRendererConfig(rendererProp) {
|
|
|
14920
15048
|
return { primaryCanvas: void 0, scheduler: void 0, renderer: rendererProp };
|
|
14921
15049
|
}
|
|
14922
15050
|
|
|
14923
|
-
const RESOURCE_KINDS = ["nodes", "uniforms", "buffers", "gpuStorage"];
|
|
14924
|
-
const registries = /* @__PURE__ */ new WeakMap();
|
|
14925
|
-
function getKindRegistry(store, kind) {
|
|
14926
|
-
let registry = registries.get(store);
|
|
14927
|
-
if (!registry) {
|
|
14928
|
-
registry = {
|
|
14929
|
-
nodes: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14930
|
-
uniforms: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14931
|
-
buffers: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14932
|
-
gpuStorage: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() }
|
|
14933
|
-
};
|
|
14934
|
-
registries.set(store, registry);
|
|
14935
|
-
}
|
|
14936
|
-
return registry[kind];
|
|
14937
|
-
}
|
|
14938
|
-
function invalidateResource(store, kind, scopeKey) {
|
|
14939
|
-
const registry = getKindRegistry(store, kind);
|
|
14940
|
-
{
|
|
14941
|
-
registry.valid.clear();
|
|
14942
|
-
registry.staged.clear();
|
|
14943
|
-
}
|
|
14944
|
-
}
|
|
14945
|
-
function invalidateAllResources(store) {
|
|
14946
|
-
for (const kind of RESOURCE_KINDS) invalidateResource(store, kind);
|
|
14947
|
-
}
|
|
14948
|
-
|
|
14949
|
-
function clearHmrCaches(store) {
|
|
14950
|
-
const primary = store.getState().primaryStore ?? store;
|
|
14951
|
-
invalidateAllResources(primary);
|
|
14952
|
-
primary.setState((state) => ({ _hmrVersion: state._hmrVersion + 1 }));
|
|
14953
|
-
}
|
|
14954
|
-
|
|
14955
15051
|
function CanvasImpl({
|
|
14956
15052
|
ref,
|
|
14957
15053
|
children,
|
|
@@ -14989,9 +15085,9 @@ function CanvasImpl({
|
|
|
14989
15085
|
React__namespace.useMemo(() => extend(THREE), []);
|
|
14990
15086
|
const Bridge = useBridge();
|
|
14991
15087
|
const backgroundProps = React__namespace.useMemo(() => parseBackground(background), [background]);
|
|
14992
|
-
const
|
|
15088
|
+
const [hasInitialSize, setHasInitialSize] = React__namespace.useState(false);
|
|
14993
15089
|
const measureConfig = React__namespace.useMemo(() => {
|
|
14994
|
-
if (!
|
|
15090
|
+
if (!hasInitialSize) {
|
|
14995
15091
|
return {
|
|
14996
15092
|
...resize,
|
|
14997
15093
|
scroll: resize?.scroll ?? true,
|
|
@@ -15003,7 +15099,7 @@ function CanvasImpl({
|
|
|
15003
15099
|
debounce: { scroll: 50, resize: 0 },
|
|
15004
15100
|
...resize
|
|
15005
15101
|
};
|
|
15006
|
-
}, [
|
|
15102
|
+
}, [hasInitialSize, resize]);
|
|
15007
15103
|
const [containerRef, containerRect] = useMeasure__default(measureConfig);
|
|
15008
15104
|
const effectiveSize = React__namespace.useMemo(() => {
|
|
15009
15105
|
let w = width ?? containerRect.width;
|
|
@@ -15019,9 +15115,7 @@ function CanvasImpl({
|
|
|
15019
15115
|
left: containerRect.left
|
|
15020
15116
|
};
|
|
15021
15117
|
}, [width, height, containerRect, forceEven]);
|
|
15022
|
-
if (!
|
|
15023
|
-
hasInitialSizeRef.current = true;
|
|
15024
|
-
}
|
|
15118
|
+
if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
|
|
15025
15119
|
const canvasRef = React__namespace.useRef(null);
|
|
15026
15120
|
const divRef = React__namespace.useRef(null);
|
|
15027
15121
|
React__namespace.useImperativeHandle(ref, () => canvasRef.current);
|
|
@@ -15135,6 +15229,7 @@ function CanvasImpl({
|
|
|
15135
15229
|
const canvas = canvasRef.current;
|
|
15136
15230
|
if (canvas) {
|
|
15137
15231
|
return () => {
|
|
15232
|
+
if (canvas.isConnected) return;
|
|
15138
15233
|
unmountComponentAtNode(canvas);
|
|
15139
15234
|
root.current = null;
|
|
15140
15235
|
};
|
|
@@ -15147,7 +15242,7 @@ function CanvasImpl({
|
|
|
15147
15242
|
const handleHMR = () => {
|
|
15148
15243
|
queueMicrotask(() => {
|
|
15149
15244
|
const rootEntry = _roots.get(canvas);
|
|
15150
|
-
if (rootEntry?.store)
|
|
15245
|
+
if (rootEntry?.store) notifyRootExtensionsHmr(rootEntry.store);
|
|
15151
15246
|
});
|
|
15152
15247
|
};
|
|
15153
15248
|
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('legacy.cjs', document.baseURI).href)) }) !== "undefined" && undefined) {
|
|
@@ -15193,11 +15288,14 @@ function CanvasImpl({
|
|
|
15193
15288
|
}
|
|
15194
15289
|
);
|
|
15195
15290
|
}
|
|
15196
|
-
function Canvas(props) {
|
|
15291
|
+
function Canvas$1(props) {
|
|
15197
15292
|
return /* @__PURE__ */ jsxRuntime.jsx(itsFine.FiberProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(CanvasImpl, { ...props }) });
|
|
15198
15293
|
}
|
|
15199
15294
|
|
|
15200
15295
|
extend(THREE);
|
|
15296
|
+
const useThree = useThree$1;
|
|
15297
|
+
const useFrame = useFrame$1;
|
|
15298
|
+
const Canvas = Canvas$1;
|
|
15201
15299
|
|
|
15202
15300
|
exports.Scheduler = scheduler.Scheduler;
|
|
15203
15301
|
exports.getScheduler = scheduler.getScheduler;
|
|
@@ -15265,8 +15363,10 @@ exports.prepare = prepare;
|
|
|
15265
15363
|
exports.presetsObj = presetsObj;
|
|
15266
15364
|
exports.reconciler = reconciler;
|
|
15267
15365
|
exports.registerPrimary = registerPrimary;
|
|
15366
|
+
exports.registerRootExtension = registerRootExtension;
|
|
15268
15367
|
exports.removeInteractivity = removeInteractivity;
|
|
15269
15368
|
exports.resolve = resolve;
|
|
15369
|
+
exports.setRenderOverride = setRenderOverride;
|
|
15270
15370
|
exports.swapInteractivity = swapInteractivity;
|
|
15271
15371
|
exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
15272
15372
|
exports.unregisterPrimary = unregisterPrimary;
|