@react-three/fiber 10.0.0-canary.4bc4a97 → 10.0.0-canary.4bf885a
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 +984 -899
- package/dist/index.d.cts +337 -156
- package/dist/index.d.mts +337 -156
- package/dist/index.d.ts +335 -182
- package/dist/index.mjs +985 -902
- package/dist/legacy.cjs +997 -913
- package/dist/legacy.d.cts +358 -209
- package/dist/legacy.d.mts +358 -209
- package/dist/legacy.d.ts +356 -233
- package/dist/legacy.mjs +998 -916
- package/dist/webgpu/index.cjs +899 -736
- package/dist/webgpu/index.d.cts +412 -262
- package/dist/webgpu/index.d.mts +412 -262
- package/dist/webgpu/index.d.ts +410 -288
- package/dist/webgpu/index.mjs +900 -739
- package/package.json +7 -2
package/dist/webgpu/index.mjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as webgpu from 'three/webgpu';
|
|
2
|
-
import { CubeRenderTarget, RenderTarget, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, ShaderMaterial, Uniform, SRGBColorSpace, RGBAFormat, UnsignedByteType,
|
|
3
|
-
import { Inspector } from 'three/addons/inspector/Inspector.js';
|
|
2
|
+
import { CubeRenderTarget, RenderTarget, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, ShaderMaterial, Uniform, SRGBColorSpace, RGBAFormat, UnsignedByteType, TextureLoader, Texture as Texture$1, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, Vector3, Vector2, CanvasTarget, Raycaster, OrthographicCamera, PerspectiveCamera, Scene, PCFShadowMap, VSMShadowMap, BasicShadowMap, ACESFilmicToneMapping, WebGPURenderer, HalfFloatType, Color, Vector4, RenderPipeline } from 'three/webgpu';
|
|
4
3
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
5
4
|
import * as React from 'react';
|
|
6
|
-
import React__default, { useRef, useMemo, useLayoutEffect, useEffect,
|
|
5
|
+
import React__default, { useContext, useRef, useMemo, useLayoutEffect, useEffect, useImperativeHandle, useCallback, useState } from 'react';
|
|
7
6
|
import useMeasure from 'react-use-measure';
|
|
8
7
|
import { useFiber, useContextBridge, traverseFiber, FiberProvider } from 'its-fine';
|
|
9
8
|
import { createWithEqualityFn } from 'zustand/traditional';
|
|
@@ -12,6 +11,7 @@ export { Scheduler, getScheduler } from '@pmndrs/scheduler';
|
|
|
12
11
|
import Tb, { unstable_getCurrentPriorityLevel, unstable_IdlePriority, unstable_LowPriority, unstable_NormalPriority, unstable_UserBlockingPriority, unstable_ImmediatePriority, unstable_scheduleCallback } from 'scheduler';
|
|
13
12
|
import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
|
|
14
13
|
import { HDRLoader } from 'three/examples/jsm/loaders/HDRLoader.js';
|
|
14
|
+
import { HDRCubeTextureLoader } from 'three/examples/jsm/loaders/HDRCubeTextureLoader.js';
|
|
15
15
|
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
|
|
16
16
|
import { UltraHDRLoader } from 'three/examples/jsm/loaders/UltraHDRLoader.js';
|
|
17
17
|
import { GainMapLoader } from '@monogrid/gainmap-js';
|
|
@@ -34,6 +34,10 @@ function _mergeNamespaces(n, m) {
|
|
|
34
34
|
|
|
35
35
|
const R3F_BUILD_LEGACY = false;
|
|
36
36
|
const R3F_BUILD_WEBGPU = true;
|
|
37
|
+
async function loadInspector() {
|
|
38
|
+
const { Inspector } = await import('three/addons/inspector/Inspector.js');
|
|
39
|
+
return Inspector;
|
|
40
|
+
}
|
|
37
41
|
const WebGLRenderer = class WebGLRenderer2 {
|
|
38
42
|
constructor() {
|
|
39
43
|
throw new Error(
|
|
@@ -47,13 +51,13 @@ const WebGLCubeRenderTarget = null;
|
|
|
47
51
|
const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
48
52
|
__proto__: null,
|
|
49
53
|
CubeRenderTargetCompat: CubeRenderTarget,
|
|
50
|
-
Inspector: Inspector,
|
|
51
54
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
52
55
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
53
56
|
RenderTargetCompat: RenderTarget,
|
|
54
57
|
WebGLCubeRenderTarget: WebGLCubeRenderTarget,
|
|
55
58
|
WebGLRenderTarget: WebGLRenderTarget,
|
|
56
|
-
WebGLRenderer: WebGLRenderer
|
|
59
|
+
WebGLRenderer: WebGLRenderer,
|
|
60
|
+
loadInspector: loadInspector
|
|
57
61
|
}, [webgpu]);
|
|
58
62
|
|
|
59
63
|
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
@@ -300,7 +304,6 @@ function prepare(target, root, type, props) {
|
|
|
300
304
|
}
|
|
301
305
|
function invalidateInstance(instance) {
|
|
302
306
|
if (!instance.parent) return;
|
|
303
|
-
instance.props.onUpdate?.(instance.object);
|
|
304
307
|
const state = instance.root?.getState?.();
|
|
305
308
|
if (state && state.internal.frames === 0) state.invalidate();
|
|
306
309
|
}
|
|
@@ -516,8 +519,10 @@ function hasVisibilityHandlers(handlers) {
|
|
|
516
519
|
}
|
|
517
520
|
|
|
518
521
|
const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
|
|
519
|
-
function fromRef(ref) {
|
|
520
|
-
|
|
522
|
+
function fromRef(ref, transform) {
|
|
523
|
+
const marker = { [FROM_REF]: ref };
|
|
524
|
+
if (transform) marker.transform = transform;
|
|
525
|
+
return marker;
|
|
521
526
|
}
|
|
522
527
|
function isFromRef(value) {
|
|
523
528
|
return value !== null && typeof value === "object" && FROM_REF in value;
|
|
@@ -531,6 +536,63 @@ function isOnce(value) {
|
|
|
531
536
|
return value !== null && typeof value === "object" && ONCE in value;
|
|
532
537
|
}
|
|
533
538
|
|
|
539
|
+
const shownNotices = /* @__PURE__ */ new Set();
|
|
540
|
+
function notifyDepreciated({ heading, body, link }) {
|
|
541
|
+
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
if (shownNotices.has(heading)) return;
|
|
545
|
+
shownNotices.add(heading);
|
|
546
|
+
const caller = getCallerFrame();
|
|
547
|
+
if (caller) {
|
|
548
|
+
console.log();
|
|
549
|
+
}
|
|
550
|
+
const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
|
|
551
|
+
if (caller) {
|
|
552
|
+
console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
|
|
553
|
+
}
|
|
554
|
+
if (body || link) {
|
|
555
|
+
let message = "";
|
|
556
|
+
if (body) message += body;
|
|
557
|
+
if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
|
|
558
|
+
console.warn(`%c${message}`, "font-weight: bold;");
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
function getCallerFrame(depth = 3) {
|
|
562
|
+
const stack = new Error().stack;
|
|
563
|
+
if (!stack) return null;
|
|
564
|
+
const lines = stack.split("\n");
|
|
565
|
+
const frame = lines[depth];
|
|
566
|
+
if (!frame) return null;
|
|
567
|
+
let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
|
|
568
|
+
if (!match) {
|
|
569
|
+
match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
|
|
570
|
+
}
|
|
571
|
+
if (!match) return null;
|
|
572
|
+
const [, fn, url, line] = match;
|
|
573
|
+
return {
|
|
574
|
+
functionName: fn ?? "<anonymous>",
|
|
575
|
+
location: formatLocation(url, Number(line))
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
function formatLocation(url, line) {
|
|
579
|
+
const clean = url.split("?")[0];
|
|
580
|
+
const file = clean.split("/").pop() ?? clean;
|
|
581
|
+
return `${file}:${line}`;
|
|
582
|
+
}
|
|
583
|
+
function notifyAlpha({ message, link }) {
|
|
584
|
+
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
if (shownNotices.has(message)) return;
|
|
588
|
+
shownNotices.add(message);
|
|
589
|
+
const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
|
|
590
|
+
console.log(`%c\u{1F52C} ${message}`, boxStyle);
|
|
591
|
+
{
|
|
592
|
+
console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
534
596
|
const RESERVED_PROPS = [
|
|
535
597
|
"children",
|
|
536
598
|
"key",
|
|
@@ -540,7 +602,6 @@ const RESERVED_PROPS = [
|
|
|
540
602
|
"dispose",
|
|
541
603
|
"attach",
|
|
542
604
|
"object",
|
|
543
|
-
"onUpdate",
|
|
544
605
|
// Behavior flags
|
|
545
606
|
"dispose"
|
|
546
607
|
];
|
|
@@ -618,11 +679,9 @@ function diffProps(instance, newProps) {
|
|
|
618
679
|
for (const prop in instance.props) {
|
|
619
680
|
if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
|
|
620
681
|
const { root, key } = resolve(instance.object, prop);
|
|
621
|
-
if (
|
|
682
|
+
if (typeof root?.constructor === "function") {
|
|
622
683
|
const ctor = getMemoizedPrototype(root);
|
|
623
684
|
if (!is.und(ctor)) changedProps[prop] = ctor[key];
|
|
624
|
-
} else {
|
|
625
|
-
changedProps[prop] = 0;
|
|
626
685
|
}
|
|
627
686
|
}
|
|
628
687
|
return changedProps;
|
|
@@ -634,6 +693,13 @@ function applyProps(object, props) {
|
|
|
634
693
|
for (const prop in props) {
|
|
635
694
|
const value = props[prop];
|
|
636
695
|
if (RESERVED_PROPS.includes(prop)) continue;
|
|
696
|
+
if (prop === "onUpdate") {
|
|
697
|
+
notifyDepreciated({
|
|
698
|
+
heading: "onUpdate is no longer an R3F prop",
|
|
699
|
+
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.",
|
|
700
|
+
link: "https://docs.pmnd.rs/react-three-fiber/migration/v10#onupdate-removed"
|
|
701
|
+
});
|
|
702
|
+
}
|
|
637
703
|
if (instance && EVENT_REGEX.test(prop)) {
|
|
638
704
|
if (typeof value === "function") instance.handlers[prop] = value;
|
|
639
705
|
else delete instance.handlers[prop];
|
|
@@ -705,380 +771,51 @@ function applyProps(object, props) {
|
|
|
705
771
|
root[key].format === RGBAFormat && root[key].type === UnsignedByteType) {
|
|
706
772
|
root[key].colorSpace = rootState.textureColorSpace;
|
|
707
773
|
}
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
if (instance?.parent && rootState?.internal && instance.object?.isObject3D && prevHandlers !== instance.eventCount) {
|
|
711
|
-
const object2 = instance.object;
|
|
712
|
-
const index = rootState.internal.interaction.indexOf(object2);
|
|
713
|
-
if (index > -1) rootState.internal.interaction.splice(index, 1);
|
|
714
|
-
if (instance.eventCount && object2.raycast !== null) {
|
|
715
|
-
rootState.internal.interaction.push(object2);
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
if (instance?.parent && rootState?.internal && instance.object?.isObject3D) {
|
|
719
|
-
const object2 = instance.object;
|
|
720
|
-
const root = findInitialRoot(instance);
|
|
721
|
-
const visibilityHandlers = {
|
|
722
|
-
onFramed: instance.handlers.onFramed,
|
|
723
|
-
onOccluded: instance.handlers.onOccluded,
|
|
724
|
-
onVisible: instance.handlers.onVisible
|
|
725
|
-
};
|
|
726
|
-
if (hasVisibilityHandlers(visibilityHandlers)) {
|
|
727
|
-
if (!updateVisibilityHandlers(root, object2, visibilityHandlers)) {
|
|
728
|
-
registerVisibility(root, object2, visibilityHandlers);
|
|
729
|
-
}
|
|
730
|
-
} else {
|
|
731
|
-
unregisterVisibility(root, object2);
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
if (instance && instance.props.attach === void 0) {
|
|
735
|
-
if (instance.object.isBufferGeometry) instance.props.attach = "geometry";
|
|
736
|
-
else if (instance.object.isMaterial) instance.props.attach = "material";
|
|
737
|
-
}
|
|
738
|
-
if (instance) invalidateInstance(instance);
|
|
739
|
-
return object;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
const shownNotices = /* @__PURE__ */ new Set();
|
|
743
|
-
function notifyDepreciated({ heading, body, link }) {
|
|
744
|
-
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
if (shownNotices.has(heading)) return;
|
|
748
|
-
shownNotices.add(heading);
|
|
749
|
-
const caller = getCallerFrame();
|
|
750
|
-
if (caller) {
|
|
751
|
-
console.log();
|
|
752
|
-
}
|
|
753
|
-
const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
|
|
754
|
-
if (caller) {
|
|
755
|
-
console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
|
|
756
|
-
}
|
|
757
|
-
if (body || link) {
|
|
758
|
-
let message = "";
|
|
759
|
-
if (body) message += body;
|
|
760
|
-
if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
|
|
761
|
-
console.warn(`%c${message}`, "font-weight: bold;");
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
function getCallerFrame(depth = 3) {
|
|
765
|
-
const stack = new Error().stack;
|
|
766
|
-
if (!stack) return null;
|
|
767
|
-
const lines = stack.split("\n");
|
|
768
|
-
const frame = lines[depth];
|
|
769
|
-
if (!frame) return null;
|
|
770
|
-
let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
|
|
771
|
-
if (!match) {
|
|
772
|
-
match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
|
|
773
|
-
}
|
|
774
|
-
if (!match) return null;
|
|
775
|
-
const [, fn, url, line] = match;
|
|
776
|
-
return {
|
|
777
|
-
functionName: fn ?? "<anonymous>",
|
|
778
|
-
location: formatLocation(url, Number(line))
|
|
779
|
-
};
|
|
780
|
-
}
|
|
781
|
-
function formatLocation(url, line) {
|
|
782
|
-
const clean = url.split("?")[0];
|
|
783
|
-
const file = clean.split("/").pop() ?? clean;
|
|
784
|
-
return `${file}:${line}`;
|
|
785
|
-
}
|
|
786
|
-
function notifyAlpha({ message, link }) {
|
|
787
|
-
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
|
|
788
|
-
return;
|
|
789
|
-
}
|
|
790
|
-
if (shownNotices.has(message)) return;
|
|
791
|
-
shownNotices.add(message);
|
|
792
|
-
const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
|
|
793
|
-
console.log(`%c\u{1F52C} ${message}`, boxStyle);
|
|
794
|
-
{
|
|
795
|
-
console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
|
|
800
|
-
function isInternalRendererAccess(stack, callerDepth = 2) {
|
|
801
|
-
if (!stack) return false;
|
|
802
|
-
const caller = stack.split("\n")[callerDepth] ?? "";
|
|
803
|
-
return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
807
|
-
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React.createContext(null));
|
|
808
|
-
const createStore = (invalidate, advance) => {
|
|
809
|
-
const rootStore = createWithEqualityFn((set, get) => {
|
|
810
|
-
const position = new Vector3();
|
|
811
|
-
const defaultTarget = new Vector3();
|
|
812
|
-
const tempTarget = new Vector3();
|
|
813
|
-
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
814
|
-
const { width, height, top, left } = size;
|
|
815
|
-
const aspect = width / height;
|
|
816
|
-
if (target.isVector3) tempTarget.copy(target);
|
|
817
|
-
else tempTarget.set(...target);
|
|
818
|
-
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
819
|
-
if (isOrthographicCamera(camera)) {
|
|
820
|
-
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
821
|
-
} else {
|
|
822
|
-
const fov = camera.fov * Math.PI / 180;
|
|
823
|
-
const h = 2 * Math.tan(fov / 2) * distance;
|
|
824
|
-
const w = h * (width / height);
|
|
825
|
-
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
let performanceTimeout = void 0;
|
|
829
|
-
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
830
|
-
const pointer = new Vector2();
|
|
831
|
-
const rootState = {
|
|
832
|
-
set,
|
|
833
|
-
get,
|
|
834
|
-
// Mock objects that have to be configured
|
|
835
|
-
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
836
|
-
primaryStore: null,
|
|
837
|
-
gl: null,
|
|
838
|
-
renderer: null,
|
|
839
|
-
camera: null,
|
|
840
|
-
frustum: new Frustum(),
|
|
841
|
-
autoUpdateFrustum: true,
|
|
842
|
-
raycaster: null,
|
|
843
|
-
events: {
|
|
844
|
-
priority: 1,
|
|
845
|
-
enabled: true,
|
|
846
|
-
connected: false,
|
|
847
|
-
frameTimedRaycasts: true,
|
|
848
|
-
alwaysFireOnScroll: true,
|
|
849
|
-
updateOnFrame: false
|
|
850
|
-
},
|
|
851
|
-
scene: null,
|
|
852
|
-
rootScene: null,
|
|
853
|
-
xr: null,
|
|
854
|
-
inspector: null,
|
|
855
|
-
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
856
|
-
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
857
|
-
textureColorSpace: SRGBColorSpace,
|
|
858
|
-
isLegacy: false,
|
|
859
|
-
webGPUSupported: false,
|
|
860
|
-
isNative: false,
|
|
861
|
-
controls: null,
|
|
862
|
-
pointer,
|
|
863
|
-
mouse: pointer,
|
|
864
|
-
frameloop: "always",
|
|
865
|
-
onPointerMissed: void 0,
|
|
866
|
-
onDragOverMissed: void 0,
|
|
867
|
-
onDropMissed: void 0,
|
|
868
|
-
performance: {
|
|
869
|
-
current: 1,
|
|
870
|
-
min: 0.5,
|
|
871
|
-
max: 1,
|
|
872
|
-
debounce: 200,
|
|
873
|
-
regress: () => {
|
|
874
|
-
const state2 = get();
|
|
875
|
-
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
876
|
-
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
877
|
-
performanceTimeout = setTimeout(
|
|
878
|
-
() => setPerformanceCurrent(get().performance.max),
|
|
879
|
-
state2.performance.debounce
|
|
880
|
-
);
|
|
881
|
-
}
|
|
882
|
-
},
|
|
883
|
-
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
884
|
-
viewport: {
|
|
885
|
-
initialDpr: 0,
|
|
886
|
-
dpr: 0,
|
|
887
|
-
width: 0,
|
|
888
|
-
height: 0,
|
|
889
|
-
top: 0,
|
|
890
|
-
left: 0,
|
|
891
|
-
aspect: 0,
|
|
892
|
-
distance: 0,
|
|
893
|
-
factor: 0,
|
|
894
|
-
getCurrentViewport
|
|
895
|
-
},
|
|
896
|
-
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
897
|
-
setSize: (width, height, top, left) => {
|
|
898
|
-
const state2 = get();
|
|
899
|
-
if (width === void 0) {
|
|
900
|
-
set({ _sizeImperative: false });
|
|
901
|
-
if (state2._sizeProps) {
|
|
902
|
-
const { width: propW, height: propH } = state2._sizeProps;
|
|
903
|
-
if (propW !== void 0 || propH !== void 0) {
|
|
904
|
-
const currentSize = state2.size;
|
|
905
|
-
const newSize = {
|
|
906
|
-
width: propW ?? currentSize.width,
|
|
907
|
-
height: propH ?? currentSize.height,
|
|
908
|
-
top: currentSize.top,
|
|
909
|
-
left: currentSize.left
|
|
910
|
-
};
|
|
911
|
-
set((s) => ({
|
|
912
|
-
size: newSize,
|
|
913
|
-
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
914
|
-
}));
|
|
915
|
-
getScheduler().invalidate();
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
return;
|
|
919
|
-
}
|
|
920
|
-
const w = width;
|
|
921
|
-
const h = height ?? width;
|
|
922
|
-
const t = top ?? state2.size.top;
|
|
923
|
-
const l = left ?? state2.size.left;
|
|
924
|
-
const size = { width: w, height: h, top: t, left: l };
|
|
925
|
-
set((s) => ({
|
|
926
|
-
size,
|
|
927
|
-
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
928
|
-
_sizeImperative: true
|
|
929
|
-
}));
|
|
930
|
-
getScheduler().invalidate();
|
|
931
|
-
},
|
|
932
|
-
setDpr: (dpr) => set((state2) => {
|
|
933
|
-
const resolved = calculateDpr(dpr);
|
|
934
|
-
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
935
|
-
}),
|
|
936
|
-
setFrameloop: (frameloop = "always") => {
|
|
937
|
-
set(() => ({ frameloop }));
|
|
938
|
-
getScheduler().frameloop = frameloop;
|
|
939
|
-
},
|
|
940
|
-
setError: (error) => set(() => ({ error })),
|
|
941
|
-
error: null,
|
|
942
|
-
//* TSL State (managed via hooks: useUniforms, useNodes, useBuffers, useGPUStorage, useTextures, useRenderPipeline) ==============================
|
|
943
|
-
uniforms: {},
|
|
944
|
-
nodes: {},
|
|
945
|
-
buffers: {},
|
|
946
|
-
gpuStorage: {},
|
|
947
|
-
textures: /* @__PURE__ */ new Map(),
|
|
948
|
-
_textureRefs: /* @__PURE__ */ new Map(),
|
|
949
|
-
renderPipeline: null,
|
|
950
|
-
passes: {},
|
|
951
|
-
_hmrVersion: 0,
|
|
952
|
-
_sizeImperative: false,
|
|
953
|
-
_sizeProps: null,
|
|
954
|
-
previousRoot: void 0,
|
|
955
|
-
internal: {
|
|
956
|
-
// Events
|
|
957
|
-
interaction: [],
|
|
958
|
-
subscribers: [],
|
|
959
|
-
// Per-pointer state (new unified structure)
|
|
960
|
-
pointerMap: /* @__PURE__ */ new Map(),
|
|
961
|
-
pointerDirty: /* @__PURE__ */ new Map(),
|
|
962
|
-
lastEvent: React.createRef(),
|
|
963
|
-
// Deprecated but kept for backwards compatibility
|
|
964
|
-
hovered: /* @__PURE__ */ new Map(),
|
|
965
|
-
initialClick: [0, 0],
|
|
966
|
-
initialHits: [],
|
|
967
|
-
capturedMap: /* @__PURE__ */ new Map(),
|
|
968
|
-
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
969
|
-
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
970
|
-
// Occlusion system (WebGPU only)
|
|
971
|
-
occlusionEnabled: false,
|
|
972
|
-
occlusionObserver: null,
|
|
973
|
-
occlusionCache: /* @__PURE__ */ new Map(),
|
|
974
|
-
helperGroup: null,
|
|
975
|
-
// Updates
|
|
976
|
-
active: false,
|
|
977
|
-
frames: 0,
|
|
978
|
-
priority: 0,
|
|
979
|
-
subscribe: (ref, priority, store) => {
|
|
980
|
-
const internal = get().internal;
|
|
981
|
-
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
982
|
-
internal.subscribers.push({ ref, priority, store });
|
|
983
|
-
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
984
|
-
return () => {
|
|
985
|
-
const internal2 = get().internal;
|
|
986
|
-
if (internal2?.subscribers) {
|
|
987
|
-
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
988
|
-
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
989
|
-
}
|
|
990
|
-
};
|
|
991
|
-
},
|
|
992
|
-
// Renderer Storage (single source of truth)
|
|
993
|
-
actualRenderer: null,
|
|
994
|
-
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
995
|
-
scheduler: null
|
|
996
|
-
}
|
|
997
|
-
};
|
|
998
|
-
return rootState;
|
|
999
|
-
});
|
|
1000
|
-
const state = rootStore.getState();
|
|
1001
|
-
Object.defineProperty(state, "gl", {
|
|
1002
|
-
get() {
|
|
1003
|
-
const currentState = rootStore.getState();
|
|
1004
|
-
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1005
|
-
const stack = new Error().stack || "";
|
|
1006
|
-
if (!isInternalRendererAccess(stack)) {
|
|
1007
|
-
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1008
|
-
notifyDepreciated({
|
|
1009
|
-
heading: "Accessing state.gl in WebGPU mode",
|
|
1010
|
-
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
|
|
1011
|
-
});
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
|
-
return currentState.internal.actualRenderer;
|
|
1015
|
-
},
|
|
1016
|
-
set(value) {
|
|
1017
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1018
|
-
},
|
|
1019
|
-
enumerable: true,
|
|
1020
|
-
configurable: true
|
|
1021
|
-
});
|
|
1022
|
-
Object.defineProperty(state, "renderer", {
|
|
1023
|
-
get() {
|
|
1024
|
-
return rootStore.getState().internal.actualRenderer;
|
|
1025
|
-
},
|
|
1026
|
-
set(value) {
|
|
1027
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1028
|
-
},
|
|
1029
|
-
enumerable: true,
|
|
1030
|
-
configurable: true
|
|
1031
|
-
});
|
|
1032
|
-
let oldScene = state.scene;
|
|
1033
|
-
rootStore.subscribe(() => {
|
|
1034
|
-
const currentState = rootStore.getState();
|
|
1035
|
-
const { scene, rootScene, set } = currentState;
|
|
1036
|
-
if (scene !== oldScene) {
|
|
1037
|
-
oldScene = scene;
|
|
1038
|
-
if (scene?.isScene && scene !== rootScene) {
|
|
1039
|
-
set({ rootScene: scene });
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
});
|
|
1043
|
-
let oldSize = state.size;
|
|
1044
|
-
let oldDpr = state.viewport.dpr;
|
|
1045
|
-
let oldCamera = state.camera;
|
|
1046
|
-
rootStore.subscribe(() => {
|
|
1047
|
-
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
1048
|
-
const actualRenderer = internal.actualRenderer;
|
|
1049
|
-
const canvasTarget = internal.canvasTarget;
|
|
1050
|
-
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
1051
|
-
oldSize = size;
|
|
1052
|
-
oldDpr = viewport.dpr;
|
|
1053
|
-
updateCamera(camera, size);
|
|
1054
|
-
if (internal.isSecondary && canvasTarget) {
|
|
1055
|
-
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1056
|
-
canvasTarget.setSize(size.width, size.height, false);
|
|
1057
|
-
} else {
|
|
1058
|
-
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1059
|
-
actualRenderer.setSize(size.width, size.height, false);
|
|
1060
|
-
if (canvasTarget) {
|
|
1061
|
-
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1062
|
-
canvasTarget.setSize(size.width, size.height, false);
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
if (camera !== oldCamera) {
|
|
1067
|
-
oldCamera = camera;
|
|
1068
|
-
const { rootScene } = rootStore.getState();
|
|
1069
|
-
if (camera && rootScene && !camera.parent) {
|
|
1070
|
-
rootScene.add(camera);
|
|
1071
|
-
}
|
|
1072
|
-
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
1073
|
-
const currentState = rootStore.getState();
|
|
1074
|
-
if (currentState.autoUpdateFrustum && camera) {
|
|
1075
|
-
updateFrustum(camera, currentState.frustum);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
if (instance?.parent && rootState?.internal && instance.object?.isObject3D && prevHandlers !== instance.eventCount) {
|
|
777
|
+
const object2 = instance.object;
|
|
778
|
+
const index = rootState.internal.interaction.indexOf(object2);
|
|
779
|
+
if (index > -1) rootState.internal.interaction.splice(index, 1);
|
|
780
|
+
if (instance.eventCount && object2.raycast !== null) {
|
|
781
|
+
rootState.internal.interaction.push(object2);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
if (instance?.parent && rootState?.internal && instance.object?.isObject3D) {
|
|
785
|
+
const object2 = instance.object;
|
|
786
|
+
const root = findInitialRoot(instance);
|
|
787
|
+
const visibilityHandlers = {
|
|
788
|
+
onFramed: instance.handlers.onFramed,
|
|
789
|
+
onOccluded: instance.handlers.onOccluded,
|
|
790
|
+
onVisible: instance.handlers.onVisible
|
|
791
|
+
};
|
|
792
|
+
if (hasVisibilityHandlers(visibilityHandlers)) {
|
|
793
|
+
if (!updateVisibilityHandlers(root, object2, visibilityHandlers)) {
|
|
794
|
+
registerVisibility(root, object2, visibilityHandlers);
|
|
1076
795
|
}
|
|
796
|
+
} else {
|
|
797
|
+
unregisterVisibility(root, object2);
|
|
1077
798
|
}
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
799
|
+
}
|
|
800
|
+
if (instance && instance.props.attach === void 0) {
|
|
801
|
+
if (instance.object.isBufferGeometry) instance.props.attach = "geometry";
|
|
802
|
+
else if (instance.object.isMaterial) instance.props.attach = "material";
|
|
803
|
+
}
|
|
804
|
+
if (instance) invalidateInstance(instance);
|
|
805
|
+
return object;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
809
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React.createContext(null));
|
|
810
|
+
|
|
811
|
+
function useStore() {
|
|
812
|
+
const store = useContext(context);
|
|
813
|
+
if (!store) throw new Error("R3F: Hooks can only be used within the Canvas component!");
|
|
814
|
+
return store;
|
|
815
|
+
}
|
|
816
|
+
function useThree$1(selector = (state) => state, equalityFn) {
|
|
817
|
+
return useStore()(selector, equalityFn);
|
|
818
|
+
}
|
|
1082
819
|
|
|
1083
820
|
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
1084
821
|
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
@@ -1123,7 +860,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
|
1123
860
|
const results = cacheKeys.map(
|
|
1124
861
|
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1125
862
|
);
|
|
1126
|
-
|
|
863
|
+
const stableRef = useRef(null);
|
|
864
|
+
const previous = stableRef.current;
|
|
865
|
+
const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
|
|
866
|
+
stableRef.current = stable;
|
|
867
|
+
return Array.isArray(input) ? stable : stable[0];
|
|
1127
868
|
}
|
|
1128
869
|
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
1129
870
|
const inputs = Array.isArray(input) ? input : [input];
|
|
@@ -1138,7 +879,7 @@ useLoader.clear = function(loader, input, cacheKey) {
|
|
|
1138
879
|
};
|
|
1139
880
|
useLoader.loader = getLoader$1;
|
|
1140
881
|
|
|
1141
|
-
function useFrame(callback, priorityOrOptions) {
|
|
882
|
+
function useFrame$1(callback, priorityOrOptions) {
|
|
1142
883
|
const store = React.useContext(context);
|
|
1143
884
|
const isInsideCanvas = store !== null;
|
|
1144
885
|
const scheduler = getScheduler();
|
|
@@ -1243,6 +984,13 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1243
984
|
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1244
985
|
*/
|
|
1245
986
|
scheduler: scheduler2,
|
|
987
|
+
/**
|
|
988
|
+
* The root that currently owns this job. Resolve on access because ambient
|
|
989
|
+
* jobs can be adopted by a Canvas after the controls object is created.
|
|
990
|
+
*/
|
|
991
|
+
get rootId() {
|
|
992
|
+
return getScheduler().getJobRootId(id);
|
|
993
|
+
},
|
|
1246
994
|
/**
|
|
1247
995
|
* Manually step this job only.
|
|
1248
996
|
* Bypasses FPS limiting - always runs.
|
|
@@ -1259,6 +1007,14 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
1259
1007
|
stepAll: (timestamp) => {
|
|
1260
1008
|
getScheduler().step(timestamp);
|
|
1261
1009
|
},
|
|
1010
|
+
/**
|
|
1011
|
+
* Request frames for this job's owning root without waking sibling roots.
|
|
1012
|
+
*/
|
|
1013
|
+
invalidate: (frames, stackFrames) => {
|
|
1014
|
+
const scheduler3 = getScheduler();
|
|
1015
|
+
const rootId = scheduler3.getJobRootId(id);
|
|
1016
|
+
if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
|
|
1017
|
+
},
|
|
1262
1018
|
/**
|
|
1263
1019
|
* Pause this job (set enabled=false).
|
|
1264
1020
|
* Job remains registered but won't run.
|
|
@@ -1288,6 +1044,11 @@ function getUrls(input) {
|
|
|
1288
1044
|
if (Array.isArray(input)) return input;
|
|
1289
1045
|
return Object.values(input);
|
|
1290
1046
|
}
|
|
1047
|
+
function inputSignature(input) {
|
|
1048
|
+
if (typeof input === "string") return input;
|
|
1049
|
+
if (Array.isArray(input)) return input.join("\0");
|
|
1050
|
+
return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
|
|
1051
|
+
}
|
|
1291
1052
|
function allUrlsCached(urls, textureCache) {
|
|
1292
1053
|
return urls.every((url) => textureCache.has(url));
|
|
1293
1054
|
}
|
|
@@ -1306,31 +1067,44 @@ function buildFromCache(input, textureCache) {
|
|
|
1306
1067
|
}
|
|
1307
1068
|
}
|
|
1308
1069
|
function useTexture(input, optionsOrOnLoad) {
|
|
1309
|
-
const renderer = useThree((state) => state.internal.actualRenderer);
|
|
1070
|
+
const renderer = useThree$1((state) => state.internal.actualRenderer);
|
|
1310
1071
|
const store = useStore();
|
|
1311
1072
|
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
1312
1073
|
const { onLoad, cache = true } = options;
|
|
1313
1074
|
const onLoadRef = useRef(onLoad);
|
|
1314
1075
|
onLoadRef.current = onLoad;
|
|
1315
1076
|
const onLoadCalledForRef = useRef(null);
|
|
1316
|
-
const
|
|
1077
|
+
const inputKey = useMemo(() => inputSignature(input), [input]);
|
|
1078
|
+
const stableInput = useMemo(() => input, [inputKey]);
|
|
1079
|
+
const urls = useMemo(() => getUrls(stableInput), [stableInput]);
|
|
1317
1080
|
const cachedResult = useMemo(() => {
|
|
1318
1081
|
if (!cache) return null;
|
|
1319
1082
|
const textures = store.getState().textures;
|
|
1320
1083
|
if (!allUrlsCached(urls, textures)) return null;
|
|
1321
|
-
return buildFromCache(
|
|
1322
|
-
}, [cache, urls,
|
|
1084
|
+
return buildFromCache(stableInput, textures);
|
|
1085
|
+
}, [cache, urls, stableInput, store]);
|
|
1323
1086
|
const loadedTextures = useLoader(
|
|
1324
1087
|
TextureLoader,
|
|
1325
|
-
IsObject(
|
|
1088
|
+
IsObject(stableInput) ? Object.values(stableInput) : stableInput
|
|
1326
1089
|
);
|
|
1327
|
-
const
|
|
1090
|
+
const mappedTextures = useMemo(() => {
|
|
1091
|
+
if (cachedResult) return cachedResult;
|
|
1092
|
+
if (IsObject(stableInput)) {
|
|
1093
|
+
const keyed = {};
|
|
1094
|
+
const textureArray = loadedTextures;
|
|
1095
|
+
let i = 0;
|
|
1096
|
+
for (const key in stableInput) keyed[key] = textureArray[i++];
|
|
1097
|
+
return keyed;
|
|
1098
|
+
} else {
|
|
1099
|
+
return loadedTextures;
|
|
1100
|
+
}
|
|
1101
|
+
}, [stableInput, loadedTextures, cachedResult]);
|
|
1328
1102
|
useLayoutEffect(() => {
|
|
1329
1103
|
if (cachedResult) return;
|
|
1330
1104
|
if (onLoadCalledForRef.current === inputKey) return;
|
|
1331
1105
|
onLoadCalledForRef.current = inputKey;
|
|
1332
|
-
onLoadRef.current?.(
|
|
1333
|
-
}, [cachedResult,
|
|
1106
|
+
onLoadRef.current?.(mappedTextures);
|
|
1107
|
+
}, [cachedResult, mappedTextures, inputKey]);
|
|
1334
1108
|
useEffect(() => {
|
|
1335
1109
|
if (cachedResult) return;
|
|
1336
1110
|
if ("initTexture" in renderer) {
|
|
@@ -1349,30 +1123,18 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1349
1123
|
});
|
|
1350
1124
|
}
|
|
1351
1125
|
}, [renderer, loadedTextures, cachedResult]);
|
|
1352
|
-
const mappedTextures = useMemo(() => {
|
|
1353
|
-
if (cachedResult) return cachedResult;
|
|
1354
|
-
if (IsObject(input)) {
|
|
1355
|
-
const keyed = {};
|
|
1356
|
-
const textureArray = loadedTextures;
|
|
1357
|
-
let i = 0;
|
|
1358
|
-
for (const key in input) keyed[key] = textureArray[i++];
|
|
1359
|
-
return keyed;
|
|
1360
|
-
} else {
|
|
1361
|
-
return loadedTextures;
|
|
1362
|
-
}
|
|
1363
|
-
}, [input, loadedTextures, cachedResult]);
|
|
1364
1126
|
useEffect(() => {
|
|
1365
1127
|
if (!cache) return;
|
|
1366
1128
|
const urlTextureMap = [];
|
|
1367
|
-
if (typeof
|
|
1368
|
-
urlTextureMap.push([
|
|
1369
|
-
} else if (Array.isArray(
|
|
1129
|
+
if (typeof stableInput === "string") {
|
|
1130
|
+
urlTextureMap.push([stableInput, mappedTextures]);
|
|
1131
|
+
} else if (Array.isArray(stableInput)) {
|
|
1370
1132
|
const textureArray = mappedTextures;
|
|
1371
|
-
|
|
1372
|
-
} else if (IsObject(
|
|
1133
|
+
stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1134
|
+
} else if (IsObject(stableInput)) {
|
|
1373
1135
|
const textureRecord = mappedTextures;
|
|
1374
|
-
for (const key in
|
|
1375
|
-
const url =
|
|
1136
|
+
for (const key in stableInput) {
|
|
1137
|
+
const url = stableInput[key];
|
|
1376
1138
|
urlTextureMap.push([url, textureRecord[key]]);
|
|
1377
1139
|
}
|
|
1378
1140
|
}
|
|
@@ -1401,7 +1163,7 @@ function useTexture(input, optionsOrOnLoad) {
|
|
|
1401
1163
|
}
|
|
1402
1164
|
return { _textureRefs: refs };
|
|
1403
1165
|
});
|
|
1404
|
-
}, [cache,
|
|
1166
|
+
}, [cache, stableInput, mappedTextures, store]);
|
|
1405
1167
|
return mappedTextures;
|
|
1406
1168
|
}
|
|
1407
1169
|
useTexture.preload = (url) => useLoader.preload(TextureLoader, url);
|
|
@@ -1472,13 +1234,13 @@ function useTextures(selector) {
|
|
|
1472
1234
|
};
|
|
1473
1235
|
}, [store]);
|
|
1474
1236
|
const subscribe = selector ? () => selector(registry) : (state) => state.textures;
|
|
1475
|
-
const selected = useThree(subscribe);
|
|
1237
|
+
const selected = useThree$1(subscribe);
|
|
1476
1238
|
return selector ? selected : registry;
|
|
1477
1239
|
}
|
|
1478
1240
|
|
|
1479
1241
|
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
1480
|
-
const isLegacy = useThree((s) => s.isLegacy);
|
|
1481
|
-
const size = useThree((s) => s.size);
|
|
1242
|
+
const isLegacy = useThree$1((s) => s.isLegacy);
|
|
1243
|
+
const size = useThree$1((s) => s.size);
|
|
1482
1244
|
let width;
|
|
1483
1245
|
let height;
|
|
1484
1246
|
let opts;
|
|
@@ -1535,7 +1297,7 @@ function useEnvironment({
|
|
|
1535
1297
|
const { extension, isCubemap } = getExtension(files);
|
|
1536
1298
|
const loader = getLoader(extension);
|
|
1537
1299
|
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1538
|
-
const renderer = useThree((state) => state.renderer);
|
|
1300
|
+
const renderer = useThree$1((state) => state.renderer);
|
|
1539
1301
|
useLayoutEffect(() => {
|
|
1540
1302
|
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
1541
1303
|
function clearGainmapTexture() {
|
|
@@ -1562,7 +1324,7 @@ function useEnvironment({
|
|
|
1562
1324
|
texture = texture.renderTarget?.texture;
|
|
1563
1325
|
}
|
|
1564
1326
|
texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
|
|
1565
|
-
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
1327
|
+
texture.colorSpace = colorSpace ?? (isCubemap && extension !== "hdr-cube" ? "srgb" : "srgb-linear");
|
|
1566
1328
|
return texture;
|
|
1567
1329
|
}
|
|
1568
1330
|
const preloadDefaultOptions = {
|
|
@@ -1615,22 +1377,15 @@ function getExtension(files) {
|
|
|
1615
1377
|
const isCubemap = isArray(files) && files.length === 6;
|
|
1616
1378
|
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
1617
1379
|
const firstEntry = isArray(files) ? files[0] : files;
|
|
1618
|
-
const
|
|
1380
|
+
const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
1381
|
+
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;
|
|
1619
1382
|
return { extension, isCubemap, isGainmap };
|
|
1620
1383
|
}
|
|
1621
1384
|
function getLoader(extension) {
|
|
1622
|
-
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
1385
|
+
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr-cube" ? HDRCubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
1623
1386
|
return loader;
|
|
1624
1387
|
}
|
|
1625
1388
|
|
|
1626
|
-
function useStore() {
|
|
1627
|
-
const store = useContext(context);
|
|
1628
|
-
if (!store) throw new Error("R3F: Hooks can only be used within the Canvas component!");
|
|
1629
|
-
return store;
|
|
1630
|
-
}
|
|
1631
|
-
function useThree(selector = (state) => state, equalityFn) {
|
|
1632
|
-
return useStore()(selector, equalityFn);
|
|
1633
|
-
}
|
|
1634
1389
|
function useInstanceHandle(ref) {
|
|
1635
1390
|
const instance = useRef(null);
|
|
1636
1391
|
useImperativeHandle(instance, () => ref.current.__r3f, [ref]);
|
|
@@ -1670,22 +1425,28 @@ function addTail(callback) {
|
|
|
1670
1425
|
return getScheduler().onIdle(callback);
|
|
1671
1426
|
}
|
|
1672
1427
|
function invalidate(state, frames = 1, stackFrames = false) {
|
|
1673
|
-
|
|
1428
|
+
const rootId = state?.internal?.rootId;
|
|
1429
|
+
const scheduler = getScheduler();
|
|
1430
|
+
if (rootId) scheduler.invalidateRoot(rootId, frames, stackFrames);
|
|
1431
|
+
else scheduler.invalidate(frames, stackFrames);
|
|
1674
1432
|
}
|
|
1675
|
-
function advance(timestamp) {
|
|
1676
|
-
|
|
1433
|
+
function advance(timestamp, runGlobalEffects, state) {
|
|
1434
|
+
const rootId = state?.internal?.rootId;
|
|
1435
|
+
const scheduler = getScheduler();
|
|
1436
|
+
if (rootId) scheduler.stepRoot(rootId, timestamp);
|
|
1437
|
+
else scheduler.step(timestamp);
|
|
1677
1438
|
}
|
|
1678
1439
|
|
|
1679
|
-
const version = "10.0.0-alpha.
|
|
1440
|
+
const version = "10.0.0-alpha.5";
|
|
1680
1441
|
const packageData = {
|
|
1681
1442
|
version: version};
|
|
1682
1443
|
|
|
1683
1444
|
function Xb(Tt) {
|
|
1684
1445
|
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
1685
1446
|
}
|
|
1686
|
-
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
1447
|
+
var Rm = { exports: {} }, Og = { exports: {} }, _b$1;
|
|
1687
1448
|
function Kb() {
|
|
1688
|
-
return _b || (_b = 1, (function(Tt) {
|
|
1449
|
+
return _b$1 || (_b$1 = 1, (function(Tt) {
|
|
1689
1450
|
Tt.exports = function(m) {
|
|
1690
1451
|
function Yn(t, r, a, l) {
|
|
1691
1452
|
return new uc(t, r, a, l);
|
|
@@ -13535,7 +13296,10 @@ function extend(objects) {
|
|
|
13535
13296
|
catalogue[Component] = objects;
|
|
13536
13297
|
return Component;
|
|
13537
13298
|
} else {
|
|
13538
|
-
|
|
13299
|
+
for (const name in objects) {
|
|
13300
|
+
const object = objects[name];
|
|
13301
|
+
if (isConstructor(object)) catalogue[name] = object;
|
|
13302
|
+
}
|
|
13539
13303
|
}
|
|
13540
13304
|
}
|
|
13541
13305
|
function validateInstance(type, props) {
|
|
@@ -13883,7 +13647,7 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13883
13647
|
getRootHostContext: () => NO_CONTEXT,
|
|
13884
13648
|
getChildHostContext: () => NO_CONTEXT,
|
|
13885
13649
|
commitUpdate(instance, type, oldProps, newProps, fiber) {
|
|
13886
|
-
validateInstance(type, newProps);
|
|
13650
|
+
validateInstance(instance.type, newProps);
|
|
13887
13651
|
let reconstruct = false;
|
|
13888
13652
|
if (instance.type === "primitive" && oldProps.object !== newProps.object) reconstruct = true;
|
|
13889
13653
|
else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
|
|
@@ -13910,8 +13674,8 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13910
13674
|
for (const prop in instance.props) {
|
|
13911
13675
|
const value = instance.props[prop];
|
|
13912
13676
|
if (isFromRef(value)) {
|
|
13913
|
-
const ref = value
|
|
13914
|
-
if (ref.current != null) resolved[prop] = ref.current;
|
|
13677
|
+
const { [FROM_REF]: ref, transform } = value;
|
|
13678
|
+
if (ref.current != null) resolved[prop] = transform ? transform(ref.current) : ref.current;
|
|
13915
13679
|
}
|
|
13916
13680
|
}
|
|
13917
13681
|
if (Object.keys(resolved).length) applyProps(instance.object, resolved);
|
|
@@ -14055,6 +13819,335 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14055
13819
|
getSuspendedCommitReason: (_state, _rootContainer) => null
|
|
14056
13820
|
});
|
|
14057
13821
|
|
|
13822
|
+
const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
|
|
13823
|
+
function isInternalRendererAccess(stack, callerDepth = 2) {
|
|
13824
|
+
if (!stack) return false;
|
|
13825
|
+
const caller = stack.split("\n")[callerDepth] ?? "";
|
|
13826
|
+
return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
|
|
13827
|
+
}
|
|
13828
|
+
|
|
13829
|
+
const createStore = (invalidate, advance) => {
|
|
13830
|
+
const rootStore = createWithEqualityFn((set, get) => {
|
|
13831
|
+
const position = new Vector3();
|
|
13832
|
+
const defaultTarget = new Vector3();
|
|
13833
|
+
const tempTarget = new Vector3();
|
|
13834
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
13835
|
+
const { width, height, top, left } = size;
|
|
13836
|
+
const aspect = width / height;
|
|
13837
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
13838
|
+
else tempTarget.set(...target);
|
|
13839
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
13840
|
+
if (isOrthographicCamera(camera)) {
|
|
13841
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
13842
|
+
} else {
|
|
13843
|
+
const fov = camera.fov * Math.PI / 180;
|
|
13844
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
13845
|
+
const w = h * (width / height);
|
|
13846
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
13847
|
+
}
|
|
13848
|
+
}
|
|
13849
|
+
let performanceTimeout = void 0;
|
|
13850
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
13851
|
+
const pointer = new Vector2();
|
|
13852
|
+
const rootState = {
|
|
13853
|
+
set,
|
|
13854
|
+
get,
|
|
13855
|
+
// Mock objects that have to be configured
|
|
13856
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
13857
|
+
primaryStore: null,
|
|
13858
|
+
gl: null,
|
|
13859
|
+
renderer: null,
|
|
13860
|
+
camera: null,
|
|
13861
|
+
frustum: new Frustum(),
|
|
13862
|
+
autoUpdateFrustum: true,
|
|
13863
|
+
raycaster: null,
|
|
13864
|
+
events: {
|
|
13865
|
+
priority: 1,
|
|
13866
|
+
enabled: true,
|
|
13867
|
+
connected: false,
|
|
13868
|
+
frameTimedRaycasts: true,
|
|
13869
|
+
alwaysFireOnScroll: true,
|
|
13870
|
+
updateOnFrame: false
|
|
13871
|
+
},
|
|
13872
|
+
scene: null,
|
|
13873
|
+
rootScene: null,
|
|
13874
|
+
xr: null,
|
|
13875
|
+
inspector: null,
|
|
13876
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
13877
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
13878
|
+
textureColorSpace: SRGBColorSpace,
|
|
13879
|
+
isLegacy: false,
|
|
13880
|
+
webGPUSupported: false,
|
|
13881
|
+
isNative: false,
|
|
13882
|
+
controls: null,
|
|
13883
|
+
pointer,
|
|
13884
|
+
mouse: pointer,
|
|
13885
|
+
frameloop: "always",
|
|
13886
|
+
onPointerMissed: void 0,
|
|
13887
|
+
onDragOverMissed: void 0,
|
|
13888
|
+
onDropMissed: void 0,
|
|
13889
|
+
performance: {
|
|
13890
|
+
current: 1,
|
|
13891
|
+
min: 0.5,
|
|
13892
|
+
max: 1,
|
|
13893
|
+
debounce: 200,
|
|
13894
|
+
regress: () => {
|
|
13895
|
+
const state2 = get();
|
|
13896
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
13897
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
13898
|
+
performanceTimeout = setTimeout(
|
|
13899
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
13900
|
+
state2.performance.debounce
|
|
13901
|
+
);
|
|
13902
|
+
}
|
|
13903
|
+
},
|
|
13904
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
13905
|
+
viewport: {
|
|
13906
|
+
initialDpr: 0,
|
|
13907
|
+
dpr: 0,
|
|
13908
|
+
width: 0,
|
|
13909
|
+
height: 0,
|
|
13910
|
+
top: 0,
|
|
13911
|
+
left: 0,
|
|
13912
|
+
aspect: 0,
|
|
13913
|
+
distance: 0,
|
|
13914
|
+
factor: 0,
|
|
13915
|
+
getCurrentViewport
|
|
13916
|
+
},
|
|
13917
|
+
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
13918
|
+
setSize: (width, height, top, left) => {
|
|
13919
|
+
const state2 = get();
|
|
13920
|
+
if (width === void 0) {
|
|
13921
|
+
set({ _sizeImperative: false });
|
|
13922
|
+
if (state2._sizeProps) {
|
|
13923
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
13924
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
13925
|
+
const currentSize = state2.size;
|
|
13926
|
+
const newSize = {
|
|
13927
|
+
width: propW ?? currentSize.width,
|
|
13928
|
+
height: propH ?? currentSize.height,
|
|
13929
|
+
top: currentSize.top,
|
|
13930
|
+
left: currentSize.left
|
|
13931
|
+
};
|
|
13932
|
+
set((s) => ({
|
|
13933
|
+
size: newSize,
|
|
13934
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
13935
|
+
}));
|
|
13936
|
+
get().invalidate();
|
|
13937
|
+
}
|
|
13938
|
+
}
|
|
13939
|
+
return;
|
|
13940
|
+
}
|
|
13941
|
+
const w = width;
|
|
13942
|
+
const h = height ?? width;
|
|
13943
|
+
const t = top ?? state2.size.top;
|
|
13944
|
+
const l = left ?? state2.size.left;
|
|
13945
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
13946
|
+
set((s) => ({
|
|
13947
|
+
size,
|
|
13948
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
13949
|
+
_sizeImperative: true
|
|
13950
|
+
}));
|
|
13951
|
+
get().invalidate();
|
|
13952
|
+
},
|
|
13953
|
+
setDpr: (dpr) => set((state2) => {
|
|
13954
|
+
const resolved = calculateDpr(dpr);
|
|
13955
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
13956
|
+
}),
|
|
13957
|
+
setFrameloop: (frameloop = "always") => {
|
|
13958
|
+
const rootId = get().internal.rootId;
|
|
13959
|
+
if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
|
|
13960
|
+
set(() => ({ frameloop }));
|
|
13961
|
+
},
|
|
13962
|
+
setError: (error) => set(() => ({ error })),
|
|
13963
|
+
error: null,
|
|
13964
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useBuffers, useGPUStorage, useTextures, useRenderPipeline) ==============================
|
|
13965
|
+
uniforms: {},
|
|
13966
|
+
nodes: {},
|
|
13967
|
+
buffers: {},
|
|
13968
|
+
gpuStorage: {},
|
|
13969
|
+
textures: /* @__PURE__ */ new Map(),
|
|
13970
|
+
_textureRefs: /* @__PURE__ */ new Map(),
|
|
13971
|
+
renderPipeline: null,
|
|
13972
|
+
passes: {},
|
|
13973
|
+
_hmrVersion: 0,
|
|
13974
|
+
_sizeImperative: false,
|
|
13975
|
+
_sizeProps: null,
|
|
13976
|
+
previousRoot: void 0,
|
|
13977
|
+
internal: {
|
|
13978
|
+
// Events
|
|
13979
|
+
interaction: [],
|
|
13980
|
+
subscribers: [],
|
|
13981
|
+
// Per-pointer state (new unified structure)
|
|
13982
|
+
pointerMap: /* @__PURE__ */ new Map(),
|
|
13983
|
+
pointerDirty: /* @__PURE__ */ new Map(),
|
|
13984
|
+
lastEvent: React.createRef(),
|
|
13985
|
+
// Deprecated but kept for backwards compatibility
|
|
13986
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
13987
|
+
initialClick: [0, 0],
|
|
13988
|
+
initialHits: [],
|
|
13989
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
13990
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
13991
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
13992
|
+
// Occlusion system (WebGPU only)
|
|
13993
|
+
occlusionEnabled: false,
|
|
13994
|
+
occlusionObserver: null,
|
|
13995
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
13996
|
+
helperGroup: null,
|
|
13997
|
+
// Updates
|
|
13998
|
+
active: false,
|
|
13999
|
+
frames: 0,
|
|
14000
|
+
priority: 0,
|
|
14001
|
+
subscribe: (ref, priority, store) => {
|
|
14002
|
+
const internal = get().internal;
|
|
14003
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
14004
|
+
internal.subscribers.push({ ref, priority, store });
|
|
14005
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
14006
|
+
return () => {
|
|
14007
|
+
const internal2 = get().internal;
|
|
14008
|
+
if (internal2?.subscribers) {
|
|
14009
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
14010
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
14011
|
+
}
|
|
14012
|
+
};
|
|
14013
|
+
},
|
|
14014
|
+
// Renderer Storage (single source of truth)
|
|
14015
|
+
actualRenderer: null,
|
|
14016
|
+
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
14017
|
+
scheduler: null,
|
|
14018
|
+
// Replaces the default render call when set (see setRenderOverride)
|
|
14019
|
+
renderOverride: null
|
|
14020
|
+
}
|
|
14021
|
+
};
|
|
14022
|
+
return rootState;
|
|
14023
|
+
});
|
|
14024
|
+
const state = rootStore.getState();
|
|
14025
|
+
Object.defineProperty(state, "gl", {
|
|
14026
|
+
get() {
|
|
14027
|
+
const currentState = rootStore.getState();
|
|
14028
|
+
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
14029
|
+
const stack = new Error().stack || "";
|
|
14030
|
+
if (!isInternalRendererAccess(stack)) {
|
|
14031
|
+
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
14032
|
+
notifyDepreciated({
|
|
14033
|
+
heading: "Accessing state.gl in WebGPU mode",
|
|
14034
|
+
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
|
|
14035
|
+
});
|
|
14036
|
+
}
|
|
14037
|
+
}
|
|
14038
|
+
return currentState.internal.actualRenderer;
|
|
14039
|
+
},
|
|
14040
|
+
set(value) {
|
|
14041
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
14042
|
+
},
|
|
14043
|
+
enumerable: true,
|
|
14044
|
+
configurable: true
|
|
14045
|
+
});
|
|
14046
|
+
Object.defineProperty(state, "renderer", {
|
|
14047
|
+
get() {
|
|
14048
|
+
return rootStore.getState().internal.actualRenderer;
|
|
14049
|
+
},
|
|
14050
|
+
set(value) {
|
|
14051
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
14052
|
+
},
|
|
14053
|
+
enumerable: true,
|
|
14054
|
+
configurable: true
|
|
14055
|
+
});
|
|
14056
|
+
let oldScene = state.scene;
|
|
14057
|
+
rootStore.subscribe(() => {
|
|
14058
|
+
const currentState = rootStore.getState();
|
|
14059
|
+
const { scene, rootScene, set } = currentState;
|
|
14060
|
+
if (scene !== oldScene) {
|
|
14061
|
+
oldScene = scene;
|
|
14062
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
14063
|
+
set({ rootScene: scene });
|
|
14064
|
+
}
|
|
14065
|
+
}
|
|
14066
|
+
});
|
|
14067
|
+
let oldSize = state.size;
|
|
14068
|
+
let oldDpr = state.viewport.dpr;
|
|
14069
|
+
let oldCamera = state.camera;
|
|
14070
|
+
rootStore.subscribe(() => {
|
|
14071
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
14072
|
+
const actualRenderer = internal.actualRenderer;
|
|
14073
|
+
const canvasTarget = internal.canvasTarget;
|
|
14074
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
14075
|
+
oldSize = size;
|
|
14076
|
+
oldDpr = viewport.dpr;
|
|
14077
|
+
updateCamera(camera, size);
|
|
14078
|
+
const resizeTarget = canvasTarget ?? actualRenderer;
|
|
14079
|
+
if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
|
|
14080
|
+
resizeTarget.setSize(size.width, size.height, false);
|
|
14081
|
+
const activeTarget = actualRenderer.getCanvasTarget?.();
|
|
14082
|
+
if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
|
|
14083
|
+
}
|
|
14084
|
+
if (camera !== oldCamera) {
|
|
14085
|
+
oldCamera = camera;
|
|
14086
|
+
const { rootScene } = rootStore.getState();
|
|
14087
|
+
if (camera && rootScene && !camera.parent) {
|
|
14088
|
+
rootScene.add(camera);
|
|
14089
|
+
}
|
|
14090
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
14091
|
+
const currentState = rootStore.getState();
|
|
14092
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
14093
|
+
updateFrustum(camera, currentState.frustum);
|
|
14094
|
+
}
|
|
14095
|
+
}
|
|
14096
|
+
});
|
|
14097
|
+
rootStore.subscribe((state2) => invalidate(state2));
|
|
14098
|
+
return rootStore;
|
|
14099
|
+
};
|
|
14100
|
+
|
|
14101
|
+
const R3F_EXTENSIONS = Symbol.for("@react-three/fiber.extensions");
|
|
14102
|
+
function getRegistry() {
|
|
14103
|
+
return globalThis[R3F_EXTENSIONS] ?? (globalThis[R3F_EXTENSIONS] = {
|
|
14104
|
+
extensions: /* @__PURE__ */ new Map(),
|
|
14105
|
+
roots: /* @__PURE__ */ new Set(),
|
|
14106
|
+
applied: /* @__PURE__ */ new WeakMap()
|
|
14107
|
+
});
|
|
14108
|
+
}
|
|
14109
|
+
function setupRoot(registry, store, extension) {
|
|
14110
|
+
let applied = registry.applied.get(store);
|
|
14111
|
+
if (!applied) registry.applied.set(store, applied = /* @__PURE__ */ new Map());
|
|
14112
|
+
if (applied.has(extension.name)) return;
|
|
14113
|
+
applied.set(extension.name, extension);
|
|
14114
|
+
const patch = extension.setup?.(store);
|
|
14115
|
+
if (patch) store.setState(patch);
|
|
14116
|
+
}
|
|
14117
|
+
function registerRootExtension(extension) {
|
|
14118
|
+
const registry = getRegistry();
|
|
14119
|
+
registry.extensions.set(extension.name, extension);
|
|
14120
|
+
for (const store of registry.roots) setupRoot(registry, store, extension);
|
|
14121
|
+
return () => {
|
|
14122
|
+
if (registry.extensions.get(extension.name) === extension) registry.extensions.delete(extension.name);
|
|
14123
|
+
};
|
|
14124
|
+
}
|
|
14125
|
+
function setRenderOverride(store, render) {
|
|
14126
|
+
store.getState().internal.renderOverride = render;
|
|
14127
|
+
}
|
|
14128
|
+
function attachRootExtensions(store) {
|
|
14129
|
+
const registry = getRegistry();
|
|
14130
|
+
registry.roots.add(store);
|
|
14131
|
+
for (const extension of registry.extensions.values()) setupRoot(registry, store, extension);
|
|
14132
|
+
}
|
|
14133
|
+
function current(registry, setUpBy) {
|
|
14134
|
+
return registry.extensions.get(setUpBy.name) ?? setUpBy;
|
|
14135
|
+
}
|
|
14136
|
+
function detachRootExtensions(store) {
|
|
14137
|
+
const registry = getRegistry();
|
|
14138
|
+
if (!registry.roots.delete(store)) return;
|
|
14139
|
+
const applied = registry.applied.get(store);
|
|
14140
|
+
registry.applied.delete(store);
|
|
14141
|
+
if (!applied) return;
|
|
14142
|
+
for (const setUpBy of applied.values()) current(registry, setUpBy).dispose?.(store);
|
|
14143
|
+
}
|
|
14144
|
+
function notifyRootExtensionsHmr(store) {
|
|
14145
|
+
const registry = getRegistry();
|
|
14146
|
+
const applied = registry.applied.get(store);
|
|
14147
|
+
if (!applied) return;
|
|
14148
|
+
for (const setUpBy of applied.values()) current(registry, setUpBy).hmr?.(store);
|
|
14149
|
+
}
|
|
14150
|
+
|
|
14058
14151
|
const isRenderer = (def) => !!def?.render;
|
|
14059
14152
|
const _roots = /* @__PURE__ */ new Map();
|
|
14060
14153
|
const shallowLoose = { objects: "shallow", strict: false };
|
|
@@ -14192,9 +14285,8 @@ function createRoot(canvas) {
|
|
|
14192
14285
|
if (!renderer.hasInitialized?.()) {
|
|
14193
14286
|
const size2 = computeInitialSize(canvas, propsSize);
|
|
14194
14287
|
if (size2.width > 0 && size2.height > 0) {
|
|
14195
|
-
|
|
14196
|
-
|
|
14197
|
-
canvas.height = size2.height * pixelRatio;
|
|
14288
|
+
renderer.setPixelRatio(calculateDpr(dpr));
|
|
14289
|
+
renderer.setSize(size2.width, size2.height, false);
|
|
14198
14290
|
}
|
|
14199
14291
|
await renderer.init();
|
|
14200
14292
|
}
|
|
@@ -14203,7 +14295,7 @@ function createRoot(canvas) {
|
|
|
14203
14295
|
state.internal.actualRenderer = renderer;
|
|
14204
14296
|
state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
|
|
14205
14297
|
if (canvasId && !state.internal.isSecondary) {
|
|
14206
|
-
const canvasTarget =
|
|
14298
|
+
const canvasTarget = renderer.getCanvasTarget?.();
|
|
14207
14299
|
const unregisterPrimary = registerPrimary(canvasId, renderer, store);
|
|
14208
14300
|
state.set((prev) => ({
|
|
14209
14301
|
internal: {
|
|
@@ -14317,7 +14409,7 @@ function createRoot(canvas) {
|
|
|
14317
14409
|
const handleXRFrame = (timestamp, _frame) => {
|
|
14318
14410
|
const state2 = store.getState();
|
|
14319
14411
|
if (state2.frameloop === "never") return;
|
|
14320
|
-
advance(timestamp);
|
|
14412
|
+
advance(timestamp, true, state2);
|
|
14321
14413
|
};
|
|
14322
14414
|
const actualRenderer = state.internal.actualRenderer;
|
|
14323
14415
|
const handleSessionChange = () => {
|
|
@@ -14325,7 +14417,7 @@ function createRoot(canvas) {
|
|
|
14325
14417
|
const renderer2 = state2.internal.actualRenderer;
|
|
14326
14418
|
actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
|
|
14327
14419
|
renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
|
|
14328
|
-
if (!renderer2.xr.isPresenting) invalidate();
|
|
14420
|
+
if (!renderer2.xr.isPresenting) invalidate(state2);
|
|
14329
14421
|
};
|
|
14330
14422
|
const xr = {
|
|
14331
14423
|
connect() {
|
|
@@ -14407,14 +14499,23 @@ function createRoot(canvas) {
|
|
|
14407
14499
|
const newRootId = canvasId || scheduler.generateRootId();
|
|
14408
14500
|
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14409
14501
|
getState: () => store.getState(),
|
|
14410
|
-
onError: (err) => store.getState().setError(err)
|
|
14502
|
+
onError: (err) => store.getState().setError(err),
|
|
14503
|
+
frameloop: store.getState().frameloop,
|
|
14504
|
+
before: schedulerConfig?.before,
|
|
14505
|
+
after: schedulerConfig?.after,
|
|
14506
|
+
order: schedulerConfig?.order
|
|
14411
14507
|
});
|
|
14412
14508
|
const unregisterCanvasTarget = scheduler.register(
|
|
14413
14509
|
() => {
|
|
14414
14510
|
const state2 = store.getState();
|
|
14415
|
-
|
|
14511
|
+
const canvasTarget = state2.internal.canvasTarget;
|
|
14512
|
+
if (canvasTarget) {
|
|
14416
14513
|
const renderer2 = state2.internal.actualRenderer;
|
|
14417
|
-
renderer2.setCanvasTarget(
|
|
14514
|
+
if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
|
|
14515
|
+
if (state2.internal.canvasTargetSizeDirty) {
|
|
14516
|
+
state2.internal.canvasTargetSizeDirty = false;
|
|
14517
|
+
renderer2.backend?.updateSize?.();
|
|
14518
|
+
}
|
|
14418
14519
|
}
|
|
14419
14520
|
},
|
|
14420
14521
|
{
|
|
@@ -14470,7 +14571,8 @@ function createRoot(canvas) {
|
|
|
14470
14571
|
const userHandlesRender = scheduler.hasUserJobsInPhase("render", newRootId);
|
|
14471
14572
|
if (userHandlesRender || state2.internal.priority) return;
|
|
14472
14573
|
try {
|
|
14473
|
-
|
|
14574
|
+
const renderOverride = state2.internal.renderOverride;
|
|
14575
|
+
if (renderOverride) renderOverride();
|
|
14474
14576
|
else if (renderer2?.render) renderer2.render(state2.scene, state2.camera);
|
|
14475
14577
|
} catch (error) {
|
|
14476
14578
|
state2.setError(error instanceof Error ? error : new Error(String(error)));
|
|
@@ -14483,8 +14585,7 @@ function createRoot(canvas) {
|
|
|
14483
14585
|
phase: "render",
|
|
14484
14586
|
system: true,
|
|
14485
14587
|
// Internal flag: this is a system job, not user-controlled
|
|
14486
|
-
//
|
|
14487
|
-
...schedulerConfig?.after && { after: schedulerConfig.after },
|
|
14588
|
+
// FPS throttles only the default render job; Canvas ordering belongs to the root.
|
|
14488
14589
|
...schedulerConfig?.fps && { fps: schedulerConfig.fps }
|
|
14489
14590
|
}
|
|
14490
14591
|
);
|
|
@@ -14503,8 +14604,22 @@ function createRoot(canvas) {
|
|
|
14503
14604
|
scheduler
|
|
14504
14605
|
}
|
|
14505
14606
|
}));
|
|
14607
|
+
} else {
|
|
14608
|
+
const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
|
|
14609
|
+
if (constraintsChanged) {
|
|
14610
|
+
scheduler.setRootConstraints(rootId, {
|
|
14611
|
+
before: schedulerConfig?.before,
|
|
14612
|
+
after: schedulerConfig?.after
|
|
14613
|
+
});
|
|
14614
|
+
}
|
|
14615
|
+
if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
|
|
14616
|
+
scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
|
|
14617
|
+
}
|
|
14506
14618
|
}
|
|
14507
|
-
|
|
14619
|
+
lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
|
|
14620
|
+
lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
|
|
14621
|
+
lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
|
|
14622
|
+
attachRootExtensions(store);
|
|
14508
14623
|
onCreated = onCreatedCallback;
|
|
14509
14624
|
configured = true;
|
|
14510
14625
|
resolve();
|
|
@@ -14546,18 +14661,24 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14546
14661
|
const fiber = root?.fiber;
|
|
14547
14662
|
if (fiber) {
|
|
14548
14663
|
const state = root?.store.getState();
|
|
14549
|
-
if (state)
|
|
14664
|
+
if (state) {
|
|
14665
|
+
state.internal.active = false;
|
|
14666
|
+
const unregisterRoot = state.internal.unregisterRoot;
|
|
14667
|
+
if (unregisterRoot) {
|
|
14668
|
+
unregisterRoot();
|
|
14669
|
+
state.internal.unregisterRoot = void 0;
|
|
14670
|
+
}
|
|
14671
|
+
}
|
|
14550
14672
|
reconciler.updateContainer(null, fiber, null, () => {
|
|
14673
|
+
if (root?.store) detachRootExtensions(root.store);
|
|
14551
14674
|
if (state) {
|
|
14552
14675
|
setTimeout(() => {
|
|
14553
14676
|
try {
|
|
14554
14677
|
const renderer = state.internal.actualRenderer;
|
|
14555
|
-
const unregisterRoot = state.internal.unregisterRoot;
|
|
14556
|
-
if (unregisterRoot) unregisterRoot();
|
|
14557
14678
|
const unregisterPrimary = state.internal.unregisterPrimary;
|
|
14558
14679
|
if (unregisterPrimary) unregisterPrimary();
|
|
14559
14680
|
const canvasTarget = state.internal.canvasTarget;
|
|
14560
|
-
if (canvasTarget?.dispose) canvasTarget.dispose();
|
|
14681
|
+
if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
|
|
14561
14682
|
state.events.disconnect?.();
|
|
14562
14683
|
cleanupHelperGroup(root.store);
|
|
14563
14684
|
if (state.isLegacy && renderer) {
|
|
@@ -14698,16 +14819,11 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
|
|
|
14698
14819
|
const oldbg = target.background;
|
|
14699
14820
|
const oldenv = target.environment;
|
|
14700
14821
|
const oldSceneProps = {
|
|
14701
|
-
// @ts-ignore
|
|
14702
14822
|
backgroundBlurriness: target.backgroundBlurriness,
|
|
14703
|
-
// @ts-ignore
|
|
14704
14823
|
backgroundIntensity: target.backgroundIntensity,
|
|
14705
|
-
|
|
14706
|
-
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
14707
|
-
// @ts-ignore
|
|
14824
|
+
backgroundRotation: target.backgroundRotation.clone(),
|
|
14708
14825
|
environmentIntensity: target.environmentIntensity,
|
|
14709
|
-
|
|
14710
|
-
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
14826
|
+
environmentRotation: target.environmentRotation.clone()
|
|
14711
14827
|
};
|
|
14712
14828
|
if (background !== "only") target.environment = texture;
|
|
14713
14829
|
if (background) target.background = texture;
|
|
@@ -14719,7 +14835,7 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
|
|
|
14719
14835
|
};
|
|
14720
14836
|
}
|
|
14721
14837
|
function EnvironmentMap({ scene, background = false, map, ...config }) {
|
|
14722
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14838
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14723
14839
|
React.useLayoutEffect(() => {
|
|
14724
14840
|
if (map) return setEnvProps(background, scene, defaultScene, map, config);
|
|
14725
14841
|
});
|
|
@@ -14737,7 +14853,7 @@ function EnvironmentCube({
|
|
|
14737
14853
|
...rest
|
|
14738
14854
|
}) {
|
|
14739
14855
|
const texture = useEnvironment(rest);
|
|
14740
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14856
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14741
14857
|
React.useLayoutEffect(() => {
|
|
14742
14858
|
return setEnvProps(background, scene, defaultScene, texture, {
|
|
14743
14859
|
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
@@ -14774,9 +14890,9 @@ function EnvironmentPortal({
|
|
|
14774
14890
|
preset = void 0,
|
|
14775
14891
|
extensions
|
|
14776
14892
|
}) {
|
|
14777
|
-
const renderer = useThree((state) => state.renderer);
|
|
14778
|
-
const isLegacy = useThree((state) => state.isLegacy);
|
|
14779
|
-
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);
|
|
14780
14896
|
const camera = React.useRef(null);
|
|
14781
14897
|
const [virtualScene] = React.useState(() => new Scene());
|
|
14782
14898
|
const fbo = React.useMemo(() => {
|
|
@@ -14820,7 +14936,7 @@ function EnvironmentPortal({
|
|
|
14820
14936
|
environmentRotation
|
|
14821
14937
|
]);
|
|
14822
14938
|
let count = 1;
|
|
14823
|
-
useFrame(() => {
|
|
14939
|
+
useFrame$1(() => {
|
|
14824
14940
|
if (frames === Infinity || count < frames) {
|
|
14825
14941
|
const autoClear = renderer.autoClear;
|
|
14826
14942
|
renderer.autoClear = true;
|
|
@@ -14860,7 +14976,7 @@ function EnvironmentGround(props) {
|
|
|
14860
14976
|
] });
|
|
14861
14977
|
}
|
|
14862
14978
|
function EnvironmentColor({ color, scene }) {
|
|
14863
|
-
const defaultScene = useThree((state) => state.scene);
|
|
14979
|
+
const defaultScene = useThree$1((state) => state.scene);
|
|
14864
14980
|
React.useLayoutEffect(() => {
|
|
14865
14981
|
if (color === void 0) return;
|
|
14866
14982
|
const target = resolveScene(scene || defaultScene);
|
|
@@ -14909,156 +15025,27 @@ function parseBackground(background) {
|
|
|
14909
15025
|
return { preset: background, background: true };
|
|
14910
15026
|
}
|
|
14911
15027
|
if (/^(https?:\/\/|\/|\.\/|\.\.\/)|\.(hdr|exr|jpg|jpeg|png|webp|gif)$/i.test(background)) {
|
|
14912
|
-
return { files: background, background: true };
|
|
14913
|
-
}
|
|
14914
|
-
return { color: background, background: true };
|
|
14915
|
-
}
|
|
14916
|
-
if (background.isColor) {
|
|
14917
|
-
return { color: background, background: true };
|
|
14918
|
-
}
|
|
14919
|
-
return null;
|
|
14920
|
-
}
|
|
14921
|
-
|
|
14922
|
-
function parseRendererConfig(rendererProp) {
|
|
14923
|
-
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
14924
|
-
if (isRendererConfig) {
|
|
14925
|
-
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
14926
|
-
return {
|
|
14927
|
-
primaryCanvas: pc,
|
|
14928
|
-
scheduler: sc,
|
|
14929
|
-
renderer: Object.keys(rest).length > 0 ? rest : rendererProp
|
|
14930
|
-
};
|
|
14931
|
-
}
|
|
14932
|
-
return { primaryCanvas: void 0, scheduler: void 0, renderer: rendererProp };
|
|
14933
|
-
}
|
|
14934
|
-
|
|
14935
|
-
const RESOURCE_KINDS = ["nodes", "uniforms", "buffers", "gpuStorage"];
|
|
14936
|
-
const ROOT_SCOPE = "";
|
|
14937
|
-
const registries = /* @__PURE__ */ new WeakMap();
|
|
14938
|
-
function getKindRegistry(store, kind) {
|
|
14939
|
-
let registry = registries.get(store);
|
|
14940
|
-
if (!registry) {
|
|
14941
|
-
registry = {
|
|
14942
|
-
nodes: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14943
|
-
uniforms: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14944
|
-
buffers: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14945
|
-
gpuStorage: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() }
|
|
14946
|
-
};
|
|
14947
|
-
registries.set(store, registry);
|
|
14948
|
-
}
|
|
14949
|
-
return registry[kind];
|
|
14950
|
-
}
|
|
14951
|
-
function resolvePrimary$1(store) {
|
|
14952
|
-
return store.getState().primaryStore ?? store;
|
|
14953
|
-
}
|
|
14954
|
-
function isScopeValid(store, kind, scopeKey) {
|
|
14955
|
-
return getKindRegistry(store, kind).valid.has(scopeKey);
|
|
14956
|
-
}
|
|
14957
|
-
function peekStaged(store, kind, scopeKey) {
|
|
14958
|
-
return getKindRegistry(store, kind).staged.get(scopeKey);
|
|
14959
|
-
}
|
|
14960
|
-
function stageEntries(store, kind, scopeKey, entries) {
|
|
14961
|
-
const { staged } = getKindRegistry(store, kind);
|
|
14962
|
-
const current = staged.get(scopeKey);
|
|
14963
|
-
if (current) Object.assign(current, entries);
|
|
14964
|
-
else staged.set(scopeKey, { ...entries });
|
|
14965
|
-
}
|
|
14966
|
-
function readCommittedScope(map, scopeKey, isLeaf) {
|
|
14967
|
-
if (scopeKey === ROOT_SCOPE) {
|
|
14968
|
-
const leaves = {};
|
|
14969
|
-
for (const [key, value] of Object.entries(map)) if (isLeaf(value)) leaves[key] = value;
|
|
14970
|
-
return leaves;
|
|
14971
|
-
}
|
|
14972
|
-
const scopeData = map[scopeKey];
|
|
14973
|
-
if (scopeData && typeof scopeData === "object" && !isLeaf(scopeData)) return scopeData;
|
|
14974
|
-
return {};
|
|
14975
|
-
}
|
|
14976
|
-
function withStagedOverlay(store, kind, committed) {
|
|
14977
|
-
const { staged } = getKindRegistry(store, kind);
|
|
14978
|
-
if (staged.size === 0) return committed;
|
|
14979
|
-
const view = { ...committed };
|
|
14980
|
-
for (const [scopeKey, entries] of staged) {
|
|
14981
|
-
if (scopeKey === ROOT_SCOPE) Object.assign(view, entries);
|
|
14982
|
-
else view[scopeKey] = { ...view[scopeKey], ...entries };
|
|
14983
|
-
}
|
|
14984
|
-
return view;
|
|
14985
|
-
}
|
|
14986
|
-
function flushStagedScope(store, kind, scopeKey, isLeaf) {
|
|
14987
|
-
const registry = getKindRegistry(store, kind);
|
|
14988
|
-
const staged = registry.staged.get(scopeKey);
|
|
14989
|
-
if (!staged) return;
|
|
14990
|
-
registry.staged.delete(scopeKey);
|
|
14991
|
-
const replace = !registry.valid.has(scopeKey);
|
|
14992
|
-
store.setState((state) => {
|
|
14993
|
-
const map = state[kind];
|
|
14994
|
-
if (scopeKey === ROOT_SCOPE) {
|
|
14995
|
-
if (!replace) return { [kind]: { ...map, ...staged } };
|
|
14996
|
-
const next = {};
|
|
14997
|
-
for (const [key, value] of Object.entries(map)) if (!isLeaf(value)) next[key] = value;
|
|
14998
|
-
return { [kind]: { ...next, ...staged } };
|
|
14999
|
-
}
|
|
15000
|
-
const current = replace ? {} : map[scopeKey] ?? {};
|
|
15001
|
-
return { [kind]: { ...map, [scopeKey]: { ...current, ...staged } } };
|
|
15002
|
-
});
|
|
15003
|
-
registry.valid.add(scopeKey);
|
|
15004
|
-
}
|
|
15005
|
-
function invalidateResource(store, kind, scopeKey) {
|
|
15006
|
-
const registry = getKindRegistry(store, kind);
|
|
15007
|
-
if (scopeKey === void 0) {
|
|
15008
|
-
registry.valid.clear();
|
|
15009
|
-
registry.staged.clear();
|
|
15010
|
-
} else {
|
|
15011
|
-
registry.valid.delete(scopeKey);
|
|
15012
|
-
registry.staged.delete(scopeKey);
|
|
15013
|
-
}
|
|
15014
|
-
}
|
|
15015
|
-
function rebuildResource(store, kind, userScope) {
|
|
15016
|
-
const primary = resolvePrimary$1(store);
|
|
15017
|
-
invalidateResource(primary, kind, userScope === "root" ? ROOT_SCOPE : userScope);
|
|
15018
|
-
primary.setState((state) => ({ _hmrVersion: state._hmrVersion + 1 }));
|
|
15019
|
-
}
|
|
15020
|
-
function invalidateAllResources(store) {
|
|
15021
|
-
for (const kind of RESOURCE_KINDS) invalidateResource(store, kind);
|
|
15022
|
-
}
|
|
15023
|
-
function removeResourceEntries(store, kind, names, scope, isLeaf) {
|
|
15024
|
-
const staged = peekStaged(store, kind, scope ?? ROOT_SCOPE);
|
|
15025
|
-
if (staged) for (const name of names) delete staged[name];
|
|
15026
|
-
store.setState((state) => {
|
|
15027
|
-
const map = state[kind];
|
|
15028
|
-
if (scope) {
|
|
15029
|
-
const currentScope = { ...map[scope] };
|
|
15030
|
-
for (const name of names) delete currentScope[name];
|
|
15031
|
-
return { [kind]: { ...map, [scope]: currentScope } };
|
|
15032
|
-
}
|
|
15033
|
-
const next = { ...map };
|
|
15034
|
-
for (const name of names) if (isLeaf(next[name])) delete next[name];
|
|
15035
|
-
return { [kind]: next };
|
|
15036
|
-
});
|
|
15037
|
-
}
|
|
15038
|
-
function clearResourceEntries(store, kind, scope, isLeaf) {
|
|
15039
|
-
const registry = getKindRegistry(store, kind);
|
|
15040
|
-
if (scope && scope !== "root") registry.staged.delete(scope);
|
|
15041
|
-
else if (scope === "root") registry.staged.delete(ROOT_SCOPE);
|
|
15042
|
-
else registry.staged.clear();
|
|
15043
|
-
store.setState((state) => {
|
|
15044
|
-
const map = state[kind];
|
|
15045
|
-
if (scope && scope !== "root") {
|
|
15046
|
-
const { [scope]: _, ...rest } = map;
|
|
15047
|
-
return { [kind]: rest };
|
|
15048
|
-
}
|
|
15049
|
-
if (scope === "root") {
|
|
15050
|
-
const next = {};
|
|
15051
|
-
for (const [key, value] of Object.entries(map)) if (!isLeaf(value)) next[key] = value;
|
|
15052
|
-
return { [kind]: next };
|
|
15028
|
+
return { files: background, background: true };
|
|
15053
15029
|
}
|
|
15054
|
-
return {
|
|
15055
|
-
}
|
|
15030
|
+
return { color: background, background: true };
|
|
15031
|
+
}
|
|
15032
|
+
if (background.isColor) {
|
|
15033
|
+
return { color: background, background: true };
|
|
15034
|
+
}
|
|
15035
|
+
return null;
|
|
15056
15036
|
}
|
|
15057
15037
|
|
|
15058
|
-
function
|
|
15059
|
-
const
|
|
15060
|
-
|
|
15061
|
-
|
|
15038
|
+
function parseRendererConfig(rendererProp) {
|
|
15039
|
+
const isRendererConfig = typeof rendererProp === "object" && rendererProp !== null && !("render" in rendererProp) && ("primaryCanvas" in rendererProp || "scheduler" in rendererProp);
|
|
15040
|
+
if (isRendererConfig) {
|
|
15041
|
+
const { primaryCanvas: pc, scheduler: sc, ...rest } = rendererProp;
|
|
15042
|
+
return {
|
|
15043
|
+
primaryCanvas: pc,
|
|
15044
|
+
scheduler: sc,
|
|
15045
|
+
renderer: Object.keys(rest).length > 0 ? rest : rendererProp
|
|
15046
|
+
};
|
|
15047
|
+
}
|
|
15048
|
+
return { primaryCanvas: void 0, scheduler: void 0, renderer: rendererProp };
|
|
15062
15049
|
}
|
|
15063
15050
|
|
|
15064
15051
|
function CanvasImpl({
|
|
@@ -15098,9 +15085,9 @@ function CanvasImpl({
|
|
|
15098
15085
|
React.useMemo(() => extend(THREE), []);
|
|
15099
15086
|
const Bridge = useBridge();
|
|
15100
15087
|
const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
|
|
15101
|
-
const
|
|
15088
|
+
const [hasInitialSize, setHasInitialSize] = React.useState(false);
|
|
15102
15089
|
const measureConfig = React.useMemo(() => {
|
|
15103
|
-
if (!
|
|
15090
|
+
if (!hasInitialSize) {
|
|
15104
15091
|
return {
|
|
15105
15092
|
...resize,
|
|
15106
15093
|
scroll: resize?.scroll ?? true,
|
|
@@ -15112,7 +15099,7 @@ function CanvasImpl({
|
|
|
15112
15099
|
debounce: { scroll: 50, resize: 0 },
|
|
15113
15100
|
...resize
|
|
15114
15101
|
};
|
|
15115
|
-
}, [
|
|
15102
|
+
}, [hasInitialSize, resize]);
|
|
15116
15103
|
const [containerRef, containerRect] = useMeasure(measureConfig);
|
|
15117
15104
|
const effectiveSize = React.useMemo(() => {
|
|
15118
15105
|
let w = width ?? containerRect.width;
|
|
@@ -15128,9 +15115,7 @@ function CanvasImpl({
|
|
|
15128
15115
|
left: containerRect.left
|
|
15129
15116
|
};
|
|
15130
15117
|
}, [width, height, containerRect, forceEven]);
|
|
15131
|
-
if (!
|
|
15132
|
-
hasInitialSizeRef.current = true;
|
|
15133
|
-
}
|
|
15118
|
+
if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
|
|
15134
15119
|
const canvasRef = React.useRef(null);
|
|
15135
15120
|
const divRef = React.useRef(null);
|
|
15136
15121
|
React.useImperativeHandle(ref, () => canvasRef.current);
|
|
@@ -15244,6 +15229,7 @@ function CanvasImpl({
|
|
|
15244
15229
|
const canvas = canvasRef.current;
|
|
15245
15230
|
if (canvas) {
|
|
15246
15231
|
return () => {
|
|
15232
|
+
if (canvas.isConnected) return;
|
|
15247
15233
|
unmountComponentAtNode(canvas);
|
|
15248
15234
|
root.current = null;
|
|
15249
15235
|
};
|
|
@@ -15256,7 +15242,7 @@ function CanvasImpl({
|
|
|
15256
15242
|
const handleHMR = () => {
|
|
15257
15243
|
queueMicrotask(() => {
|
|
15258
15244
|
const rootEntry = _roots.get(canvas);
|
|
15259
|
-
if (rootEntry?.store)
|
|
15245
|
+
if (rootEntry?.store) notifyRootExtensionsHmr(rootEntry.store);
|
|
15260
15246
|
});
|
|
15261
15247
|
};
|
|
15262
15248
|
if (typeof import.meta !== "undefined" && import.meta.hot) {
|
|
@@ -15302,20 +15288,159 @@ function CanvasImpl({
|
|
|
15302
15288
|
}
|
|
15303
15289
|
);
|
|
15304
15290
|
}
|
|
15305
|
-
function Canvas(props) {
|
|
15291
|
+
function Canvas$1(props) {
|
|
15306
15292
|
return /* @__PURE__ */ jsx(FiberProvider, { children: /* @__PURE__ */ jsx(CanvasImpl, { ...props }) });
|
|
15307
15293
|
}
|
|
15308
15294
|
|
|
15295
|
+
const RESOURCE_KINDS = ["nodes", "uniforms", "buffers", "gpuStorage"];
|
|
15296
|
+
const ROOT_SCOPE = "";
|
|
15297
|
+
const registries = /* @__PURE__ */ new WeakMap();
|
|
15298
|
+
function getKindRegistry(store, kind) {
|
|
15299
|
+
let registry = registries.get(store);
|
|
15300
|
+
if (!registry) {
|
|
15301
|
+
registry = {
|
|
15302
|
+
nodes: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
15303
|
+
uniforms: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
15304
|
+
buffers: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
15305
|
+
gpuStorage: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() }
|
|
15306
|
+
};
|
|
15307
|
+
registries.set(store, registry);
|
|
15308
|
+
}
|
|
15309
|
+
return registry[kind];
|
|
15310
|
+
}
|
|
15311
|
+
function resolvePrimary$1(store) {
|
|
15312
|
+
return store.getState().primaryStore ?? store;
|
|
15313
|
+
}
|
|
15314
|
+
function isScopeValid(store, kind, scopeKey) {
|
|
15315
|
+
return getKindRegistry(store, kind).valid.has(scopeKey);
|
|
15316
|
+
}
|
|
15317
|
+
function peekStaged(store, kind, scopeKey) {
|
|
15318
|
+
return getKindRegistry(store, kind).staged.get(scopeKey);
|
|
15319
|
+
}
|
|
15320
|
+
function stageEntries(store, kind, scopeKey, entries) {
|
|
15321
|
+
const { staged } = getKindRegistry(store, kind);
|
|
15322
|
+
const current = staged.get(scopeKey);
|
|
15323
|
+
if (current) Object.assign(current, entries);
|
|
15324
|
+
else staged.set(scopeKey, { ...entries });
|
|
15325
|
+
}
|
|
15326
|
+
function readCommittedScope(map, scopeKey, isLeaf) {
|
|
15327
|
+
if (scopeKey === ROOT_SCOPE) {
|
|
15328
|
+
const leaves = {};
|
|
15329
|
+
for (const [key, value] of Object.entries(map)) if (isLeaf(value)) leaves[key] = value;
|
|
15330
|
+
return leaves;
|
|
15331
|
+
}
|
|
15332
|
+
const scopeData = map[scopeKey];
|
|
15333
|
+
if (scopeData && typeof scopeData === "object" && !isLeaf(scopeData)) return scopeData;
|
|
15334
|
+
return {};
|
|
15335
|
+
}
|
|
15336
|
+
function withStagedOverlay(store, kind, committed) {
|
|
15337
|
+
const { staged } = getKindRegistry(store, kind);
|
|
15338
|
+
if (staged.size === 0) return committed;
|
|
15339
|
+
const view = { ...committed };
|
|
15340
|
+
for (const [scopeKey, entries] of staged) {
|
|
15341
|
+
if (scopeKey === ROOT_SCOPE) Object.assign(view, entries);
|
|
15342
|
+
else view[scopeKey] = { ...view[scopeKey], ...entries };
|
|
15343
|
+
}
|
|
15344
|
+
return view;
|
|
15345
|
+
}
|
|
15346
|
+
function flushStagedScope(store, kind, scopeKey, isLeaf) {
|
|
15347
|
+
const registry = getKindRegistry(store, kind);
|
|
15348
|
+
const staged = registry.staged.get(scopeKey);
|
|
15349
|
+
if (!staged) return;
|
|
15350
|
+
registry.staged.delete(scopeKey);
|
|
15351
|
+
const replace = !registry.valid.has(scopeKey);
|
|
15352
|
+
store.setState((state) => {
|
|
15353
|
+
const map = state[kind];
|
|
15354
|
+
if (scopeKey === ROOT_SCOPE) {
|
|
15355
|
+
if (!replace) return { [kind]: { ...map, ...staged } };
|
|
15356
|
+
const next = {};
|
|
15357
|
+
for (const [key, value] of Object.entries(map)) if (!isLeaf(value)) next[key] = value;
|
|
15358
|
+
return { [kind]: { ...next, ...staged } };
|
|
15359
|
+
}
|
|
15360
|
+
const current = replace ? {} : map[scopeKey] ?? {};
|
|
15361
|
+
return { [kind]: { ...map, [scopeKey]: { ...current, ...staged } } };
|
|
15362
|
+
});
|
|
15363
|
+
registry.valid.add(scopeKey);
|
|
15364
|
+
}
|
|
15365
|
+
function invalidateResource(store, kind, scopeKey) {
|
|
15366
|
+
const registry = getKindRegistry(store, kind);
|
|
15367
|
+
if (scopeKey === void 0) {
|
|
15368
|
+
registry.valid.clear();
|
|
15369
|
+
registry.staged.clear();
|
|
15370
|
+
} else {
|
|
15371
|
+
registry.valid.delete(scopeKey);
|
|
15372
|
+
registry.staged.delete(scopeKey);
|
|
15373
|
+
}
|
|
15374
|
+
}
|
|
15375
|
+
function rebuildResource(store, kind, userScope) {
|
|
15376
|
+
const primary = resolvePrimary$1(store);
|
|
15377
|
+
invalidateResource(primary, kind, userScope === "root" ? ROOT_SCOPE : userScope);
|
|
15378
|
+
primary.setState((state) => ({ _hmrVersion: state._hmrVersion + 1 }));
|
|
15379
|
+
}
|
|
15380
|
+
function invalidateAllResources(store) {
|
|
15381
|
+
for (const kind of RESOURCE_KINDS) invalidateResource(store, kind);
|
|
15382
|
+
}
|
|
15383
|
+
function removeResourceEntries(store, kind, names, scope, isLeaf) {
|
|
15384
|
+
const staged = peekStaged(store, kind, scope ?? ROOT_SCOPE);
|
|
15385
|
+
if (staged) for (const name of names) delete staged[name];
|
|
15386
|
+
store.setState((state) => {
|
|
15387
|
+
const map = state[kind];
|
|
15388
|
+
if (scope) {
|
|
15389
|
+
const currentScope = { ...map[scope] };
|
|
15390
|
+
for (const name of names) delete currentScope[name];
|
|
15391
|
+
return { [kind]: { ...map, [scope]: currentScope } };
|
|
15392
|
+
}
|
|
15393
|
+
const next = { ...map };
|
|
15394
|
+
for (const name of names) if (isLeaf(next[name])) delete next[name];
|
|
15395
|
+
return { [kind]: next };
|
|
15396
|
+
});
|
|
15397
|
+
}
|
|
15398
|
+
function clearResourceEntries(store, kind, scope, isLeaf) {
|
|
15399
|
+
const registry = getKindRegistry(store, kind);
|
|
15400
|
+
if (scope && scope !== "root") registry.staged.delete(scope);
|
|
15401
|
+
else if (scope === "root") registry.staged.delete(ROOT_SCOPE);
|
|
15402
|
+
else registry.staged.clear();
|
|
15403
|
+
store.setState((state) => {
|
|
15404
|
+
const map = state[kind];
|
|
15405
|
+
if (scope && scope !== "root") {
|
|
15406
|
+
const { [scope]: _, ...rest } = map;
|
|
15407
|
+
return { [kind]: rest };
|
|
15408
|
+
}
|
|
15409
|
+
if (scope === "root") {
|
|
15410
|
+
const next = {};
|
|
15411
|
+
for (const [key, value] of Object.entries(map)) if (!isLeaf(value)) next[key] = value;
|
|
15412
|
+
return { [kind]: next };
|
|
15413
|
+
}
|
|
15414
|
+
return { [kind]: {} };
|
|
15415
|
+
});
|
|
15416
|
+
}
|
|
15417
|
+
|
|
15418
|
+
const isObjectLike = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
15419
|
+
const hasValidLegacyNodeMarkers = (value) => {
|
|
15420
|
+
const hasUuid = "uuid" in value;
|
|
15421
|
+
const hasNodeType = "nodeType" in value;
|
|
15422
|
+
const uuid = Reflect.get(value, "uuid");
|
|
15423
|
+
const nodeType = Reflect.get(value, "nodeType");
|
|
15424
|
+
return (hasUuid || hasNodeType) && (!hasUuid || uuid === void 0 || typeof uuid === "string") && (!hasNodeType || nodeType === void 0 || nodeType === null || typeof nodeType === "string");
|
|
15425
|
+
};
|
|
15426
|
+
const isUniformNode = (value) => isObjectLike(value) && "isUniformNode" in value && value.isUniformNode === true;
|
|
15427
|
+
const isTSLNode = (value) => isObjectLike(value) && (Reflect.get(value, "isNode") === true || Reflect.get(value, "shaderNode") !== void 0 && typeof Reflect.get(value, "id") === "number" || hasValidLegacyNodeMarkers(value));
|
|
15428
|
+
const isBufferLike = (value) => ArrayBuffer.isView(value) && !(value instanceof DataView) || isObjectLike(value) && ("isBufferAttribute" in value || "isInterleavedBufferAttribute" in value || isTSLNode(value));
|
|
15429
|
+
const isStorageLike = (value) => isObjectLike(value) && ("isTexture" in value || "isData3DTexture" in value || isTSLNode(value));
|
|
15430
|
+
|
|
15309
15431
|
var __defProp = Object.defineProperty;
|
|
15310
15432
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
15311
15433
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
15312
|
-
var _a;
|
|
15434
|
+
var _a, _b;
|
|
15313
15435
|
const INTERNAL_DATA = Symbol("ScopedStore.data");
|
|
15314
|
-
|
|
15436
|
+
const INTERNAL_IS_LEAF = Symbol("ScopedStore.isLeaf");
|
|
15437
|
+
_b = INTERNAL_DATA, _a = INTERNAL_IS_LEAF;
|
|
15315
15438
|
const _ScopedStore = class _ScopedStore {
|
|
15316
|
-
constructor(data) {
|
|
15439
|
+
constructor(data, isLeaf) {
|
|
15440
|
+
__publicField(this, _b);
|
|
15317
15441
|
__publicField(this, _a);
|
|
15318
15442
|
this[INTERNAL_DATA] = data;
|
|
15443
|
+
this[INTERNAL_IS_LEAF] = isLeaf;
|
|
15319
15444
|
return new Proxy(this, {
|
|
15320
15445
|
get(target, prop, receiver) {
|
|
15321
15446
|
if (typeof prop === "string") {
|
|
@@ -15349,10 +15474,10 @@ const _ScopedStore = class _ScopedStore {
|
|
|
15349
15474
|
* If the key doesn't exist or isn't a scope object, returns an empty ScopedStore.
|
|
15350
15475
|
*/
|
|
15351
15476
|
scope(key) {
|
|
15352
|
-
const
|
|
15353
|
-
|
|
15354
|
-
|
|
15355
|
-
);
|
|
15477
|
+
const value = this[INTERNAL_DATA][key];
|
|
15478
|
+
const isLeaf = this[INTERNAL_IS_LEAF];
|
|
15479
|
+
const scope = value && typeof value === "object" && !isLeaf(value) ? value : {};
|
|
15480
|
+
return new _ScopedStore(scope, isLeaf);
|
|
15356
15481
|
}
|
|
15357
15482
|
/**
|
|
15358
15483
|
* Check if a key exists in the store.
|
|
@@ -15368,8 +15493,8 @@ const _ScopedStore = class _ScopedStore {
|
|
|
15368
15493
|
}
|
|
15369
15494
|
};
|
|
15370
15495
|
let ScopedStore = _ScopedStore;
|
|
15371
|
-
function createScopedStore(data) {
|
|
15372
|
-
return new ScopedStore(data);
|
|
15496
|
+
function createScopedStore(data, isLeaf) {
|
|
15497
|
+
return new ScopedStore(data, isLeaf);
|
|
15373
15498
|
}
|
|
15374
15499
|
function createLazyCreatorState(state, store) {
|
|
15375
15500
|
let _uniforms = null;
|
|
@@ -15380,22 +15505,22 @@ function createLazyCreatorState(state, store) {
|
|
|
15380
15505
|
return Object.create(state, {
|
|
15381
15506
|
uniforms: {
|
|
15382
15507
|
get() {
|
|
15383
|
-
return _uniforms ?? (_uniforms = createScopedStore(view("uniforms")));
|
|
15508
|
+
return _uniforms ?? (_uniforms = createScopedStore(view("uniforms"), isUniformNode));
|
|
15384
15509
|
}
|
|
15385
15510
|
},
|
|
15386
15511
|
nodes: {
|
|
15387
15512
|
get() {
|
|
15388
|
-
return _nodes ?? (_nodes = createScopedStore(view("nodes")));
|
|
15513
|
+
return _nodes ?? (_nodes = createScopedStore(view("nodes"), isTSLNode));
|
|
15389
15514
|
}
|
|
15390
15515
|
},
|
|
15391
15516
|
buffers: {
|
|
15392
15517
|
get() {
|
|
15393
|
-
return _buffers ?? (_buffers = createScopedStore(view("buffers")));
|
|
15518
|
+
return _buffers ?? (_buffers = createScopedStore(view("buffers"), isBufferLike));
|
|
15394
15519
|
}
|
|
15395
15520
|
},
|
|
15396
15521
|
gpuStorage: {
|
|
15397
15522
|
get() {
|
|
15398
|
-
return _gpuStorage ?? (_gpuStorage = createScopedStore(view("gpuStorage")));
|
|
15523
|
+
return _gpuStorage ?? (_gpuStorage = createScopedStore(view("gpuStorage"), isStorageLike));
|
|
15399
15524
|
}
|
|
15400
15525
|
}
|
|
15401
15526
|
});
|
|
@@ -15415,44 +15540,10 @@ function usePrimaryThree(selector = (state) => state, equalityFn) {
|
|
|
15415
15540
|
return primary(selector, equalityFn);
|
|
15416
15541
|
}
|
|
15417
15542
|
|
|
15418
|
-
function
|
|
15419
|
-
|
|
15420
|
-
|
|
15421
|
-
|
|
15422
|
-
return { textures: newMap };
|
|
15423
|
-
});
|
|
15424
|
-
}
|
|
15425
|
-
function addTextures(set, items) {
|
|
15426
|
-
set((state) => {
|
|
15427
|
-
const newMap = new Map(state.textures);
|
|
15428
|
-
const entries = items instanceof Map ? items.entries() : Object.entries(items);
|
|
15429
|
-
for (const [key, value] of entries) {
|
|
15430
|
-
newMap.set(key, value);
|
|
15431
|
-
}
|
|
15432
|
-
return { textures: newMap };
|
|
15433
|
-
});
|
|
15434
|
-
}
|
|
15435
|
-
function removeTexture(set, key) {
|
|
15436
|
-
set((state) => {
|
|
15437
|
-
const newMap = new Map(state.textures);
|
|
15438
|
-
newMap.delete(key);
|
|
15439
|
-
return { textures: newMap };
|
|
15440
|
-
});
|
|
15441
|
-
}
|
|
15442
|
-
function removeTextures(set, keys) {
|
|
15443
|
-
set((state) => {
|
|
15444
|
-
const newMap = new Map(state.textures);
|
|
15445
|
-
for (const key of keys) newMap.delete(key);
|
|
15446
|
-
return { textures: newMap };
|
|
15447
|
-
});
|
|
15448
|
-
}
|
|
15449
|
-
function createTextureOperations(set) {
|
|
15450
|
-
return {
|
|
15451
|
-
add: (key, value) => addTexture(set, key, value),
|
|
15452
|
-
addMultiple: (items) => addTextures(set, items),
|
|
15453
|
-
remove: (key) => removeTexture(set, key),
|
|
15454
|
-
removeMultiple: (keys) => removeTextures(set, keys)
|
|
15455
|
-
};
|
|
15543
|
+
function scopedNodeName(scope, name) {
|
|
15544
|
+
const raw = scope ? `${scope}_${name}` : name;
|
|
15545
|
+
const safe = raw.replace(/[^A-Za-z0-9_]/g, "_");
|
|
15546
|
+
return /^[A-Za-z_]/.test(safe) ? safe : `_${safe}`;
|
|
15456
15547
|
}
|
|
15457
15548
|
function extractTSLValue(value) {
|
|
15458
15549
|
if (value === null || value === void 0) return value;
|
|
@@ -15491,7 +15582,7 @@ function vectorize(inObject) {
|
|
|
15491
15582
|
return extractTSLValue(inObject);
|
|
15492
15583
|
}
|
|
15493
15584
|
if (obj.isVector2 || obj.isVector3 || obj.isVector4) return inObject;
|
|
15494
|
-
if (obj.isMatrix3 || obj.isMatrix4) return inObject;
|
|
15585
|
+
if (obj.isMatrix2 || obj.isMatrix3 || obj.isMatrix4) return inObject;
|
|
15495
15586
|
if (obj.isColor || obj.isEuler || obj.isQuaternion || obj.isSpherical) return inObject;
|
|
15496
15587
|
if ("r" in obj && "g" in obj && "b" in obj && typeof obj.r === "number" && typeof obj.g === "number" && typeof obj.b === "number") {
|
|
15497
15588
|
const scale = obj.r > 1 || obj.g > 1 || obj.b > 1 ? 1 / 255 : 1;
|
|
@@ -15518,8 +15609,26 @@ function useCompareMemoize(value, deep) {
|
|
|
15518
15609
|
return ref.current;
|
|
15519
15610
|
}
|
|
15520
15611
|
|
|
15612
|
+
function clearHmrCaches(store) {
|
|
15613
|
+
const primary = store.getState().primaryStore ?? store;
|
|
15614
|
+
invalidateAllResources(primary);
|
|
15615
|
+
primary.setState((state) => ({ _hmrVersion: state._hmrVersion + 1 }));
|
|
15616
|
+
}
|
|
15617
|
+
|
|
15618
|
+
let registered = false;
|
|
15619
|
+
function ensureTSLExtension() {
|
|
15620
|
+
if (registered) return;
|
|
15621
|
+
registered = true;
|
|
15622
|
+
registerRootExtension({
|
|
15623
|
+
name: "@react-three/tsl",
|
|
15624
|
+
// Resolves primaryStore itself, so every canvas sharing a renderer refreshes the same resources.
|
|
15625
|
+
hmr: clearHmrCaches
|
|
15626
|
+
});
|
|
15627
|
+
}
|
|
15628
|
+
|
|
15521
15629
|
function useScopedResource(options) {
|
|
15522
15630
|
const { store, kind, scope, isLeaf, create, prepare, reconcile, input } = options;
|
|
15631
|
+
ensureTSLExtension();
|
|
15523
15632
|
const scopeKey = scope ?? ROOT_SCOPE;
|
|
15524
15633
|
const version = store((s) => s._hmrVersion);
|
|
15525
15634
|
const entries = useMemo(() => {
|
|
@@ -15549,22 +15658,21 @@ function useScopedResource(options) {
|
|
|
15549
15658
|
return entries;
|
|
15550
15659
|
}
|
|
15551
15660
|
|
|
15552
|
-
const isUniformNode$1 = (value) => value !== null && typeof value === "object" && "value" in value && "uuid" in value;
|
|
15553
15661
|
function useUniforms(creatorOrScope, scope) {
|
|
15554
15662
|
const store = usePrimaryStore();
|
|
15555
15663
|
const removeUniforms2 = useCallback(
|
|
15556
|
-
(names, targetScope) => removeResourceEntries(store, "uniforms", Array.isArray(names) ? names : [names], targetScope, isUniformNode
|
|
15664
|
+
(names, targetScope) => removeResourceEntries(store, "uniforms", Array.isArray(names) ? names : [names], targetScope, isUniformNode),
|
|
15557
15665
|
[store]
|
|
15558
15666
|
);
|
|
15559
15667
|
const clearUniforms = useCallback(
|
|
15560
|
-
(targetScope) => clearResourceEntries(store, "uniforms", targetScope, isUniformNode
|
|
15668
|
+
(targetScope) => clearResourceEntries(store, "uniforms", targetScope, isUniformNode),
|
|
15561
15669
|
[store]
|
|
15562
15670
|
);
|
|
15563
15671
|
const rebuildUniforms = useCallback(
|
|
15564
15672
|
(targetScope) => rebuildResource(store, "uniforms", targetScope),
|
|
15565
15673
|
[store]
|
|
15566
15674
|
);
|
|
15567
|
-
const
|
|
15675
|
+
const processedInput = useMemo(() => {
|
|
15568
15676
|
let raw = creatorOrScope;
|
|
15569
15677
|
if (is.fun(creatorOrScope)) {
|
|
15570
15678
|
const wrappedState = createLazyCreatorState(store.getState(), store);
|
|
@@ -15575,23 +15683,24 @@ function useUniforms(creatorOrScope, scope) {
|
|
|
15575
15683
|
for (const [key, value] of Object.entries(raw)) {
|
|
15576
15684
|
normalized[key] = vectorize(value);
|
|
15577
15685
|
}
|
|
15578
|
-
return normalized;
|
|
15686
|
+
return { candidates: raw, normalized };
|
|
15579
15687
|
}
|
|
15580
|
-
return raw;
|
|
15688
|
+
return { candidates: raw, normalized: raw };
|
|
15581
15689
|
}, [creatorOrScope, store]);
|
|
15582
|
-
const memoizedInput = useCompareMemoize(
|
|
15690
|
+
const memoizedInput = useCompareMemoize(processedInput.normalized);
|
|
15583
15691
|
const isReader = memoizedInput === void 0 || typeof memoizedInput === "string";
|
|
15584
15692
|
const storeUniforms = usePrimaryThree((s) => s.uniforms);
|
|
15585
15693
|
const created = useScopedResource({
|
|
15586
15694
|
store,
|
|
15587
15695
|
kind: "uniforms",
|
|
15588
15696
|
scope: isReader ? void 0 : scope,
|
|
15589
|
-
isLeaf: isUniformNode
|
|
15697
|
+
isLeaf: isUniformNode,
|
|
15590
15698
|
input: memoizedInput,
|
|
15591
15699
|
create: () => {
|
|
15592
15700
|
if (isReader) return {};
|
|
15593
|
-
if (typeof
|
|
15594
|
-
|
|
15701
|
+
if (typeof processedInput.candidates !== "object" || processedInput.candidates === null)
|
|
15702
|
+
throw new Error("Invalid uniform input");
|
|
15703
|
+
return processedInput.candidates;
|
|
15595
15704
|
},
|
|
15596
15705
|
prepare: (name, candidate) => createUniform(name, candidate, scope),
|
|
15597
15706
|
reconcile: (existing, candidate) => {
|
|
@@ -15613,7 +15722,7 @@ function useUniforms(creatorOrScope, scope) {
|
|
|
15613
15722
|
uniforms = storeUniforms;
|
|
15614
15723
|
} else if (typeof memoizedInput === "string") {
|
|
15615
15724
|
const scopeData = storeUniforms[memoizedInput];
|
|
15616
|
-
uniforms = scopeData && !isUniformNode
|
|
15725
|
+
uniforms = scopeData && !isUniformNode(scopeData) ? scopeData : {};
|
|
15617
15726
|
}
|
|
15618
15727
|
return { ...uniforms, removeUniforms: removeUniforms2, clearUniforms, rebuildUniforms };
|
|
15619
15728
|
}
|
|
@@ -15628,7 +15737,7 @@ function removeUniforms(set, names, scope) {
|
|
|
15628
15737
|
return { uniforms: { ...state.uniforms, [scope]: currentScope } };
|
|
15629
15738
|
}
|
|
15630
15739
|
const uniforms = { ...state.uniforms };
|
|
15631
|
-
for (const name of names) if (isUniformNode
|
|
15740
|
+
for (const name of names) if (isUniformNode(uniforms[name])) delete uniforms[name];
|
|
15632
15741
|
return { uniforms };
|
|
15633
15742
|
});
|
|
15634
15743
|
}
|
|
@@ -15642,7 +15751,7 @@ function clearRootUniforms(set) {
|
|
|
15642
15751
|
set((state) => {
|
|
15643
15752
|
const uniforms = {};
|
|
15644
15753
|
for (const [key, value] of Object.entries(state.uniforms)) {
|
|
15645
|
-
if (!isUniformNode
|
|
15754
|
+
if (!isUniformNode(value)) uniforms[key] = value;
|
|
15646
15755
|
}
|
|
15647
15756
|
return { uniforms };
|
|
15648
15757
|
});
|
|
@@ -15652,8 +15761,7 @@ function createUniform(inName, node, scope) {
|
|
|
15652
15761
|
const inValue = vectorize(node);
|
|
15653
15762
|
const newUniform = uniform(inValue);
|
|
15654
15763
|
if (typeof newUniform.setName === "function") {
|
|
15655
|
-
|
|
15656
|
-
newUniform.setName(name);
|
|
15764
|
+
newUniform.setName(scopedNodeName(scope, inName));
|
|
15657
15765
|
}
|
|
15658
15766
|
return newUniform;
|
|
15659
15767
|
}
|
|
@@ -15679,12 +15787,10 @@ function hasEqualsMethod(value) {
|
|
|
15679
15787
|
function isSameThreeType(a, b) {
|
|
15680
15788
|
const obj_a = a;
|
|
15681
15789
|
const obj_b = b;
|
|
15682
|
-
return obj_a.isColor && obj_b.isColor || obj_a.isMatrix3 && obj_b.isMatrix3 || obj_a.isMatrix4 && obj_b.isMatrix4 || obj_a.isEuler && obj_b.isEuler || obj_a.isQuaternion && obj_b.isQuaternion;
|
|
15790
|
+
return obj_a.isColor && obj_b.isColor || obj_a.isMatrix2 && obj_b.isMatrix2 || obj_a.isMatrix3 && obj_b.isMatrix3 || obj_a.isMatrix4 && obj_b.isMatrix4 || obj_a.isEuler && obj_b.isEuler || obj_a.isQuaternion && obj_b.isQuaternion;
|
|
15683
15791
|
}
|
|
15684
15792
|
|
|
15685
15793
|
const uniformOf = uniform;
|
|
15686
|
-
const isUniformNode = (value) => value !== null && typeof value === "object" && "value" in value && "uuid" in value;
|
|
15687
|
-
const isTSLNode$1 = (value) => value !== null && typeof value === "object" && "uuid" in value && "nodeType" in value;
|
|
15688
15794
|
function useUniform(name, value) {
|
|
15689
15795
|
const store = useStore();
|
|
15690
15796
|
const registered = useScopedResource({
|
|
@@ -15696,7 +15802,7 @@ function useUniform(name, value) {
|
|
|
15696
15802
|
create: () => value === void 0 ? {} : { [name]: value },
|
|
15697
15803
|
prepare: createNamedUniform,
|
|
15698
15804
|
reconcile: (existing2) => {
|
|
15699
|
-
if (value !== void 0 && !isTSLNode
|
|
15805
|
+
if (value !== void 0 && !isTSLNode(value) && !isUniformNode(value)) {
|
|
15700
15806
|
existing2.value = typeof value === "string" ? new Color(value) : value;
|
|
15701
15807
|
}
|
|
15702
15808
|
}
|
|
@@ -15712,7 +15818,7 @@ function createNamedUniform(name, value) {
|
|
|
15712
15818
|
let node;
|
|
15713
15819
|
if (isUniformNode(value)) {
|
|
15714
15820
|
node = value;
|
|
15715
|
-
} else if (isTSLNode
|
|
15821
|
+
} else if (isTSLNode(value)) {
|
|
15716
15822
|
node = uniformOf(value);
|
|
15717
15823
|
} else if (typeof value === "string") {
|
|
15718
15824
|
node = uniform(new Color(value));
|
|
@@ -15725,7 +15831,6 @@ function createNamedUniform(name, value) {
|
|
|
15725
15831
|
return node;
|
|
15726
15832
|
}
|
|
15727
15833
|
|
|
15728
|
-
const isTSLNode = (value) => value !== null && typeof value === "object" && ("uuid" in value || "nodeType" in value);
|
|
15729
15834
|
function useNodes(creatorOrScope, scope) {
|
|
15730
15835
|
const store = usePrimaryStore();
|
|
15731
15836
|
const removeNodes2 = useCallback(
|
|
@@ -15752,7 +15857,8 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15752
15857
|
return creatorOrScope(createLazyCreatorState(store.getState(), store));
|
|
15753
15858
|
},
|
|
15754
15859
|
prepare: (name, node) => {
|
|
15755
|
-
|
|
15860
|
+
const setName = Reflect.get(node, "setName");
|
|
15861
|
+
if (typeof setName === "function") setName.call(node, scopedNodeName(scope, name));
|
|
15756
15862
|
return node;
|
|
15757
15863
|
}
|
|
15758
15864
|
});
|
|
@@ -15807,13 +15913,6 @@ function useLocalNodes(creator) {
|
|
|
15807
15913
|
}, [store, creator, uniforms, nodes, textures, hmrVersion]);
|
|
15808
15914
|
}
|
|
15809
15915
|
|
|
15810
|
-
const isBufferLike = (value) => {
|
|
15811
|
-
if (value === null || typeof value !== "object") return false;
|
|
15812
|
-
if (ArrayBuffer.isView(value)) return true;
|
|
15813
|
-
if ("isBufferAttribute" in value) return true;
|
|
15814
|
-
if ("uuid" in value || "nodeType" in value) return true;
|
|
15815
|
-
return false;
|
|
15816
|
-
};
|
|
15817
15916
|
const disposeBuffer = (buffer) => {
|
|
15818
15917
|
if (buffer === null || typeof buffer !== "object") return;
|
|
15819
15918
|
if ("dispose" in buffer && typeof buffer.dispose === "function") {
|
|
@@ -15860,9 +15959,8 @@ function useBuffers(creatorOrScope, scope) {
|
|
|
15860
15959
|
return creatorOrScope(createLazyCreatorState(store.getState(), store));
|
|
15861
15960
|
},
|
|
15862
15961
|
prepare: (name, buffer) => {
|
|
15863
|
-
|
|
15864
|
-
|
|
15865
|
-
}
|
|
15962
|
+
const setName = Reflect.get(buffer, "setName");
|
|
15963
|
+
if (typeof setName === "function") setName.call(buffer, scopedNodeName(scope, name));
|
|
15866
15964
|
return buffer;
|
|
15867
15965
|
}
|
|
15868
15966
|
});
|
|
@@ -15879,13 +15977,6 @@ function rebuildAllBuffers(store, scope) {
|
|
|
15879
15977
|
rebuildResource(store, "buffers", scope);
|
|
15880
15978
|
}
|
|
15881
15979
|
|
|
15882
|
-
const isStorageLike = (value) => {
|
|
15883
|
-
if (value === null || typeof value !== "object") return false;
|
|
15884
|
-
if ("isTexture" in value) return true;
|
|
15885
|
-
if ("isData3DTexture" in value) return true;
|
|
15886
|
-
if ("uuid" in value || "nodeType" in value) return true;
|
|
15887
|
-
return false;
|
|
15888
|
-
};
|
|
15889
15980
|
const disposeStorage = (storage) => {
|
|
15890
15981
|
if (storage === null || typeof storage !== "object") return;
|
|
15891
15982
|
if ("dispose" in storage && typeof storage.dispose === "function") {
|
|
@@ -15932,10 +16023,9 @@ function useGPUStorage(creatorOrScope, scope) {
|
|
|
15932
16023
|
return creatorOrScope(createLazyCreatorState(store.getState(), store));
|
|
15933
16024
|
},
|
|
15934
16025
|
prepare: (name, storage) => {
|
|
15935
|
-
const label = scope
|
|
15936
|
-
|
|
15937
|
-
|
|
15938
|
-
}
|
|
16026
|
+
const label = scopedNodeName(scope, name);
|
|
16027
|
+
const setName = Reflect.get(storage, "setName");
|
|
16028
|
+
if (typeof setName === "function") setName.call(storage, label);
|
|
15939
16029
|
if ("name" in storage && typeof storage.name === "string") {
|
|
15940
16030
|
storage.name = label;
|
|
15941
16031
|
}
|
|
@@ -15961,11 +16051,58 @@ function rebuildAllStorage(store, scope) {
|
|
|
15961
16051
|
rebuildResource(store, "gpuStorage", scope);
|
|
15962
16052
|
}
|
|
15963
16053
|
|
|
16054
|
+
function addTexture(set, key, value) {
|
|
16055
|
+
set((state) => {
|
|
16056
|
+
const newMap = new Map(state.textures);
|
|
16057
|
+
newMap.set(key, value);
|
|
16058
|
+
return { textures: newMap };
|
|
16059
|
+
});
|
|
16060
|
+
}
|
|
16061
|
+
function addTextures(set, items) {
|
|
16062
|
+
set((state) => {
|
|
16063
|
+
const newMap = new Map(state.textures);
|
|
16064
|
+
const entries = items instanceof Map ? items.entries() : Object.entries(items);
|
|
16065
|
+
for (const [key, value] of entries) {
|
|
16066
|
+
newMap.set(key, value);
|
|
16067
|
+
}
|
|
16068
|
+
return { textures: newMap };
|
|
16069
|
+
});
|
|
16070
|
+
}
|
|
16071
|
+
function removeTexture(set, key) {
|
|
16072
|
+
set((state) => {
|
|
16073
|
+
const newMap = new Map(state.textures);
|
|
16074
|
+
newMap.delete(key);
|
|
16075
|
+
return { textures: newMap };
|
|
16076
|
+
});
|
|
16077
|
+
}
|
|
16078
|
+
function removeTextures(set, keys) {
|
|
16079
|
+
set((state) => {
|
|
16080
|
+
const newMap = new Map(state.textures);
|
|
16081
|
+
for (const key of keys) newMap.delete(key);
|
|
16082
|
+
return { textures: newMap };
|
|
16083
|
+
});
|
|
16084
|
+
}
|
|
16085
|
+
function createTextureOperations(set) {
|
|
16086
|
+
return {
|
|
16087
|
+
add: (key, value) => addTexture(set, key, value),
|
|
16088
|
+
addMultiple: (items) => addTextures(set, items),
|
|
16089
|
+
remove: (key) => removeTexture(set, key),
|
|
16090
|
+
removeMultiple: (keys) => removeTextures(set, keys)
|
|
16091
|
+
};
|
|
16092
|
+
}
|
|
16093
|
+
|
|
16094
|
+
function renderThroughPipeline(store) {
|
|
16095
|
+
return () => {
|
|
16096
|
+
const pipeline = store.getState().renderPipeline;
|
|
16097
|
+
if (pipeline?.render) pipeline.render();
|
|
16098
|
+
};
|
|
16099
|
+
}
|
|
15964
16100
|
function useRenderPipeline(mainCB, setupCB) {
|
|
15965
16101
|
const store = useStore();
|
|
15966
|
-
const { scene, camera, renderer, isLegacy } = useThree();
|
|
16102
|
+
const { scene, camera, renderer, isLegacy } = useThree$1();
|
|
15967
16103
|
const callbacksRanRef = useRef(false);
|
|
15968
16104
|
const scenePassCacheRef = useRef(null);
|
|
16105
|
+
const forceScenePassRebuildRef = useRef(false);
|
|
15969
16106
|
const mainCBRef = useRef(mainCB);
|
|
15970
16107
|
const setupCBRef = useRef(setupCB);
|
|
15971
16108
|
mainCBRef.current = mainCB;
|
|
@@ -15973,7 +16110,7 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
15973
16110
|
const [rebuildVersion, setRebuildVersion] = useState(0);
|
|
15974
16111
|
useEffect(() => {
|
|
15975
16112
|
callbacksRanRef.current = false;
|
|
15976
|
-
|
|
16113
|
+
forceScenePassRebuildRef.current = true;
|
|
15977
16114
|
}, []);
|
|
15978
16115
|
const clearPasses = useCallback(() => {
|
|
15979
16116
|
store.setState({ passes: {} });
|
|
@@ -15983,12 +16120,15 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
15983
16120
|
renderPipeline: null,
|
|
15984
16121
|
passes: {}
|
|
15985
16122
|
});
|
|
16123
|
+
setRenderOverride(store, null);
|
|
16124
|
+
scenePassCacheRef.current?.scenePass.dispose();
|
|
15986
16125
|
callbacksRanRef.current = false;
|
|
15987
16126
|
scenePassCacheRef.current = null;
|
|
16127
|
+
forceScenePassRebuildRef.current = false;
|
|
15988
16128
|
}, [store]);
|
|
15989
16129
|
const rebuild = useCallback(() => {
|
|
15990
16130
|
callbacksRanRef.current = false;
|
|
15991
|
-
|
|
16131
|
+
forceScenePassRebuildRef.current = true;
|
|
15992
16132
|
setRebuildVersion((v) => v + 1);
|
|
15993
16133
|
}, []);
|
|
15994
16134
|
useLayoutEffect(() => {
|
|
@@ -15996,6 +16136,9 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
15996
16136
|
throw new Error("useRenderPipeline is only available with WebGPU renderer. Set renderer prop on Canvas.");
|
|
15997
16137
|
}
|
|
15998
16138
|
if (!renderer || !scene || !camera) return;
|
|
16139
|
+
if (!("isWebGPURenderer" in renderer)) {
|
|
16140
|
+
throw new Error("useRenderPipeline: renderer is not a WebGPURenderer but isLegacy is false.");
|
|
16141
|
+
}
|
|
15999
16142
|
const state = store.getState();
|
|
16000
16143
|
const set = store.setState;
|
|
16001
16144
|
try {
|
|
@@ -16006,21 +16149,34 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16006
16149
|
pipeline = new RenderPipeline(renderer);
|
|
16007
16150
|
justCreatedPipeline = true;
|
|
16008
16151
|
}
|
|
16009
|
-
const cacheValid = scenePassCacheRef.current && scenePassCacheRef.current.sceneUuid === scene.uuid && scenePassCacheRef.current.cameraUuid === camera.uuid;
|
|
16152
|
+
const cacheValid = !forceScenePassRebuildRef.current && scenePassCacheRef.current && scenePassCacheRef.current.sceneUuid === scene.uuid && scenePassCacheRef.current.cameraUuid === camera.uuid;
|
|
16153
|
+
let outgoingScenePass = null;
|
|
16010
16154
|
let scenePass;
|
|
16011
16155
|
if (cacheValid) {
|
|
16012
16156
|
scenePass = scenePassCacheRef.current.scenePass;
|
|
16013
16157
|
} else {
|
|
16158
|
+
outgoingScenePass = scenePassCacheRef.current?.scenePass ?? null;
|
|
16014
16159
|
scenePass = pass(scene, camera);
|
|
16015
16160
|
scenePassCacheRef.current = { sceneUuid: scene.uuid, cameraUuid: camera.uuid, scenePass };
|
|
16161
|
+
forceScenePassRebuildRef.current = false;
|
|
16016
16162
|
}
|
|
16017
16163
|
currentPasses.scenePass = scenePass;
|
|
16018
|
-
|
|
16164
|
+
let outputNodeChanged = false;
|
|
16165
|
+
if (!pipeline.outputNode || justCreatedPipeline || pipeline.outputNode === outgoingScenePass) {
|
|
16166
|
+
pipeline.outputNode = scenePass;
|
|
16167
|
+
outputNodeChanged = true;
|
|
16168
|
+
}
|
|
16019
16169
|
set({ renderPipeline: pipeline, passes: currentPasses });
|
|
16170
|
+
setRenderOverride(store, renderThroughPipeline(store));
|
|
16020
16171
|
const shouldRunCallbacks = justCreatedPipeline || !callbacksRanRef.current || !cacheValid;
|
|
16021
16172
|
if (shouldRunCallbacks) {
|
|
16022
16173
|
if (setupCBRef.current) {
|
|
16023
|
-
const freshState = store.getState()
|
|
16174
|
+
const freshState = Object.assign({}, store.getState(), {
|
|
16175
|
+
renderPipeline: pipeline,
|
|
16176
|
+
passes: { ...currentPasses, scenePass },
|
|
16177
|
+
renderer,
|
|
16178
|
+
isLegacy: false
|
|
16179
|
+
});
|
|
16024
16180
|
const setupResult = setupCBRef.current(freshState);
|
|
16025
16181
|
if (setupResult && typeof setupResult === "object") {
|
|
16026
16182
|
currentPasses = { ...currentPasses, ...setupResult };
|
|
@@ -16028,32 +16184,37 @@ function useRenderPipeline(mainCB, setupCB) {
|
|
|
16028
16184
|
}
|
|
16029
16185
|
}
|
|
16030
16186
|
if (mainCBRef.current) {
|
|
16031
|
-
const freshState = store.getState()
|
|
16187
|
+
const freshState = Object.assign({}, store.getState(), {
|
|
16188
|
+
renderPipeline: pipeline,
|
|
16189
|
+
passes: { ...currentPasses, scenePass },
|
|
16190
|
+
renderer,
|
|
16191
|
+
isLegacy: false
|
|
16192
|
+
});
|
|
16032
16193
|
const mainResult = mainCBRef.current(freshState);
|
|
16033
16194
|
if (mainResult && typeof mainResult === "object") {
|
|
16034
16195
|
currentPasses = { ...currentPasses, ...mainResult };
|
|
16035
16196
|
set({ passes: currentPasses });
|
|
16036
16197
|
}
|
|
16037
16198
|
}
|
|
16199
|
+
outputNodeChanged = true;
|
|
16038
16200
|
callbacksRanRef.current = true;
|
|
16039
16201
|
}
|
|
16202
|
+
if (outputNodeChanged) pipeline.needsUpdate = true;
|
|
16203
|
+
if (outgoingScenePass && outgoingScenePass !== scenePass) outgoingScenePass.dispose();
|
|
16040
16204
|
} catch (error) {
|
|
16041
16205
|
console.warn("[useRenderPipeline] Setup failed; the render pipeline was not configured:", error);
|
|
16042
16206
|
}
|
|
16043
16207
|
}, [store, renderer, scene, camera, isLegacy, rebuildVersion]);
|
|
16044
|
-
const passes = useThree((s) => s.passes);
|
|
16045
|
-
const renderPipeline = useThree((s) => s.renderPipeline);
|
|
16046
|
-
|
|
16047
|
-
|
|
16048
|
-
|
|
16049
|
-
clearPasses,
|
|
16050
|
-
reset,
|
|
16051
|
-
rebuild,
|
|
16052
|
-
// isReady indicates if RenderPipeline is configured and ready for rendering
|
|
16053
|
-
isReady: renderPipeline !== null
|
|
16054
|
-
};
|
|
16208
|
+
const passes = useThree$1((s) => s.passes);
|
|
16209
|
+
const renderPipeline = useThree$1((s) => s.renderPipeline);
|
|
16210
|
+
const actions = { passes, clearPasses, reset, rebuild };
|
|
16211
|
+
if (renderPipeline) return { ...actions, isReady: true, renderPipeline };
|
|
16212
|
+
return { ...actions, isReady: false, renderPipeline: null };
|
|
16055
16213
|
}
|
|
16056
16214
|
|
|
16057
16215
|
extend(THREE);
|
|
16216
|
+
const useThree = useThree$1;
|
|
16217
|
+
const useFrame = useFrame$1;
|
|
16218
|
+
const Canvas = Canvas$1;
|
|
16058
16219
|
|
|
16059
|
-
export { Block, Canvas, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, ErrorBoundary, FROM_REF, IsObject, ONCE, Portal, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, Texture, _roots, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, clearNodeScope, clearRootNodes, clearRootUniforms, clearScope, context, createEvents, createPointerEvents, createPortal, createRoot, createScopedStore, createStore, createTextureOperations, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, fromRef, getInstanceProps, getPrimary, getPrimaryIds, getRootState, getUuidPrefix, hasConstructor, hasPrimary, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isFromRef, isObject3D, isOnce, isOrthographicCamera, isRef$1 as isRef, isRenderer, isTexture, isVectorLike, once, prepare, presetsObj, rebuildAllBuffers, rebuildAllNodes, rebuildAllStorage, rebuildAllUniforms, reconciler, registerPrimary, removeInteractivity, removeNodes, removeUniforms, resolve, swapInteractivity, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useBuffers, useEnvironment, useFrame, useGPUStorage, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes, useRenderPipeline, useRenderTarget, useStore, useTexture, useTextures, useThree, useUniform, useUniforms, waitForPrimary };
|
|
16220
|
+
export { Block, Canvas, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, ErrorBoundary, FROM_REF, IsObject, ONCE, Portal, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, Texture, _roots, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, clearNodeScope, clearRootNodes, clearRootUniforms, clearScope, context, createEvents, createPointerEvents, createPortal, createRoot, createScopedStore, createStore, createTextureOperations, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, fromRef, getInstanceProps, getPrimary, getPrimaryIds, getRootState, getUuidPrefix, hasConstructor, hasPrimary, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isFromRef, isObject3D, isOnce, isOrthographicCamera, isRef$1 as isRef, isRenderer, isTexture, isVectorLike, once, prepare, presetsObj, rebuildAllBuffers, rebuildAllNodes, rebuildAllStorage, rebuildAllUniforms, reconciler, registerPrimary, registerRootExtension, removeInteractivity, removeNodes, removeUniforms, resolve, setRenderOverride, swapInteractivity, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useBuffers, useEnvironment, useFrame, useGPUStorage, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useLocalNodes, useMutableCallback, useNodes, useRenderPipeline, useRenderTarget, useStore, useTexture, useTextures, useThree, useUniform, useUniforms, waitForPrimary };
|