@react-three/fiber 10.0.0-canary.f046a54 → 10.0.0-canary.fd3335d
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/index.cjs +2207 -2024
- package/dist/index.d.cts +74 -33
- package/dist/index.d.mts +74 -33
- package/dist/index.d.ts +74 -33
- package/dist/index.mjs +2210 -2027
- package/dist/legacy.cjs +2205 -2027
- package/dist/legacy.d.cts +73 -35
- package/dist/legacy.d.mts +73 -35
- package/dist/legacy.d.ts +73 -35
- package/dist/legacy.mjs +2207 -2029
- package/dist/webgpu/index.cjs +2437 -2495
- package/dist/webgpu/index.d.cts +107 -37
- package/dist/webgpu/index.d.mts +107 -37
- package/dist/webgpu/index.d.ts +107 -37
- package/dist/webgpu/index.mjs +2440 -2498
- package/package.json +5 -5
- package/readme.md +1 -2
- package/react-reconciler/constants.d.ts +0 -7
- package/react-reconciler/constants.js +0 -1
- package/react-reconciler/index.d.ts +0 -1044
- package/react-reconciler/index.js +0 -208
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import * as webgpu from 'three/webgpu';
|
|
2
|
-
import {
|
|
3
|
-
import { WebGLRenderTarget, WebGLRenderer } from 'three';
|
|
4
|
-
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, Vector3, Vector2, TextureLoader, Texture as Texture$1, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, CanvasTarget, Raycaster, OrthographicCamera, PerspectiveCamera, Scene, PCFShadowMap, VSMShadowMap, BasicShadowMap, ACESFilmicToneMapping, WebGPURenderer, HalfFloatType, Color } from 'three/webgpu';
|
|
3
|
+
import { WebGLCubeRenderTarget, WebGLRenderTarget, WebGLRenderer } from 'three';
|
|
5
4
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
6
5
|
import * as React from 'react';
|
|
7
|
-
import React__default, {
|
|
6
|
+
import React__default, { useRef, useMemo, useLayoutEffect, useEffect, useContext, useImperativeHandle, useCallback, useState } from 'react';
|
|
8
7
|
import useMeasure from 'react-use-measure';
|
|
9
8
|
import { useFiber, useContextBridge, traverseFiber, FiberProvider } from 'its-fine';
|
|
10
|
-
import {
|
|
9
|
+
import { createWithEqualityFn } from 'zustand/traditional';
|
|
10
|
+
import { getScheduler } from '@pmndrs/scheduler';
|
|
11
|
+
export { Scheduler, getScheduler } from '@pmndrs/scheduler';
|
|
12
|
+
import Tb, { unstable_getCurrentPriorityLevel, unstable_IdlePriority, unstable_LowPriority, unstable_NormalPriority, unstable_UserBlockingPriority, unstable_ImmediatePriority, unstable_scheduleCallback } from 'scheduler';
|
|
11
13
|
import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
|
|
12
14
|
import { HDRLoader } from 'three/examples/jsm/loaders/HDRLoader.js';
|
|
13
15
|
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
|
|
14
16
|
import { UltraHDRLoader } from 'three/examples/jsm/loaders/UltraHDRLoader.js';
|
|
15
17
|
import { GainMapLoader } from '@monogrid/gainmap-js';
|
|
16
|
-
import Tb, { unstable_scheduleCallback, unstable_IdlePriority } from 'scheduler';
|
|
17
|
-
import { createWithEqualityFn } from 'zustand/traditional';
|
|
18
|
-
import { getScheduler } from '@pmndrs/scheduler';
|
|
19
|
-
export { Scheduler, getScheduler } from '@pmndrs/scheduler';
|
|
20
18
|
import { suspend, preload, clear } from 'suspend-react';
|
|
21
19
|
|
|
22
20
|
function _mergeNamespaces(n, m) {
|
|
@@ -33,15 +31,22 @@ function _mergeNamespaces(n, m) {
|
|
|
33
31
|
|
|
34
32
|
const R3F_BUILD_LEGACY = true;
|
|
35
33
|
const R3F_BUILD_WEBGPU = true;
|
|
34
|
+
async function loadInspector() {
|
|
35
|
+
const { Inspector } = await import('three/addons/inspector/Inspector.js');
|
|
36
|
+
return Inspector;
|
|
37
|
+
}
|
|
36
38
|
|
|
37
39
|
const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
38
40
|
__proto__: null,
|
|
39
|
-
|
|
41
|
+
CubeRenderTarget: CubeRenderTarget,
|
|
42
|
+
CubeRenderTargetCompat: CubeRenderTarget,
|
|
40
43
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
41
44
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
42
45
|
RenderTargetCompat: RenderTarget,
|
|
46
|
+
WebGLCubeRenderTarget: WebGLCubeRenderTarget,
|
|
43
47
|
WebGLRenderTarget: WebGLRenderTarget,
|
|
44
|
-
WebGLRenderer: WebGLRenderer
|
|
48
|
+
WebGLRenderer: WebGLRenderer,
|
|
49
|
+
loadInspector: loadInspector
|
|
45
50
|
}, [webgpu]);
|
|
46
51
|
|
|
47
52
|
const primaryRegistry = /* @__PURE__ */ new Map();
|
|
@@ -102,550 +107,223 @@ function getPrimaryIds() {
|
|
|
102
107
|
return Array.from(primaryRegistry.keys());
|
|
103
108
|
}
|
|
104
109
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
var __defProp = Object.defineProperty;
|
|
111
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
112
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
113
|
+
const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React.useLayoutEffect : React.useEffect;
|
|
114
|
+
function useMutableCallback(fn) {
|
|
115
|
+
const ref = React.useRef(fn);
|
|
116
|
+
useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
|
|
117
|
+
return ref;
|
|
118
|
+
}
|
|
119
|
+
function useBridge() {
|
|
120
|
+
const fiber = useFiber();
|
|
121
|
+
const ContextBridge = useContextBridge();
|
|
122
|
+
return React.useMemo(
|
|
123
|
+
() => ({ children }) => {
|
|
124
|
+
const strict = !!traverseFiber(fiber, true, (node) => node.type === React.StrictMode);
|
|
125
|
+
const Root = strict ? React.StrictMode : React.Fragment;
|
|
126
|
+
return /* @__PURE__ */ jsx(Root, { children: /* @__PURE__ */ jsx(ContextBridge, { children }) });
|
|
127
|
+
},
|
|
128
|
+
[fiber, ContextBridge]
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
function Block({ set }) {
|
|
132
|
+
useIsomorphicLayoutEffect(() => {
|
|
133
|
+
set(new Promise(() => null));
|
|
134
|
+
return () => set(false);
|
|
135
|
+
}, [set]);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const ErrorBoundary = /* @__PURE__ */ (() => {
|
|
139
|
+
var _a;
|
|
140
|
+
return _a = class extends React.Component {
|
|
141
|
+
constructor() {
|
|
142
|
+
super(...arguments);
|
|
143
|
+
__publicField(this, "state", { error: false });
|
|
144
|
+
}
|
|
145
|
+
componentDidCatch(err) {
|
|
146
|
+
this.props.set(err);
|
|
147
|
+
}
|
|
148
|
+
render() {
|
|
149
|
+
return this.state.error ? null : this.props.children;
|
|
150
|
+
}
|
|
151
|
+
}, __publicField(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
|
|
152
|
+
})();
|
|
117
153
|
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
} = {}) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
useLoader$1.clear(loader, multiFile ? [files] : files);
|
|
154
|
+
const is = {
|
|
155
|
+
obj: (a) => a === Object(a) && !is.arr(a) && typeof a !== "function",
|
|
156
|
+
fun: (a) => typeof a === "function",
|
|
157
|
+
str: (a) => typeof a === "string",
|
|
158
|
+
num: (a) => typeof a === "number",
|
|
159
|
+
boo: (a) => typeof a === "boolean",
|
|
160
|
+
und: (a) => a === void 0,
|
|
161
|
+
nul: (a) => a === null,
|
|
162
|
+
arr: (a) => Array.isArray(a),
|
|
163
|
+
equ(a, b, { arrays = "shallow", objects = "reference", strict = true } = {}) {
|
|
164
|
+
if (typeof a !== typeof b || !!a !== !!b) return false;
|
|
165
|
+
if (is.str(a) || is.num(a) || is.boo(a)) return a === b;
|
|
166
|
+
const isObj = is.obj(a);
|
|
167
|
+
if (isObj && objects === "reference") return a === b;
|
|
168
|
+
const isArr = is.arr(a);
|
|
169
|
+
if (isArr && arrays === "reference") return a === b;
|
|
170
|
+
if ((isArr || isObj) && a === b) return true;
|
|
171
|
+
let i;
|
|
172
|
+
for (i in a) if (!(i in b)) return false;
|
|
173
|
+
if (isObj && arrays === "shallow" && objects === "shallow") {
|
|
174
|
+
for (i in strict ? b : a) if (!is.equ(a[i], b[i], { strict, objects: "reference" })) return false;
|
|
175
|
+
} else {
|
|
176
|
+
for (i in strict ? b : a) if (a[i] !== b[i]) return false;
|
|
142
177
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
multiFile ? [files] : files,
|
|
148
|
-
(loader2) => {
|
|
149
|
-
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
150
|
-
loader2.setRenderer?.(renderer);
|
|
151
|
-
}
|
|
152
|
-
loader2.setPath?.(path);
|
|
153
|
-
if (extensions) extensions(loader2);
|
|
178
|
+
if (is.und(i)) {
|
|
179
|
+
if (isArr && a.length === 0 && b.length === 0) return true;
|
|
180
|
+
if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
|
|
181
|
+
if (a !== b) return false;
|
|
154
182
|
}
|
|
155
|
-
|
|
156
|
-
let texture = multiFile ? (
|
|
157
|
-
// @ts-ignore
|
|
158
|
-
loaderResult[0]
|
|
159
|
-
) : loaderResult;
|
|
160
|
-
if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
|
|
161
|
-
texture = texture.renderTarget?.texture;
|
|
162
|
-
}
|
|
163
|
-
texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
|
|
164
|
-
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
165
|
-
return texture;
|
|
166
|
-
}
|
|
167
|
-
const preloadDefaultOptions = {
|
|
168
|
-
files: defaultFiles,
|
|
169
|
-
path: "",
|
|
170
|
-
preset: void 0,
|
|
171
|
-
extensions: void 0
|
|
172
|
-
};
|
|
173
|
-
useEnvironment.preload = (preloadOptions) => {
|
|
174
|
-
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
175
|
-
let { files, path = "" } = options;
|
|
176
|
-
const { preset, extensions } = options;
|
|
177
|
-
if (preset) {
|
|
178
|
-
validatePreset(preset);
|
|
179
|
-
files = presetsObj[preset];
|
|
180
|
-
path = CUBEMAP_ROOT;
|
|
181
|
-
}
|
|
182
|
-
const { extension } = getExtension(files);
|
|
183
|
-
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
184
|
-
throw new Error("useEnvironment: Preloading gainmaps is not supported");
|
|
185
|
-
}
|
|
186
|
-
const loader = getLoader$1(extension);
|
|
187
|
-
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
188
|
-
useLoader$1.preload(loader, isArray(files) ? [files] : files, (loader2) => {
|
|
189
|
-
loader2.setPath?.(path);
|
|
190
|
-
if (extensions) extensions(loader2);
|
|
191
|
-
});
|
|
192
|
-
};
|
|
193
|
-
const clearDefaultOptins = {
|
|
194
|
-
files: defaultFiles,
|
|
195
|
-
preset: void 0
|
|
196
|
-
};
|
|
197
|
-
useEnvironment.clear = (clearOptions) => {
|
|
198
|
-
const options = { ...clearDefaultOptins, ...clearOptions };
|
|
199
|
-
let { files } = options;
|
|
200
|
-
const { preset } = options;
|
|
201
|
-
if (preset) {
|
|
202
|
-
validatePreset(preset);
|
|
203
|
-
files = presetsObj[preset];
|
|
183
|
+
return true;
|
|
204
184
|
}
|
|
205
|
-
const { extension } = getExtension(files);
|
|
206
|
-
const loader = getLoader$1(extension);
|
|
207
|
-
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
208
|
-
useLoader$1.clear(loader, isArray(files) ? [files] : files);
|
|
209
185
|
};
|
|
210
|
-
|
|
211
|
-
|
|
186
|
+
const isOrthographicCamera = (def) => def && def.isOrthographicCamera;
|
|
187
|
+
const isRef$1 = (obj) => obj !== null && typeof obj === "object" && obj.hasOwnProperty("current");
|
|
188
|
+
const isColorRepresentation = (value) => value != null && (typeof value === "string" || typeof value === "number" || value.isColor);
|
|
189
|
+
const isObject3D = (object) => object?.isObject3D;
|
|
190
|
+
const isTexture = (value) => !!value?.isTexture;
|
|
191
|
+
const isVectorLike = (object) => object !== null && typeof object === "object" && "set" in object && typeof object.set === "function";
|
|
192
|
+
const isCopyable = (object) => isVectorLike(object) && "copy" in object && typeof object.copy === "function";
|
|
193
|
+
const hasConstructor = (object) => !!object?.constructor;
|
|
194
|
+
|
|
195
|
+
function calculateDpr(dpr) {
|
|
196
|
+
const target = typeof window !== "undefined" ? window.devicePixelRatio ?? 2 : 1;
|
|
197
|
+
return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
|
|
212
198
|
}
|
|
213
|
-
function
|
|
214
|
-
|
|
215
|
-
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
216
|
-
const firstEntry = isArray(files) ? files[0] : files;
|
|
217
|
-
const extension = isCubemap ? "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
218
|
-
return { extension, isCubemap, isGainmap };
|
|
199
|
+
function getUuidPrefix(uuid) {
|
|
200
|
+
return uuid.split("-")[0];
|
|
219
201
|
}
|
|
220
|
-
function
|
|
221
|
-
|
|
222
|
-
|
|
202
|
+
function updateCamera(camera, size) {
|
|
203
|
+
if (camera.manual) return;
|
|
204
|
+
if (isOrthographicCamera(camera)) {
|
|
205
|
+
camera.left = size.width / -2;
|
|
206
|
+
camera.right = size.width / 2;
|
|
207
|
+
camera.top = size.height / 2;
|
|
208
|
+
camera.bottom = size.height / -2;
|
|
209
|
+
} else {
|
|
210
|
+
camera.aspect = size.width / size.height;
|
|
211
|
+
}
|
|
212
|
+
camera.updateProjectionMatrix();
|
|
223
213
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
backgroundIntensity: 1,
|
|
231
|
-
backgroundRotation: [0, 0, 0],
|
|
232
|
-
environmentIntensity: 1,
|
|
233
|
-
environmentRotation: [0, 0, 0],
|
|
234
|
-
...sceneProps
|
|
235
|
-
};
|
|
236
|
-
const target = resolveScene(scene || defaultScene);
|
|
237
|
-
const oldbg = target.background;
|
|
238
|
-
const oldenv = target.environment;
|
|
239
|
-
const oldSceneProps = {
|
|
240
|
-
// @ts-ignore
|
|
241
|
-
backgroundBlurriness: target.backgroundBlurriness,
|
|
242
|
-
// @ts-ignore
|
|
243
|
-
backgroundIntensity: target.backgroundIntensity,
|
|
244
|
-
// @ts-ignore
|
|
245
|
-
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
246
|
-
// @ts-ignore
|
|
247
|
-
environmentIntensity: target.environmentIntensity,
|
|
248
|
-
// @ts-ignore
|
|
249
|
-
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
250
|
-
};
|
|
251
|
-
if (background !== "only") target.environment = texture;
|
|
252
|
-
if (background) target.background = texture;
|
|
253
|
-
applyProps$1(target, sceneProps);
|
|
254
|
-
return () => {
|
|
255
|
-
if (background !== "only") target.environment = oldenv;
|
|
256
|
-
if (background) target.background = oldbg;
|
|
257
|
-
applyProps$1(target, oldSceneProps);
|
|
258
|
-
};
|
|
214
|
+
const frustumMatrix = new Matrix4();
|
|
215
|
+
function updateFrustum(camera, frustum) {
|
|
216
|
+
const target = frustum ?? new Frustum();
|
|
217
|
+
frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
218
|
+
target.setFromProjectionMatrix(frustumMatrix);
|
|
219
|
+
return target;
|
|
259
220
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return
|
|
221
|
+
|
|
222
|
+
const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
|
|
223
|
+
function findInitialRoot(instance) {
|
|
224
|
+
let root = instance.root;
|
|
225
|
+
while (root.getState().previousRoot) root = root.getState().previousRoot;
|
|
226
|
+
return root;
|
|
266
227
|
}
|
|
267
|
-
function
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
...rest
|
|
277
|
-
}) {
|
|
278
|
-
const texture = useEnvironment(rest);
|
|
279
|
-
const defaultScene = useThree$1((state) => state.scene);
|
|
280
|
-
React.useLayoutEffect(() => {
|
|
281
|
-
return setEnvProps(background, scene, defaultScene, texture, {
|
|
282
|
-
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
283
|
-
backgroundIntensity,
|
|
284
|
-
backgroundRotation,
|
|
285
|
-
environmentIntensity,
|
|
286
|
-
environmentRotation
|
|
228
|
+
function getRootState(obj) {
|
|
229
|
+
let state = obj.__r3f?.root.getState();
|
|
230
|
+
if (!state) {
|
|
231
|
+
obj.traverseAncestors((ancestor) => {
|
|
232
|
+
const parentState = ancestor.__r3f?.root.getState();
|
|
233
|
+
if (parentState) {
|
|
234
|
+
state = parentState;
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
287
237
|
});
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return () => {
|
|
291
|
-
texture.dispose();
|
|
292
|
-
};
|
|
293
|
-
}, [texture]);
|
|
294
|
-
return null;
|
|
238
|
+
}
|
|
239
|
+
return state;
|
|
295
240
|
}
|
|
296
|
-
function
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
path,
|
|
313
|
-
preset = void 0,
|
|
314
|
-
extensions
|
|
315
|
-
}) {
|
|
316
|
-
const gl = useThree$1((state) => state.gl);
|
|
317
|
-
const defaultScene = useThree$1((state) => state.scene);
|
|
318
|
-
const camera = React.useRef(null);
|
|
319
|
-
const [virtualScene] = React.useState(() => new Scene());
|
|
320
|
-
const fbo = React.useMemo(() => {
|
|
321
|
-
const fbo2 = new WebGLCubeRenderTarget(resolution);
|
|
322
|
-
fbo2.texture.type = HalfFloatType;
|
|
323
|
-
return fbo2;
|
|
324
|
-
}, [resolution]);
|
|
325
|
-
React.useEffect(() => {
|
|
326
|
-
return () => {
|
|
327
|
-
fbo.dispose();
|
|
328
|
-
};
|
|
329
|
-
}, [fbo]);
|
|
330
|
-
React.useLayoutEffect(() => {
|
|
331
|
-
if (frames === 1) {
|
|
332
|
-
const autoClear = gl.autoClear;
|
|
333
|
-
gl.autoClear = true;
|
|
334
|
-
camera.current.update(gl, virtualScene);
|
|
335
|
-
gl.autoClear = autoClear;
|
|
336
|
-
}
|
|
337
|
-
return setEnvProps(background, scene, defaultScene, fbo.texture, {
|
|
338
|
-
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
339
|
-
backgroundIntensity,
|
|
340
|
-
backgroundRotation,
|
|
341
|
-
environmentIntensity,
|
|
342
|
-
environmentRotation
|
|
241
|
+
function buildGraph(object) {
|
|
242
|
+
const data = { nodes: {}, materials: {}, meshes: {} };
|
|
243
|
+
if (object) {
|
|
244
|
+
object.traverse((obj) => {
|
|
245
|
+
if (obj.name) data.nodes[obj.name] = obj;
|
|
246
|
+
if (obj.material) {
|
|
247
|
+
const material = Array.isArray(obj.material) ? obj.material[0] : obj.material;
|
|
248
|
+
const nameAlreadyUsed = data.materials[material.name];
|
|
249
|
+
let materialName = material.name;
|
|
250
|
+
if (nameAlreadyUsed) {
|
|
251
|
+
materialName = materialName + `-${getUuidPrefix(material.uuid)}`;
|
|
252
|
+
material.userData.materialCacheName = materialName;
|
|
253
|
+
}
|
|
254
|
+
data.materials[materialName] = material;
|
|
255
|
+
}
|
|
256
|
+
if (obj.isMesh && !data.meshes[obj.name]) data.meshes[obj.name] = obj;
|
|
343
257
|
});
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
virtualScene,
|
|
347
|
-
fbo.texture,
|
|
348
|
-
scene,
|
|
349
|
-
defaultScene,
|
|
350
|
-
background,
|
|
351
|
-
frames,
|
|
352
|
-
gl,
|
|
353
|
-
blur,
|
|
354
|
-
backgroundBlurriness,
|
|
355
|
-
backgroundIntensity,
|
|
356
|
-
backgroundRotation,
|
|
357
|
-
environmentIntensity,
|
|
358
|
-
environmentRotation
|
|
359
|
-
]);
|
|
360
|
-
let count = 1;
|
|
361
|
-
useFrame$1(() => {
|
|
362
|
-
if (frames === Infinity || count < frames) {
|
|
363
|
-
const autoClear = gl.autoClear;
|
|
364
|
-
gl.autoClear = true;
|
|
365
|
-
camera.current.update(gl, virtualScene);
|
|
366
|
-
gl.autoClear = autoClear;
|
|
367
|
-
count++;
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
return /* @__PURE__ */ jsx(Fragment, { children: createPortal$1(
|
|
371
|
-
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
372
|
-
children,
|
|
373
|
-
/* @__PURE__ */ jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
|
|
374
|
-
files || preset ? /* @__PURE__ */ jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsx(EnvironmentMap, { background: true, map, extensions }) : null
|
|
375
|
-
] }),
|
|
376
|
-
virtualScene
|
|
377
|
-
) });
|
|
378
|
-
}
|
|
379
|
-
function EnvironmentGround(props) {
|
|
380
|
-
const textureDefault = useEnvironment(props);
|
|
381
|
-
const texture = props.map || textureDefault;
|
|
382
|
-
React.useMemo(() => extend$1({ GroundProjectedEnvImpl: GroundedSkybox }), []);
|
|
383
|
-
React.useEffect(() => {
|
|
384
|
-
return () => {
|
|
385
|
-
textureDefault.dispose();
|
|
386
|
-
};
|
|
387
|
-
}, [textureDefault]);
|
|
388
|
-
const height = props.ground?.height ?? 15;
|
|
389
|
-
const radius = props.ground?.radius ?? 60;
|
|
390
|
-
const scale = props.ground?.scale ?? 1e3;
|
|
391
|
-
const args = React.useMemo(
|
|
392
|
-
() => [texture, height, radius],
|
|
393
|
-
[texture, height, radius]
|
|
394
|
-
);
|
|
395
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
396
|
-
/* @__PURE__ */ jsx(EnvironmentMap, { ...props, map: texture }),
|
|
397
|
-
/* @__PURE__ */ jsx("groundProjectedEnvImpl", { args, scale })
|
|
398
|
-
] });
|
|
399
|
-
}
|
|
400
|
-
function EnvironmentColor({ color, scene }) {
|
|
401
|
-
const defaultScene = useThree$1((state) => state.scene);
|
|
402
|
-
React.useLayoutEffect(() => {
|
|
403
|
-
if (color === void 0) return;
|
|
404
|
-
const target = resolveScene(scene || defaultScene);
|
|
405
|
-
const oldBg = target.background;
|
|
406
|
-
target.background = new Color(color);
|
|
407
|
-
return () => {
|
|
408
|
-
target.background = oldBg;
|
|
409
|
-
};
|
|
410
|
-
});
|
|
411
|
-
return null;
|
|
412
|
-
}
|
|
413
|
-
function EnvironmentDualSource(props) {
|
|
414
|
-
const { backgroundFiles, ...envProps } = props;
|
|
415
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
416
|
-
/* @__PURE__ */ jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
417
|
-
/* @__PURE__ */ jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
|
|
418
|
-
] });
|
|
258
|
+
}
|
|
259
|
+
return data;
|
|
419
260
|
}
|
|
420
|
-
function
|
|
421
|
-
if (
|
|
422
|
-
|
|
261
|
+
function dispose(obj) {
|
|
262
|
+
if (obj.type !== "Scene") obj.dispose?.();
|
|
263
|
+
for (const p in obj) {
|
|
264
|
+
const prop = obj[p];
|
|
265
|
+
if (prop?.type !== "Scene") prop?.dispose?.();
|
|
423
266
|
}
|
|
424
|
-
|
|
425
|
-
|
|
267
|
+
}
|
|
268
|
+
function getInstanceProps(pendingProps) {
|
|
269
|
+
const props = {};
|
|
270
|
+
for (const key in pendingProps) {
|
|
271
|
+
if (!REACT_INTERNAL_PROPS.includes(key)) props[key] = pendingProps[key];
|
|
426
272
|
}
|
|
427
|
-
return props
|
|
273
|
+
return props;
|
|
428
274
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
275
|
+
function prepare(target, root, type, props) {
|
|
276
|
+
const object = target;
|
|
277
|
+
let instance = object?.__r3f;
|
|
278
|
+
if (!instance) {
|
|
279
|
+
instance = {
|
|
280
|
+
root,
|
|
281
|
+
type,
|
|
282
|
+
parent: null,
|
|
283
|
+
children: [],
|
|
284
|
+
props: getInstanceProps(props),
|
|
285
|
+
object,
|
|
286
|
+
eventCount: 0,
|
|
287
|
+
handlers: {},
|
|
288
|
+
isHidden: false
|
|
289
|
+
};
|
|
290
|
+
if (object) object.__r3f = instance;
|
|
291
|
+
}
|
|
292
|
+
return instance;
|
|
439
293
|
}
|
|
440
|
-
function
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
const strict = !!traverseFiber(fiber, true, (node) => node.type === React.StrictMode);
|
|
446
|
-
const Root = strict ? React.StrictMode : React.Fragment;
|
|
447
|
-
return /* @__PURE__ */ jsx(Root, { children: /* @__PURE__ */ jsx(ContextBridge, { children }) });
|
|
448
|
-
},
|
|
449
|
-
[fiber, ContextBridge]
|
|
450
|
-
);
|
|
294
|
+
function invalidateInstance(instance) {
|
|
295
|
+
if (!instance.parent) return;
|
|
296
|
+
instance.props.onUpdate?.(instance.object);
|
|
297
|
+
const state = instance.root?.getState?.();
|
|
298
|
+
if (state && state.internal.frames === 0) state.invalidate();
|
|
451
299
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
return
|
|
300
|
+
|
|
301
|
+
const tempFrustum = new Frustum();
|
|
302
|
+
let hasWarnedWebGL = false;
|
|
303
|
+
let tslModule = null;
|
|
304
|
+
async function loadTSL() {
|
|
305
|
+
if (tslModule) return tslModule;
|
|
306
|
+
try {
|
|
307
|
+
const tsl = await import('three/tsl');
|
|
308
|
+
tslModule = { uniform: tsl.uniform, nodeObject: tsl.nodeObject };
|
|
309
|
+
return tslModule;
|
|
310
|
+
} catch {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
458
313
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}, __publicField(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
|
|
473
|
-
})();
|
|
474
|
-
|
|
475
|
-
const is = {
|
|
476
|
-
obj: (a) => a === Object(a) && !is.arr(a) && typeof a !== "function",
|
|
477
|
-
fun: (a) => typeof a === "function",
|
|
478
|
-
str: (a) => typeof a === "string",
|
|
479
|
-
num: (a) => typeof a === "number",
|
|
480
|
-
boo: (a) => typeof a === "boolean",
|
|
481
|
-
und: (a) => a === void 0,
|
|
482
|
-
nul: (a) => a === null,
|
|
483
|
-
arr: (a) => Array.isArray(a),
|
|
484
|
-
equ(a, b, { arrays = "shallow", objects = "reference", strict = true } = {}) {
|
|
485
|
-
if (typeof a !== typeof b || !!a !== !!b) return false;
|
|
486
|
-
if (is.str(a) || is.num(a) || is.boo(a)) return a === b;
|
|
487
|
-
const isObj = is.obj(a);
|
|
488
|
-
if (isObj && objects === "reference") return a === b;
|
|
489
|
-
const isArr = is.arr(a);
|
|
490
|
-
if (isArr && arrays === "reference") return a === b;
|
|
491
|
-
if ((isArr || isObj) && a === b) return true;
|
|
492
|
-
let i;
|
|
493
|
-
for (i in a) if (!(i in b)) return false;
|
|
494
|
-
if (isObj && arrays === "shallow" && objects === "shallow") {
|
|
495
|
-
for (i in strict ? b : a) if (!is.equ(a[i], b[i], { strict, objects: "reference" })) return false;
|
|
496
|
-
} else {
|
|
497
|
-
for (i in strict ? b : a) if (a[i] !== b[i]) return false;
|
|
498
|
-
}
|
|
499
|
-
if (is.und(i)) {
|
|
500
|
-
if (isArr && a.length === 0 && b.length === 0) return true;
|
|
501
|
-
if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
|
|
502
|
-
if (a !== b) return false;
|
|
503
|
-
}
|
|
504
|
-
return true;
|
|
505
|
-
}
|
|
506
|
-
};
|
|
507
|
-
const isOrthographicCamera = (def) => def && def.isOrthographicCamera;
|
|
508
|
-
const isRef = (obj) => obj !== null && typeof obj === "object" && obj.hasOwnProperty("current");
|
|
509
|
-
const isColorRepresentation = (value) => value != null && (typeof value === "string" || typeof value === "number" || value.isColor);
|
|
510
|
-
const isObject3D = (object) => object?.isObject3D;
|
|
511
|
-
const isTexture = (value) => !!value?.isTexture;
|
|
512
|
-
const isVectorLike = (object) => object !== null && typeof object === "object" && "set" in object && typeof object.set === "function";
|
|
513
|
-
const isCopyable = (object) => isVectorLike(object) && "copy" in object && typeof object.copy === "function";
|
|
514
|
-
const hasConstructor = (object) => !!object?.constructor;
|
|
515
|
-
|
|
516
|
-
function calculateDpr(dpr) {
|
|
517
|
-
const target = typeof window !== "undefined" ? window.devicePixelRatio ?? 2 : 1;
|
|
518
|
-
return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
|
|
519
|
-
}
|
|
520
|
-
function getUuidPrefix(uuid) {
|
|
521
|
-
return uuid.split("-")[0];
|
|
522
|
-
}
|
|
523
|
-
function updateCamera(camera, size) {
|
|
524
|
-
if (camera.manual) return;
|
|
525
|
-
if (isOrthographicCamera(camera)) {
|
|
526
|
-
camera.left = size.width / -2;
|
|
527
|
-
camera.right = size.width / 2;
|
|
528
|
-
camera.top = size.height / 2;
|
|
529
|
-
camera.bottom = size.height / -2;
|
|
530
|
-
} else {
|
|
531
|
-
camera.aspect = size.width / size.height;
|
|
532
|
-
}
|
|
533
|
-
camera.updateProjectionMatrix();
|
|
534
|
-
}
|
|
535
|
-
const frustumMatrix = new Matrix4();
|
|
536
|
-
function updateFrustum(camera, frustum) {
|
|
537
|
-
const target = frustum ?? new Frustum();
|
|
538
|
-
frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
539
|
-
target.setFromProjectionMatrix(frustumMatrix);
|
|
540
|
-
return target;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
|
|
544
|
-
function findInitialRoot(instance) {
|
|
545
|
-
let root = instance.root;
|
|
546
|
-
while (root.getState().previousRoot) root = root.getState().previousRoot;
|
|
547
|
-
return root;
|
|
548
|
-
}
|
|
549
|
-
function getRootState(obj) {
|
|
550
|
-
let state = obj.__r3f?.root.getState();
|
|
551
|
-
if (!state) {
|
|
552
|
-
obj.traverseAncestors((ancestor) => {
|
|
553
|
-
const parentState = ancestor.__r3f?.root.getState();
|
|
554
|
-
if (parentState) {
|
|
555
|
-
state = parentState;
|
|
556
|
-
return false;
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
return state;
|
|
561
|
-
}
|
|
562
|
-
function buildGraph(object) {
|
|
563
|
-
const data = { nodes: {}, materials: {}, meshes: {} };
|
|
564
|
-
if (object) {
|
|
565
|
-
object.traverse((obj) => {
|
|
566
|
-
if (obj.name) data.nodes[obj.name] = obj;
|
|
567
|
-
if (obj.material) {
|
|
568
|
-
const material = Array.isArray(obj.material) ? obj.material[0] : obj.material;
|
|
569
|
-
const nameAlreadyUsed = data.materials[material.name];
|
|
570
|
-
let materialName = material.name;
|
|
571
|
-
if (nameAlreadyUsed) {
|
|
572
|
-
materialName = materialName + `-${getUuidPrefix(material.uuid)}`;
|
|
573
|
-
material.userData.materialCacheName = materialName;
|
|
574
|
-
}
|
|
575
|
-
data.materials[materialName] = material;
|
|
576
|
-
}
|
|
577
|
-
if (obj.isMesh && !data.meshes[obj.name]) data.meshes[obj.name] = obj;
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
return data;
|
|
581
|
-
}
|
|
582
|
-
function dispose(obj) {
|
|
583
|
-
if (obj.type !== "Scene") obj.dispose?.();
|
|
584
|
-
for (const p in obj) {
|
|
585
|
-
const prop = obj[p];
|
|
586
|
-
if (prop?.type !== "Scene") prop?.dispose?.();
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
function getInstanceProps(pendingProps) {
|
|
590
|
-
const props = {};
|
|
591
|
-
for (const key in pendingProps) {
|
|
592
|
-
if (!REACT_INTERNAL_PROPS.includes(key)) props[key] = pendingProps[key];
|
|
593
|
-
}
|
|
594
|
-
return props;
|
|
595
|
-
}
|
|
596
|
-
function prepare(target, root, type, props) {
|
|
597
|
-
const object = target;
|
|
598
|
-
let instance = object?.__r3f;
|
|
599
|
-
if (!instance) {
|
|
600
|
-
instance = {
|
|
601
|
-
root,
|
|
602
|
-
type,
|
|
603
|
-
parent: null,
|
|
604
|
-
children: [],
|
|
605
|
-
props: getInstanceProps(props),
|
|
606
|
-
object,
|
|
607
|
-
eventCount: 0,
|
|
608
|
-
handlers: {},
|
|
609
|
-
isHidden: false,
|
|
610
|
-
deferredRefs: []
|
|
611
|
-
};
|
|
612
|
-
if (object) object.__r3f = instance;
|
|
613
|
-
}
|
|
614
|
-
return instance;
|
|
615
|
-
}
|
|
616
|
-
function invalidateInstance(instance) {
|
|
617
|
-
if (!instance.parent) return;
|
|
618
|
-
instance.props.onUpdate?.(instance.object);
|
|
619
|
-
const state = instance.root?.getState?.();
|
|
620
|
-
if (state && state.internal.frames === 0) state.invalidate();
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
const tempFrustum = new Frustum();
|
|
624
|
-
let hasWarnedWebGL = false;
|
|
625
|
-
let tslModule = null;
|
|
626
|
-
async function loadTSL() {
|
|
627
|
-
if (tslModule) return tslModule;
|
|
628
|
-
try {
|
|
629
|
-
const tsl = await import('three/tsl');
|
|
630
|
-
tslModule = { uniform: tsl.uniform, nodeObject: tsl.nodeObject };
|
|
631
|
-
return tslModule;
|
|
632
|
-
} catch {
|
|
633
|
-
return null;
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
function createOcclusionObserverNode(store, uniform) {
|
|
637
|
-
const node = new Node("float");
|
|
638
|
-
node.updateType = NodeUpdateType.OBJECT;
|
|
639
|
-
node.update = function(frame) {
|
|
640
|
-
const { internal } = store.getState();
|
|
641
|
-
const registry = internal.visibilityRegistry;
|
|
642
|
-
const cache = internal.occlusionCache;
|
|
643
|
-
for (const entry of registry.values()) {
|
|
644
|
-
const { object, handlers } = entry;
|
|
645
|
-
if (handlers.onOccluded || handlers.onVisible) {
|
|
646
|
-
const isOccluded = frame.renderer.isOccluded(object);
|
|
647
|
-
cache.set(object, isOccluded);
|
|
648
|
-
}
|
|
314
|
+
function createOcclusionObserverNode(store, uniform) {
|
|
315
|
+
const node = new Node("float");
|
|
316
|
+
node.updateType = NodeUpdateType.OBJECT;
|
|
317
|
+
node.update = function(frame) {
|
|
318
|
+
const { internal } = store.getState();
|
|
319
|
+
const registry = internal.visibilityRegistry;
|
|
320
|
+
const cache = internal.occlusionCache;
|
|
321
|
+
for (const entry of registry.values()) {
|
|
322
|
+
const { object, handlers } = entry;
|
|
323
|
+
if (handlers.onOccluded || handlers.onVisible) {
|
|
324
|
+
const isOccluded = frame.renderer.isOccluded(object);
|
|
325
|
+
cache.set(object, isOccluded);
|
|
326
|
+
}
|
|
649
327
|
}
|
|
650
328
|
};
|
|
651
329
|
node.setup = function() {
|
|
@@ -764,6 +442,17 @@ function unregisterVisibility(store, object) {
|
|
|
764
442
|
internal.visibilityRegistry.delete(object.uuid);
|
|
765
443
|
internal.occlusionCache.delete(object);
|
|
766
444
|
}
|
|
445
|
+
function updateVisibilityHandlers(store, object, handlers) {
|
|
446
|
+
const { internal } = store.getState();
|
|
447
|
+
const entry = internal.visibilityRegistry.get(object.uuid);
|
|
448
|
+
if (!entry) return false;
|
|
449
|
+
entry.handlers = handlers;
|
|
450
|
+
if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
|
|
451
|
+
object.occlusionTest = true;
|
|
452
|
+
enableOcclusion(store);
|
|
453
|
+
}
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
767
456
|
function checkVisibility(state) {
|
|
768
457
|
const { internal, camera } = state;
|
|
769
458
|
const registry = internal.visibilityRegistry;
|
|
@@ -924,9 +613,9 @@ function diffProps(instance, newProps) {
|
|
|
924
613
|
const { root, key } = resolve(instance.object, prop);
|
|
925
614
|
if (root.constructor && root.constructor.length === 0) {
|
|
926
615
|
const ctor = getMemoizedPrototype(root);
|
|
927
|
-
if (!is.und(ctor)) changedProps[
|
|
616
|
+
if (!is.und(ctor)) changedProps[prop] = ctor[key];
|
|
928
617
|
} else {
|
|
929
|
-
changedProps[
|
|
618
|
+
changedProps[prop] = 0;
|
|
930
619
|
}
|
|
931
620
|
}
|
|
932
621
|
return changedProps;
|
|
@@ -951,10 +640,7 @@ function applyProps(object, props) {
|
|
|
951
640
|
continue;
|
|
952
641
|
}
|
|
953
642
|
if (value === void 0) continue;
|
|
954
|
-
if (isFromRef(value))
|
|
955
|
-
instance?.deferredRefs?.push({ prop, ref: value[FROM_REF] });
|
|
956
|
-
continue;
|
|
957
|
-
}
|
|
643
|
+
if (isFromRef(value)) continue;
|
|
958
644
|
if (isOnce(value)) {
|
|
959
645
|
if (instance?.appliedOnce?.has(prop)) continue;
|
|
960
646
|
if (instance) {
|
|
@@ -1021,6 +707,9 @@ function applyProps(object, props) {
|
|
|
1021
707
|
if (instance.eventCount && object2.raycast !== null) {
|
|
1022
708
|
rootState.internal.interaction.push(object2);
|
|
1023
709
|
}
|
|
710
|
+
}
|
|
711
|
+
if (instance?.parent && rootState?.internal && instance.object?.isObject3D) {
|
|
712
|
+
const object2 = instance.object;
|
|
1024
713
|
const root = findInitialRoot(instance);
|
|
1025
714
|
const visibilityHandlers = {
|
|
1026
715
|
onFramed: instance.handlers.onFramed,
|
|
@@ -1028,7 +717,9 @@ function applyProps(object, props) {
|
|
|
1028
717
|
onVisible: instance.handlers.onVisible
|
|
1029
718
|
};
|
|
1030
719
|
if (hasVisibilityHandlers(visibilityHandlers)) {
|
|
1031
|
-
|
|
720
|
+
if (!updateVisibilityHandlers(root, object2, visibilityHandlers)) {
|
|
721
|
+
registerVisibility(root, object2, visibilityHandlers);
|
|
722
|
+
}
|
|
1032
723
|
} else {
|
|
1033
724
|
unregisterVisibility(root, object2);
|
|
1034
725
|
}
|
|
@@ -1041,1314 +732,890 @@ function applyProps(object, props) {
|
|
|
1041
732
|
return object;
|
|
1042
733
|
}
|
|
1043
734
|
|
|
1044
|
-
const
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
735
|
+
const shownNotices = /* @__PURE__ */ new Set();
|
|
736
|
+
function notifyDepreciated({ heading, body, link }) {
|
|
737
|
+
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
if (shownNotices.has(heading)) return;
|
|
741
|
+
shownNotices.add(heading);
|
|
742
|
+
const caller = getCallerFrame();
|
|
743
|
+
if (caller) {
|
|
744
|
+
console.log();
|
|
745
|
+
}
|
|
746
|
+
const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
|
|
747
|
+
if (caller) {
|
|
748
|
+
console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
|
|
749
|
+
}
|
|
750
|
+
if (body || link) {
|
|
751
|
+
let message = "";
|
|
752
|
+
if (body) message += body;
|
|
753
|
+
if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
|
|
754
|
+
console.warn(`%c${message}`, "font-weight: bold;");
|
|
1056
755
|
}
|
|
1057
|
-
return state;
|
|
1058
756
|
}
|
|
1059
|
-
function
|
|
1060
|
-
|
|
757
|
+
function getCallerFrame(depth = 3) {
|
|
758
|
+
const stack = new Error().stack;
|
|
759
|
+
if (!stack) return null;
|
|
760
|
+
const lines = stack.split("\n");
|
|
761
|
+
const frame = lines[depth];
|
|
762
|
+
if (!frame) return null;
|
|
763
|
+
let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
|
|
764
|
+
if (!match) {
|
|
765
|
+
match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
|
|
766
|
+
}
|
|
767
|
+
if (!match) return null;
|
|
768
|
+
const [, fn, url, line] = match;
|
|
769
|
+
return {
|
|
770
|
+
functionName: fn ?? "<anonymous>",
|
|
771
|
+
location: formatLocation(url, Number(line))
|
|
772
|
+
};
|
|
1061
773
|
}
|
|
1062
|
-
function
|
|
1063
|
-
|
|
774
|
+
function formatLocation(url, line) {
|
|
775
|
+
const clean = url.split("?")[0];
|
|
776
|
+
const file = clean.split("/").pop() ?? clean;
|
|
777
|
+
return `${file}:${line}`;
|
|
1064
778
|
}
|
|
1065
|
-
function
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
const captureData = pointerState.captured.get(obj);
|
|
1069
|
-
if (captureData) {
|
|
1070
|
-
pointerState.captured.delete(obj);
|
|
1071
|
-
captureData.target.releasePointerCapture(pointerId);
|
|
779
|
+
function notifyAlpha({ message, link }) {
|
|
780
|
+
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
|
|
781
|
+
return;
|
|
1072
782
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
pointerState.hovered.forEach((value, key) => {
|
|
1080
|
-
if (value.eventObject === object || value.object === object) {
|
|
1081
|
-
pointerState.hovered.delete(key);
|
|
1082
|
-
}
|
|
1083
|
-
});
|
|
1084
|
-
if (pointerState.captured.has(object)) {
|
|
1085
|
-
releaseInternalPointerCapture(internal, object, pointerId);
|
|
1086
|
-
}
|
|
783
|
+
if (shownNotices.has(message)) return;
|
|
784
|
+
shownNotices.add(message);
|
|
785
|
+
const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
|
|
786
|
+
console.log(`%c\u{1F52C} ${message}`, boxStyle);
|
|
787
|
+
{
|
|
788
|
+
console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
|
|
1087
789
|
}
|
|
1088
|
-
unregisterVisibility(store, object);
|
|
1089
790
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
if (!state.previousRoot) {
|
|
1121
|
-
state.events.compute?.(event, state);
|
|
1122
|
-
}
|
|
1123
|
-
function handleRaycast(obj) {
|
|
1124
|
-
const state2 = getRootState(obj);
|
|
1125
|
-
if (!state2 || !state2.events.enabled || state2.raycaster.camera === null) return [];
|
|
1126
|
-
if (state2.raycaster.camera === void 0) {
|
|
1127
|
-
state2.events.compute?.(event, state2, state2.previousRoot?.getState());
|
|
1128
|
-
if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
|
|
1129
|
-
}
|
|
1130
|
-
return state2.raycaster.camera ? state2.raycaster.intersectObject(obj, true) : [];
|
|
1131
|
-
}
|
|
1132
|
-
let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
|
|
1133
|
-
const aInteractivePriority = a.object.userData?.interactivePriority;
|
|
1134
|
-
const bInteractivePriority = b.object.userData?.interactivePriority;
|
|
1135
|
-
if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
|
|
1136
|
-
if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
|
|
1137
|
-
if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
|
|
1138
|
-
if (aInteractivePriority !== bInteractivePriority) {
|
|
1139
|
-
return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
const aState = getRootState(a.object);
|
|
1143
|
-
const bState = getRootState(b.object);
|
|
1144
|
-
const aPriority = aState?.events?.priority ?? 1;
|
|
1145
|
-
const bPriority = bState?.events?.priority ?? 1;
|
|
1146
|
-
return bPriority - aPriority || a.distance - b.distance;
|
|
1147
|
-
}).filter((item) => {
|
|
1148
|
-
const id = makeId(item);
|
|
1149
|
-
if (duplicates.has(id)) return false;
|
|
1150
|
-
duplicates.add(id);
|
|
1151
|
-
return true;
|
|
1152
|
-
});
|
|
1153
|
-
if (state.events.filter) hits = state.events.filter(hits, state);
|
|
1154
|
-
for (const hit of hits) {
|
|
1155
|
-
let eventObject = hit.object;
|
|
1156
|
-
while (eventObject) {
|
|
1157
|
-
if (eventObject.__r3f?.eventCount) {
|
|
1158
|
-
intersections.push({ ...hit, eventObject });
|
|
1159
|
-
}
|
|
1160
|
-
eventObject = eventObject.parent;
|
|
791
|
+
|
|
792
|
+
const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
|
|
793
|
+
function isInternalRendererAccess(stack, callerDepth = 2) {
|
|
794
|
+
if (!stack) return false;
|
|
795
|
+
const caller = stack.split("\n")[callerDepth] ?? "";
|
|
796
|
+
return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
800
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React.createContext(null));
|
|
801
|
+
const createStore = (invalidate, advance) => {
|
|
802
|
+
const rootStore = createWithEqualityFn((set, get) => {
|
|
803
|
+
const position = new Vector3();
|
|
804
|
+
const defaultTarget = new Vector3();
|
|
805
|
+
const tempTarget = new Vector3();
|
|
806
|
+
function getCurrentViewport(camera = get().camera, target = defaultTarget, size = get().size) {
|
|
807
|
+
const { width, height, top, left } = size;
|
|
808
|
+
const aspect = width / height;
|
|
809
|
+
if (target.isVector3) tempTarget.copy(target);
|
|
810
|
+
else tempTarget.set(...target);
|
|
811
|
+
const distance = camera.getWorldPosition(position).distanceTo(tempTarget);
|
|
812
|
+
if (isOrthographicCamera(camera)) {
|
|
813
|
+
return { width: width / camera.zoom, height: height / camera.zoom, top, left, factor: 1, distance, aspect };
|
|
814
|
+
} else {
|
|
815
|
+
const fov = camera.fov * Math.PI / 180;
|
|
816
|
+
const h = 2 * Math.tan(fov / 2) * distance;
|
|
817
|
+
const w = h * (width / height);
|
|
818
|
+
return { width: w, height: h, top, left, factor: width / w, distance, aspect };
|
|
1161
819
|
}
|
|
1162
820
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
821
|
+
let performanceTimeout = void 0;
|
|
822
|
+
const setPerformanceCurrent = (current) => set((state2) => ({ performance: { ...state2.performance, current } }));
|
|
823
|
+
const pointer = new Vector2();
|
|
824
|
+
const rootState = {
|
|
825
|
+
set,
|
|
826
|
+
get,
|
|
827
|
+
// Mock objects that have to be configured
|
|
828
|
+
// primaryStore is set after store creation (self-reference for primary, primary's store for secondary)
|
|
829
|
+
primaryStore: null,
|
|
830
|
+
gl: null,
|
|
831
|
+
renderer: null,
|
|
832
|
+
camera: null,
|
|
833
|
+
frustum: new Frustum(),
|
|
834
|
+
autoUpdateFrustum: true,
|
|
835
|
+
raycaster: null,
|
|
836
|
+
events: {
|
|
837
|
+
priority: 1,
|
|
838
|
+
enabled: true,
|
|
839
|
+
connected: false,
|
|
840
|
+
frameTimedRaycasts: true,
|
|
841
|
+
alwaysFireOnScroll: true,
|
|
842
|
+
updateOnFrame: false
|
|
843
|
+
},
|
|
844
|
+
scene: null,
|
|
845
|
+
rootScene: null,
|
|
846
|
+
xr: null,
|
|
847
|
+
inspector: null,
|
|
848
|
+
invalidate: (frames = 1, stackFrames = false) => invalidate(get(), frames, stackFrames),
|
|
849
|
+
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
850
|
+
textureColorSpace: SRGBColorSpace,
|
|
851
|
+
isLegacy: false,
|
|
852
|
+
webGPUSupported: false,
|
|
853
|
+
isNative: false,
|
|
854
|
+
controls: null,
|
|
855
|
+
pointer,
|
|
856
|
+
mouse: pointer,
|
|
857
|
+
frameloop: "always",
|
|
858
|
+
onPointerMissed: void 0,
|
|
859
|
+
onDragOverMissed: void 0,
|
|
860
|
+
onDropMissed: void 0,
|
|
861
|
+
performance: {
|
|
862
|
+
current: 1,
|
|
863
|
+
min: 0.5,
|
|
864
|
+
max: 1,
|
|
865
|
+
debounce: 200,
|
|
866
|
+
regress: () => {
|
|
867
|
+
const state2 = get();
|
|
868
|
+
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
869
|
+
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
870
|
+
performanceTimeout = setTimeout(
|
|
871
|
+
() => setPerformanceCurrent(get().performance.max),
|
|
872
|
+
state2.performance.debounce
|
|
873
|
+
);
|
|
1169
874
|
}
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
875
|
+
},
|
|
876
|
+
size: { width: 0, height: 0, top: 0, left: 0 },
|
|
877
|
+
viewport: {
|
|
878
|
+
initialDpr: 0,
|
|
879
|
+
dpr: 0,
|
|
880
|
+
width: 0,
|
|
881
|
+
height: 0,
|
|
882
|
+
top: 0,
|
|
883
|
+
left: 0,
|
|
884
|
+
aspect: 0,
|
|
885
|
+
distance: 0,
|
|
886
|
+
factor: 0,
|
|
887
|
+
getCurrentViewport
|
|
888
|
+
},
|
|
889
|
+
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
890
|
+
setSize: (width, height, top, left) => {
|
|
891
|
+
const state2 = get();
|
|
892
|
+
if (width === void 0) {
|
|
893
|
+
set({ _sizeImperative: false });
|
|
894
|
+
if (state2._sizeProps) {
|
|
895
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
896
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
897
|
+
const currentSize = state2.size;
|
|
898
|
+
const newSize = {
|
|
899
|
+
width: propW ?? currentSize.width,
|
|
900
|
+
height: propH ?? currentSize.height,
|
|
901
|
+
top: currentSize.top,
|
|
902
|
+
left: currentSize.left
|
|
903
|
+
};
|
|
904
|
+
set((s) => ({
|
|
905
|
+
size: newSize,
|
|
906
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
907
|
+
}));
|
|
908
|
+
getScheduler().invalidate();
|
|
909
|
+
}
|
|
1199
910
|
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
const w = width;
|
|
914
|
+
const h = height ?? width;
|
|
915
|
+
const t = top ?? state2.size.top;
|
|
916
|
+
const l = left ?? state2.size.left;
|
|
917
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
918
|
+
set((s) => ({
|
|
919
|
+
size,
|
|
920
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
921
|
+
_sizeImperative: true
|
|
922
|
+
}));
|
|
923
|
+
getScheduler().invalidate();
|
|
924
|
+
},
|
|
925
|
+
setDpr: (dpr) => set((state2) => {
|
|
926
|
+
const resolved = calculateDpr(dpr);
|
|
927
|
+
return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
|
|
928
|
+
}),
|
|
929
|
+
setFrameloop: (frameloop = "always") => {
|
|
930
|
+
set(() => ({ frameloop }));
|
|
931
|
+
getScheduler().frameloop = frameloop;
|
|
932
|
+
},
|
|
933
|
+
setError: (error) => set(() => ({ error })),
|
|
934
|
+
error: null,
|
|
935
|
+
//* TSL State (managed via hooks: useUniforms, useNodes, useBuffers, useGPUStorage, useTextures, useRenderPipeline) ==============================
|
|
936
|
+
uniforms: {},
|
|
937
|
+
nodes: {},
|
|
938
|
+
buffers: {},
|
|
939
|
+
gpuStorage: {},
|
|
940
|
+
textures: /* @__PURE__ */ new Map(),
|
|
941
|
+
_textureRefs: /* @__PURE__ */ new Map(),
|
|
942
|
+
renderPipeline: null,
|
|
943
|
+
passes: {},
|
|
944
|
+
_hmrVersion: 0,
|
|
945
|
+
_sizeImperative: false,
|
|
946
|
+
_sizeProps: null,
|
|
947
|
+
previousRoot: void 0,
|
|
948
|
+
internal: {
|
|
949
|
+
// Events
|
|
950
|
+
interaction: [],
|
|
951
|
+
subscribers: [],
|
|
952
|
+
// Per-pointer state (new unified structure)
|
|
953
|
+
pointerMap: /* @__PURE__ */ new Map(),
|
|
954
|
+
pointerDirty: /* @__PURE__ */ new Map(),
|
|
955
|
+
lastEvent: React.createRef(),
|
|
956
|
+
// Deprecated but kept for backwards compatibility
|
|
957
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
958
|
+
initialClick: [0, 0],
|
|
959
|
+
initialHits: [],
|
|
960
|
+
capturedMap: /* @__PURE__ */ new Map(),
|
|
961
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
962
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
963
|
+
// Occlusion system (WebGPU only)
|
|
964
|
+
occlusionEnabled: false,
|
|
965
|
+
occlusionObserver: null,
|
|
966
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
967
|
+
helperGroup: null,
|
|
968
|
+
// Updates
|
|
969
|
+
active: false,
|
|
970
|
+
frames: 0,
|
|
971
|
+
priority: 0,
|
|
972
|
+
subscribe: (ref, priority, store) => {
|
|
973
|
+
const internal = get().internal;
|
|
974
|
+
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
975
|
+
internal.subscribers.push({ ref, priority, store });
|
|
976
|
+
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
977
|
+
return () => {
|
|
978
|
+
const internal2 = get().internal;
|
|
979
|
+
if (internal2?.subscribers) {
|
|
980
|
+
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
981
|
+
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
982
|
+
}
|
|
1231
983
|
};
|
|
1232
|
-
|
|
1233
|
-
|
|
984
|
+
},
|
|
985
|
+
// Renderer Storage (single source of truth)
|
|
986
|
+
actualRenderer: null,
|
|
987
|
+
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
988
|
+
scheduler: null
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
return rootState;
|
|
992
|
+
});
|
|
993
|
+
const state = rootStore.getState();
|
|
994
|
+
Object.defineProperty(state, "gl", {
|
|
995
|
+
get() {
|
|
996
|
+
const currentState = rootStore.getState();
|
|
997
|
+
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
998
|
+
const stack = new Error().stack || "";
|
|
999
|
+
if (!isInternalRendererAccess(stack)) {
|
|
1000
|
+
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1001
|
+
notifyDepreciated({
|
|
1002
|
+
heading: "Accessing state.gl in WebGPU mode",
|
|
1003
|
+
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
|
|
1004
|
+
});
|
|
1234
1005
|
}
|
|
1235
1006
|
}
|
|
1007
|
+
return currentState.internal.actualRenderer;
|
|
1008
|
+
},
|
|
1009
|
+
set(value) {
|
|
1010
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
1011
|
+
},
|
|
1012
|
+
enumerable: true,
|
|
1013
|
+
configurable: true
|
|
1014
|
+
});
|
|
1015
|
+
Object.defineProperty(state, "renderer", {
|
|
1016
|
+
get() {
|
|
1017
|
+
return rootStore.getState().internal.actualRenderer;
|
|
1018
|
+
},
|
|
1019
|
+
set(value) {
|
|
1020
|
+
rootStore.getState().internal.actualRenderer = value;
|
|
1021
|
+
},
|
|
1022
|
+
enumerable: true,
|
|
1023
|
+
configurable: true
|
|
1024
|
+
});
|
|
1025
|
+
let oldScene = state.scene;
|
|
1026
|
+
rootStore.subscribe(() => {
|
|
1027
|
+
const currentState = rootStore.getState();
|
|
1028
|
+
const { scene, rootScene, set } = currentState;
|
|
1029
|
+
if (scene !== oldScene) {
|
|
1030
|
+
oldScene = scene;
|
|
1031
|
+
if (scene?.isScene && scene !== rootScene) {
|
|
1032
|
+
set({ rootScene: scene });
|
|
1033
|
+
}
|
|
1236
1034
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
const
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1035
|
+
});
|
|
1036
|
+
let oldSize = state.size;
|
|
1037
|
+
let oldDpr = state.viewport.dpr;
|
|
1038
|
+
let oldCamera = state.camera;
|
|
1039
|
+
rootStore.subscribe(() => {
|
|
1040
|
+
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
1041
|
+
const actualRenderer = internal.actualRenderer;
|
|
1042
|
+
const canvasTarget = internal.canvasTarget;
|
|
1043
|
+
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
1044
|
+
oldSize = size;
|
|
1045
|
+
oldDpr = viewport.dpr;
|
|
1046
|
+
updateCamera(camera, size);
|
|
1047
|
+
if (internal.isSecondary && canvasTarget) {
|
|
1048
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1049
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
1050
|
+
} else {
|
|
1051
|
+
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1052
|
+
actualRenderer.setSize(size.width, size.height, false);
|
|
1053
|
+
if (canvasTarget) {
|
|
1054
|
+
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1055
|
+
canvasTarget.setSize(size.width, size.height, false);
|
|
1257
1056
|
}
|
|
1258
1057
|
}
|
|
1259
1058
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1059
|
+
if (camera !== oldCamera) {
|
|
1060
|
+
oldCamera = camera;
|
|
1061
|
+
const { rootScene } = rootStore.getState();
|
|
1062
|
+
if (camera && rootScene && !camera.parent) {
|
|
1063
|
+
rootScene.add(camera);
|
|
1064
|
+
}
|
|
1065
|
+
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
1066
|
+
const currentState = rootStore.getState();
|
|
1067
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
1068
|
+
updateFrustum(camera, currentState.frustum);
|
|
1069
|
+
}
|
|
1271
1070
|
}
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1071
|
+
});
|
|
1072
|
+
rootStore.subscribe((state2) => invalidate(state2));
|
|
1073
|
+
return rootStore;
|
|
1074
|
+
};
|
|
1075
|
+
|
|
1076
|
+
const memoizedLoaders = /* @__PURE__ */ new WeakMap();
|
|
1077
|
+
const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
|
|
1078
|
+
function getLoader$1(Proto) {
|
|
1079
|
+
if (isConstructor$1(Proto)) {
|
|
1080
|
+
let loader = memoizedLoaders.get(Proto);
|
|
1081
|
+
if (!loader) {
|
|
1082
|
+
loader = new Proto();
|
|
1083
|
+
memoizedLoaders.set(Proto, loader);
|
|
1277
1084
|
}
|
|
1085
|
+
return loader;
|
|
1278
1086
|
}
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
handlers.onPointerLeave?.(data);
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
internal.pointerMap.delete(pointerId);
|
|
1087
|
+
return Proto;
|
|
1088
|
+
}
|
|
1089
|
+
function loadingFn(extensions, onProgress) {
|
|
1090
|
+
return function(Proto, input) {
|
|
1091
|
+
const loader = getLoader$1(Proto);
|
|
1092
|
+
if (extensions) extensions(loader);
|
|
1093
|
+
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
1094
|
+
return loader.loadAsync(input, onProgress).then((data) => {
|
|
1095
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1096
|
+
return data;
|
|
1097
|
+
});
|
|
1294
1098
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1099
|
+
return new Promise(
|
|
1100
|
+
(res, reject) => loader.load(
|
|
1101
|
+
input,
|
|
1102
|
+
(data) => {
|
|
1103
|
+
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1104
|
+
res(data);
|
|
1105
|
+
},
|
|
1106
|
+
onProgress,
|
|
1107
|
+
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
1108
|
+
)
|
|
1109
|
+
);
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
1113
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
1114
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
1115
|
+
const fn = loadingFn(extensions, onProgress);
|
|
1116
|
+
const results = cacheKeys.map(
|
|
1117
|
+
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1118
|
+
);
|
|
1119
|
+
return Array.isArray(input) ? results : results[0];
|
|
1120
|
+
}
|
|
1121
|
+
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
1122
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
1123
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
1124
|
+
cacheKeys.forEach(
|
|
1125
|
+
(key, index) => preload(() => loadingFn(extensions, onProgress)(loader, inputs[index]), [loader, key])
|
|
1126
|
+
);
|
|
1127
|
+
};
|
|
1128
|
+
useLoader.clear = function(loader, input, cacheKey) {
|
|
1129
|
+
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
1130
|
+
cacheKeys.forEach((key) => clear([loader, key]));
|
|
1131
|
+
};
|
|
1132
|
+
useLoader.loader = getLoader$1;
|
|
1133
|
+
|
|
1134
|
+
function useFrame(callback, priorityOrOptions) {
|
|
1135
|
+
const store = React.useContext(context);
|
|
1136
|
+
const isInsideCanvas = store !== null;
|
|
1137
|
+
const scheduler = getScheduler();
|
|
1138
|
+
const optionsKey = typeof priorityOrOptions === "number" ? `p:${priorityOrOptions}` : priorityOrOptions ? JSON.stringify({
|
|
1139
|
+
id: priorityOrOptions.id,
|
|
1140
|
+
phase: priorityOrOptions.phase,
|
|
1141
|
+
priority: priorityOrOptions.priority,
|
|
1142
|
+
fps: priorityOrOptions.fps,
|
|
1143
|
+
drop: priorityOrOptions.drop,
|
|
1144
|
+
enabled: priorityOrOptions.enabled,
|
|
1145
|
+
before: priorityOrOptions.before,
|
|
1146
|
+
after: priorityOrOptions.after
|
|
1147
|
+
}) : "";
|
|
1148
|
+
const options = React.useMemo(() => {
|
|
1149
|
+
return typeof priorityOrOptions === "number" ? { priority: priorityOrOptions } : priorityOrOptions ?? {};
|
|
1150
|
+
}, [optionsKey]);
|
|
1151
|
+
const reactId = React.useId();
|
|
1152
|
+
const id = options.id ?? reactId;
|
|
1153
|
+
const callbackRef = useMutableCallback(callback);
|
|
1154
|
+
const isLegacyPriority = typeof priorityOrOptions === "number" && priorityOrOptions > 0;
|
|
1155
|
+
useIsomorphicLayoutEffect(() => {
|
|
1156
|
+
if (!callback) return;
|
|
1157
|
+
if (isInsideCanvas) {
|
|
1353
1158
|
const state = store.getState();
|
|
1354
|
-
const
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
const isPointerDown = name === "onPointerDown";
|
|
1363
|
-
const isPointerUp = name === "onPointerUp";
|
|
1364
|
-
const isWheel = name === "onWheel";
|
|
1365
|
-
const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
|
|
1366
|
-
if (isPointerMove && canDeferRaycasts) {
|
|
1367
|
-
events.compute?.(event, state);
|
|
1368
|
-
internal.pointerDirty.set(pointerId, event);
|
|
1369
|
-
return;
|
|
1370
|
-
}
|
|
1371
|
-
if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
|
|
1372
|
-
events.compute?.(event, state);
|
|
1373
|
-
internal.pointerDirty.set(pointerId, event);
|
|
1374
|
-
return;
|
|
1375
|
-
}
|
|
1376
|
-
if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
|
|
1377
|
-
const deferredEvent = internal.pointerDirty.get(pointerId);
|
|
1378
|
-
internal.pointerDirty.delete(pointerId);
|
|
1379
|
-
processDeferredPointer(deferredEvent, pointerId);
|
|
1380
|
-
}
|
|
1381
|
-
const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
|
|
1382
|
-
const hits = intersect(event, filter);
|
|
1383
|
-
const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
|
|
1384
|
-
if (isPointerDown) {
|
|
1385
|
-
const pointerState2 = getPointerState(internal, pointerId);
|
|
1386
|
-
pointerState2.initialClick = [event.offsetX, event.offsetY];
|
|
1387
|
-
pointerState2.initialHits = hits.map((hit) => hit.eventObject);
|
|
1388
|
-
}
|
|
1389
|
-
const pointerState = internal.pointerMap.get(pointerId);
|
|
1390
|
-
const initialHits = pointerState?.initialHits ?? [];
|
|
1391
|
-
if (isClickEvent && !hits.length) {
|
|
1392
|
-
if (delta <= 2) {
|
|
1393
|
-
pointerMissed(event, internal.interaction);
|
|
1394
|
-
if (onPointerMissed) onPointerMissed(event);
|
|
1159
|
+
const rootId = state.internal.rootId;
|
|
1160
|
+
if (isLegacyPriority) {
|
|
1161
|
+
state.internal.priority++;
|
|
1162
|
+
let parentRoot = state.previousRoot;
|
|
1163
|
+
while (parentRoot) {
|
|
1164
|
+
const parentState = parentRoot.getState();
|
|
1165
|
+
if (parentState?.internal) parentState.internal.priority++;
|
|
1166
|
+
parentRoot = parentState?.previousRoot;
|
|
1395
1167
|
}
|
|
1168
|
+
notifyDepreciated({
|
|
1169
|
+
heading: "useFrame with numeric priority is deprecated",
|
|
1170
|
+
body: 'Using useFrame(callback, number) to control render order is deprecated.\n\nFor custom rendering, use: useFrame(callback, { phase: "render" })\nFor execution order within update phase, use: useFrame(callback, { priority: number })',
|
|
1171
|
+
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
1172
|
+
});
|
|
1396
1173
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
handlers.onPointerMove?.(data);
|
|
1427
|
-
} else if (isDragOver) {
|
|
1428
|
-
const id = makeId(data);
|
|
1429
|
-
const pointerState2 = getPointerState(internal, pointerId);
|
|
1430
|
-
const hoveredItem = pointerState2.hovered.get(id);
|
|
1431
|
-
if (!hoveredItem) {
|
|
1432
|
-
pointerState2.hovered.set(id, data);
|
|
1433
|
-
handlers.onDragOverEnter?.(data);
|
|
1434
|
-
} else if (hoveredItem.stopped) {
|
|
1435
|
-
data.stopPropagation();
|
|
1436
|
-
}
|
|
1437
|
-
handlers.onDragOver?.(data);
|
|
1438
|
-
} else if (isDrop) {
|
|
1439
|
-
handlers.onDrop?.(data);
|
|
1440
|
-
} else {
|
|
1441
|
-
const handler = handlers[name];
|
|
1442
|
-
if (handler) {
|
|
1443
|
-
if (!isClickEvent || initialHits.includes(eventObject)) {
|
|
1444
|
-
pointerMissed(
|
|
1445
|
-
event,
|
|
1446
|
-
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
1447
|
-
);
|
|
1448
|
-
handler(data);
|
|
1449
|
-
}
|
|
1450
|
-
} else {
|
|
1451
|
-
if (isClickEvent && initialHits.includes(eventObject)) {
|
|
1452
|
-
pointerMissed(
|
|
1453
|
-
event,
|
|
1454
|
-
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
1455
|
-
);
|
|
1174
|
+
const wrappedCallback = (frameState, delta) => {
|
|
1175
|
+
const localState = store.getState();
|
|
1176
|
+
const mergedState = {
|
|
1177
|
+
...localState,
|
|
1178
|
+
time: frameState.time,
|
|
1179
|
+
delta: frameState.delta,
|
|
1180
|
+
elapsed: frameState.elapsed,
|
|
1181
|
+
frame: frameState.frame
|
|
1182
|
+
};
|
|
1183
|
+
callbackRef.current?.(mergedState, delta);
|
|
1184
|
+
};
|
|
1185
|
+
const unregister = scheduler.register(wrappedCallback, {
|
|
1186
|
+
id,
|
|
1187
|
+
rootId,
|
|
1188
|
+
...options
|
|
1189
|
+
});
|
|
1190
|
+
return () => {
|
|
1191
|
+
unregister();
|
|
1192
|
+
if (isLegacyPriority) {
|
|
1193
|
+
const currentState = store.getState();
|
|
1194
|
+
if (currentState.internal) {
|
|
1195
|
+
currentState.internal.priority--;
|
|
1196
|
+
let parentRoot = currentState.previousRoot;
|
|
1197
|
+
while (parentRoot) {
|
|
1198
|
+
const parentState = parentRoot.getState();
|
|
1199
|
+
if (parentState?.internal) parentState.internal.priority--;
|
|
1200
|
+
parentRoot = parentState?.previousRoot;
|
|
1456
1201
|
}
|
|
1457
1202
|
}
|
|
1458
1203
|
}
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
internal.pointerDirty.clear();
|
|
1470
|
-
}
|
|
1471
|
-
return { handlePointer, flushDeferredPointers, processDeferredPointer };
|
|
1472
|
-
}
|
|
1473
|
-
const DOM_EVENTS = {
|
|
1474
|
-
onClick: ["click", false],
|
|
1475
|
-
onContextMenu: ["contextmenu", false],
|
|
1476
|
-
onDoubleClick: ["dblclick", false],
|
|
1477
|
-
onDragEnter: ["dragenter", false],
|
|
1478
|
-
onDragLeave: ["dragleave", false],
|
|
1479
|
-
onDragOver: ["dragover", false],
|
|
1480
|
-
onDrop: ["drop", false],
|
|
1481
|
-
onWheel: ["wheel", true],
|
|
1482
|
-
onPointerDown: ["pointerdown", true],
|
|
1483
|
-
onPointerUp: ["pointerup", true],
|
|
1484
|
-
onPointerLeave: ["pointerleave", true],
|
|
1485
|
-
onPointerMove: ["pointermove", true],
|
|
1486
|
-
onPointerCancel: ["pointercancel", true],
|
|
1487
|
-
onLostPointerCapture: ["lostpointercapture", true]
|
|
1488
|
-
};
|
|
1489
|
-
function createPointerEvents(store) {
|
|
1490
|
-
const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
|
|
1491
|
-
let nextXRPointerId = XR_POINTER_ID_START;
|
|
1492
|
-
const xrPointers = /* @__PURE__ */ new Map();
|
|
1493
|
-
return {
|
|
1494
|
-
priority: 1,
|
|
1495
|
-
enabled: true,
|
|
1496
|
-
frameTimedRaycasts: true,
|
|
1497
|
-
alwaysFireOnScroll: true,
|
|
1498
|
-
updateOnFrame: false,
|
|
1499
|
-
compute(event, state) {
|
|
1500
|
-
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
1501
|
-
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
1502
|
-
},
|
|
1503
|
-
connected: void 0,
|
|
1504
|
-
handlers: Object.keys(DOM_EVENTS).reduce(
|
|
1505
|
-
(acc, key) => ({ ...acc, [key]: handlePointer(key) }),
|
|
1506
|
-
{}
|
|
1507
|
-
),
|
|
1508
|
-
update: (pointerId) => {
|
|
1509
|
-
const { events, internal } = store.getState();
|
|
1510
|
-
if (!events.handlers) return;
|
|
1511
|
-
if (pointerId !== void 0) {
|
|
1512
|
-
const event = internal.pointerDirty.get(pointerId);
|
|
1513
|
-
if (event) {
|
|
1514
|
-
internal.pointerDirty.delete(pointerId);
|
|
1515
|
-
processDeferredPointer(event, pointerId);
|
|
1516
|
-
} else if (internal.lastEvent?.current) {
|
|
1517
|
-
processDeferredPointer(internal.lastEvent.current, pointerId);
|
|
1518
|
-
}
|
|
1519
|
-
} else {
|
|
1520
|
-
flushDeferredPointers();
|
|
1521
|
-
if (internal.lastEvent?.current) {
|
|
1522
|
-
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
|
-
},
|
|
1526
|
-
flush: () => {
|
|
1527
|
-
const { events, internal } = store.getState();
|
|
1528
|
-
flushDeferredPointers();
|
|
1529
|
-
if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
|
|
1530
|
-
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
1531
|
-
}
|
|
1532
|
-
},
|
|
1533
|
-
connect: (target) => {
|
|
1534
|
-
if (!target) return;
|
|
1535
|
-
const { set, events } = store.getState();
|
|
1536
|
-
events.disconnect?.();
|
|
1537
|
-
set((state) => ({ events: { ...state.events, connected: target } }));
|
|
1538
|
-
if (events.handlers) {
|
|
1539
|
-
for (const name in events.handlers) {
|
|
1540
|
-
const event = events.handlers[name];
|
|
1541
|
-
const [eventName, passive] = DOM_EVENTS[name];
|
|
1542
|
-
target.addEventListener(eventName, event, { passive });
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
},
|
|
1546
|
-
disconnect: () => {
|
|
1547
|
-
const { set, events } = store.getState();
|
|
1548
|
-
if (events.connected) {
|
|
1549
|
-
if (events.handlers) {
|
|
1550
|
-
for (const name in events.handlers) {
|
|
1551
|
-
const event = events.handlers[name];
|
|
1552
|
-
const [eventName] = DOM_EVENTS[name];
|
|
1553
|
-
events.connected.removeEventListener(eventName, event);
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
set((state) => ({ events: { ...state.events, connected: void 0 } }));
|
|
1557
|
-
}
|
|
1558
|
-
},
|
|
1559
|
-
registerPointer: (config) => {
|
|
1560
|
-
const pointerId = nextXRPointerId++;
|
|
1561
|
-
xrPointers.set(pointerId, config);
|
|
1562
|
-
const { internal } = store.getState();
|
|
1563
|
-
getPointerState(internal, pointerId);
|
|
1564
|
-
return pointerId;
|
|
1565
|
-
},
|
|
1566
|
-
unregisterPointer: (pointerId) => {
|
|
1567
|
-
xrPointers.delete(pointerId);
|
|
1568
|
-
const { internal } = store.getState();
|
|
1569
|
-
const pointerState = internal.pointerMap.get(pointerId);
|
|
1570
|
-
if (pointerState) {
|
|
1571
|
-
for (const [, hoveredObj] of pointerState.hovered) {
|
|
1572
|
-
const eventObject = hoveredObj.eventObject;
|
|
1573
|
-
const instance = eventObject.__r3f;
|
|
1574
|
-
if (instance?.eventCount) {
|
|
1575
|
-
const handlers = instance.handlers;
|
|
1576
|
-
const data = { ...hoveredObj, intersections: [] };
|
|
1577
|
-
handlers.onPointerOut?.(data);
|
|
1578
|
-
handlers.onPointerLeave?.(data);
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
internal.pointerMap.delete(pointerId);
|
|
1582
|
-
}
|
|
1583
|
-
internal.pointerDirty.delete(pointerId);
|
|
1204
|
+
};
|
|
1205
|
+
} else {
|
|
1206
|
+
return scheduler.register(
|
|
1207
|
+
(state, delta) => {
|
|
1208
|
+
const frameState = state;
|
|
1209
|
+
if (!frameState.renderer) return;
|
|
1210
|
+
callbackRef.current?.(frameState, delta);
|
|
1211
|
+
},
|
|
1212
|
+
{ id, ...options }
|
|
1213
|
+
);
|
|
1584
1214
|
}
|
|
1585
|
-
};
|
|
1215
|
+
}, [store, scheduler, id, optionsKey, isLegacyPriority, isInsideCanvas]);
|
|
1216
|
+
const isPaused = React.useSyncExternalStore(
|
|
1217
|
+
// Subscribe function
|
|
1218
|
+
React.useCallback(
|
|
1219
|
+
(onStoreChange) => {
|
|
1220
|
+
return getScheduler().subscribeJobState(id, onStoreChange);
|
|
1221
|
+
},
|
|
1222
|
+
[id]
|
|
1223
|
+
),
|
|
1224
|
+
// getSnapshot function
|
|
1225
|
+
React.useCallback(() => getScheduler().isJobPaused(id), [id]),
|
|
1226
|
+
// getServerSnapshot function (SSR)
|
|
1227
|
+
React.useCallback(() => false, [])
|
|
1228
|
+
);
|
|
1229
|
+
const controls = React.useMemo(() => {
|
|
1230
|
+
const scheduler2 = getScheduler();
|
|
1231
|
+
return {
|
|
1232
|
+
/** The job's unique ID */
|
|
1233
|
+
id,
|
|
1234
|
+
/**
|
|
1235
|
+
* Access to the global scheduler for frame loop control.
|
|
1236
|
+
* Use for controlling the entire frame loop, adding phases, etc.
|
|
1237
|
+
*/
|
|
1238
|
+
scheduler: scheduler2,
|
|
1239
|
+
/**
|
|
1240
|
+
* Manually step this job only.
|
|
1241
|
+
* Bypasses FPS limiting - always runs.
|
|
1242
|
+
* @param timestamp Optional timestamp (defaults to performance.now())
|
|
1243
|
+
*/
|
|
1244
|
+
step: (timestamp) => {
|
|
1245
|
+
getScheduler().stepJob(id, timestamp);
|
|
1246
|
+
},
|
|
1247
|
+
/**
|
|
1248
|
+
* Manually step ALL jobs in the scheduler.
|
|
1249
|
+
* Useful for frameloop='never' mode.
|
|
1250
|
+
* @param timestamp Optional timestamp (defaults to performance.now())
|
|
1251
|
+
*/
|
|
1252
|
+
stepAll: (timestamp) => {
|
|
1253
|
+
getScheduler().step(timestamp);
|
|
1254
|
+
},
|
|
1255
|
+
/**
|
|
1256
|
+
* Pause this job (set enabled=false).
|
|
1257
|
+
* Job remains registered but won't run.
|
|
1258
|
+
*/
|
|
1259
|
+
pause: () => {
|
|
1260
|
+
getScheduler().pauseJob(id);
|
|
1261
|
+
},
|
|
1262
|
+
/**
|
|
1263
|
+
* Resume this job (set enabled=true).
|
|
1264
|
+
*/
|
|
1265
|
+
resume: () => {
|
|
1266
|
+
getScheduler().resumeJob(id);
|
|
1267
|
+
},
|
|
1268
|
+
/**
|
|
1269
|
+
* Reactive paused state - automatically updates when pause/resume is called.
|
|
1270
|
+
* No need for forceUpdate() in your components.
|
|
1271
|
+
*/
|
|
1272
|
+
isPaused
|
|
1273
|
+
};
|
|
1274
|
+
}, [id, isPaused]);
|
|
1275
|
+
return controls;
|
|
1586
1276
|
}
|
|
1587
1277
|
|
|
1588
|
-
const
|
|
1589
|
-
function
|
|
1590
|
-
if (typeof
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
if (shownNotices.has(heading)) return;
|
|
1594
|
-
shownNotices.add(heading);
|
|
1595
|
-
const caller = getCallerFrame();
|
|
1596
|
-
if (caller) {
|
|
1597
|
-
console.log();
|
|
1598
|
-
}
|
|
1599
|
-
const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
|
|
1600
|
-
if (caller) {
|
|
1601
|
-
console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
|
|
1602
|
-
}
|
|
1603
|
-
if (body || link) {
|
|
1604
|
-
let message = "";
|
|
1605
|
-
if (body) message += body;
|
|
1606
|
-
if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
|
|
1607
|
-
console.warn(`%c${message}`, "font-weight: bold;");
|
|
1608
|
-
}
|
|
1609
|
-
}
|
|
1610
|
-
function getCallerFrame(depth = 3) {
|
|
1611
|
-
const stack = new Error().stack;
|
|
1612
|
-
if (!stack) return null;
|
|
1613
|
-
const lines = stack.split("\n");
|
|
1614
|
-
const frame = lines[depth];
|
|
1615
|
-
if (!frame) return null;
|
|
1616
|
-
let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
|
|
1617
|
-
if (!match) {
|
|
1618
|
-
match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
|
|
1619
|
-
}
|
|
1620
|
-
if (!match) return null;
|
|
1621
|
-
const [, fn, url, line] = match;
|
|
1622
|
-
return {
|
|
1623
|
-
functionName: fn ?? "<anonymous>",
|
|
1624
|
-
location: formatLocation(url, Number(line))
|
|
1625
|
-
};
|
|
1278
|
+
const IsObject = (url) => url === Object(url) && !Array.isArray(url) && typeof url !== "function";
|
|
1279
|
+
function getUrls(input) {
|
|
1280
|
+
if (typeof input === "string") return [input];
|
|
1281
|
+
if (Array.isArray(input)) return input;
|
|
1282
|
+
return Object.values(input);
|
|
1626
1283
|
}
|
|
1627
|
-
function
|
|
1628
|
-
|
|
1629
|
-
const file = clean.split("/").pop() ?? clean;
|
|
1630
|
-
return `${file}:${line}`;
|
|
1284
|
+
function allUrlsCached(urls, textureCache) {
|
|
1285
|
+
return urls.every((url) => textureCache.has(url));
|
|
1631
1286
|
}
|
|
1632
|
-
function
|
|
1633
|
-
if (typeof
|
|
1634
|
-
return;
|
|
1635
|
-
}
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1287
|
+
function buildFromCache(input, textureCache) {
|
|
1288
|
+
if (typeof input === "string") {
|
|
1289
|
+
return textureCache.get(input);
|
|
1290
|
+
} else if (Array.isArray(input)) {
|
|
1291
|
+
return input.map((url) => textureCache.get(url));
|
|
1292
|
+
} else {
|
|
1293
|
+
const result = {};
|
|
1294
|
+
const objInput = input;
|
|
1295
|
+
for (const key in objInput) {
|
|
1296
|
+
result[key] = textureCache.get(objInput[key]);
|
|
1297
|
+
}
|
|
1298
|
+
return result;
|
|
1642
1299
|
}
|
|
1643
1300
|
}
|
|
1644
|
-
|
|
1645
|
-
const
|
|
1646
|
-
const
|
|
1647
|
-
function
|
|
1648
|
-
|
|
1649
|
-
const
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
const
|
|
1654
|
-
|
|
1655
|
-
const
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1301
|
+
function useTexture(input, optionsOrOnLoad) {
|
|
1302
|
+
const renderer = useThree((state) => state.internal.actualRenderer);
|
|
1303
|
+
const store = useStore();
|
|
1304
|
+
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
1305
|
+
const { onLoad, cache = true } = options;
|
|
1306
|
+
const onLoadRef = useRef(onLoad);
|
|
1307
|
+
onLoadRef.current = onLoad;
|
|
1308
|
+
const onLoadCalledForRef = useRef(null);
|
|
1309
|
+
const urls = useMemo(() => getUrls(input), [input]);
|
|
1310
|
+
const cachedResult = useMemo(() => {
|
|
1311
|
+
if (!cache) return null;
|
|
1312
|
+
const textures = store.getState().textures;
|
|
1313
|
+
if (!allUrlsCached(urls, textures)) return null;
|
|
1314
|
+
return buildFromCache(input, textures);
|
|
1315
|
+
}, [cache, urls, input, store]);
|
|
1316
|
+
const loadedTextures = useLoader(
|
|
1317
|
+
TextureLoader,
|
|
1318
|
+
IsObject(input) ? Object.values(input) : input
|
|
1319
|
+
);
|
|
1320
|
+
const inputKey = urls.join("\0");
|
|
1321
|
+
useLayoutEffect(() => {
|
|
1322
|
+
if (cachedResult) return;
|
|
1323
|
+
if (onLoadCalledForRef.current === inputKey) return;
|
|
1324
|
+
onLoadCalledForRef.current = inputKey;
|
|
1325
|
+
onLoadRef.current?.(loadedTextures);
|
|
1326
|
+
}, [cachedResult, loadedTextures, inputKey]);
|
|
1327
|
+
useEffect(() => {
|
|
1328
|
+
if (cachedResult) return;
|
|
1329
|
+
if ("initTexture" in renderer) {
|
|
1330
|
+
let textureArray = [];
|
|
1331
|
+
if (Array.isArray(loadedTextures)) {
|
|
1332
|
+
textureArray = loadedTextures;
|
|
1333
|
+
} else if (loadedTextures instanceof Texture$1) {
|
|
1334
|
+
textureArray = [loadedTextures];
|
|
1335
|
+
} else if (IsObject(loadedTextures)) {
|
|
1336
|
+
textureArray = Object.values(loadedTextures);
|
|
1673
1337
|
}
|
|
1338
|
+
textureArray.forEach((texture) => {
|
|
1339
|
+
if (texture instanceof Texture$1) {
|
|
1340
|
+
renderer.initTexture(texture);
|
|
1341
|
+
}
|
|
1342
|
+
});
|
|
1674
1343
|
}
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
onDropMissed: void 0,
|
|
1715
|
-
performance: {
|
|
1716
|
-
current: 1,
|
|
1717
|
-
min: 0.5,
|
|
1718
|
-
max: 1,
|
|
1719
|
-
debounce: 200,
|
|
1720
|
-
regress: () => {
|
|
1721
|
-
const state2 = get();
|
|
1722
|
-
if (performanceTimeout) clearTimeout(performanceTimeout);
|
|
1723
|
-
if (state2.performance.current !== state2.performance.min) setPerformanceCurrent(state2.performance.min);
|
|
1724
|
-
performanceTimeout = setTimeout(
|
|
1725
|
-
() => setPerformanceCurrent(get().performance.max),
|
|
1726
|
-
state2.performance.debounce
|
|
1727
|
-
);
|
|
1344
|
+
}, [renderer, loadedTextures, cachedResult]);
|
|
1345
|
+
const mappedTextures = useMemo(() => {
|
|
1346
|
+
if (cachedResult) return cachedResult;
|
|
1347
|
+
if (IsObject(input)) {
|
|
1348
|
+
const keyed = {};
|
|
1349
|
+
const textureArray = loadedTextures;
|
|
1350
|
+
let i = 0;
|
|
1351
|
+
for (const key in input) keyed[key] = textureArray[i++];
|
|
1352
|
+
return keyed;
|
|
1353
|
+
} else {
|
|
1354
|
+
return loadedTextures;
|
|
1355
|
+
}
|
|
1356
|
+
}, [input, loadedTextures, cachedResult]);
|
|
1357
|
+
useEffect(() => {
|
|
1358
|
+
if (!cache) return;
|
|
1359
|
+
const urlTextureMap = [];
|
|
1360
|
+
if (typeof input === "string") {
|
|
1361
|
+
urlTextureMap.push([input, mappedTextures]);
|
|
1362
|
+
} else if (Array.isArray(input)) {
|
|
1363
|
+
const textureArray = mappedTextures;
|
|
1364
|
+
input.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
1365
|
+
} else if (IsObject(input)) {
|
|
1366
|
+
const textureRecord = mappedTextures;
|
|
1367
|
+
for (const key in input) {
|
|
1368
|
+
const url = input[key];
|
|
1369
|
+
urlTextureMap.push([url, textureRecord[key]]);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
store.setState((state) => {
|
|
1373
|
+
const refs = new Map(state._textureRefs);
|
|
1374
|
+
let textures = state.textures;
|
|
1375
|
+
let added = false;
|
|
1376
|
+
for (const [url, texture] of urlTextureMap) {
|
|
1377
|
+
if (!textures.has(url)) {
|
|
1378
|
+
if (!added) {
|
|
1379
|
+
textures = new Map(textures);
|
|
1380
|
+
added = true;
|
|
1381
|
+
}
|
|
1382
|
+
textures.set(url, texture);
|
|
1728
1383
|
}
|
|
1384
|
+
refs.set(url, (refs.get(url) ?? 0) + 1);
|
|
1385
|
+
}
|
|
1386
|
+
return added ? { textures, _textureRefs: refs } : { _textureRefs: refs };
|
|
1387
|
+
});
|
|
1388
|
+
return () => store.setState((state) => {
|
|
1389
|
+
const refs = new Map(state._textureRefs);
|
|
1390
|
+
for (const [url] of urlTextureMap) {
|
|
1391
|
+
const next = (refs.get(url) ?? 0) - 1;
|
|
1392
|
+
if (next <= 0) refs.delete(url);
|
|
1393
|
+
else refs.set(url, next);
|
|
1394
|
+
}
|
|
1395
|
+
return { _textureRefs: refs };
|
|
1396
|
+
});
|
|
1397
|
+
}, [cache, input, mappedTextures, store]);
|
|
1398
|
+
return mappedTextures;
|
|
1399
|
+
}
|
|
1400
|
+
useTexture.preload = (url) => useLoader.preload(TextureLoader, url);
|
|
1401
|
+
useTexture.clear = (input) => useLoader.clear(TextureLoader, input);
|
|
1402
|
+
const Texture = ({
|
|
1403
|
+
children,
|
|
1404
|
+
input,
|
|
1405
|
+
onLoad,
|
|
1406
|
+
cache
|
|
1407
|
+
}) => {
|
|
1408
|
+
const options = typeof onLoad === "function" ? { onLoad, cache } : { ...onLoad, cache };
|
|
1409
|
+
const ret = useTexture(input, options);
|
|
1410
|
+
return /* @__PURE__ */ jsx(Fragment, { children: children?.(ret) });
|
|
1411
|
+
};
|
|
1412
|
+
|
|
1413
|
+
function useTextures(selector) {
|
|
1414
|
+
const store = useStore();
|
|
1415
|
+
const registry = useMemo(() => {
|
|
1416
|
+
const getState = store.getState;
|
|
1417
|
+
const setState = store.setState;
|
|
1418
|
+
const getOne = (key) => getState().textures.get(key);
|
|
1419
|
+
return {
|
|
1420
|
+
get all() {
|
|
1421
|
+
return getState().textures;
|
|
1729
1422
|
},
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
top: 0,
|
|
1737
|
-
left: 0,
|
|
1738
|
-
aspect: 0,
|
|
1739
|
-
distance: 0,
|
|
1740
|
-
factor: 0,
|
|
1741
|
-
getCurrentViewport
|
|
1423
|
+
get(input) {
|
|
1424
|
+
if (typeof input === "string") return getOne(input);
|
|
1425
|
+
if (Array.isArray(input)) return input.map(getOne);
|
|
1426
|
+
const out = {};
|
|
1427
|
+
for (const name in input) out[name] = getOne(input[name]);
|
|
1428
|
+
return out;
|
|
1742
1429
|
},
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
const currentSize = state2.size;
|
|
1752
|
-
const newSize = {
|
|
1753
|
-
width: propW ?? currentSize.width,
|
|
1754
|
-
height: propH ?? currentSize.height,
|
|
1755
|
-
top: currentSize.top,
|
|
1756
|
-
left: currentSize.left
|
|
1757
|
-
};
|
|
1758
|
-
set((s) => ({
|
|
1759
|
-
size: newSize,
|
|
1760
|
-
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
1761
|
-
}));
|
|
1762
|
-
getScheduler().invalidate();
|
|
1763
|
-
}
|
|
1430
|
+
has: (key) => getState().textures.has(key),
|
|
1431
|
+
add(keyOrRecord, texture) {
|
|
1432
|
+
setState((state) => {
|
|
1433
|
+
const textures = new Map(state.textures);
|
|
1434
|
+
if (typeof keyOrRecord === "string") {
|
|
1435
|
+
textures.set(keyOrRecord, texture);
|
|
1436
|
+
} else {
|
|
1437
|
+
for (const key in keyOrRecord) textures.set(key, keyOrRecord[key]);
|
|
1764
1438
|
}
|
|
1765
|
-
return;
|
|
1766
|
-
}
|
|
1767
|
-
const w = width;
|
|
1768
|
-
const h = height ?? width;
|
|
1769
|
-
const t = top ?? state2.size.top;
|
|
1770
|
-
const l = left ?? state2.size.left;
|
|
1771
|
-
const size = { width: w, height: h, top: t, left: l };
|
|
1772
|
-
set((s) => ({
|
|
1773
|
-
size,
|
|
1774
|
-
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
1775
|
-
_sizeImperative: true
|
|
1776
|
-
}));
|
|
1777
|
-
getScheduler().invalidate();
|
|
1439
|
+
return { textures };
|
|
1440
|
+
});
|
|
1778
1441
|
},
|
|
1779
|
-
|
|
1780
|
-
const
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1442
|
+
dispose(key, options) {
|
|
1443
|
+
const state = getState();
|
|
1444
|
+
const refs = state._textureRefs.get(key) ?? 0;
|
|
1445
|
+
if (refs > 0 && !options?.force) {
|
|
1446
|
+
console.warn(
|
|
1447
|
+
`[useTextures] "${key}" still has ${refs} active reference(s); skipping dispose. Pass { force: true } to override.`
|
|
1448
|
+
);
|
|
1449
|
+
return false;
|
|
1450
|
+
}
|
|
1451
|
+
state.textures.get(key)?.dispose();
|
|
1452
|
+
setState((s) => {
|
|
1453
|
+
const textures = new Map(s.textures);
|
|
1454
|
+
textures.delete(key);
|
|
1455
|
+
const nextRefs = new Map(s._textureRefs);
|
|
1456
|
+
nextRefs.delete(key);
|
|
1457
|
+
return { textures, _textureRefs: nextRefs };
|
|
1458
|
+
});
|
|
1459
|
+
return true;
|
|
1785
1460
|
},
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
uniforms: {},
|
|
1790
|
-
nodes: {},
|
|
1791
|
-
buffers: {},
|
|
1792
|
-
gpuStorage: {},
|
|
1793
|
-
textures: /* @__PURE__ */ new Map(),
|
|
1794
|
-
_textureRefs: /* @__PURE__ */ new Map(),
|
|
1795
|
-
renderPipeline: null,
|
|
1796
|
-
passes: {},
|
|
1797
|
-
_hmrVersion: 0,
|
|
1798
|
-
_sizeImperative: false,
|
|
1799
|
-
_sizeProps: null,
|
|
1800
|
-
previousRoot: void 0,
|
|
1801
|
-
internal: {
|
|
1802
|
-
// Events
|
|
1803
|
-
interaction: [],
|
|
1804
|
-
subscribers: [],
|
|
1805
|
-
// Per-pointer state (new unified structure)
|
|
1806
|
-
pointerMap: /* @__PURE__ */ new Map(),
|
|
1807
|
-
pointerDirty: /* @__PURE__ */ new Map(),
|
|
1808
|
-
lastEvent: React.createRef(),
|
|
1809
|
-
// Deprecated but kept for backwards compatibility
|
|
1810
|
-
hovered: /* @__PURE__ */ new Map(),
|
|
1811
|
-
initialClick: [0, 0],
|
|
1812
|
-
initialHits: [],
|
|
1813
|
-
capturedMap: /* @__PURE__ */ new Map(),
|
|
1814
|
-
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
1815
|
-
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
1816
|
-
// Occlusion system (WebGPU only)
|
|
1817
|
-
occlusionEnabled: false,
|
|
1818
|
-
occlusionObserver: null,
|
|
1819
|
-
occlusionCache: /* @__PURE__ */ new Map(),
|
|
1820
|
-
helperGroup: null,
|
|
1821
|
-
// Updates
|
|
1822
|
-
active: false,
|
|
1823
|
-
frames: 0,
|
|
1824
|
-
priority: 0,
|
|
1825
|
-
subscribe: (ref, priority, store) => {
|
|
1826
|
-
const internal = get().internal;
|
|
1827
|
-
internal.priority = internal.priority + (priority > 0 ? 1 : 0);
|
|
1828
|
-
internal.subscribers.push({ ref, priority, store });
|
|
1829
|
-
internal.subscribers = internal.subscribers.sort((a, b) => a.priority - b.priority);
|
|
1830
|
-
return () => {
|
|
1831
|
-
const internal2 = get().internal;
|
|
1832
|
-
if (internal2?.subscribers) {
|
|
1833
|
-
internal2.priority = internal2.priority - (priority > 0 ? 1 : 0);
|
|
1834
|
-
internal2.subscribers = internal2.subscribers.filter((s) => s.ref !== ref);
|
|
1835
|
-
}
|
|
1836
|
-
};
|
|
1837
|
-
},
|
|
1838
|
-
// Renderer Storage (single source of truth)
|
|
1839
|
-
actualRenderer: null,
|
|
1840
|
-
// Scheduler for useFrameNext (initialized in renderer.tsx)
|
|
1841
|
-
scheduler: null
|
|
1461
|
+
disposeAll() {
|
|
1462
|
+
for (const texture of getState().textures.values()) texture.dispose();
|
|
1463
|
+
setState({ textures: /* @__PURE__ */ new Map(), _textureRefs: /* @__PURE__ */ new Map() });
|
|
1842
1464
|
}
|
|
1843
1465
|
};
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
const
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
const currentState = rootStore.getState();
|
|
1850
|
-
if (!currentState.isLegacy && currentState.internal.actualRenderer) {
|
|
1851
|
-
const stack = new Error().stack || "";
|
|
1852
|
-
if (!isInternalRendererAccess(stack)) {
|
|
1853
|
-
const cleanedStack = stack.split("\n").slice(2).join("\n") || "Stack trace unavailable";
|
|
1854
|
-
notifyDepreciated({
|
|
1855
|
-
heading: "Accessing state.gl in WebGPU mode",
|
|
1856
|
-
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
|
|
1857
|
-
});
|
|
1858
|
-
}
|
|
1859
|
-
}
|
|
1860
|
-
return currentState.internal.actualRenderer;
|
|
1861
|
-
},
|
|
1862
|
-
set(value) {
|
|
1863
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1864
|
-
},
|
|
1865
|
-
enumerable: true,
|
|
1866
|
-
configurable: true
|
|
1867
|
-
});
|
|
1868
|
-
Object.defineProperty(state, "renderer", {
|
|
1869
|
-
get() {
|
|
1870
|
-
return rootStore.getState().internal.actualRenderer;
|
|
1871
|
-
},
|
|
1872
|
-
set(value) {
|
|
1873
|
-
rootStore.getState().internal.actualRenderer = value;
|
|
1874
|
-
},
|
|
1875
|
-
enumerable: true,
|
|
1876
|
-
configurable: true
|
|
1877
|
-
});
|
|
1878
|
-
let oldScene = state.scene;
|
|
1879
|
-
rootStore.subscribe(() => {
|
|
1880
|
-
const currentState = rootStore.getState();
|
|
1881
|
-
const { scene, rootScene, set } = currentState;
|
|
1882
|
-
if (scene !== oldScene) {
|
|
1883
|
-
oldScene = scene;
|
|
1884
|
-
if (scene?.isScene && scene !== rootScene) {
|
|
1885
|
-
set({ rootScene: scene });
|
|
1886
|
-
}
|
|
1887
|
-
}
|
|
1888
|
-
});
|
|
1889
|
-
let oldSize = state.size;
|
|
1890
|
-
let oldDpr = state.viewport.dpr;
|
|
1891
|
-
let oldCamera = state.camera;
|
|
1892
|
-
rootStore.subscribe(() => {
|
|
1893
|
-
const { camera, size, viewport, set, internal } = rootStore.getState();
|
|
1894
|
-
const actualRenderer = internal.actualRenderer;
|
|
1895
|
-
const canvasTarget = internal.canvasTarget;
|
|
1896
|
-
if (size.width !== oldSize.width || size.height !== oldSize.height || viewport.dpr !== oldDpr) {
|
|
1897
|
-
oldSize = size;
|
|
1898
|
-
oldDpr = viewport.dpr;
|
|
1899
|
-
updateCamera(camera, size);
|
|
1900
|
-
if (internal.isSecondary && canvasTarget) {
|
|
1901
|
-
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1902
|
-
canvasTarget.setSize(size.width, size.height, false);
|
|
1903
|
-
} else {
|
|
1904
|
-
if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
|
|
1905
|
-
actualRenderer.setSize(size.width, size.height, false);
|
|
1906
|
-
if (canvasTarget) {
|
|
1907
|
-
if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
|
|
1908
|
-
canvasTarget.setSize(size.width, size.height, false);
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
if (camera !== oldCamera) {
|
|
1913
|
-
oldCamera = camera;
|
|
1914
|
-
const { rootScene } = rootStore.getState();
|
|
1915
|
-
if (camera && rootScene && !camera.parent) {
|
|
1916
|
-
rootScene.add(camera);
|
|
1917
|
-
}
|
|
1918
|
-
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
1919
|
-
const currentState = rootStore.getState();
|
|
1920
|
-
if (currentState.autoUpdateFrustum && camera) {
|
|
1921
|
-
updateFrustum(camera, currentState.frustum);
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
});
|
|
1925
|
-
rootStore.subscribe((state2) => invalidate(state2));
|
|
1926
|
-
return rootStore;
|
|
1927
|
-
};
|
|
1466
|
+
}, [store]);
|
|
1467
|
+
const subscribe = selector ? () => selector(registry) : (state) => state.textures;
|
|
1468
|
+
const selected = useThree(subscribe);
|
|
1469
|
+
return selector ? selected : registry;
|
|
1470
|
+
}
|
|
1928
1471
|
|
|
1929
|
-
|
|
1930
|
-
const
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1472
|
+
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
1473
|
+
const isLegacy = useThree((s) => s.isLegacy);
|
|
1474
|
+
const size = useThree((s) => s.size);
|
|
1475
|
+
let width;
|
|
1476
|
+
let height;
|
|
1477
|
+
let opts;
|
|
1478
|
+
if (typeof widthOrOptions === "object") {
|
|
1479
|
+
opts = widthOrOptions;
|
|
1480
|
+
} else if (typeof widthOrOptions === "number") {
|
|
1481
|
+
width = widthOrOptions;
|
|
1482
|
+
if (typeof heightOrOptions === "object") {
|
|
1483
|
+
height = widthOrOptions;
|
|
1484
|
+
opts = heightOrOptions;
|
|
1485
|
+
} else if (typeof heightOrOptions === "number") {
|
|
1486
|
+
height = heightOrOptions;
|
|
1487
|
+
opts = options;
|
|
1488
|
+
} else {
|
|
1489
|
+
height = widthOrOptions;
|
|
1937
1490
|
}
|
|
1938
|
-
return loader;
|
|
1939
1491
|
}
|
|
1940
|
-
return
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
if (extensions) extensions(loader);
|
|
1946
|
-
if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
|
|
1947
|
-
return loader.loadAsync(input, onProgress).then((data) => {
|
|
1948
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1949
|
-
return data;
|
|
1950
|
-
});
|
|
1492
|
+
return useMemo(() => {
|
|
1493
|
+
const w = width ?? size.width;
|
|
1494
|
+
const h = height ?? size.height;
|
|
1495
|
+
{
|
|
1496
|
+
return isLegacy ? new WebGLRenderTarget(w, h, opts) : new RenderTarget(w, h, opts);
|
|
1951
1497
|
}
|
|
1952
|
-
|
|
1953
|
-
(res, reject) => loader.load(
|
|
1954
|
-
input,
|
|
1955
|
-
(data) => {
|
|
1956
|
-
if (isObject3D(data?.scene)) Object.assign(data, buildGraph(data.scene));
|
|
1957
|
-
res(data);
|
|
1958
|
-
},
|
|
1959
|
-
onProgress,
|
|
1960
|
-
(error) => reject(new Error(`Could not load ${input}: ${error?.message}`))
|
|
1961
|
-
)
|
|
1962
|
-
);
|
|
1963
|
-
};
|
|
1964
|
-
}
|
|
1965
|
-
function useLoader(loader, input, extensions, onProgress, cacheKey) {
|
|
1966
|
-
const inputs = Array.isArray(input) ? input : [input];
|
|
1967
|
-
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
1968
|
-
const fn = loadingFn(extensions, onProgress);
|
|
1969
|
-
const results = cacheKeys.map(
|
|
1970
|
-
(key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
|
|
1971
|
-
);
|
|
1972
|
-
return Array.isArray(input) ? results : results[0];
|
|
1498
|
+
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
1973
1499
|
}
|
|
1974
|
-
useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
|
|
1975
|
-
const inputs = Array.isArray(input) ? input : [input];
|
|
1976
|
-
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
1977
|
-
cacheKeys.forEach(
|
|
1978
|
-
(key, index) => preload(() => loadingFn(extensions, onProgress)(loader, inputs[index]), [loader, key])
|
|
1979
|
-
);
|
|
1980
|
-
};
|
|
1981
|
-
useLoader.clear = function(loader, input, cacheKey) {
|
|
1982
|
-
const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
|
|
1983
|
-
cacheKeys.forEach((key) => clear([loader, key]));
|
|
1984
|
-
};
|
|
1985
|
-
useLoader.loader = getLoader;
|
|
1986
1500
|
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
1501
|
+
const presetsObj = {
|
|
1502
|
+
apartment: "lebombo_1k.hdr",
|
|
1503
|
+
city: "potsdamer_platz_1k.hdr",
|
|
1504
|
+
dawn: "kiara_1_dawn_1k.hdr",
|
|
1505
|
+
forest: "forest_slope_1k.hdr",
|
|
1506
|
+
lobby: "st_fagans_interior_1k.hdr",
|
|
1507
|
+
night: "dikhololo_night_1k.hdr",
|
|
1508
|
+
park: "rooitou_park_1k.hdr",
|
|
1509
|
+
studio: "studio_small_03_1k.hdr",
|
|
1510
|
+
sunset: "venice_sunset_1k.hdr",
|
|
1511
|
+
warehouse: "empty_warehouse_01_1k.hdr"
|
|
1512
|
+
};
|
|
1513
|
+
|
|
1514
|
+
const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
|
|
1515
|
+
const isArray = (arr) => Array.isArray(arr);
|
|
1516
|
+
const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
|
|
1517
|
+
function useEnvironment({
|
|
1518
|
+
files = defaultFiles,
|
|
1519
|
+
path = "",
|
|
1520
|
+
preset = void 0,
|
|
1521
|
+
colorSpace = void 0,
|
|
1522
|
+
extensions
|
|
1523
|
+
} = {}) {
|
|
1524
|
+
if (preset) {
|
|
1525
|
+
validatePreset(preset);
|
|
1526
|
+
files = presetsObj[preset];
|
|
1527
|
+
path = CUBEMAP_ROOT;
|
|
1528
|
+
}
|
|
1529
|
+
const multiFile = isArray(files);
|
|
1530
|
+
const { extension, isCubemap } = getExtension(files);
|
|
1531
|
+
const loader = getLoader(extension);
|
|
1532
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1533
|
+
const renderer = useThree((state) => state.renderer);
|
|
1534
|
+
useLayoutEffect(() => {
|
|
1535
|
+
if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
|
|
1536
|
+
function clearGainmapTexture() {
|
|
1537
|
+
useLoader.clear(loader, multiFile ? [files] : files);
|
|
1538
|
+
}
|
|
1539
|
+
renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
|
|
1540
|
+
}, [extension, files, loader, multiFile, renderer.domElement]);
|
|
1541
|
+
const loaderResult = useLoader(
|
|
1542
|
+
loader,
|
|
1543
|
+
multiFile ? [files] : files,
|
|
1544
|
+
(loader2) => {
|
|
1545
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
1546
|
+
loader2.setRenderer?.(renderer);
|
|
2026
1547
|
}
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
const mergedState = {
|
|
2030
|
-
...localState,
|
|
2031
|
-
time: frameState.time,
|
|
2032
|
-
delta: frameState.delta,
|
|
2033
|
-
elapsed: frameState.elapsed,
|
|
2034
|
-
frame: frameState.frame
|
|
2035
|
-
};
|
|
2036
|
-
callbackRef.current?.(mergedState, delta);
|
|
2037
|
-
};
|
|
2038
|
-
const unregister = scheduler.register(wrappedCallback, {
|
|
2039
|
-
id,
|
|
2040
|
-
rootId,
|
|
2041
|
-
...options
|
|
2042
|
-
});
|
|
2043
|
-
return () => {
|
|
2044
|
-
unregister();
|
|
2045
|
-
if (isLegacyPriority) {
|
|
2046
|
-
const currentState = store.getState();
|
|
2047
|
-
if (currentState.internal) {
|
|
2048
|
-
currentState.internal.priority--;
|
|
2049
|
-
let parentRoot = currentState.previousRoot;
|
|
2050
|
-
while (parentRoot) {
|
|
2051
|
-
const parentState = parentRoot.getState();
|
|
2052
|
-
if (parentState?.internal) parentState.internal.priority--;
|
|
2053
|
-
parentRoot = parentState?.previousRoot;
|
|
2054
|
-
}
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
};
|
|
2058
|
-
} else {
|
|
2059
|
-
return scheduler.register(
|
|
2060
|
-
(state, delta) => {
|
|
2061
|
-
const frameState = state;
|
|
2062
|
-
if (!frameState.renderer) return;
|
|
2063
|
-
callbackRef.current?.(frameState, delta);
|
|
2064
|
-
},
|
|
2065
|
-
{ id, ...options }
|
|
2066
|
-
);
|
|
1548
|
+
loader2.setPath?.(path);
|
|
1549
|
+
if (extensions) extensions(loader2);
|
|
2067
1550
|
}
|
|
2068
|
-
}, [store, scheduler, id, optionsKey, isLegacyPriority, isInsideCanvas]);
|
|
2069
|
-
const isPaused = React.useSyncExternalStore(
|
|
2070
|
-
// Subscribe function
|
|
2071
|
-
React.useCallback(
|
|
2072
|
-
(onStoreChange) => {
|
|
2073
|
-
return getScheduler().subscribeJobState(id, onStoreChange);
|
|
2074
|
-
},
|
|
2075
|
-
[id]
|
|
2076
|
-
),
|
|
2077
|
-
// getSnapshot function
|
|
2078
|
-
React.useCallback(() => getScheduler().isJobPaused(id), [id]),
|
|
2079
|
-
// getServerSnapshot function (SSR)
|
|
2080
|
-
React.useCallback(() => false, [])
|
|
2081
1551
|
);
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
/**
|
|
2093
|
-
* Manually step this job only.
|
|
2094
|
-
* Bypasses FPS limiting - always runs.
|
|
2095
|
-
* @param timestamp Optional timestamp (defaults to performance.now())
|
|
2096
|
-
*/
|
|
2097
|
-
step: (timestamp) => {
|
|
2098
|
-
getScheduler().stepJob(id, timestamp);
|
|
2099
|
-
},
|
|
2100
|
-
/**
|
|
2101
|
-
* Manually step ALL jobs in the scheduler.
|
|
2102
|
-
* Useful for frameloop='never' mode.
|
|
2103
|
-
* @param timestamp Optional timestamp (defaults to performance.now())
|
|
2104
|
-
*/
|
|
2105
|
-
stepAll: (timestamp) => {
|
|
2106
|
-
getScheduler().step(timestamp);
|
|
2107
|
-
},
|
|
2108
|
-
/**
|
|
2109
|
-
* Pause this job (set enabled=false).
|
|
2110
|
-
* Job remains registered but won't run.
|
|
2111
|
-
*/
|
|
2112
|
-
pause: () => {
|
|
2113
|
-
getScheduler().pauseJob(id);
|
|
2114
|
-
},
|
|
2115
|
-
/**
|
|
2116
|
-
* Resume this job (set enabled=true).
|
|
2117
|
-
*/
|
|
2118
|
-
resume: () => {
|
|
2119
|
-
getScheduler().resumeJob(id);
|
|
2120
|
-
},
|
|
2121
|
-
/**
|
|
2122
|
-
* Reactive paused state - automatically updates when pause/resume is called.
|
|
2123
|
-
* No need for forceUpdate() in your components.
|
|
2124
|
-
*/
|
|
2125
|
-
isPaused
|
|
2126
|
-
};
|
|
2127
|
-
}, [id, isPaused]);
|
|
2128
|
-
return controls;
|
|
1552
|
+
let texture = multiFile ? (
|
|
1553
|
+
// @ts-ignore
|
|
1554
|
+
loaderResult[0]
|
|
1555
|
+
) : loaderResult;
|
|
1556
|
+
if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
|
|
1557
|
+
texture = texture.renderTarget?.texture;
|
|
1558
|
+
}
|
|
1559
|
+
texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
|
|
1560
|
+
texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
|
|
1561
|
+
return texture;
|
|
2129
1562
|
}
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
1563
|
+
const preloadDefaultOptions = {
|
|
1564
|
+
files: defaultFiles,
|
|
1565
|
+
path: "",
|
|
1566
|
+
preset: void 0,
|
|
1567
|
+
extensions: void 0
|
|
1568
|
+
};
|
|
1569
|
+
useEnvironment.preload = (preloadOptions) => {
|
|
1570
|
+
const options = { ...preloadDefaultOptions, ...preloadOptions };
|
|
1571
|
+
let { files, path = "" } = options;
|
|
1572
|
+
const { preset, extensions } = options;
|
|
1573
|
+
if (preset) {
|
|
1574
|
+
validatePreset(preset);
|
|
1575
|
+
files = presetsObj[preset];
|
|
1576
|
+
path = CUBEMAP_ROOT;
|
|
1577
|
+
}
|
|
1578
|
+
const { extension } = getExtension(files);
|
|
1579
|
+
if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
|
|
1580
|
+
throw new Error("useEnvironment: Preloading gainmaps is not supported");
|
|
1581
|
+
}
|
|
1582
|
+
const loader = getLoader(extension);
|
|
1583
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1584
|
+
useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
|
|
1585
|
+
loader2.setPath?.(path);
|
|
1586
|
+
if (extensions) extensions(loader2);
|
|
1587
|
+
});
|
|
1588
|
+
};
|
|
1589
|
+
const clearDefaultOptins = {
|
|
1590
|
+
files: defaultFiles,
|
|
1591
|
+
preset: void 0
|
|
1592
|
+
};
|
|
1593
|
+
useEnvironment.clear = (clearOptions) => {
|
|
1594
|
+
const options = { ...clearDefaultOptins, ...clearOptions };
|
|
1595
|
+
let { files } = options;
|
|
1596
|
+
const { preset } = options;
|
|
1597
|
+
if (preset) {
|
|
1598
|
+
validatePreset(preset);
|
|
1599
|
+
files = presetsObj[preset];
|
|
1600
|
+
}
|
|
1601
|
+
const { extension } = getExtension(files);
|
|
1602
|
+
const loader = getLoader(extension);
|
|
1603
|
+
if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
|
|
1604
|
+
useLoader.clear(loader, isArray(files) ? [files] : files);
|
|
1605
|
+
};
|
|
1606
|
+
function validatePreset(preset) {
|
|
1607
|
+
if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
|
|
2136
1608
|
}
|
|
2137
|
-
function
|
|
2138
|
-
|
|
1609
|
+
function getExtension(files) {
|
|
1610
|
+
const isCubemap = isArray(files) && files.length === 6;
|
|
1611
|
+
const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
|
|
1612
|
+
const firstEntry = isArray(files) ? files[0] : files;
|
|
1613
|
+
const extension = isCubemap ? "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
|
|
1614
|
+
return { extension, isCubemap, isGainmap };
|
|
2139
1615
|
}
|
|
2140
|
-
function
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
} else if (Array.isArray(input)) {
|
|
2144
|
-
return input.map((url) => textureCache.get(url));
|
|
2145
|
-
} else {
|
|
2146
|
-
const result = {};
|
|
2147
|
-
const objInput = input;
|
|
2148
|
-
for (const key in objInput) {
|
|
2149
|
-
result[key] = textureCache.get(objInput[key]);
|
|
2150
|
-
}
|
|
2151
|
-
return result;
|
|
2152
|
-
}
|
|
2153
|
-
}
|
|
2154
|
-
function useTexture(input, optionsOrOnLoad) {
|
|
2155
|
-
const renderer = useThree((state) => state.internal.actualRenderer);
|
|
2156
|
-
const store = useStore();
|
|
2157
|
-
const options = typeof optionsOrOnLoad === "function" ? { onLoad: optionsOrOnLoad } : optionsOrOnLoad ?? {};
|
|
2158
|
-
const { onLoad, cache = true } = options;
|
|
2159
|
-
const onLoadRef = useRef(onLoad);
|
|
2160
|
-
onLoadRef.current = onLoad;
|
|
2161
|
-
const onLoadCalledForRef = useRef(null);
|
|
2162
|
-
const urls = useMemo(() => getUrls(input), [input]);
|
|
2163
|
-
const cachedResult = useMemo(() => {
|
|
2164
|
-
if (!cache) return null;
|
|
2165
|
-
const textures = store.getState().textures;
|
|
2166
|
-
if (!allUrlsCached(urls, textures)) return null;
|
|
2167
|
-
return buildFromCache(input, textures);
|
|
2168
|
-
}, [cache, urls, input, store]);
|
|
2169
|
-
const loadedTextures = useLoader(
|
|
2170
|
-
TextureLoader,
|
|
2171
|
-
IsObject(input) ? Object.values(input) : input
|
|
2172
|
-
);
|
|
2173
|
-
const inputKey = urls.join("\0");
|
|
2174
|
-
useLayoutEffect(() => {
|
|
2175
|
-
if (cachedResult) return;
|
|
2176
|
-
if (onLoadCalledForRef.current === inputKey) return;
|
|
2177
|
-
onLoadCalledForRef.current = inputKey;
|
|
2178
|
-
onLoadRef.current?.(loadedTextures);
|
|
2179
|
-
}, [cachedResult, loadedTextures, inputKey]);
|
|
2180
|
-
useEffect(() => {
|
|
2181
|
-
if (cachedResult) return;
|
|
2182
|
-
if ("initTexture" in renderer) {
|
|
2183
|
-
let textureArray = [];
|
|
2184
|
-
if (Array.isArray(loadedTextures)) {
|
|
2185
|
-
textureArray = loadedTextures;
|
|
2186
|
-
} else if (loadedTextures instanceof Texture$1) {
|
|
2187
|
-
textureArray = [loadedTextures];
|
|
2188
|
-
} else if (IsObject(loadedTextures)) {
|
|
2189
|
-
textureArray = Object.values(loadedTextures);
|
|
2190
|
-
}
|
|
2191
|
-
textureArray.forEach((texture) => {
|
|
2192
|
-
if (texture instanceof Texture$1) {
|
|
2193
|
-
renderer.initTexture(texture);
|
|
2194
|
-
}
|
|
2195
|
-
});
|
|
2196
|
-
}
|
|
2197
|
-
}, [renderer, loadedTextures, cachedResult]);
|
|
2198
|
-
const mappedTextures = useMemo(() => {
|
|
2199
|
-
if (cachedResult) return cachedResult;
|
|
2200
|
-
if (IsObject(input)) {
|
|
2201
|
-
const keyed = {};
|
|
2202
|
-
const textureArray = loadedTextures;
|
|
2203
|
-
let i = 0;
|
|
2204
|
-
for (const key in input) keyed[key] = textureArray[i++];
|
|
2205
|
-
return keyed;
|
|
2206
|
-
} else {
|
|
2207
|
-
return loadedTextures;
|
|
2208
|
-
}
|
|
2209
|
-
}, [input, loadedTextures, cachedResult]);
|
|
2210
|
-
useEffect(() => {
|
|
2211
|
-
if (!cache) return;
|
|
2212
|
-
const urlTextureMap = [];
|
|
2213
|
-
if (typeof input === "string") {
|
|
2214
|
-
urlTextureMap.push([input, mappedTextures]);
|
|
2215
|
-
} else if (Array.isArray(input)) {
|
|
2216
|
-
const textureArray = mappedTextures;
|
|
2217
|
-
input.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
|
|
2218
|
-
} else if (IsObject(input)) {
|
|
2219
|
-
const textureRecord = mappedTextures;
|
|
2220
|
-
for (const key in input) {
|
|
2221
|
-
const url = input[key];
|
|
2222
|
-
urlTextureMap.push([url, textureRecord[key]]);
|
|
2223
|
-
}
|
|
2224
|
-
}
|
|
2225
|
-
store.setState((state) => {
|
|
2226
|
-
const refs = new Map(state._textureRefs);
|
|
2227
|
-
let textures = state.textures;
|
|
2228
|
-
let added = false;
|
|
2229
|
-
for (const [url, texture] of urlTextureMap) {
|
|
2230
|
-
if (!textures.has(url)) {
|
|
2231
|
-
if (!added) {
|
|
2232
|
-
textures = new Map(textures);
|
|
2233
|
-
added = true;
|
|
2234
|
-
}
|
|
2235
|
-
textures.set(url, texture);
|
|
2236
|
-
}
|
|
2237
|
-
refs.set(url, (refs.get(url) ?? 0) + 1);
|
|
2238
|
-
}
|
|
2239
|
-
return added ? { textures, _textureRefs: refs } : { _textureRefs: refs };
|
|
2240
|
-
});
|
|
2241
|
-
return () => store.setState((state) => {
|
|
2242
|
-
const refs = new Map(state._textureRefs);
|
|
2243
|
-
for (const [url] of urlTextureMap) {
|
|
2244
|
-
const next = (refs.get(url) ?? 0) - 1;
|
|
2245
|
-
if (next <= 0) refs.delete(url);
|
|
2246
|
-
else refs.set(url, next);
|
|
2247
|
-
}
|
|
2248
|
-
return { _textureRefs: refs };
|
|
2249
|
-
});
|
|
2250
|
-
}, [cache, input, mappedTextures, store]);
|
|
2251
|
-
return mappedTextures;
|
|
2252
|
-
}
|
|
2253
|
-
useTexture.preload = (url) => useLoader.preload(TextureLoader, url);
|
|
2254
|
-
useTexture.clear = (input) => useLoader.clear(TextureLoader, input);
|
|
2255
|
-
const Texture = ({
|
|
2256
|
-
children,
|
|
2257
|
-
input,
|
|
2258
|
-
onLoad,
|
|
2259
|
-
cache
|
|
2260
|
-
}) => {
|
|
2261
|
-
const options = typeof onLoad === "function" ? { onLoad, cache } : { ...onLoad, cache };
|
|
2262
|
-
const ret = useTexture(input, options);
|
|
2263
|
-
return /* @__PURE__ */ jsx(Fragment, { children: children?.(ret) });
|
|
2264
|
-
};
|
|
2265
|
-
|
|
2266
|
-
function useTextures(selector) {
|
|
2267
|
-
const store = useStore();
|
|
2268
|
-
const registry = useMemo(() => {
|
|
2269
|
-
const getState = store.getState;
|
|
2270
|
-
const setState = store.setState;
|
|
2271
|
-
const getOne = (key) => getState().textures.get(key);
|
|
2272
|
-
return {
|
|
2273
|
-
get all() {
|
|
2274
|
-
return getState().textures;
|
|
2275
|
-
},
|
|
2276
|
-
get(input) {
|
|
2277
|
-
if (typeof input === "string") return getOne(input);
|
|
2278
|
-
if (Array.isArray(input)) return input.map(getOne);
|
|
2279
|
-
const out = {};
|
|
2280
|
-
for (const name in input) out[name] = getOne(input[name]);
|
|
2281
|
-
return out;
|
|
2282
|
-
},
|
|
2283
|
-
has: (key) => getState().textures.has(key),
|
|
2284
|
-
add(keyOrRecord, texture) {
|
|
2285
|
-
setState((state) => {
|
|
2286
|
-
const textures = new Map(state.textures);
|
|
2287
|
-
if (typeof keyOrRecord === "string") {
|
|
2288
|
-
textures.set(keyOrRecord, texture);
|
|
2289
|
-
} else {
|
|
2290
|
-
for (const key in keyOrRecord) textures.set(key, keyOrRecord[key]);
|
|
2291
|
-
}
|
|
2292
|
-
return { textures };
|
|
2293
|
-
});
|
|
2294
|
-
},
|
|
2295
|
-
dispose(key, options) {
|
|
2296
|
-
const state = getState();
|
|
2297
|
-
const refs = state._textureRefs.get(key) ?? 0;
|
|
2298
|
-
if (refs > 0 && !options?.force) {
|
|
2299
|
-
console.warn(
|
|
2300
|
-
`[useTextures] "${key}" still has ${refs} active reference(s); skipping dispose. Pass { force: true } to override.`
|
|
2301
|
-
);
|
|
2302
|
-
return false;
|
|
2303
|
-
}
|
|
2304
|
-
state.textures.get(key)?.dispose();
|
|
2305
|
-
setState((s) => {
|
|
2306
|
-
const textures = new Map(s.textures);
|
|
2307
|
-
textures.delete(key);
|
|
2308
|
-
const nextRefs = new Map(s._textureRefs);
|
|
2309
|
-
nextRefs.delete(key);
|
|
2310
|
-
return { textures, _textureRefs: nextRefs };
|
|
2311
|
-
});
|
|
2312
|
-
return true;
|
|
2313
|
-
},
|
|
2314
|
-
disposeAll() {
|
|
2315
|
-
for (const texture of getState().textures.values()) texture.dispose();
|
|
2316
|
-
setState({ textures: /* @__PURE__ */ new Map(), _textureRefs: /* @__PURE__ */ new Map() });
|
|
2317
|
-
}
|
|
2318
|
-
};
|
|
2319
|
-
}, [store]);
|
|
2320
|
-
const subscribe = selector ? () => selector(registry) : (state) => state.textures;
|
|
2321
|
-
const selected = useThree(subscribe);
|
|
2322
|
-
return selector ? selected : registry;
|
|
2323
|
-
}
|
|
2324
|
-
|
|
2325
|
-
function useRenderTarget(widthOrOptions, heightOrOptions, options) {
|
|
2326
|
-
const isLegacy = useThree((s) => s.isLegacy);
|
|
2327
|
-
const size = useThree((s) => s.size);
|
|
2328
|
-
let width;
|
|
2329
|
-
let height;
|
|
2330
|
-
let opts;
|
|
2331
|
-
if (typeof widthOrOptions === "object") {
|
|
2332
|
-
opts = widthOrOptions;
|
|
2333
|
-
} else if (typeof widthOrOptions === "number") {
|
|
2334
|
-
width = widthOrOptions;
|
|
2335
|
-
if (typeof heightOrOptions === "object") {
|
|
2336
|
-
height = widthOrOptions;
|
|
2337
|
-
opts = heightOrOptions;
|
|
2338
|
-
} else if (typeof heightOrOptions === "number") {
|
|
2339
|
-
height = heightOrOptions;
|
|
2340
|
-
opts = options;
|
|
2341
|
-
} else {
|
|
2342
|
-
height = widthOrOptions;
|
|
2343
|
-
}
|
|
2344
|
-
}
|
|
2345
|
-
return useMemo(() => {
|
|
2346
|
-
const w = width ?? size.width;
|
|
2347
|
-
const h = height ?? size.height;
|
|
2348
|
-
{
|
|
2349
|
-
return isLegacy ? new WebGLRenderTarget(w, h, opts) : new RenderTarget(w, h, opts);
|
|
2350
|
-
}
|
|
2351
|
-
}, [width, height, size.width, size.height, opts, isLegacy]);
|
|
1616
|
+
function getLoader(extension) {
|
|
1617
|
+
const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
|
|
1618
|
+
return loader;
|
|
2352
1619
|
}
|
|
2353
1620
|
|
|
2354
1621
|
function useStore() {
|
|
@@ -2368,6 +1635,8 @@ function useGraph(object) {
|
|
|
2368
1635
|
return useMemo(() => buildGraph(object), [object]);
|
|
2369
1636
|
}
|
|
2370
1637
|
|
|
1638
|
+
const t = 1, o = 8, r = 32, e = 2, i$1 = 268435456;
|
|
1639
|
+
|
|
2371
1640
|
let effectId = 0;
|
|
2372
1641
|
function addEffect(callback) {
|
|
2373
1642
|
notifyDepreciated({
|
|
@@ -2402,7 +1671,7 @@ function advance(timestamp) {
|
|
|
2402
1671
|
getScheduler().step(timestamp);
|
|
2403
1672
|
}
|
|
2404
1673
|
|
|
2405
|
-
const version = "10.0.0-alpha.
|
|
1674
|
+
const version = "10.0.0-alpha.3";
|
|
2406
1675
|
const packageData = {
|
|
2407
1676
|
version: version};
|
|
2408
1677
|
|
|
@@ -13459,206 +12728,789 @@ Check the top-level render call using <` + i + ">.");
|
|
|
13459
12728
|
var o = 1 << 31 - vn(n);
|
|
13460
12729
|
e.entanglements[1] |= o, n &= ~o;
|
|
13461
12730
|
}
|
|
13462
|
-
Kn(e), (ye & (Zn | uo)) === Jn && (Pp = me() + Fg, Wa(0));
|
|
12731
|
+
Kn(e), (ye & (Zn | uo)) === Jn && (Pp = me() + Fg, Wa(0));
|
|
12732
|
+
}
|
|
12733
|
+
}
|
|
12734
|
+
break;
|
|
12735
|
+
case 31:
|
|
12736
|
+
case 13:
|
|
12737
|
+
n = On(e, 2), n !== null && We(n, e, 2), Ls(), rl(e, 2);
|
|
12738
|
+
}
|
|
12739
|
+
}, le.batchedUpdates = function(e, n) {
|
|
12740
|
+
return e(n);
|
|
12741
|
+
}, le.createComponentSelector = function(e) {
|
|
12742
|
+
return { $$typeof: pm, value: e };
|
|
12743
|
+
}, le.createContainer = function(e, n, o, i, s, u, f, p, g, S) {
|
|
12744
|
+
return Ka(e, n, false, null, o, i, u, null, f, p, g, S);
|
|
12745
|
+
}, le.createHasPseudoClassSelector = function(e) {
|
|
12746
|
+
return { $$typeof: hm, value: e };
|
|
12747
|
+
}, le.createHydrationContainer = function(e, n, o, i, s, u, f, p, g, S, T, _, I, O) {
|
|
12748
|
+
return e = Ka(o, i, true, e, s, u, p, O, g, S, T, _), e.context = Dh(null), o = e.current, i = Nt(o), i = Xo(i), s = zo(i), s.callback = n ?? null, Mt(o, s, i), ur(i, "hydrateRoot()", null), n = i, e.current.lanes = n, Ci(e, n), Kn(e), e;
|
|
12749
|
+
}, le.createPortal = function(e, n, o) {
|
|
12750
|
+
var i = 3 < arguments.length && arguments[3] !== void 0 ? arguments[3] : null;
|
|
12751
|
+
try {
|
|
12752
|
+
vt(i);
|
|
12753
|
+
var s = false;
|
|
12754
|
+
} catch {
|
|
12755
|
+
s = true;
|
|
12756
|
+
}
|
|
12757
|
+
return s && (console.error("The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", typeof Symbol == "function" && Symbol.toStringTag && i[Symbol.toStringTag] || i.constructor.name || "Object"), vt(i)), { $$typeof: Ao, key: i == null ? null : "" + i, children: e, containerInfo: n, implementation: o };
|
|
12758
|
+
}, le.createRoleSelector = function(e) {
|
|
12759
|
+
return { $$typeof: mm, value: e };
|
|
12760
|
+
}, le.createTestNameSelector = function(e) {
|
|
12761
|
+
return { $$typeof: gm, value: e };
|
|
12762
|
+
}, le.createTextSelector = function(e) {
|
|
12763
|
+
return { $$typeof: ym, value: e };
|
|
12764
|
+
}, le.defaultOnCaughtError = function(e) {
|
|
12765
|
+
var n = bd ? "The above error occurred in the <" + bd + "> component." : "The above error occurred in one of your React components.", o = "React will try to recreate this component tree from scratch using the error boundary you provided, " + ((Cg || "Anonymous") + ".");
|
|
12766
|
+
typeof e == "object" && e !== null && typeof e.environmentName == "string" ? ri("error", [`%o
|
|
12767
|
+
|
|
12768
|
+
%s
|
|
12769
|
+
|
|
12770
|
+
%s
|
|
12771
|
+
`, e, n, o], e.environmentName)() : console.error(`%o
|
|
12772
|
+
|
|
12773
|
+
%s
|
|
12774
|
+
|
|
12775
|
+
%s
|
|
12776
|
+
`, e, n, o);
|
|
12777
|
+
}, le.defaultOnRecoverableError = function(e) {
|
|
12778
|
+
qg(e);
|
|
12779
|
+
}, le.defaultOnUncaughtError = function(e) {
|
|
12780
|
+
qg(e), console.warn(`%s
|
|
12781
|
+
|
|
12782
|
+
%s
|
|
12783
|
+
`, bd ? "An error occurred in the <" + bd + "> component." : "An error occurred in one of your React components.", `Consider adding an error boundary to your tree to customize error handling behavior.
|
|
12784
|
+
Visit https://react.dev/link/error-boundaries to learn more about error boundaries.`);
|
|
12785
|
+
}, le.deferredUpdates = function(e) {
|
|
12786
|
+
var n = x.T, o = wt();
|
|
12787
|
+
try {
|
|
12788
|
+
return an(32), x.T = null, e();
|
|
12789
|
+
} finally {
|
|
12790
|
+
an(o), x.T = n;
|
|
12791
|
+
}
|
|
12792
|
+
}, le.discreteUpdates = function(e, n, o, i, s) {
|
|
12793
|
+
var u = x.T, f = wt();
|
|
12794
|
+
try {
|
|
12795
|
+
return an(2), x.T = null, e(n, o, i, s);
|
|
12796
|
+
} finally {
|
|
12797
|
+
an(f), x.T = u, ye === Jn && (Pp = me() + Fg);
|
|
12798
|
+
}
|
|
12799
|
+
}, le.findAllNodes = kc, le.findBoundingRects = function(e, n) {
|
|
12800
|
+
if (!xr) throw Error("Test selector API is not supported by this renderer.");
|
|
12801
|
+
n = kc(e, n), e = [];
|
|
12802
|
+
for (var o = 0; o < n.length; o++) e.push(ma(n[o]));
|
|
12803
|
+
for (n = e.length - 1; 0 < n; n--) {
|
|
12804
|
+
o = e[n];
|
|
12805
|
+
for (var i = o.x, s = i + o.width, u = o.y, f = u + o.height, p = n - 1; 0 <= p; p--) if (n !== p) {
|
|
12806
|
+
var g = e[p], S = g.x, T = S + g.width, _ = g.y, I = _ + g.height;
|
|
12807
|
+
if (i >= S && u >= _ && s <= T && f <= I) {
|
|
12808
|
+
e.splice(n, 1);
|
|
12809
|
+
break;
|
|
12810
|
+
} else if (i !== S || o.width !== g.width || I < u || _ > f) {
|
|
12811
|
+
if (!(u !== _ || o.height !== g.height || T < i || S > s)) {
|
|
12812
|
+
S > i && (g.width += S - i, g.x = i), T < s && (g.width = s - S), e.splice(n, 1);
|
|
12813
|
+
break;
|
|
12814
|
+
}
|
|
12815
|
+
} else {
|
|
12816
|
+
_ > u && (g.height += _ - u, g.y = u), I < f && (g.height = f - _), e.splice(n, 1);
|
|
12817
|
+
break;
|
|
12818
|
+
}
|
|
12819
|
+
}
|
|
12820
|
+
}
|
|
12821
|
+
return e;
|
|
12822
|
+
}, le.findHostInstance = function(e) {
|
|
12823
|
+
var n = e._reactInternals;
|
|
12824
|
+
if (n === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
|
|
12825
|
+
return e = mu(n), e === null ? null : ot(e.stateNode);
|
|
12826
|
+
}, le.findHostInstanceWithNoPortals = function(e) {
|
|
12827
|
+
return e = Ed(e), e = e !== null ? _p(e) : null, e === null ? null : ot(e.stateNode);
|
|
12828
|
+
}, le.findHostInstanceWithWarning = function(e, n) {
|
|
12829
|
+
var o = e._reactInternals;
|
|
12830
|
+
if (o === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
|
|
12831
|
+
if (e = mu(o), e === null) return null;
|
|
12832
|
+
if (e.mode & 8) {
|
|
12833
|
+
var i = G(o) || "Component";
|
|
12834
|
+
mb[i] || (mb[i] = true, B(e, function() {
|
|
12835
|
+
o.mode & 8 ? console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i) : console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i);
|
|
12836
|
+
}));
|
|
12837
|
+
}
|
|
12838
|
+
return ot(e.stateNode);
|
|
12839
|
+
}, le.flushPassiveEffects = el, le.flushSyncFromReconciler = function(e) {
|
|
12840
|
+
var n = ye;
|
|
12841
|
+
ye |= 1;
|
|
12842
|
+
var o = x.T, i = wt();
|
|
12843
|
+
try {
|
|
12844
|
+
if (an(2), x.T = null, e) return e();
|
|
12845
|
+
} finally {
|
|
12846
|
+
an(i), x.T = o, ye = n, (ye & (Zn | uo)) === Jn && Wa(0);
|
|
12847
|
+
}
|
|
12848
|
+
}, le.flushSyncWork = Ls, le.focusWithin = function(e, n) {
|
|
12849
|
+
if (!xr) throw Error("Test selector API is not supported by this renderer.");
|
|
12850
|
+
for (e = Ef(e), n = hh(e, n), n = Array.from(n), e = 0; e < n.length; ) {
|
|
12851
|
+
var o = n[e++], i = o.tag;
|
|
12852
|
+
if (!Kr(o)) {
|
|
12853
|
+
if ((i === 5 || i === 26 || i === 27) && Ft(o.stateNode)) return true;
|
|
12854
|
+
for (o = o.child; o !== null; ) n.push(o), o = o.sibling;
|
|
12855
|
+
}
|
|
12856
|
+
}
|
|
12857
|
+
return false;
|
|
12858
|
+
}, le.getFindAllNodesFailureDescription = function(e, n) {
|
|
12859
|
+
if (!xr) throw Error("Test selector API is not supported by this renderer.");
|
|
12860
|
+
var o = 0, i = [];
|
|
12861
|
+
e = [Ef(e), 0];
|
|
12862
|
+
for (var s = 0; s < e.length; ) {
|
|
12863
|
+
var u = e[s++], f = u.tag, p = e[s++], g = n[p];
|
|
12864
|
+
if ((f !== 5 && f !== 26 && f !== 27 || !Kr(u)) && (If(u, g) && (i.push(Sc(g)), p++, p > o && (o = p)), p < n.length)) for (u = u.child; u !== null; ) e.push(u, p), u = u.sibling;
|
|
12865
|
+
}
|
|
12866
|
+
if (o < n.length) {
|
|
12867
|
+
for (e = []; o < n.length; o++) e.push(Sc(n[o]));
|
|
12868
|
+
return `findAllNodes was able to match part of the selector:
|
|
12869
|
+
` + (i.join(" > ") + `
|
|
12870
|
+
|
|
12871
|
+
No matching component was found for:
|
|
12872
|
+
`) + e.join(" > ");
|
|
12873
|
+
}
|
|
12874
|
+
return null;
|
|
12875
|
+
}, le.getPublicRootInstance = function(e) {
|
|
12876
|
+
if (e = e.current, !e.child) return null;
|
|
12877
|
+
switch (e.child.tag) {
|
|
12878
|
+
case 27:
|
|
12879
|
+
case 5:
|
|
12880
|
+
return ot(e.child.stateNode);
|
|
12881
|
+
default:
|
|
12882
|
+
return e.child.stateNode;
|
|
12883
|
+
}
|
|
12884
|
+
}, le.injectIntoDevTools = function() {
|
|
12885
|
+
var e = { bundleType: 1, version: Jt, rendererPackageName: Zt, currentDispatcherRef: x, reconcilerVersion: "19.2.0" };
|
|
12886
|
+
return jo !== null && (e.rendererConfig = jo), e.overrideHookState = gb, e.overrideHookStateDeletePath = yb, e.overrideHookStateRenamePath = bb, e.overrideProps = vb, e.overridePropsDeletePath = Sb, e.overridePropsRenamePath = kb, e.scheduleUpdate = wb, e.scheduleRetry = Pb, e.setErrorHandler = xb, e.setSuspenseHandler = zb, e.scheduleRefresh = hu, e.scheduleRoot = Fl, e.setRefreshHandler = Ir, e.getCurrentFiber = Ic, Ep(e);
|
|
12887
|
+
}, le.isAlreadyRendering = Ns, le.observeVisibleRects = function(e, n, o, i) {
|
|
12888
|
+
function s() {
|
|
12889
|
+
var S = kc(e, n);
|
|
12890
|
+
u.forEach(function(T) {
|
|
12891
|
+
0 > S.indexOf(T) && g(T);
|
|
12892
|
+
}), S.forEach(function(T) {
|
|
12893
|
+
0 > u.indexOf(T) && p(T);
|
|
12894
|
+
});
|
|
12895
|
+
}
|
|
12896
|
+
if (!xr) throw Error("Test selector API is not supported by this renderer.");
|
|
12897
|
+
var u = kc(e, n);
|
|
12898
|
+
o = zr(u, o, i);
|
|
12899
|
+
var f = o.disconnect, p = o.observe, g = o.unobserve;
|
|
12900
|
+
return bm.push(s), { disconnect: function() {
|
|
12901
|
+
var S = bm.indexOf(s);
|
|
12902
|
+
0 <= S && bm.splice(S, 1), f();
|
|
12903
|
+
} };
|
|
12904
|
+
}, le.shouldError = function(e) {
|
|
12905
|
+
return pu(e);
|
|
12906
|
+
}, le.shouldSuspend = function(e) {
|
|
12907
|
+
return fu(e);
|
|
12908
|
+
}, le.startHostTransition = function(e, n, o, i) {
|
|
12909
|
+
if (e.tag !== 5) throw Error("Expected the form instance to be a HostComponent. This is a bug in React.");
|
|
12910
|
+
var s = uf(e).queue;
|
|
12911
|
+
Hp(e), nt(e, s, n, Xt, o === null ? Em : function() {
|
|
12912
|
+
x.T === null && console.error("requestFormReset was called outside a transition or action. To fix, move to an action, or wrap with startTransition.");
|
|
12913
|
+
var u = uf(e);
|
|
12914
|
+
return u.next === null && (u = e.alternate.memoizedState), qi(e, u.next.queue, {}, Nt(e)), o(i);
|
|
12915
|
+
});
|
|
12916
|
+
}, le.updateContainer = function(e, n, o, i) {
|
|
12917
|
+
var s = n.current, u = Nt(s);
|
|
12918
|
+
return As(s, u, e, n, o, i), u;
|
|
12919
|
+
}, le.updateContainerSync = Wh, le;
|
|
12920
|
+
}, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true }));
|
|
12921
|
+
})(Mg)), Mg.exports;
|
|
12922
|
+
}
|
|
12923
|
+
var Eb;
|
|
12924
|
+
function n0() {
|
|
12925
|
+
return Eb || (Eb = 1, process.env.NODE_ENV === "production" ? Rm.exports = Kb() : Rm.exports = e0()), Rm.exports;
|
|
12926
|
+
}
|
|
12927
|
+
var t0 = n0();
|
|
12928
|
+
const r0 = Xb(t0);
|
|
12929
|
+
|
|
12930
|
+
const DEFAULT_POINTER_ID = 0;
|
|
12931
|
+
const XR_POINTER_ID_START = 1e3;
|
|
12932
|
+
function getPointerState(internal, pointerId) {
|
|
12933
|
+
let state = internal.pointerMap.get(pointerId);
|
|
12934
|
+
if (!state) {
|
|
12935
|
+
state = {
|
|
12936
|
+
hovered: /* @__PURE__ */ new Map(),
|
|
12937
|
+
captured: /* @__PURE__ */ new Map(),
|
|
12938
|
+
initialClick: [0, 0],
|
|
12939
|
+
initialHits: []
|
|
12940
|
+
};
|
|
12941
|
+
internal.pointerMap.set(pointerId, state);
|
|
12942
|
+
}
|
|
12943
|
+
return state;
|
|
12944
|
+
}
|
|
12945
|
+
function getPointerId(event) {
|
|
12946
|
+
return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
|
|
12947
|
+
}
|
|
12948
|
+
function makeId(event) {
|
|
12949
|
+
return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
|
|
12950
|
+
}
|
|
12951
|
+
function releaseInternalPointerCapture(internal, obj, pointerId) {
|
|
12952
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
12953
|
+
if (!pointerState) return;
|
|
12954
|
+
const captureData = pointerState.captured.get(obj);
|
|
12955
|
+
if (captureData) {
|
|
12956
|
+
pointerState.captured.delete(obj);
|
|
12957
|
+
try {
|
|
12958
|
+
captureData.target.releasePointerCapture?.(pointerId);
|
|
12959
|
+
} catch {
|
|
12960
|
+
}
|
|
12961
|
+
}
|
|
12962
|
+
}
|
|
12963
|
+
function swapInteractivity(store, object, newObject) {
|
|
12964
|
+
const { internal } = store.getState();
|
|
12965
|
+
for (let i = 0; i < internal.interaction.length; i++) {
|
|
12966
|
+
if (internal.interaction[i] === object) internal.interaction[i] = newObject;
|
|
12967
|
+
}
|
|
12968
|
+
for (const pointerState of internal.pointerMap.values()) {
|
|
12969
|
+
for (let i = 0; i < pointerState.initialHits.length; i++) {
|
|
12970
|
+
if (pointerState.initialHits[i] === object) pointerState.initialHits[i] = newObject;
|
|
12971
|
+
}
|
|
12972
|
+
pointerState.hovered.forEach((value, key) => {
|
|
12973
|
+
if (value.eventObject === object || value.object === object) {
|
|
12974
|
+
pointerState.hovered.delete(key);
|
|
12975
|
+
const next = {
|
|
12976
|
+
...value,
|
|
12977
|
+
eventObject: value.eventObject === object ? newObject : value.eventObject,
|
|
12978
|
+
object: value.object === object ? newObject : value.object
|
|
12979
|
+
};
|
|
12980
|
+
pointerState.hovered.set(makeId(next), next);
|
|
12981
|
+
}
|
|
12982
|
+
});
|
|
12983
|
+
const captureData = pointerState.captured.get(object);
|
|
12984
|
+
if (captureData) {
|
|
12985
|
+
pointerState.captured.delete(object);
|
|
12986
|
+
pointerState.captured.set(newObject, {
|
|
12987
|
+
...captureData,
|
|
12988
|
+
intersection: {
|
|
12989
|
+
...captureData.intersection,
|
|
12990
|
+
object: captureData.intersection.object === object ? newObject : captureData.intersection.object,
|
|
12991
|
+
eventObject: captureData.intersection.eventObject === object ? newObject : captureData.intersection.eventObject
|
|
12992
|
+
}
|
|
12993
|
+
});
|
|
12994
|
+
}
|
|
12995
|
+
}
|
|
12996
|
+
unregisterVisibility(store, object);
|
|
12997
|
+
}
|
|
12998
|
+
function removeInteractivity(store, object) {
|
|
12999
|
+
const { internal } = store.getState();
|
|
13000
|
+
internal.interaction = internal.interaction.filter((o) => o !== object);
|
|
13001
|
+
for (const [pointerId, pointerState] of internal.pointerMap) {
|
|
13002
|
+
pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
|
|
13003
|
+
pointerState.hovered.forEach((value, key) => {
|
|
13004
|
+
if (value.eventObject === object || value.object === object) {
|
|
13005
|
+
pointerState.hovered.delete(key);
|
|
13006
|
+
}
|
|
13007
|
+
});
|
|
13008
|
+
if (pointerState.captured.has(object)) {
|
|
13009
|
+
releaseInternalPointerCapture(internal, object, pointerId);
|
|
13010
|
+
}
|
|
13011
|
+
}
|
|
13012
|
+
unregisterVisibility(store, object);
|
|
13013
|
+
}
|
|
13014
|
+
function createEvents(store) {
|
|
13015
|
+
function calculateDistance(event, pointerId) {
|
|
13016
|
+
const { internal } = store.getState();
|
|
13017
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
13018
|
+
if (!pointerState) return 0;
|
|
13019
|
+
const [initialX, initialY] = pointerState.initialClick;
|
|
13020
|
+
const dx = event.offsetX - initialX;
|
|
13021
|
+
const dy = event.offsetY - initialY;
|
|
13022
|
+
return Math.round(Math.sqrt(dx * dx + dy * dy));
|
|
13023
|
+
}
|
|
13024
|
+
function filterPointerEvents(objects) {
|
|
13025
|
+
return objects.filter(
|
|
13026
|
+
(obj) => ["Move", "Over", "Enter", "Out", "Leave"].some(
|
|
13027
|
+
(name) => obj.__r3f?.handlers["onPointer" + name]
|
|
13028
|
+
) || ["OverEnter", "OverLeave", "Over"].some(
|
|
13029
|
+
(name) => obj.__r3f?.handlers["onDrag" + name]
|
|
13030
|
+
) || obj.__r3f?.handlers.onDrop
|
|
13031
|
+
);
|
|
13032
|
+
}
|
|
13033
|
+
function intersect(event, filter) {
|
|
13034
|
+
const state = store.getState();
|
|
13035
|
+
const duplicates = /* @__PURE__ */ new Set();
|
|
13036
|
+
const intersections = [];
|
|
13037
|
+
const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction;
|
|
13038
|
+
for (let i = 0; i < eventsObjects.length; i++) {
|
|
13039
|
+
const state2 = getRootState(eventsObjects[i]);
|
|
13040
|
+
if (state2) {
|
|
13041
|
+
state2.raycaster.camera = void 0;
|
|
13042
|
+
}
|
|
13043
|
+
}
|
|
13044
|
+
if (!state.previousRoot) {
|
|
13045
|
+
state.events.compute?.(event, state);
|
|
13046
|
+
}
|
|
13047
|
+
function handleRaycast(obj) {
|
|
13048
|
+
const state2 = getRootState(obj);
|
|
13049
|
+
if (!state2 || !state2.events.enabled || state2.raycaster.camera === null) return [];
|
|
13050
|
+
if (state2.raycaster.camera === void 0) {
|
|
13051
|
+
state2.events.compute?.(event, state2, state2.previousRoot?.getState());
|
|
13052
|
+
if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
|
|
13053
|
+
}
|
|
13054
|
+
if (!state2.raycaster.camera) return [];
|
|
13055
|
+
obj.updateWorldMatrix(true, true);
|
|
13056
|
+
return state2.raycaster.intersectObject(obj, true);
|
|
13057
|
+
}
|
|
13058
|
+
let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
|
|
13059
|
+
const aInteractivePriority = a.object.userData?.interactivePriority;
|
|
13060
|
+
const bInteractivePriority = b.object.userData?.interactivePriority;
|
|
13061
|
+
if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
|
|
13062
|
+
if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
|
|
13063
|
+
if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
|
|
13064
|
+
if (aInteractivePriority !== bInteractivePriority) {
|
|
13065
|
+
return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
|
|
13066
|
+
}
|
|
13067
|
+
}
|
|
13068
|
+
const aState = getRootState(a.object);
|
|
13069
|
+
const bState = getRootState(b.object);
|
|
13070
|
+
const aPriority = aState?.events?.priority ?? 1;
|
|
13071
|
+
const bPriority = bState?.events?.priority ?? 1;
|
|
13072
|
+
return bPriority - aPriority || a.distance - b.distance;
|
|
13073
|
+
}).filter((item) => {
|
|
13074
|
+
const id = makeId(item);
|
|
13075
|
+
if (duplicates.has(id)) return false;
|
|
13076
|
+
duplicates.add(id);
|
|
13077
|
+
return true;
|
|
13078
|
+
});
|
|
13079
|
+
if (state.events.filter) hits = state.events.filter(hits, state);
|
|
13080
|
+
for (const hit of hits) {
|
|
13081
|
+
let eventObject = hit.object;
|
|
13082
|
+
while (eventObject) {
|
|
13083
|
+
if (eventObject.__r3f?.eventCount) {
|
|
13084
|
+
intersections.push({ ...hit, eventObject });
|
|
13085
|
+
}
|
|
13086
|
+
eventObject = eventObject.parent;
|
|
13087
|
+
}
|
|
13088
|
+
}
|
|
13089
|
+
if ("pointerId" in event) {
|
|
13090
|
+
const pointerId = event.pointerId;
|
|
13091
|
+
const pointerState = state.internal.pointerMap.get(pointerId);
|
|
13092
|
+
if (pointerState?.captured.size) {
|
|
13093
|
+
for (const captureData of pointerState.captured.values()) {
|
|
13094
|
+
if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
|
|
13095
|
+
}
|
|
13096
|
+
}
|
|
13097
|
+
}
|
|
13098
|
+
return intersections;
|
|
13099
|
+
}
|
|
13100
|
+
function handleIntersects(intersections, event, delta, callback) {
|
|
13101
|
+
if (intersections.length) {
|
|
13102
|
+
const localState = { stopped: false };
|
|
13103
|
+
for (const hit of intersections) {
|
|
13104
|
+
const state = getRootState(hit.object);
|
|
13105
|
+
if (state) {
|
|
13106
|
+
const { raycaster, pointer, camera, internal } = state;
|
|
13107
|
+
const unprojectedPoint = new Vector3(pointer.x, pointer.y, 0).unproject(camera);
|
|
13108
|
+
const hasPointerCapture = (id) => {
|
|
13109
|
+
const pointerState = internal.pointerMap.get(id);
|
|
13110
|
+
return pointerState?.captured.has(hit.eventObject) ?? false;
|
|
13111
|
+
};
|
|
13112
|
+
const setPointerCapture = (id) => {
|
|
13113
|
+
const captureData = { intersection: hit, target: event.target };
|
|
13114
|
+
const pointerState = getPointerState(internal, id);
|
|
13115
|
+
pointerState.captured.set(hit.eventObject, captureData);
|
|
13116
|
+
event.target.setPointerCapture(id);
|
|
13117
|
+
};
|
|
13118
|
+
const releasePointerCapture = (id) => {
|
|
13119
|
+
releaseInternalPointerCapture(internal, hit.eventObject, id);
|
|
13120
|
+
};
|
|
13121
|
+
const extractEventProps = {};
|
|
13122
|
+
for (const prop in event) {
|
|
13123
|
+
const property = event[prop];
|
|
13124
|
+
if (typeof property !== "function") extractEventProps[prop] = property;
|
|
13125
|
+
}
|
|
13126
|
+
const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
|
|
13127
|
+
const raycastEvent = {
|
|
13128
|
+
...hit,
|
|
13129
|
+
...extractEventProps,
|
|
13130
|
+
pointer,
|
|
13131
|
+
intersections,
|
|
13132
|
+
stopped: localState.stopped,
|
|
13133
|
+
delta,
|
|
13134
|
+
unprojectedPoint,
|
|
13135
|
+
ray: raycaster.ray,
|
|
13136
|
+
camera,
|
|
13137
|
+
pointerId: eventPointerId,
|
|
13138
|
+
// Hijack stopPropagation, which just sets a flag
|
|
13139
|
+
stopPropagation() {
|
|
13140
|
+
const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
|
|
13141
|
+
if (
|
|
13142
|
+
// ...if this pointer hasn't been captured
|
|
13143
|
+
!pointerState?.captured.size || // ... or if the hit object is capturing the pointer
|
|
13144
|
+
pointerState.captured.has(hit.eventObject)
|
|
13145
|
+
) {
|
|
13146
|
+
raycastEvent.stopped = localState.stopped = true;
|
|
13147
|
+
if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
|
|
13148
|
+
const higher = intersections.slice(0, intersections.indexOf(hit));
|
|
13149
|
+
cancelPointer([...higher, hit], eventPointerId);
|
|
13150
|
+
}
|
|
13463
13151
|
}
|
|
13464
|
-
}
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13152
|
+
},
|
|
13153
|
+
// there should be a distinction between target and currentTarget
|
|
13154
|
+
target: { hasPointerCapture, setPointerCapture, releasePointerCapture },
|
|
13155
|
+
currentTarget: { hasPointerCapture, setPointerCapture, releasePointerCapture },
|
|
13156
|
+
nativeEvent: event
|
|
13157
|
+
};
|
|
13158
|
+
callback(raycastEvent);
|
|
13159
|
+
if (localState.stopped === true) break;
|
|
13469
13160
|
}
|
|
13470
|
-
}
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13161
|
+
}
|
|
13162
|
+
}
|
|
13163
|
+
return intersections;
|
|
13164
|
+
}
|
|
13165
|
+
function cancelPointer(intersections, pointerId) {
|
|
13166
|
+
const { internal } = store.getState();
|
|
13167
|
+
const pid = pointerId ?? DEFAULT_POINTER_ID;
|
|
13168
|
+
const pointerState = internal.pointerMap.get(pid);
|
|
13169
|
+
if (!pointerState) return;
|
|
13170
|
+
for (const [hoveredId, hoveredObj] of pointerState.hovered) {
|
|
13171
|
+
if (!intersections.length || !intersections.find(
|
|
13172
|
+
(hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
|
|
13173
|
+
)) {
|
|
13174
|
+
const eventObject = hoveredObj.eventObject;
|
|
13175
|
+
const instance = eventObject.__r3f;
|
|
13176
|
+
pointerState.hovered.delete(hoveredId);
|
|
13177
|
+
if (instance?.eventCount) {
|
|
13178
|
+
const handlers = instance.handlers;
|
|
13179
|
+
const data = { ...hoveredObj, intersections };
|
|
13180
|
+
handlers.onPointerOut?.(data);
|
|
13181
|
+
handlers.onPointerLeave?.(data);
|
|
13182
|
+
handlers.onDragOverLeave?.(data);
|
|
13487
13183
|
}
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
an(o), x.T = n;
|
|
13184
|
+
}
|
|
13185
|
+
}
|
|
13186
|
+
}
|
|
13187
|
+
function pointerMissed(event, objects) {
|
|
13188
|
+
for (let i = 0; i < objects.length; i++) {
|
|
13189
|
+
const instance = objects[i].__r3f;
|
|
13190
|
+
instance?.handlers.onPointerMissed?.(event);
|
|
13191
|
+
}
|
|
13192
|
+
}
|
|
13193
|
+
function dragOverMissed(event, objects) {
|
|
13194
|
+
for (let i = 0; i < objects.length; i++) {
|
|
13195
|
+
const instance = objects[i].__r3f;
|
|
13196
|
+
instance?.handlers.onDragOverMissed?.(event);
|
|
13197
|
+
}
|
|
13198
|
+
}
|
|
13199
|
+
function dropMissed(event, objects) {
|
|
13200
|
+
for (let i = 0; i < objects.length; i++) {
|
|
13201
|
+
const instance = objects[i].__r3f;
|
|
13202
|
+
instance?.handlers.onDropMissed?.(event);
|
|
13203
|
+
}
|
|
13204
|
+
}
|
|
13205
|
+
function cleanupPointer(pointerId) {
|
|
13206
|
+
const { internal } = store.getState();
|
|
13207
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
13208
|
+
if (pointerState) {
|
|
13209
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
13210
|
+
const eventObject = hoveredObj.eventObject;
|
|
13211
|
+
const instance = eventObject.__r3f;
|
|
13212
|
+
if (instance?.eventCount) {
|
|
13213
|
+
const handlers = instance.handlers;
|
|
13214
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
13215
|
+
handlers.onPointerOut?.(data);
|
|
13216
|
+
handlers.onPointerLeave?.(data);
|
|
13522
13217
|
}
|
|
13523
|
-
}
|
|
13524
|
-
|
|
13525
|
-
|
|
13526
|
-
|
|
13527
|
-
|
|
13528
|
-
|
|
13218
|
+
}
|
|
13219
|
+
internal.pointerMap.delete(pointerId);
|
|
13220
|
+
}
|
|
13221
|
+
internal.pointerDirty.delete(pointerId);
|
|
13222
|
+
}
|
|
13223
|
+
function processDeferredPointer(event, pointerId) {
|
|
13224
|
+
const state = store.getState();
|
|
13225
|
+
const { internal } = state;
|
|
13226
|
+
if (!state.events.enabled) return;
|
|
13227
|
+
const filter = filterPointerEvents;
|
|
13228
|
+
const hits = intersect(event, filter);
|
|
13229
|
+
cancelPointer(hits, pointerId);
|
|
13230
|
+
function onIntersect(data) {
|
|
13231
|
+
const eventObject = data.eventObject;
|
|
13232
|
+
const instance = eventObject.__r3f;
|
|
13233
|
+
if (!instance?.eventCount) return;
|
|
13234
|
+
const handlers = instance.handlers;
|
|
13235
|
+
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
13236
|
+
const id = makeId(data);
|
|
13237
|
+
const pointerState = getPointerState(internal, pointerId);
|
|
13238
|
+
const hoveredItem = pointerState.hovered.get(id);
|
|
13239
|
+
if (!hoveredItem) {
|
|
13240
|
+
pointerState.hovered.set(id, data);
|
|
13241
|
+
handlers.onPointerOver?.(data);
|
|
13242
|
+
handlers.onPointerEnter?.(data);
|
|
13243
|
+
} else if (hoveredItem.stopped) {
|
|
13244
|
+
data.stopPropagation();
|
|
13529
13245
|
}
|
|
13530
|
-
}
|
|
13531
|
-
|
|
13532
|
-
|
|
13533
|
-
|
|
13534
|
-
|
|
13535
|
-
|
|
13536
|
-
|
|
13537
|
-
|
|
13538
|
-
|
|
13539
|
-
|
|
13540
|
-
|
|
13541
|
-
|
|
13542
|
-
|
|
13543
|
-
|
|
13544
|
-
|
|
13246
|
+
}
|
|
13247
|
+
handlers.onPointerMove?.(data);
|
|
13248
|
+
}
|
|
13249
|
+
handleIntersects(hits, event, 0, onIntersect);
|
|
13250
|
+
}
|
|
13251
|
+
function handlePointer(name) {
|
|
13252
|
+
switch (name) {
|
|
13253
|
+
case "onPointerLeave":
|
|
13254
|
+
case "onDragLeave":
|
|
13255
|
+
return () => cancelPointer([]);
|
|
13256
|
+
// Global cancel of these events
|
|
13257
|
+
case "onPointerCancel":
|
|
13258
|
+
return (event) => {
|
|
13259
|
+
const pointerId = getPointerId(event);
|
|
13260
|
+
cleanupPointer(pointerId);
|
|
13261
|
+
};
|
|
13262
|
+
case "onLostPointerCapture":
|
|
13263
|
+
return (event) => {
|
|
13264
|
+
const { internal } = store.getState();
|
|
13265
|
+
const pointerId = getPointerId(event);
|
|
13266
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
13267
|
+
if (pointerState?.captured.size) {
|
|
13268
|
+
requestAnimationFrame(() => {
|
|
13269
|
+
const pointerState2 = internal.pointerMap.get(pointerId);
|
|
13270
|
+
if (pointerState2?.captured.size) {
|
|
13271
|
+
pointerState2.captured.clear();
|
|
13545
13272
|
}
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13273
|
+
cancelPointer([], pointerId);
|
|
13274
|
+
});
|
|
13275
|
+
}
|
|
13276
|
+
};
|
|
13277
|
+
}
|
|
13278
|
+
return function handleEvent(event) {
|
|
13279
|
+
const state = store.getState();
|
|
13280
|
+
const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
|
|
13281
|
+
const pointerId = getPointerId(event);
|
|
13282
|
+
internal.lastEvent.current = event;
|
|
13283
|
+
if (!events.enabled) return;
|
|
13284
|
+
const isPointerMove = name === "onPointerMove";
|
|
13285
|
+
const isDragOver = name === "onDragOver";
|
|
13286
|
+
const isDrop = name === "onDrop";
|
|
13287
|
+
const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
|
|
13288
|
+
const isPointerDown = name === "onPointerDown";
|
|
13289
|
+
const isPointerUp = name === "onPointerUp";
|
|
13290
|
+
const isWheel = name === "onWheel";
|
|
13291
|
+
const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
|
|
13292
|
+
if (isPointerMove && canDeferRaycasts) {
|
|
13293
|
+
events.compute?.(event, state);
|
|
13294
|
+
internal.pointerDirty.set(pointerId, event);
|
|
13295
|
+
return;
|
|
13296
|
+
}
|
|
13297
|
+
if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
|
|
13298
|
+
events.compute?.(event, state);
|
|
13299
|
+
internal.pointerDirty.set(pointerId, event);
|
|
13300
|
+
return;
|
|
13301
|
+
}
|
|
13302
|
+
if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
|
|
13303
|
+
const deferredEvent = internal.pointerDirty.get(pointerId);
|
|
13304
|
+
internal.pointerDirty.delete(pointerId);
|
|
13305
|
+
processDeferredPointer(deferredEvent, pointerId);
|
|
13306
|
+
}
|
|
13307
|
+
const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
|
|
13308
|
+
const hits = intersect(event, filter);
|
|
13309
|
+
const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
|
|
13310
|
+
if (isPointerDown) {
|
|
13311
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
13312
|
+
pointerState2.initialClick = [event.offsetX, event.offsetY];
|
|
13313
|
+
pointerState2.initialHits = hits.map((hit) => hit.eventObject);
|
|
13314
|
+
}
|
|
13315
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
13316
|
+
const initialHits = pointerState?.initialHits ?? [];
|
|
13317
|
+
if (isClickEvent && !hits.length) {
|
|
13318
|
+
if (delta <= 2) {
|
|
13319
|
+
pointerMissed(event, internal.interaction);
|
|
13320
|
+
if (onPointerMissed) onPointerMissed(event);
|
|
13321
|
+
}
|
|
13322
|
+
}
|
|
13323
|
+
if (isDragOver && !hits.length) {
|
|
13324
|
+
dragOverMissed(event, internal.interaction);
|
|
13325
|
+
if (onDragOverMissed) onDragOverMissed(event);
|
|
13326
|
+
}
|
|
13327
|
+
if (isDrop && !hits.length) {
|
|
13328
|
+
dropMissed(event, internal.interaction);
|
|
13329
|
+
if (onDropMissed) onDropMissed(event);
|
|
13330
|
+
}
|
|
13331
|
+
if (isPointerMove || isDragOver) {
|
|
13332
|
+
cancelPointer(hits, pointerId);
|
|
13333
|
+
}
|
|
13334
|
+
function onIntersect(data) {
|
|
13335
|
+
const eventObject = data.eventObject;
|
|
13336
|
+
const instance = eventObject.__r3f;
|
|
13337
|
+
if (!instance?.eventCount) return;
|
|
13338
|
+
const handlers = instance.handlers;
|
|
13339
|
+
if (isPointerMove) {
|
|
13340
|
+
if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
|
|
13341
|
+
const id = makeId(data);
|
|
13342
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
13343
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
13344
|
+
if (!hoveredItem) {
|
|
13345
|
+
pointerState2.hovered.set(id, data);
|
|
13346
|
+
handlers.onPointerOver?.(data);
|
|
13347
|
+
handlers.onPointerEnter?.(data);
|
|
13348
|
+
} else if (hoveredItem.stopped) {
|
|
13349
|
+
data.stopPropagation();
|
|
13549
13350
|
}
|
|
13550
13351
|
}
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
|
|
13556
|
-
|
|
13557
|
-
|
|
13558
|
-
|
|
13559
|
-
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
if (
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
|
|
13569
|
-
|
|
13570
|
-
|
|
13571
|
-
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
var o = n[e++], i = o.tag;
|
|
13583
|
-
if (!Kr(o)) {
|
|
13584
|
-
if ((i === 5 || i === 26 || i === 27) && Ft(o.stateNode)) return true;
|
|
13585
|
-
for (o = o.child; o !== null; ) n.push(o), o = o.sibling;
|
|
13352
|
+
handlers.onPointerMove?.(data);
|
|
13353
|
+
} else if (isDragOver) {
|
|
13354
|
+
const id = makeId(data);
|
|
13355
|
+
const pointerState2 = getPointerState(internal, pointerId);
|
|
13356
|
+
const hoveredItem = pointerState2.hovered.get(id);
|
|
13357
|
+
if (!hoveredItem) {
|
|
13358
|
+
pointerState2.hovered.set(id, data);
|
|
13359
|
+
handlers.onDragOverEnter?.(data);
|
|
13360
|
+
} else if (hoveredItem.stopped) {
|
|
13361
|
+
data.stopPropagation();
|
|
13362
|
+
}
|
|
13363
|
+
handlers.onDragOver?.(data);
|
|
13364
|
+
} else if (isDrop) {
|
|
13365
|
+
handlers.onDrop?.(data);
|
|
13366
|
+
} else {
|
|
13367
|
+
const handler = handlers[name];
|
|
13368
|
+
if (handler) {
|
|
13369
|
+
if (!isClickEvent || initialHits.includes(eventObject)) {
|
|
13370
|
+
pointerMissed(
|
|
13371
|
+
event,
|
|
13372
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
13373
|
+
);
|
|
13374
|
+
handler(data);
|
|
13375
|
+
}
|
|
13376
|
+
} else {
|
|
13377
|
+
if (isClickEvent && initialHits.includes(eventObject)) {
|
|
13378
|
+
pointerMissed(
|
|
13379
|
+
event,
|
|
13380
|
+
internal.interaction.filter((object) => !initialHits.includes(object))
|
|
13381
|
+
);
|
|
13382
|
+
}
|
|
13586
13383
|
}
|
|
13587
13384
|
}
|
|
13588
|
-
|
|
13589
|
-
|
|
13590
|
-
|
|
13591
|
-
|
|
13592
|
-
|
|
13593
|
-
|
|
13594
|
-
|
|
13595
|
-
|
|
13385
|
+
}
|
|
13386
|
+
handleIntersects(hits, event, delta, onIntersect);
|
|
13387
|
+
};
|
|
13388
|
+
}
|
|
13389
|
+
function flushDeferredPointers() {
|
|
13390
|
+
const { internal, events } = store.getState();
|
|
13391
|
+
if (!events.frameTimedRaycasts) return;
|
|
13392
|
+
for (const [pointerId, event] of internal.pointerDirty) {
|
|
13393
|
+
processDeferredPointer(event, pointerId);
|
|
13394
|
+
}
|
|
13395
|
+
internal.pointerDirty.clear();
|
|
13396
|
+
}
|
|
13397
|
+
return { handlePointer, flushDeferredPointers, processDeferredPointer };
|
|
13398
|
+
}
|
|
13399
|
+
const DOM_EVENTS = {
|
|
13400
|
+
onClick: ["click", false],
|
|
13401
|
+
onContextMenu: ["contextmenu", false],
|
|
13402
|
+
onDoubleClick: ["dblclick", false],
|
|
13403
|
+
onDragEnter: ["dragenter", false],
|
|
13404
|
+
onDragLeave: ["dragleave", false],
|
|
13405
|
+
onDragOver: ["dragover", false],
|
|
13406
|
+
onDrop: ["drop", false],
|
|
13407
|
+
onWheel: ["wheel", true],
|
|
13408
|
+
onPointerDown: ["pointerdown", true],
|
|
13409
|
+
onPointerUp: ["pointerup", true],
|
|
13410
|
+
onPointerLeave: ["pointerleave", true],
|
|
13411
|
+
onPointerMove: ["pointermove", true],
|
|
13412
|
+
onPointerCancel: ["pointercancel", true],
|
|
13413
|
+
onLostPointerCapture: ["lostpointercapture", true]
|
|
13414
|
+
};
|
|
13415
|
+
function createPointerEvents(store) {
|
|
13416
|
+
const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
|
|
13417
|
+
let nextXRPointerId = XR_POINTER_ID_START;
|
|
13418
|
+
const xrPointers = /* @__PURE__ */ new Map();
|
|
13419
|
+
return {
|
|
13420
|
+
priority: 1,
|
|
13421
|
+
enabled: true,
|
|
13422
|
+
frameTimedRaycasts: true,
|
|
13423
|
+
alwaysFireOnScroll: true,
|
|
13424
|
+
updateOnFrame: false,
|
|
13425
|
+
compute(event, state) {
|
|
13426
|
+
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
13427
|
+
state.raycaster.setFromCamera(state.pointer, state.camera);
|
|
13428
|
+
},
|
|
13429
|
+
connected: void 0,
|
|
13430
|
+
handlers: Object.keys(DOM_EVENTS).reduce(
|
|
13431
|
+
(acc, key) => ({ ...acc, [key]: handlePointer(key) }),
|
|
13432
|
+
{}
|
|
13433
|
+
),
|
|
13434
|
+
update: (pointerId) => {
|
|
13435
|
+
const { events, internal } = store.getState();
|
|
13436
|
+
if (!events.handlers) return;
|
|
13437
|
+
if (pointerId !== void 0) {
|
|
13438
|
+
const event = internal.pointerDirty.get(pointerId);
|
|
13439
|
+
if (event) {
|
|
13440
|
+
internal.pointerDirty.delete(pointerId);
|
|
13441
|
+
processDeferredPointer(event, pointerId);
|
|
13442
|
+
} else if (internal.lastEvent?.current) {
|
|
13443
|
+
processDeferredPointer(internal.lastEvent.current, pointerId);
|
|
13596
13444
|
}
|
|
13597
|
-
|
|
13598
|
-
|
|
13599
|
-
|
|
13600
|
-
|
|
13601
|
-
|
|
13602
|
-
No matching component was found for:
|
|
13603
|
-
`) + e.join(" > ");
|
|
13445
|
+
} else {
|
|
13446
|
+
flushDeferredPointers();
|
|
13447
|
+
if (internal.lastEvent?.current) {
|
|
13448
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
13604
13449
|
}
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13608
|
-
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
|
|
13450
|
+
}
|
|
13451
|
+
},
|
|
13452
|
+
flush: () => {
|
|
13453
|
+
const { events, internal } = store.getState();
|
|
13454
|
+
flushDeferredPointers();
|
|
13455
|
+
if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
|
|
13456
|
+
events.handlers.onPointerMove(internal.lastEvent.current);
|
|
13457
|
+
}
|
|
13458
|
+
},
|
|
13459
|
+
connect: (target) => {
|
|
13460
|
+
if (!target) return;
|
|
13461
|
+
const { set, events } = store.getState();
|
|
13462
|
+
events.disconnect?.();
|
|
13463
|
+
set((state) => ({ events: { ...state.events, connected: target } }));
|
|
13464
|
+
if (events.handlers) {
|
|
13465
|
+
for (const name in events.handlers) {
|
|
13466
|
+
const event = events.handlers[name];
|
|
13467
|
+
const [eventName, passive] = DOM_EVENTS[name];
|
|
13468
|
+
target.addEventListener(eventName, event, { passive });
|
|
13614
13469
|
}
|
|
13615
|
-
}
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
}
|
|
13470
|
+
}
|
|
13471
|
+
},
|
|
13472
|
+
disconnect: () => {
|
|
13473
|
+
const { set, events } = store.getState();
|
|
13474
|
+
if (events.connected) {
|
|
13475
|
+
if (events.handlers) {
|
|
13476
|
+
for (const name in events.handlers) {
|
|
13477
|
+
const event = events.handlers[name];
|
|
13478
|
+
const [eventName] = DOM_EVENTS[name];
|
|
13479
|
+
events.connected.removeEventListener(eventName, event);
|
|
13480
|
+
}
|
|
13481
|
+
}
|
|
13482
|
+
set((state) => ({ events: { ...state.events, connected: void 0 } }));
|
|
13483
|
+
}
|
|
13484
|
+
},
|
|
13485
|
+
// PREVIEW (A8): the XR pointer registration API may change before stable.
|
|
13486
|
+
registerPointer: (config) => {
|
|
13487
|
+
const pointerId = nextXRPointerId++;
|
|
13488
|
+
xrPointers.set(pointerId, config);
|
|
13489
|
+
const { internal } = store.getState();
|
|
13490
|
+
getPointerState(internal, pointerId);
|
|
13491
|
+
return pointerId;
|
|
13492
|
+
},
|
|
13493
|
+
unregisterPointer: (pointerId) => {
|
|
13494
|
+
xrPointers.delete(pointerId);
|
|
13495
|
+
const { internal } = store.getState();
|
|
13496
|
+
const pointerState = internal.pointerMap.get(pointerId);
|
|
13497
|
+
if (pointerState) {
|
|
13498
|
+
for (const [, hoveredObj] of pointerState.hovered) {
|
|
13499
|
+
const eventObject = hoveredObj.eventObject;
|
|
13500
|
+
const instance = eventObject.__r3f;
|
|
13501
|
+
if (instance?.eventCount) {
|
|
13502
|
+
const handlers = instance.handlers;
|
|
13503
|
+
const data = { ...hoveredObj, intersections: [] };
|
|
13504
|
+
handlers.onPointerOut?.(data);
|
|
13505
|
+
handlers.onPointerLeave?.(data);
|
|
13506
|
+
}
|
|
13626
13507
|
}
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
var S = bm.indexOf(s);
|
|
13633
|
-
0 <= S && bm.splice(S, 1), f();
|
|
13634
|
-
} };
|
|
13635
|
-
}, le.shouldError = function(e) {
|
|
13636
|
-
return pu(e);
|
|
13637
|
-
}, le.shouldSuspend = function(e) {
|
|
13638
|
-
return fu(e);
|
|
13639
|
-
}, le.startHostTransition = function(e, n, o, i) {
|
|
13640
|
-
if (e.tag !== 5) throw Error("Expected the form instance to be a HostComponent. This is a bug in React.");
|
|
13641
|
-
var s = uf(e).queue;
|
|
13642
|
-
Hp(e), nt(e, s, n, Xt, o === null ? Em : function() {
|
|
13643
|
-
x.T === null && console.error("requestFormReset was called outside a transition or action. To fix, move to an action, or wrap with startTransition.");
|
|
13644
|
-
var u = uf(e);
|
|
13645
|
-
return u.next === null && (u = e.alternate.memoizedState), qi(e, u.next.queue, {}, Nt(e)), o(i);
|
|
13646
|
-
});
|
|
13647
|
-
}, le.updateContainer = function(e, n, o, i) {
|
|
13648
|
-
var s = n.current, u = Nt(s);
|
|
13649
|
-
return As(s, u, e, n, o, i), u;
|
|
13650
|
-
}, le.updateContainerSync = Wh, le;
|
|
13651
|
-
}, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true }));
|
|
13652
|
-
})(Mg)), Mg.exports;
|
|
13653
|
-
}
|
|
13654
|
-
var Eb;
|
|
13655
|
-
function n0() {
|
|
13656
|
-
return Eb || (Eb = 1, process.env.NODE_ENV === "production" ? Rm.exports = Kb() : Rm.exports = e0()), Rm.exports;
|
|
13508
|
+
internal.pointerMap.delete(pointerId);
|
|
13509
|
+
}
|
|
13510
|
+
internal.pointerDirty.delete(pointerId);
|
|
13511
|
+
}
|
|
13512
|
+
};
|
|
13657
13513
|
}
|
|
13658
|
-
var t0 = n0();
|
|
13659
|
-
const r0 = Xb(t0);
|
|
13660
|
-
|
|
13661
|
-
const t = 1, o = 8, r = 32, e = 2;
|
|
13662
13514
|
|
|
13663
13515
|
function createReconciler(config) {
|
|
13664
13516
|
const reconciler2 = r0(config);
|
|
@@ -13823,7 +13675,15 @@ function setFiberRef(fiber, publicInstance) {
|
|
|
13823
13675
|
}
|
|
13824
13676
|
}
|
|
13825
13677
|
const reconstructed = [];
|
|
13826
|
-
function
|
|
13678
|
+
function flushReconstructedInstances() {
|
|
13679
|
+
if (reconstructed.length === 0) return;
|
|
13680
|
+
try {
|
|
13681
|
+
swapReconstructedInstances();
|
|
13682
|
+
} finally {
|
|
13683
|
+
reconstructed.length = 0;
|
|
13684
|
+
}
|
|
13685
|
+
}
|
|
13686
|
+
function swapReconstructedInstances() {
|
|
13827
13687
|
for (const [instance] of reconstructed) {
|
|
13828
13688
|
const parent = instance.parent;
|
|
13829
13689
|
if (parent) {
|
|
@@ -13841,7 +13701,9 @@ function swapInstances() {
|
|
|
13841
13701
|
}
|
|
13842
13702
|
}
|
|
13843
13703
|
if (instance.isHidden) unhideInstance(instance);
|
|
13844
|
-
if (isObject3D(instance.object)
|
|
13704
|
+
if (isObject3D(instance.object) && !instance.parent) {
|
|
13705
|
+
removeInteractivity(findInitialRoot(instance), instance.object);
|
|
13706
|
+
}
|
|
13845
13707
|
if (instance.object.__r3f) delete instance.object.__r3f;
|
|
13846
13708
|
if (instance.type !== "primitive") disposeOnIdle(instance.object);
|
|
13847
13709
|
}
|
|
@@ -13850,9 +13712,13 @@ function swapInstances() {
|
|
|
13850
13712
|
const parent = instance.parent;
|
|
13851
13713
|
if (parent) {
|
|
13852
13714
|
const target = catalogue[toPascalCase(instance.type)];
|
|
13715
|
+
const prevObject = instance.object;
|
|
13853
13716
|
instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
|
|
13854
13717
|
instance.object.__r3f = instance;
|
|
13855
13718
|
setFiberRef(fiber, instance.object);
|
|
13719
|
+
if (isObject3D(prevObject) && isObject3D(instance.object)) {
|
|
13720
|
+
swapInteractivity(findInitialRoot(instance), prevObject, instance.object);
|
|
13721
|
+
}
|
|
13856
13722
|
delete instance.appliedOnce;
|
|
13857
13723
|
instance.eventCount = 0;
|
|
13858
13724
|
instance.handlers = {};
|
|
@@ -13872,14 +13738,114 @@ function swapInstances() {
|
|
|
13872
13738
|
invalidateInstance(instance);
|
|
13873
13739
|
}
|
|
13874
13740
|
}
|
|
13875
|
-
reconstructed.length = 0;
|
|
13876
13741
|
}
|
|
13877
13742
|
const handleTextInstance = () => {
|
|
13878
13743
|
};
|
|
13879
13744
|
const NO_CONTEXT = {};
|
|
13880
13745
|
let currentUpdatePriority = NoEventPriority;
|
|
13881
|
-
|
|
13882
|
-
|
|
13746
|
+
function getEventPriority(type) {
|
|
13747
|
+
switch (type) {
|
|
13748
|
+
case "beforetoggle":
|
|
13749
|
+
case "cancel":
|
|
13750
|
+
case "click":
|
|
13751
|
+
case "close":
|
|
13752
|
+
case "contextmenu":
|
|
13753
|
+
case "copy":
|
|
13754
|
+
case "cut":
|
|
13755
|
+
case "auxclick":
|
|
13756
|
+
case "dblclick":
|
|
13757
|
+
case "dragend":
|
|
13758
|
+
case "dragstart":
|
|
13759
|
+
case "drop":
|
|
13760
|
+
case "focusin":
|
|
13761
|
+
case "focusout":
|
|
13762
|
+
case "input":
|
|
13763
|
+
case "invalid":
|
|
13764
|
+
case "keydown":
|
|
13765
|
+
case "keypress":
|
|
13766
|
+
case "keyup":
|
|
13767
|
+
case "mousedown":
|
|
13768
|
+
case "mouseup":
|
|
13769
|
+
case "paste":
|
|
13770
|
+
case "pause":
|
|
13771
|
+
case "play":
|
|
13772
|
+
case "pointercancel":
|
|
13773
|
+
case "pointerdown":
|
|
13774
|
+
case "pointerup":
|
|
13775
|
+
case "ratechange":
|
|
13776
|
+
case "reset":
|
|
13777
|
+
case "resize":
|
|
13778
|
+
case "seeked":
|
|
13779
|
+
case "submit":
|
|
13780
|
+
case "touchcancel":
|
|
13781
|
+
case "touchend":
|
|
13782
|
+
case "touchstart":
|
|
13783
|
+
case "volumechange":
|
|
13784
|
+
case "change":
|
|
13785
|
+
case "selectionchange":
|
|
13786
|
+
case "compositionstart":
|
|
13787
|
+
case "compositionend":
|
|
13788
|
+
case "compositionupdate":
|
|
13789
|
+
case "beforeinput":
|
|
13790
|
+
case "blur":
|
|
13791
|
+
case "fullscreenchange":
|
|
13792
|
+
case "focus":
|
|
13793
|
+
case "hashchange":
|
|
13794
|
+
case "popstate":
|
|
13795
|
+
case "select":
|
|
13796
|
+
case "selectstart":
|
|
13797
|
+
return e;
|
|
13798
|
+
case "drag":
|
|
13799
|
+
case "dragenter":
|
|
13800
|
+
case "dragexit":
|
|
13801
|
+
case "dragleave":
|
|
13802
|
+
case "dragover":
|
|
13803
|
+
case "mousemove":
|
|
13804
|
+
case "mouseout":
|
|
13805
|
+
case "mouseover":
|
|
13806
|
+
case "pointermove":
|
|
13807
|
+
case "pointerout":
|
|
13808
|
+
case "pointerover":
|
|
13809
|
+
case "scroll":
|
|
13810
|
+
case "touchmove":
|
|
13811
|
+
case "wheel":
|
|
13812
|
+
case "mouseenter":
|
|
13813
|
+
case "mouseleave":
|
|
13814
|
+
case "pointerenter":
|
|
13815
|
+
case "pointerleave":
|
|
13816
|
+
return o;
|
|
13817
|
+
case "message": {
|
|
13818
|
+
switch (unstable_getCurrentPriorityLevel()) {
|
|
13819
|
+
case unstable_ImmediatePriority:
|
|
13820
|
+
return e;
|
|
13821
|
+
case unstable_UserBlockingPriority:
|
|
13822
|
+
return o;
|
|
13823
|
+
case unstable_NormalPriority:
|
|
13824
|
+
case unstable_LowPriority:
|
|
13825
|
+
return r;
|
|
13826
|
+
case unstable_IdlePriority:
|
|
13827
|
+
return i$1;
|
|
13828
|
+
default:
|
|
13829
|
+
return r;
|
|
13830
|
+
}
|
|
13831
|
+
}
|
|
13832
|
+
default:
|
|
13833
|
+
return r;
|
|
13834
|
+
}
|
|
13835
|
+
}
|
|
13836
|
+
function scheduleMicrotask(callback) {
|
|
13837
|
+
if (typeof queueMicrotask === "function") {
|
|
13838
|
+
queueMicrotask(callback);
|
|
13839
|
+
} else if (typeof Promise !== "undefined") {
|
|
13840
|
+
Promise.resolve().then(callback).catch((error) => {
|
|
13841
|
+
setTimeout(() => {
|
|
13842
|
+
throw error;
|
|
13843
|
+
});
|
|
13844
|
+
});
|
|
13845
|
+
} else {
|
|
13846
|
+
setTimeout(callback);
|
|
13847
|
+
}
|
|
13848
|
+
}
|
|
13883
13849
|
const reconciler = /* @__PURE__ */ createReconciler({
|
|
13884
13850
|
isPrimaryRenderer: false,
|
|
13885
13851
|
warnsIfNotActing: false,
|
|
@@ -13918,16 +13884,15 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13918
13884
|
else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
|
|
13919
13885
|
else if (newProps.args?.some((value, index) => value !== oldProps.args?.[index])) reconstruct = true;
|
|
13920
13886
|
if (reconstruct) {
|
|
13921
|
-
reconstructed.push([instance,
|
|
13887
|
+
reconstructed.push([instance, getInstanceProps(newProps), fiber]);
|
|
13922
13888
|
} else {
|
|
13923
13889
|
const changedProps = diffProps(instance, newProps);
|
|
13924
|
-
|
|
13925
|
-
|
|
13926
|
-
|
|
13927
|
-
|
|
13890
|
+
const attach2 = instance.props.attach;
|
|
13891
|
+
instance.props = getInstanceProps(newProps);
|
|
13892
|
+
if (attach2 !== void 0) instance.props.attach = attach2;
|
|
13893
|
+
else delete instance.props.attach;
|
|
13894
|
+
if (Object.keys(changedProps).length) applyProps(instance.object, changedProps);
|
|
13928
13895
|
}
|
|
13929
|
-
const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
|
|
13930
|
-
if (isTailSibling) swapInstances();
|
|
13931
13896
|
},
|
|
13932
13897
|
finalizeInitialChildren: (instance) => {
|
|
13933
13898
|
for (const prop in instance.props) {
|
|
@@ -13952,8 +13917,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13952
13917
|
const target = container.getState().internal.container ?? container.getState().scene;
|
|
13953
13918
|
return prepare(target, container, "", {});
|
|
13954
13919
|
},
|
|
13955
|
-
|
|
13956
|
-
|
|
13920
|
+
// Reconstructed instances are swapped once all mutations are committed,
|
|
13921
|
+
// before layout effects run so refs point to the new objects
|
|
13922
|
+
resetAfterCommit: flushReconstructedInstances,
|
|
13957
13923
|
shouldSetTextContent: () => false,
|
|
13958
13924
|
clearContainer: () => false,
|
|
13959
13925
|
hideInstance,
|
|
@@ -13961,6 +13927,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
13961
13927
|
createTextInstance: handleTextInstance,
|
|
13962
13928
|
hideTextInstance: handleTextInstance,
|
|
13963
13929
|
unhideTextInstance: handleTextInstance,
|
|
13930
|
+
// Mirrors react-dom, which flushes discrete work in microtasks
|
|
13931
|
+
supportsMicrotasks: true,
|
|
13932
|
+
scheduleMicrotask,
|
|
13964
13933
|
scheduleTimeout: typeof setTimeout === "function" ? setTimeout : void 0,
|
|
13965
13934
|
cancelTimeout: typeof clearTimeout === "function" ? clearTimeout : void 0,
|
|
13966
13935
|
noTimeout: -1,
|
|
@@ -14001,28 +13970,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14001
13970
|
},
|
|
14002
13971
|
resolveUpdatePriority() {
|
|
14003
13972
|
if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
|
|
14004
|
-
|
|
14005
|
-
|
|
14006
|
-
|
|
14007
|
-
case "dblclick":
|
|
14008
|
-
case "dragenter":
|
|
14009
|
-
case "dragleave":
|
|
14010
|
-
case "drop":
|
|
14011
|
-
case "pointercancel":
|
|
14012
|
-
case "pointerdown":
|
|
14013
|
-
case "pointerup":
|
|
14014
|
-
return e;
|
|
14015
|
-
case "dragover":
|
|
14016
|
-
case "pointermove":
|
|
14017
|
-
case "pointerout":
|
|
14018
|
-
case "pointerover":
|
|
14019
|
-
case "pointerenter":
|
|
14020
|
-
case "pointerleave":
|
|
14021
|
-
case "wheel":
|
|
14022
|
-
return o;
|
|
14023
|
-
default:
|
|
14024
|
-
return r;
|
|
14025
|
-
}
|
|
13973
|
+
const eventType = typeof window !== "undefined" ? window.event?.type : void 0;
|
|
13974
|
+
if (eventType === void 0) return r;
|
|
13975
|
+
return getEventPriority(eventType);
|
|
14026
13976
|
},
|
|
14027
13977
|
resetFormInstance() {
|
|
14028
13978
|
},
|
|
@@ -14071,11 +14021,15 @@ const reconciler = /* @__PURE__ */ createReconciler({
|
|
|
14071
14021
|
cloneMutableTextInstance(textInstance) {
|
|
14072
14022
|
return textInstance;
|
|
14073
14023
|
},
|
|
14024
|
+
// React 19.2 added these for root-level view transitions. They only run for hosts that opt into
|
|
14025
|
+
// view transitions by returning a container from cloneRootViewTransitionContainer; R3F renders
|
|
14026
|
+
// into a WebGL/WebGPU canvas, where cloning the root has no meaning, so we never opt in and
|
|
14027
|
+
// React never calls them. They stay as no-ops rather than throws: the host config is shared by
|
|
14028
|
+
// every root, and a throw here would turn a React-internal probe into a hard crash for users.
|
|
14029
|
+
// Guarded by a test asserting a full render + unmount never reaches them.
|
|
14074
14030
|
cloneRootViewTransitionContainer(_rootContainer) {
|
|
14075
|
-
throw new Error("Not implemented.");
|
|
14076
14031
|
},
|
|
14077
14032
|
removeRootViewTransitionClone(_rootContainer, _clone) {
|
|
14078
|
-
throw new Error("Not implemented.");
|
|
14079
14033
|
},
|
|
14080
14034
|
// https://github.com/facebook/react/pull/32465
|
|
14081
14035
|
createFragmentInstance: (_fiber) => null,
|
|
@@ -14630,7 +14584,8 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14630
14584
|
dispose(state.scene);
|
|
14631
14585
|
_roots.delete(canvas);
|
|
14632
14586
|
if (callback) callback(canvas);
|
|
14633
|
-
} catch {
|
|
14587
|
+
} catch (error) {
|
|
14588
|
+
console.warn("[R3F] Error while unmounting root; teardown may be incomplete:", error);
|
|
14634
14589
|
}
|
|
14635
14590
|
}, 500);
|
|
14636
14591
|
}
|
|
@@ -14741,6 +14696,212 @@ function flushSync(fn) {
|
|
|
14741
14696
|
return reconciler.flushSyncFromReconciler(fn);
|
|
14742
14697
|
}
|
|
14743
14698
|
|
|
14699
|
+
const isRef = (obj) => obj.current && obj.current.isScene;
|
|
14700
|
+
const resolveScene = (scene) => isRef(scene) ? scene.current : scene;
|
|
14701
|
+
function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
|
|
14702
|
+
sceneProps = {
|
|
14703
|
+
backgroundBlurriness: 0,
|
|
14704
|
+
backgroundIntensity: 1,
|
|
14705
|
+
backgroundRotation: [0, 0, 0],
|
|
14706
|
+
environmentIntensity: 1,
|
|
14707
|
+
environmentRotation: [0, 0, 0],
|
|
14708
|
+
...sceneProps
|
|
14709
|
+
};
|
|
14710
|
+
const target = resolveScene(scene || defaultScene);
|
|
14711
|
+
const oldbg = target.background;
|
|
14712
|
+
const oldenv = target.environment;
|
|
14713
|
+
const oldSceneProps = {
|
|
14714
|
+
// @ts-ignore
|
|
14715
|
+
backgroundBlurriness: target.backgroundBlurriness,
|
|
14716
|
+
// @ts-ignore
|
|
14717
|
+
backgroundIntensity: target.backgroundIntensity,
|
|
14718
|
+
// @ts-ignore
|
|
14719
|
+
backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
|
|
14720
|
+
// @ts-ignore
|
|
14721
|
+
environmentIntensity: target.environmentIntensity,
|
|
14722
|
+
// @ts-ignore
|
|
14723
|
+
environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
|
|
14724
|
+
};
|
|
14725
|
+
if (background !== "only") target.environment = texture;
|
|
14726
|
+
if (background) target.background = texture;
|
|
14727
|
+
applyProps(target, sceneProps);
|
|
14728
|
+
return () => {
|
|
14729
|
+
if (background !== "only") target.environment = oldenv;
|
|
14730
|
+
if (background) target.background = oldbg;
|
|
14731
|
+
applyProps(target, oldSceneProps);
|
|
14732
|
+
};
|
|
14733
|
+
}
|
|
14734
|
+
function EnvironmentMap({ scene, background = false, map, ...config }) {
|
|
14735
|
+
const defaultScene = useThree((state) => state.scene);
|
|
14736
|
+
React.useLayoutEffect(() => {
|
|
14737
|
+
if (map) return setEnvProps(background, scene, defaultScene, map, config);
|
|
14738
|
+
});
|
|
14739
|
+
return null;
|
|
14740
|
+
}
|
|
14741
|
+
function EnvironmentCube({
|
|
14742
|
+
background = false,
|
|
14743
|
+
scene,
|
|
14744
|
+
blur,
|
|
14745
|
+
backgroundBlurriness,
|
|
14746
|
+
backgroundIntensity,
|
|
14747
|
+
backgroundRotation,
|
|
14748
|
+
environmentIntensity,
|
|
14749
|
+
environmentRotation,
|
|
14750
|
+
...rest
|
|
14751
|
+
}) {
|
|
14752
|
+
const texture = useEnvironment(rest);
|
|
14753
|
+
const defaultScene = useThree((state) => state.scene);
|
|
14754
|
+
React.useLayoutEffect(() => {
|
|
14755
|
+
return setEnvProps(background, scene, defaultScene, texture, {
|
|
14756
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
14757
|
+
backgroundIntensity,
|
|
14758
|
+
backgroundRotation,
|
|
14759
|
+
environmentIntensity,
|
|
14760
|
+
environmentRotation
|
|
14761
|
+
});
|
|
14762
|
+
});
|
|
14763
|
+
React.useEffect(() => {
|
|
14764
|
+
return () => {
|
|
14765
|
+
texture.dispose();
|
|
14766
|
+
};
|
|
14767
|
+
}, [texture]);
|
|
14768
|
+
return null;
|
|
14769
|
+
}
|
|
14770
|
+
function EnvironmentPortal({
|
|
14771
|
+
children,
|
|
14772
|
+
near = 0.1,
|
|
14773
|
+
far = 1e3,
|
|
14774
|
+
resolution = 256,
|
|
14775
|
+
frames = 1,
|
|
14776
|
+
map,
|
|
14777
|
+
background = false,
|
|
14778
|
+
blur,
|
|
14779
|
+
backgroundBlurriness,
|
|
14780
|
+
backgroundIntensity,
|
|
14781
|
+
backgroundRotation,
|
|
14782
|
+
environmentIntensity,
|
|
14783
|
+
environmentRotation,
|
|
14784
|
+
scene,
|
|
14785
|
+
files,
|
|
14786
|
+
path,
|
|
14787
|
+
preset = void 0,
|
|
14788
|
+
extensions
|
|
14789
|
+
}) {
|
|
14790
|
+
const renderer = useThree((state) => state.renderer);
|
|
14791
|
+
const isLegacy = useThree((state) => state.isLegacy);
|
|
14792
|
+
const defaultScene = useThree((state) => state.scene);
|
|
14793
|
+
const camera = React.useRef(null);
|
|
14794
|
+
const [virtualScene] = React.useState(() => new Scene());
|
|
14795
|
+
const fbo = React.useMemo(() => {
|
|
14796
|
+
const fbo2 = isLegacy ? new WebGLCubeRenderTarget(resolution) : new CubeRenderTarget(resolution);
|
|
14797
|
+
fbo2.texture.type = HalfFloatType;
|
|
14798
|
+
return fbo2;
|
|
14799
|
+
}, [resolution, isLegacy]);
|
|
14800
|
+
React.useEffect(() => {
|
|
14801
|
+
return () => {
|
|
14802
|
+
fbo.dispose();
|
|
14803
|
+
};
|
|
14804
|
+
}, [fbo]);
|
|
14805
|
+
React.useLayoutEffect(() => {
|
|
14806
|
+
if (frames === 1) {
|
|
14807
|
+
const autoClear = renderer.autoClear;
|
|
14808
|
+
renderer.autoClear = true;
|
|
14809
|
+
camera.current.update(renderer, virtualScene);
|
|
14810
|
+
renderer.autoClear = autoClear;
|
|
14811
|
+
}
|
|
14812
|
+
return setEnvProps(background, scene, defaultScene, fbo.texture, {
|
|
14813
|
+
backgroundBlurriness: blur ?? backgroundBlurriness,
|
|
14814
|
+
backgroundIntensity,
|
|
14815
|
+
backgroundRotation,
|
|
14816
|
+
environmentIntensity,
|
|
14817
|
+
environmentRotation
|
|
14818
|
+
});
|
|
14819
|
+
}, [
|
|
14820
|
+
children,
|
|
14821
|
+
virtualScene,
|
|
14822
|
+
fbo.texture,
|
|
14823
|
+
scene,
|
|
14824
|
+
defaultScene,
|
|
14825
|
+
background,
|
|
14826
|
+
frames,
|
|
14827
|
+
renderer,
|
|
14828
|
+
blur,
|
|
14829
|
+
backgroundBlurriness,
|
|
14830
|
+
backgroundIntensity,
|
|
14831
|
+
backgroundRotation,
|
|
14832
|
+
environmentIntensity,
|
|
14833
|
+
environmentRotation
|
|
14834
|
+
]);
|
|
14835
|
+
let count = 1;
|
|
14836
|
+
useFrame(() => {
|
|
14837
|
+
if (frames === Infinity || count < frames) {
|
|
14838
|
+
const autoClear = renderer.autoClear;
|
|
14839
|
+
renderer.autoClear = true;
|
|
14840
|
+
camera.current.update(renderer, virtualScene);
|
|
14841
|
+
renderer.autoClear = autoClear;
|
|
14842
|
+
count++;
|
|
14843
|
+
}
|
|
14844
|
+
});
|
|
14845
|
+
return /* @__PURE__ */ jsx(Fragment, { children: createPortal(
|
|
14846
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14847
|
+
children,
|
|
14848
|
+
/* @__PURE__ */ jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
|
|
14849
|
+
files || preset ? /* @__PURE__ */ jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsx(EnvironmentMap, { background: true, map, extensions }) : null
|
|
14850
|
+
] }),
|
|
14851
|
+
virtualScene
|
|
14852
|
+
) });
|
|
14853
|
+
}
|
|
14854
|
+
function EnvironmentGround(props) {
|
|
14855
|
+
const textureDefault = useEnvironment(props);
|
|
14856
|
+
const texture = props.map || textureDefault;
|
|
14857
|
+
React.useMemo(() => extend({ GroundProjectedEnvImpl: GroundedSkybox }), []);
|
|
14858
|
+
React.useEffect(() => {
|
|
14859
|
+
return () => {
|
|
14860
|
+
textureDefault.dispose();
|
|
14861
|
+
};
|
|
14862
|
+
}, [textureDefault]);
|
|
14863
|
+
const height = props.ground?.height ?? 15;
|
|
14864
|
+
const radius = props.ground?.radius ?? 60;
|
|
14865
|
+
const scale = props.ground?.scale ?? 1e3;
|
|
14866
|
+
const args = React.useMemo(
|
|
14867
|
+
() => [texture, height, radius],
|
|
14868
|
+
[texture, height, radius]
|
|
14869
|
+
);
|
|
14870
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14871
|
+
/* @__PURE__ */ jsx(EnvironmentMap, { ...props, map: texture }),
|
|
14872
|
+
/* @__PURE__ */ jsx("groundProjectedEnvImpl", { args, scale })
|
|
14873
|
+
] });
|
|
14874
|
+
}
|
|
14875
|
+
function EnvironmentColor({ color, scene }) {
|
|
14876
|
+
const defaultScene = useThree((state) => state.scene);
|
|
14877
|
+
React.useLayoutEffect(() => {
|
|
14878
|
+
if (color === void 0) return;
|
|
14879
|
+
const target = resolveScene(scene || defaultScene);
|
|
14880
|
+
const oldBg = target.background;
|
|
14881
|
+
target.background = new Color(color);
|
|
14882
|
+
return () => {
|
|
14883
|
+
target.background = oldBg;
|
|
14884
|
+
};
|
|
14885
|
+
});
|
|
14886
|
+
return null;
|
|
14887
|
+
}
|
|
14888
|
+
function EnvironmentDualSource(props) {
|
|
14889
|
+
const { backgroundFiles, ...envProps } = props;
|
|
14890
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14891
|
+
/* @__PURE__ */ jsx(EnvironmentCube, { ...envProps, background: false }),
|
|
14892
|
+
/* @__PURE__ */ jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
|
|
14893
|
+
] });
|
|
14894
|
+
}
|
|
14895
|
+
function Environment(props) {
|
|
14896
|
+
if (props.color && !props.files && !props.preset && !props.map) {
|
|
14897
|
+
return /* @__PURE__ */ jsx(EnvironmentColor, { ...props });
|
|
14898
|
+
}
|
|
14899
|
+
if (props.backgroundFiles && props.backgroundFiles !== props.files) {
|
|
14900
|
+
return /* @__PURE__ */ jsx(EnvironmentDualSource, { ...props });
|
|
14901
|
+
}
|
|
14902
|
+
return props.ground ? /* @__PURE__ */ jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsx(EnvironmentCube, { ...props });
|
|
14903
|
+
}
|
|
14904
|
+
|
|
14744
14905
|
function parseBackground(background) {
|
|
14745
14906
|
if (!background) return null;
|
|
14746
14907
|
if (typeof background === "object" && !background.isColor) {
|
|
@@ -14784,14 +14945,36 @@ function parseRendererConfig(rendererProp) {
|
|
|
14784
14945
|
return { primaryCanvas: void 0, scheduler: void 0, renderer: rendererProp };
|
|
14785
14946
|
}
|
|
14786
14947
|
|
|
14948
|
+
const RESOURCE_KINDS = ["nodes", "uniforms", "buffers", "gpuStorage"];
|
|
14949
|
+
const registries = /* @__PURE__ */ new WeakMap();
|
|
14950
|
+
function getKindRegistry(store, kind) {
|
|
14951
|
+
let registry = registries.get(store);
|
|
14952
|
+
if (!registry) {
|
|
14953
|
+
registry = {
|
|
14954
|
+
nodes: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14955
|
+
uniforms: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14956
|
+
buffers: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() },
|
|
14957
|
+
gpuStorage: { valid: /* @__PURE__ */ new Set(), staged: /* @__PURE__ */ new Map() }
|
|
14958
|
+
};
|
|
14959
|
+
registries.set(store, registry);
|
|
14960
|
+
}
|
|
14961
|
+
return registry[kind];
|
|
14962
|
+
}
|
|
14963
|
+
function invalidateResource(store, kind, scopeKey) {
|
|
14964
|
+
const registry = getKindRegistry(store, kind);
|
|
14965
|
+
{
|
|
14966
|
+
registry.valid.clear();
|
|
14967
|
+
registry.staged.clear();
|
|
14968
|
+
}
|
|
14969
|
+
}
|
|
14970
|
+
function invalidateAllResources(store) {
|
|
14971
|
+
for (const kind of RESOURCE_KINDS) invalidateResource(store, kind);
|
|
14972
|
+
}
|
|
14973
|
+
|
|
14787
14974
|
function clearHmrCaches(store) {
|
|
14788
|
-
store.
|
|
14789
|
-
|
|
14790
|
-
|
|
14791
|
-
buffers: {},
|
|
14792
|
-
gpuStorage: {},
|
|
14793
|
-
_hmrVersion: state._hmrVersion + 1
|
|
14794
|
-
}));
|
|
14975
|
+
const primary = store.getState().primaryStore ?? store;
|
|
14976
|
+
invalidateAllResources(primary);
|
|
14977
|
+
primary.setState((state) => ({ _hmrVersion: state._hmrVersion + 1 }));
|
|
14795
14978
|
}
|
|
14796
14979
|
|
|
14797
14980
|
function CanvasImpl({
|
|
@@ -14928,7 +15111,7 @@ function CanvasImpl({
|
|
|
14928
15111
|
onDropMissed: (...args) => handleDropMissed.current?.(...args),
|
|
14929
15112
|
onCreated: (state) => {
|
|
14930
15113
|
state.events.connect?.(
|
|
14931
|
-
eventSource ? isRef(eventSource) ? eventSource.current : eventSource : divRef.current
|
|
15114
|
+
eventSource ? isRef$1(eventSource) ? eventSource.current : eventSource : divRef.current
|
|
14932
15115
|
);
|
|
14933
15116
|
if (eventPrefix) {
|
|
14934
15117
|
state.setEvents({
|
|
@@ -15041,4 +15224,4 @@ function Canvas(props) {
|
|
|
15041
15224
|
|
|
15042
15225
|
extend(THREE);
|
|
15043
15226
|
|
|
15044
|
-
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,
|
|
15227
|
+
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, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, 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, reconciler, registerPrimary, removeInteractivity, resolve, swapInteractivity, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useEnvironment, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useMutableCallback, useRenderTarget, useStore, useTexture, useTextures, useThree, waitForPrimary };
|