@react-three/fiber 10.0.0-alpha.0 → 10.0.0-alpha.2
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 +613 -146
- package/dist/index.d.cts +230 -43
- package/dist/index.d.mts +230 -43
- package/dist/index.d.ts +230 -43
- package/dist/index.mjs +613 -149
- package/dist/legacy.cjs +607 -144
- package/dist/legacy.d.cts +231 -42
- package/dist/legacy.d.mts +231 -42
- package/dist/legacy.d.ts +231 -42
- package/dist/legacy.mjs +606 -146
- package/dist/webgpu/index.cjs +925 -251
- package/dist/webgpu/index.d.cts +361 -60
- package/dist/webgpu/index.d.mts +361 -60
- package/dist/webgpu/index.d.ts +361 -60
- package/dist/webgpu/index.mjs +921 -253
- package/package.json +5 -5
- package/react-reconciler/constants.js +1 -9
- package/react-reconciler/index.js +4 -20
package/dist/webgpu/index.cjs
CHANGED
|
@@ -13,6 +13,7 @@ const lite = require('dequal/lite');
|
|
|
13
13
|
require('zustand/shallow');
|
|
14
14
|
const tsl = require('three/tsl');
|
|
15
15
|
|
|
16
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
16
17
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
17
18
|
|
|
18
19
|
function _interopNamespaceCompat(e) {
|
|
@@ -54,18 +55,21 @@ const WebGLRenderer = class WebGLRenderer2 {
|
|
|
54
55
|
);
|
|
55
56
|
}
|
|
56
57
|
};
|
|
58
|
+
const WebGLRenderTarget = null;
|
|
57
59
|
|
|
58
60
|
const THREE = /*#__PURE__*/_mergeNamespaces({
|
|
59
61
|
__proto__: null,
|
|
60
62
|
Inspector: Inspector_js.Inspector,
|
|
61
63
|
R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
|
|
62
64
|
R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
|
|
65
|
+
RenderTargetCompat: webgpu.RenderTarget,
|
|
66
|
+
WebGLRenderTarget: WebGLRenderTarget,
|
|
63
67
|
WebGLRenderer: WebGLRenderer
|
|
64
68
|
}, [webgpu__namespace]);
|
|
65
69
|
|
|
66
|
-
var __defProp$
|
|
67
|
-
var __defNormalProp$
|
|
68
|
-
var __publicField$
|
|
70
|
+
var __defProp$3 = Object.defineProperty;
|
|
71
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
72
|
+
var __publicField$3 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
69
73
|
const act = React__namespace["act"];
|
|
70
74
|
const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React__namespace.useLayoutEffect : React__namespace.useEffect;
|
|
71
75
|
function useMutableCallback(fn) {
|
|
@@ -97,7 +101,7 @@ const ErrorBoundary = /* @__PURE__ */ (() => {
|
|
|
97
101
|
return _a = class extends React__namespace.Component {
|
|
98
102
|
constructor() {
|
|
99
103
|
super(...arguments);
|
|
100
|
-
__publicField$
|
|
104
|
+
__publicField$3(this, "state", { error: false });
|
|
101
105
|
}
|
|
102
106
|
componentDidCatch(err) {
|
|
103
107
|
this.props.set(err);
|
|
@@ -105,7 +109,7 @@ const ErrorBoundary = /* @__PURE__ */ (() => {
|
|
|
105
109
|
render() {
|
|
106
110
|
return this.state.error ? null : this.props.children;
|
|
107
111
|
}
|
|
108
|
-
}, __publicField$
|
|
112
|
+
}, __publicField$3(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
|
|
109
113
|
})();
|
|
110
114
|
|
|
111
115
|
const is = {
|
|
@@ -168,6 +172,13 @@ function updateCamera(camera, size) {
|
|
|
168
172
|
}
|
|
169
173
|
camera.updateProjectionMatrix();
|
|
170
174
|
}
|
|
175
|
+
const frustumMatrix = new webgpu.Matrix4();
|
|
176
|
+
function updateFrustum(camera, frustum) {
|
|
177
|
+
const target = frustum ?? new webgpu.Frustum();
|
|
178
|
+
frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
179
|
+
target.setFromProjectionMatrix(frustumMatrix);
|
|
180
|
+
return target;
|
|
181
|
+
}
|
|
171
182
|
|
|
172
183
|
const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
|
|
173
184
|
function findInitialRoot(instance) {
|
|
@@ -248,6 +259,205 @@ function invalidateInstance(instance) {
|
|
|
248
259
|
if (state && state.internal.frames === 0) state.invalidate();
|
|
249
260
|
}
|
|
250
261
|
|
|
262
|
+
const tempFrustum = new webgpu.Frustum();
|
|
263
|
+
let hasWarnedWebGL = false;
|
|
264
|
+
let tslModule = null;
|
|
265
|
+
async function loadTSL() {
|
|
266
|
+
if (tslModule) return tslModule;
|
|
267
|
+
try {
|
|
268
|
+
const tsl = await import('three/tsl');
|
|
269
|
+
tslModule = { uniform: tsl.uniform, nodeObject: tsl.nodeObject };
|
|
270
|
+
return tslModule;
|
|
271
|
+
} catch {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function createOcclusionObserverNode(store, uniform) {
|
|
276
|
+
const node = new webgpu.Node("float");
|
|
277
|
+
node.updateType = webgpu.NodeUpdateType.OBJECT;
|
|
278
|
+
node.update = function(frame) {
|
|
279
|
+
const { internal } = store.getState();
|
|
280
|
+
const registry = internal.visibilityRegistry;
|
|
281
|
+
const cache = internal.occlusionCache;
|
|
282
|
+
for (const entry of registry.values()) {
|
|
283
|
+
const { object, handlers } = entry;
|
|
284
|
+
if (handlers.onOccluded || handlers.onVisible) {
|
|
285
|
+
const isOccluded = frame.renderer.isOccluded(object);
|
|
286
|
+
cache.set(object, isOccluded);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
node.setup = function() {
|
|
291
|
+
return uniform(0);
|
|
292
|
+
};
|
|
293
|
+
return node;
|
|
294
|
+
}
|
|
295
|
+
let occlusionSetupPromise = null;
|
|
296
|
+
function enableOcclusion(store) {
|
|
297
|
+
const state = store.getState();
|
|
298
|
+
const { internal, renderer, rootScene } = state;
|
|
299
|
+
if (internal.occlusionEnabled || occlusionSetupPromise) return;
|
|
300
|
+
const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
|
|
301
|
+
if (!hasOcclusionSupport) {
|
|
302
|
+
if (!hasWarnedWebGL) {
|
|
303
|
+
console.warn(
|
|
304
|
+
"[R3F] Warning: onOccluded/onVisible occlusion queries require WebGPU renderer. Occlusion events will not fire on WebGL."
|
|
305
|
+
);
|
|
306
|
+
hasWarnedWebGL = true;
|
|
307
|
+
}
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
occlusionSetupPromise = setupOcclusion(store);
|
|
311
|
+
}
|
|
312
|
+
async function setupOcclusion(store) {
|
|
313
|
+
const state = store.getState();
|
|
314
|
+
const { internal, rootScene, set } = state;
|
|
315
|
+
const tsl = await loadTSL();
|
|
316
|
+
if (!tsl) {
|
|
317
|
+
console.warn("[R3F] Warning: TSL module not available. Occlusion queries disabled.");
|
|
318
|
+
occlusionSetupPromise = null;
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const { uniform, nodeObject } = tsl;
|
|
322
|
+
let helperGroup = internal.helperGroup;
|
|
323
|
+
if (!helperGroup) {
|
|
324
|
+
helperGroup = new webgpu.Group();
|
|
325
|
+
helperGroup.name = "__r3fInternal";
|
|
326
|
+
helperGroup.__r3fInternal = true;
|
|
327
|
+
rootScene.add(helperGroup);
|
|
328
|
+
}
|
|
329
|
+
const geometry = new webgpu.BoxGeometry(1, 1, 1);
|
|
330
|
+
const material = new webgpu.MeshBasicNodeMaterial({
|
|
331
|
+
transparent: true,
|
|
332
|
+
opacity: 0
|
|
333
|
+
});
|
|
334
|
+
const observerNode = nodeObject(createOcclusionObserverNode(store, uniform));
|
|
335
|
+
material.colorNode = observerNode;
|
|
336
|
+
material.needsUpdate = true;
|
|
337
|
+
const mesh = new webgpu.Mesh(geometry, material);
|
|
338
|
+
mesh.name = "__r3fOcclusionObserver";
|
|
339
|
+
mesh.scale.setScalar(1e-4);
|
|
340
|
+
mesh.frustumCulled = false;
|
|
341
|
+
mesh.__r3fInternal = true;
|
|
342
|
+
helperGroup.add(mesh);
|
|
343
|
+
set((state2) => ({
|
|
344
|
+
internal: {
|
|
345
|
+
...state2.internal,
|
|
346
|
+
helperGroup,
|
|
347
|
+
occlusionObserver: mesh,
|
|
348
|
+
occlusionEnabled: true
|
|
349
|
+
}
|
|
350
|
+
}));
|
|
351
|
+
occlusionSetupPromise = null;
|
|
352
|
+
}
|
|
353
|
+
function disableOcclusion(store) {
|
|
354
|
+
const { internal, set } = store.getState();
|
|
355
|
+
if (!internal.occlusionEnabled) return;
|
|
356
|
+
if (internal.occlusionObserver) {
|
|
357
|
+
internal.occlusionObserver.removeFromParent();
|
|
358
|
+
internal.occlusionObserver.geometry.dispose();
|
|
359
|
+
internal.occlusionObserver.material.dispose();
|
|
360
|
+
}
|
|
361
|
+
internal.occlusionCache.clear();
|
|
362
|
+
set((state) => ({
|
|
363
|
+
internal: {
|
|
364
|
+
...state.internal,
|
|
365
|
+
occlusionObserver: null,
|
|
366
|
+
occlusionEnabled: false
|
|
367
|
+
}
|
|
368
|
+
}));
|
|
369
|
+
}
|
|
370
|
+
function cleanupHelperGroup(store) {
|
|
371
|
+
const { internal, set } = store.getState();
|
|
372
|
+
disableOcclusion(store);
|
|
373
|
+
if (internal.helperGroup) {
|
|
374
|
+
internal.helperGroup.removeFromParent();
|
|
375
|
+
set((state) => ({
|
|
376
|
+
internal: {
|
|
377
|
+
...state.internal,
|
|
378
|
+
helperGroup: null
|
|
379
|
+
}
|
|
380
|
+
}));
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function registerVisibility(store, object, handlers) {
|
|
384
|
+
const { internal } = store.getState();
|
|
385
|
+
const registry = internal.visibilityRegistry;
|
|
386
|
+
const entry = {
|
|
387
|
+
object,
|
|
388
|
+
handlers,
|
|
389
|
+
lastFramedState: null,
|
|
390
|
+
lastOccludedState: null,
|
|
391
|
+
lastVisibleState: null
|
|
392
|
+
};
|
|
393
|
+
registry.set(object.uuid, entry);
|
|
394
|
+
if (handlers.onOccluded || handlers.onVisible) {
|
|
395
|
+
object.occlusionTest = true;
|
|
396
|
+
if (!internal.occlusionEnabled) {
|
|
397
|
+
enableOcclusion(store);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function unregisterVisibility(store, object) {
|
|
402
|
+
const { internal } = store.getState();
|
|
403
|
+
internal.visibilityRegistry.delete(object.uuid);
|
|
404
|
+
internal.occlusionCache.delete(object);
|
|
405
|
+
}
|
|
406
|
+
function checkVisibility(state) {
|
|
407
|
+
const { internal, camera } = state;
|
|
408
|
+
const registry = internal.visibilityRegistry;
|
|
409
|
+
if (registry.size === 0) return;
|
|
410
|
+
updateFrustum(camera, tempFrustum);
|
|
411
|
+
for (const entry of registry.values()) {
|
|
412
|
+
const { object, handlers, lastFramedState, lastOccludedState, lastVisibleState } = entry;
|
|
413
|
+
let inFrustum = null;
|
|
414
|
+
const computeFrustum = () => {
|
|
415
|
+
if (inFrustum === null) {
|
|
416
|
+
if (object.geometry?.boundingSphere === null) {
|
|
417
|
+
object.geometry?.computeBoundingSphere();
|
|
418
|
+
}
|
|
419
|
+
inFrustum = tempFrustum.intersectsObject(object);
|
|
420
|
+
}
|
|
421
|
+
return inFrustum;
|
|
422
|
+
};
|
|
423
|
+
if (handlers.onFramed) {
|
|
424
|
+
const currentInFrustum = computeFrustum();
|
|
425
|
+
if (currentInFrustum !== lastFramedState) {
|
|
426
|
+
entry.lastFramedState = currentInFrustum;
|
|
427
|
+
handlers.onFramed(currentInFrustum);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
let currentOcclusion = null;
|
|
431
|
+
if (handlers.onOccluded && internal.occlusionEnabled) {
|
|
432
|
+
currentOcclusion = internal.occlusionCache.get(object) ?? null;
|
|
433
|
+
if (currentOcclusion !== null && currentOcclusion !== lastOccludedState) {
|
|
434
|
+
entry.lastOccludedState = currentOcclusion;
|
|
435
|
+
handlers.onOccluded(currentOcclusion);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
if (handlers.onVisible) {
|
|
439
|
+
const currentInFrustum = computeFrustum();
|
|
440
|
+
if (!handlers.onFramed && currentInFrustum !== lastFramedState) {
|
|
441
|
+
entry.lastFramedState = currentInFrustum;
|
|
442
|
+
}
|
|
443
|
+
let isOccluded = currentOcclusion;
|
|
444
|
+
if (isOccluded === null && internal.occlusionEnabled) {
|
|
445
|
+
isOccluded = internal.occlusionCache.get(object) ?? null;
|
|
446
|
+
}
|
|
447
|
+
if (isOccluded === null) isOccluded = false;
|
|
448
|
+
const isVisible = currentInFrustum && !isOccluded && object.visible;
|
|
449
|
+
if (isVisible !== lastVisibleState) {
|
|
450
|
+
entry.lastVisibleState = isVisible;
|
|
451
|
+
handlers.onVisible(isVisible);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
function hasVisibilityHandlers(handlers) {
|
|
457
|
+
if (!handlers) return false;
|
|
458
|
+
return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
|
|
459
|
+
}
|
|
460
|
+
|
|
251
461
|
const RESERVED_PROPS = [
|
|
252
462
|
"children",
|
|
253
463
|
"key",
|
|
@@ -262,6 +472,7 @@ const RESERVED_PROPS = [
|
|
|
262
472
|
"dispose"
|
|
263
473
|
];
|
|
264
474
|
const EVENT_REGEX = /^on(Pointer|Drag|Drop|Click|DoubleClick|ContextMenu|Wheel)/;
|
|
475
|
+
const VISIBILITY_EVENT_REGEX = /^on(Framed|Occluded|Visible)$/;
|
|
265
476
|
const INDEX_REGEX = /-\d+$/;
|
|
266
477
|
const MEMOIZED_PROTOTYPES = /* @__PURE__ */ new Map();
|
|
267
478
|
const colorMaps = ["map", "emissiveMap", "sheenColorMap", "specularColorMap", "envMap"];
|
|
@@ -348,7 +559,7 @@ function applyProps(object, props) {
|
|
|
348
559
|
const rootState = instance && findInitialRoot(instance).getState();
|
|
349
560
|
const prevHandlers = instance?.eventCount;
|
|
350
561
|
for (const prop in props) {
|
|
351
|
-
|
|
562
|
+
const value = props[prop];
|
|
352
563
|
if (RESERVED_PROPS.includes(prop)) continue;
|
|
353
564
|
if (instance && EVENT_REGEX.test(prop)) {
|
|
354
565
|
if (typeof value === "function") instance.handlers[prop] = value;
|
|
@@ -356,6 +567,12 @@ function applyProps(object, props) {
|
|
|
356
567
|
instance.eventCount = Object.keys(instance.handlers).length;
|
|
357
568
|
continue;
|
|
358
569
|
}
|
|
570
|
+
if (instance && VISIBILITY_EVENT_REGEX.test(prop)) {
|
|
571
|
+
if (typeof value === "function") instance.handlers[prop] = value;
|
|
572
|
+
else delete instance.handlers[prop];
|
|
573
|
+
instance.eventCount = Object.keys(instance.handlers).length;
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
359
576
|
if (value === void 0) continue;
|
|
360
577
|
let { root, key, target } = resolve(object, prop);
|
|
361
578
|
if (target === void 0 && (typeof root !== "object" || root === null)) {
|
|
@@ -392,6 +609,17 @@ function applyProps(object, props) {
|
|
|
392
609
|
if (instance.eventCount && object2.raycast !== null) {
|
|
393
610
|
rootState.internal.interaction.push(object2);
|
|
394
611
|
}
|
|
612
|
+
const root = findInitialRoot(instance);
|
|
613
|
+
const visibilityHandlers = {
|
|
614
|
+
onFramed: instance.handlers.onFramed,
|
|
615
|
+
onOccluded: instance.handlers.onOccluded,
|
|
616
|
+
onVisible: instance.handlers.onVisible
|
|
617
|
+
};
|
|
618
|
+
if (hasVisibilityHandlers(visibilityHandlers)) {
|
|
619
|
+
registerVisibility(root, object2, visibilityHandlers);
|
|
620
|
+
} else {
|
|
621
|
+
unregisterVisibility(root, object2);
|
|
622
|
+
}
|
|
395
623
|
}
|
|
396
624
|
if (instance && instance.props.attach === void 0) {
|
|
397
625
|
if (instance.object.isBufferGeometry) instance.props.attach = "geometry";
|
|
@@ -426,6 +654,7 @@ function removeInteractivity(store, object) {
|
|
|
426
654
|
internal.capturedMap.forEach((captures, pointerId) => {
|
|
427
655
|
releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
|
|
428
656
|
});
|
|
657
|
+
unregisterVisibility(store, object);
|
|
429
658
|
}
|
|
430
659
|
function createEvents(store) {
|
|
431
660
|
function calculateDistance(event) {
|
|
@@ -482,13 +711,14 @@ function createEvents(store) {
|
|
|
482
711
|
for (const hit of hits) {
|
|
483
712
|
let eventObject = hit.object;
|
|
484
713
|
while (eventObject) {
|
|
485
|
-
if (eventObject.__r3f?.eventCount)
|
|
714
|
+
if (eventObject.__r3f?.eventCount) {
|
|
486
715
|
intersections.push({ ...hit, eventObject });
|
|
716
|
+
}
|
|
487
717
|
eventObject = eventObject.parent;
|
|
488
718
|
}
|
|
489
719
|
}
|
|
490
720
|
if ("pointerId" in event && state.internal.capturedMap.has(event.pointerId)) {
|
|
491
|
-
for (
|
|
721
|
+
for (const captureData of state.internal.capturedMap.get(event.pointerId).values()) {
|
|
492
722
|
if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
|
|
493
723
|
}
|
|
494
724
|
}
|
|
@@ -518,12 +748,12 @@ function createEvents(store) {
|
|
|
518
748
|
releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
|
|
519
749
|
}
|
|
520
750
|
};
|
|
521
|
-
|
|
522
|
-
for (
|
|
523
|
-
|
|
751
|
+
const extractEventProps = {};
|
|
752
|
+
for (const prop in event) {
|
|
753
|
+
const property = event[prop];
|
|
524
754
|
if (typeof property !== "function") extractEventProps[prop] = property;
|
|
525
755
|
}
|
|
526
|
-
|
|
756
|
+
const raycastEvent = {
|
|
527
757
|
...hit,
|
|
528
758
|
...extractEventProps,
|
|
529
759
|
pointer,
|
|
@@ -808,8 +1038,21 @@ function formatLocation(url, line) {
|
|
|
808
1038
|
const file = clean.split("/").pop() ?? clean;
|
|
809
1039
|
return `${file}:${line}`;
|
|
810
1040
|
}
|
|
1041
|
+
function notifyAlpha({ message, link }) {
|
|
1042
|
+
if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
if (shownNotices.has(message)) return;
|
|
1046
|
+
shownNotices.add(message);
|
|
1047
|
+
const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
|
|
1048
|
+
console.log(`%c\u{1F52C} ${message}`, boxStyle);
|
|
1049
|
+
{
|
|
1050
|
+
console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
811
1053
|
|
|
812
|
-
const
|
|
1054
|
+
const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
|
|
1055
|
+
const context = globalThis[R3F_CONTEXT] ?? (globalThis[R3F_CONTEXT] = React__namespace.createContext(null));
|
|
813
1056
|
const createStore = (invalidate, advance) => {
|
|
814
1057
|
const rootStore = traditional.createWithEqualityFn((set, get) => {
|
|
815
1058
|
const position = new webgpu.Vector3();
|
|
@@ -840,6 +1083,8 @@ const createStore = (invalidate, advance) => {
|
|
|
840
1083
|
gl: null,
|
|
841
1084
|
renderer: null,
|
|
842
1085
|
camera: null,
|
|
1086
|
+
frustum: new webgpu.Frustum(),
|
|
1087
|
+
autoUpdateFrustum: true,
|
|
843
1088
|
raycaster: null,
|
|
844
1089
|
events: { priority: 1, enabled: true, connected: false },
|
|
845
1090
|
scene: null,
|
|
@@ -891,10 +1136,38 @@ const createStore = (invalidate, advance) => {
|
|
|
891
1136
|
getCurrentViewport
|
|
892
1137
|
},
|
|
893
1138
|
setEvents: (events) => set((state2) => ({ ...state2, events: { ...state2.events, ...events } })),
|
|
894
|
-
setSize: (width, height, top
|
|
895
|
-
const
|
|
896
|
-
|
|
897
|
-
|
|
1139
|
+
setSize: (width, height, top, left) => {
|
|
1140
|
+
const state2 = get();
|
|
1141
|
+
if (width === void 0) {
|
|
1142
|
+
set({ _sizeImperative: false });
|
|
1143
|
+
if (state2._sizeProps) {
|
|
1144
|
+
const { width: propW, height: propH } = state2._sizeProps;
|
|
1145
|
+
if (propW !== void 0 || propH !== void 0) {
|
|
1146
|
+
const currentSize = state2.size;
|
|
1147
|
+
const newSize = {
|
|
1148
|
+
width: propW ?? currentSize.width,
|
|
1149
|
+
height: propH ?? currentSize.height,
|
|
1150
|
+
top: currentSize.top,
|
|
1151
|
+
left: currentSize.left
|
|
1152
|
+
};
|
|
1153
|
+
set((s) => ({
|
|
1154
|
+
size: newSize,
|
|
1155
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
|
|
1156
|
+
}));
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
const w = width;
|
|
1162
|
+
const h = height ?? width;
|
|
1163
|
+
const t = top ?? state2.size.top;
|
|
1164
|
+
const l = left ?? state2.size.left;
|
|
1165
|
+
const size = { width: w, height: h, top: t, left: l };
|
|
1166
|
+
set((s) => ({
|
|
1167
|
+
size,
|
|
1168
|
+
viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
|
|
1169
|
+
_sizeImperative: true
|
|
1170
|
+
}));
|
|
898
1171
|
},
|
|
899
1172
|
setDpr: (dpr) => set((state2) => {
|
|
900
1173
|
const resolved = calculateDpr(dpr);
|
|
@@ -911,6 +1184,9 @@ const createStore = (invalidate, advance) => {
|
|
|
911
1184
|
textures: /* @__PURE__ */ new Map(),
|
|
912
1185
|
postProcessing: null,
|
|
913
1186
|
passes: {},
|
|
1187
|
+
_hmrVersion: 0,
|
|
1188
|
+
_sizeImperative: false,
|
|
1189
|
+
_sizeProps: null,
|
|
914
1190
|
previousRoot: void 0,
|
|
915
1191
|
internal: {
|
|
916
1192
|
// Events
|
|
@@ -921,6 +1197,13 @@ const createStore = (invalidate, advance) => {
|
|
|
921
1197
|
initialHits: [],
|
|
922
1198
|
capturedMap: /* @__PURE__ */ new Map(),
|
|
923
1199
|
lastEvent: React__namespace.createRef(),
|
|
1200
|
+
// Visibility tracking (onFramed, onOccluded, onVisible)
|
|
1201
|
+
visibilityRegistry: /* @__PURE__ */ new Map(),
|
|
1202
|
+
// Occlusion system (WebGPU only)
|
|
1203
|
+
occlusionEnabled: false,
|
|
1204
|
+
occlusionObserver: null,
|
|
1205
|
+
occlusionCache: /* @__PURE__ */ new Map(),
|
|
1206
|
+
helperGroup: null,
|
|
924
1207
|
// Updates
|
|
925
1208
|
active: false,
|
|
926
1209
|
frames: 0,
|
|
@@ -1006,7 +1289,15 @@ const createStore = (invalidate, advance) => {
|
|
|
1006
1289
|
}
|
|
1007
1290
|
if (camera !== oldCamera) {
|
|
1008
1291
|
oldCamera = camera;
|
|
1292
|
+
const { rootScene } = rootStore.getState();
|
|
1293
|
+
if (camera && rootScene && !camera.parent) {
|
|
1294
|
+
rootScene.add(camera);
|
|
1295
|
+
}
|
|
1009
1296
|
set((state2) => ({ viewport: { ...state2.viewport, ...state2.viewport.getCurrentViewport(camera) } }));
|
|
1297
|
+
const currentState = rootStore.getState();
|
|
1298
|
+
if (currentState.autoUpdateFrustum && camera) {
|
|
1299
|
+
updateFrustum(camera, currentState.frustum);
|
|
1300
|
+
}
|
|
1010
1301
|
}
|
|
1011
1302
|
});
|
|
1012
1303
|
rootStore.subscribe((state2) => invalidate(state2));
|
|
@@ -1065,18 +1356,18 @@ useLoader.clear = function(loader, input) {
|
|
|
1065
1356
|
};
|
|
1066
1357
|
useLoader.loader = getLoader;
|
|
1067
1358
|
|
|
1068
|
-
var __defProp$
|
|
1069
|
-
var __defNormalProp$
|
|
1070
|
-
var __publicField$
|
|
1359
|
+
var __defProp$2 = Object.defineProperty;
|
|
1360
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1361
|
+
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1071
1362
|
const DEFAULT_PHASES = ["start", "input", "physics", "update", "render", "finish"];
|
|
1072
1363
|
class PhaseGraph {
|
|
1073
1364
|
constructor() {
|
|
1074
1365
|
/** Ordered list of phase nodes */
|
|
1075
|
-
__publicField$
|
|
1366
|
+
__publicField$2(this, "phases", []);
|
|
1076
1367
|
/** Quick lookup by name */
|
|
1077
|
-
__publicField$
|
|
1368
|
+
__publicField$2(this, "phaseMap", /* @__PURE__ */ new Map());
|
|
1078
1369
|
/** Cached ordered names (invalidated on changes) */
|
|
1079
|
-
__publicField$
|
|
1370
|
+
__publicField$2(this, "orderedNamesCache", null);
|
|
1080
1371
|
this.initializeDefaultPhases();
|
|
1081
1372
|
}
|
|
1082
1373
|
//* Initialization --------------------------------
|
|
@@ -1103,8 +1394,9 @@ class PhaseGraph {
|
|
|
1103
1394
|
const node = { name, isAutoGenerated: false };
|
|
1104
1395
|
let insertIndex = this.phases.length;
|
|
1105
1396
|
const targetIndex = this.getPhaseIndex(before ?? after);
|
|
1106
|
-
if (targetIndex !== -1)
|
|
1107
|
-
|
|
1397
|
+
if (targetIndex !== -1) {
|
|
1398
|
+
insertIndex = before ? targetIndex : targetIndex + 1;
|
|
1399
|
+
} else {
|
|
1108
1400
|
const constraintType = before ? "before" : "after";
|
|
1109
1401
|
console.warn(`[useFrame] Phase "${before ?? after}" not found for '${constraintType}' constraint`);
|
|
1110
1402
|
}
|
|
@@ -1332,9 +1624,9 @@ function resetJobTiming(job) {
|
|
|
1332
1624
|
job.lastRun = void 0;
|
|
1333
1625
|
}
|
|
1334
1626
|
|
|
1335
|
-
var __defProp = Object.defineProperty;
|
|
1336
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1337
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1627
|
+
var __defProp$1 = Object.defineProperty;
|
|
1628
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1629
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1338
1630
|
const hmrData = (() => {
|
|
1339
1631
|
if (typeof process !== "undefined" && process.env.NODE_ENV === "test") return void 0;
|
|
1340
1632
|
if (typeof import_meta_hot !== "undefined") return import_meta_hot;
|
|
@@ -1348,9 +1640,9 @@ const _Scheduler = class _Scheduler {
|
|
|
1348
1640
|
//* Constructor ================================
|
|
1349
1641
|
constructor() {
|
|
1350
1642
|
//* Critical State ================================
|
|
1351
|
-
__publicField(this, "roots", /* @__PURE__ */ new Map());
|
|
1352
|
-
__publicField(this, "phaseGraph");
|
|
1353
|
-
__publicField(this, "loopState", {
|
|
1643
|
+
__publicField$1(this, "roots", /* @__PURE__ */ new Map());
|
|
1644
|
+
__publicField$1(this, "phaseGraph");
|
|
1645
|
+
__publicField$1(this, "loopState", {
|
|
1354
1646
|
running: false,
|
|
1355
1647
|
rafHandle: null,
|
|
1356
1648
|
lastTime: null,
|
|
@@ -1359,17 +1651,21 @@ const _Scheduler = class _Scheduler {
|
|
|
1359
1651
|
elapsedTime: 0,
|
|
1360
1652
|
createdAt: performance.now()
|
|
1361
1653
|
});
|
|
1362
|
-
__publicField(this, "stoppedTime", 0);
|
|
1654
|
+
__publicField$1(this, "stoppedTime", 0);
|
|
1363
1655
|
//* Private State ================================
|
|
1364
|
-
__publicField(this, "nextRootIndex", 0);
|
|
1365
|
-
__publicField(this, "globalBeforeJobs", /* @__PURE__ */ new Map());
|
|
1366
|
-
__publicField(this, "globalAfterJobs", /* @__PURE__ */ new Map());
|
|
1367
|
-
__publicField(this, "nextGlobalIndex", 0);
|
|
1368
|
-
__publicField(this, "idleCallbacks", /* @__PURE__ */ new Set());
|
|
1369
|
-
__publicField(this, "nextJobIndex", 0);
|
|
1370
|
-
__publicField(this, "jobStateListeners", /* @__PURE__ */ new Map());
|
|
1371
|
-
__publicField(this, "pendingFrames", 0);
|
|
1372
|
-
__publicField(this, "_frameloop", "always");
|
|
1656
|
+
__publicField$1(this, "nextRootIndex", 0);
|
|
1657
|
+
__publicField$1(this, "globalBeforeJobs", /* @__PURE__ */ new Map());
|
|
1658
|
+
__publicField$1(this, "globalAfterJobs", /* @__PURE__ */ new Map());
|
|
1659
|
+
__publicField$1(this, "nextGlobalIndex", 0);
|
|
1660
|
+
__publicField$1(this, "idleCallbacks", /* @__PURE__ */ new Set());
|
|
1661
|
+
__publicField$1(this, "nextJobIndex", 0);
|
|
1662
|
+
__publicField$1(this, "jobStateListeners", /* @__PURE__ */ new Map());
|
|
1663
|
+
__publicField$1(this, "pendingFrames", 0);
|
|
1664
|
+
__publicField$1(this, "_frameloop", "always");
|
|
1665
|
+
//* Independent Mode & Error Handling State ================================
|
|
1666
|
+
__publicField$1(this, "_independent", false);
|
|
1667
|
+
__publicField$1(this, "errorHandler", null);
|
|
1668
|
+
__publicField$1(this, "rootReadyCallbacks", /* @__PURE__ */ new Set());
|
|
1373
1669
|
//* Core Loop Execution Methods ================================
|
|
1374
1670
|
/**
|
|
1375
1671
|
* Main RAF loop callback.
|
|
@@ -1378,7 +1674,7 @@ const _Scheduler = class _Scheduler {
|
|
|
1378
1674
|
* @returns {void}
|
|
1379
1675
|
* @private
|
|
1380
1676
|
*/
|
|
1381
|
-
__publicField(this, "loop", (timestamp) => {
|
|
1677
|
+
__publicField$1(this, "loop", (timestamp) => {
|
|
1382
1678
|
if (!this.loopState.running) return;
|
|
1383
1679
|
this.executeFrame(timestamp);
|
|
1384
1680
|
if (this._frameloop === "demand") {
|
|
@@ -1392,6 +1688,12 @@ const _Scheduler = class _Scheduler {
|
|
|
1392
1688
|
});
|
|
1393
1689
|
this.phaseGraph = new PhaseGraph();
|
|
1394
1690
|
}
|
|
1691
|
+
static get instance() {
|
|
1692
|
+
return globalThis[_Scheduler.INSTANCE_KEY] ?? null;
|
|
1693
|
+
}
|
|
1694
|
+
static set instance(value) {
|
|
1695
|
+
globalThis[_Scheduler.INSTANCE_KEY] = value;
|
|
1696
|
+
}
|
|
1395
1697
|
/**
|
|
1396
1698
|
* Get the global scheduler instance (creates if doesn't exist).
|
|
1397
1699
|
* Uses HMR data to preserve instance across hot reloads.
|
|
@@ -1440,29 +1742,43 @@ const _Scheduler = class _Scheduler {
|
|
|
1440
1742
|
get isRunning() {
|
|
1441
1743
|
return this.loopState.running;
|
|
1442
1744
|
}
|
|
1745
|
+
get isReady() {
|
|
1746
|
+
return this.roots.size > 0;
|
|
1747
|
+
}
|
|
1748
|
+
get independent() {
|
|
1749
|
+
return this._independent;
|
|
1750
|
+
}
|
|
1751
|
+
set independent(value) {
|
|
1752
|
+
this._independent = value;
|
|
1753
|
+
if (value) this.ensureDefaultRoot();
|
|
1754
|
+
}
|
|
1443
1755
|
//* Root Management Methods ================================
|
|
1444
1756
|
/**
|
|
1445
1757
|
* Register a root (Canvas) with the scheduler.
|
|
1446
1758
|
* The first root to register starts the RAF loop (if frameloop='always').
|
|
1447
1759
|
* @param {string} id - Unique identifier for this root
|
|
1448
|
-
* @param {
|
|
1760
|
+
* @param {RootOptions} [options] - Optional configuration with getState and onError callbacks
|
|
1449
1761
|
* @returns {() => void} Unsubscribe function to remove this root
|
|
1450
1762
|
*/
|
|
1451
|
-
registerRoot(id,
|
|
1763
|
+
registerRoot(id, options = {}) {
|
|
1452
1764
|
if (this.roots.has(id)) {
|
|
1453
1765
|
console.warn(`[Scheduler] Root "${id}" already registered`);
|
|
1454
1766
|
return () => this.unregisterRoot(id);
|
|
1455
1767
|
}
|
|
1456
1768
|
const entry = {
|
|
1457
1769
|
id,
|
|
1458
|
-
getState,
|
|
1770
|
+
getState: options.getState ?? (() => ({})),
|
|
1459
1771
|
jobs: /* @__PURE__ */ new Map(),
|
|
1460
1772
|
sortedJobs: [],
|
|
1461
1773
|
needsRebuild: false
|
|
1462
1774
|
};
|
|
1775
|
+
if (options.onError) {
|
|
1776
|
+
this.errorHandler = options.onError;
|
|
1777
|
+
}
|
|
1463
1778
|
this.roots.set(id, entry);
|
|
1464
|
-
if (this.roots.size === 1
|
|
1465
|
-
this.
|
|
1779
|
+
if (this.roots.size === 1) {
|
|
1780
|
+
this.notifyRootReady();
|
|
1781
|
+
if (this._frameloop === "always") this.start();
|
|
1466
1782
|
}
|
|
1467
1783
|
return () => this.unregisterRoot(id);
|
|
1468
1784
|
}
|
|
@@ -1482,7 +1798,60 @@ const _Scheduler = class _Scheduler {
|
|
|
1482
1798
|
this.roots.delete(id);
|
|
1483
1799
|
if (this.roots.size === 0) {
|
|
1484
1800
|
this.stop();
|
|
1801
|
+
this.errorHandler = null;
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
/**
|
|
1805
|
+
* Subscribe to be notified when a root becomes available.
|
|
1806
|
+
* Fires immediately if a root already exists.
|
|
1807
|
+
* @param {() => void} callback - Function called when first root registers
|
|
1808
|
+
* @returns {() => void} Unsubscribe function
|
|
1809
|
+
*/
|
|
1810
|
+
onRootReady(callback) {
|
|
1811
|
+
if (this.roots.size > 0) {
|
|
1812
|
+
callback();
|
|
1813
|
+
return () => {
|
|
1814
|
+
};
|
|
1485
1815
|
}
|
|
1816
|
+
this.rootReadyCallbacks.add(callback);
|
|
1817
|
+
return () => this.rootReadyCallbacks.delete(callback);
|
|
1818
|
+
}
|
|
1819
|
+
/**
|
|
1820
|
+
* Notify all registered root-ready callbacks.
|
|
1821
|
+
* Called when the first root registers.
|
|
1822
|
+
* @returns {void}
|
|
1823
|
+
* @private
|
|
1824
|
+
*/
|
|
1825
|
+
notifyRootReady() {
|
|
1826
|
+
for (const cb of this.rootReadyCallbacks) {
|
|
1827
|
+
try {
|
|
1828
|
+
cb();
|
|
1829
|
+
} catch (error) {
|
|
1830
|
+
console.error("[Scheduler] Error in root-ready callback:", error);
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
this.rootReadyCallbacks.clear();
|
|
1834
|
+
}
|
|
1835
|
+
/**
|
|
1836
|
+
* Ensure a default root exists for independent mode.
|
|
1837
|
+
* Creates a minimal root with no state provider.
|
|
1838
|
+
* @returns {void}
|
|
1839
|
+
* @private
|
|
1840
|
+
*/
|
|
1841
|
+
ensureDefaultRoot() {
|
|
1842
|
+
if (!this.roots.has("__default__")) {
|
|
1843
|
+
this.registerRoot("__default__");
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
/**
|
|
1847
|
+
* Trigger error handling for job errors.
|
|
1848
|
+
* Uses the bound error handler if available, otherwise logs to console.
|
|
1849
|
+
* @param {Error} error - The error to handle
|
|
1850
|
+
* @returns {void}
|
|
1851
|
+
*/
|
|
1852
|
+
triggerError(error) {
|
|
1853
|
+
if (this.errorHandler) this.errorHandler(error);
|
|
1854
|
+
else console.error("[Scheduler]", error);
|
|
1486
1855
|
}
|
|
1487
1856
|
//* Phase Management Methods ================================
|
|
1488
1857
|
/**
|
|
@@ -1842,9 +2211,9 @@ const _Scheduler = class _Scheduler {
|
|
|
1842
2211
|
const deltaMs = this.loopState.lastTime !== null ? now - this.loopState.lastTime : 0;
|
|
1843
2212
|
const delta = deltaMs / 1e3;
|
|
1844
2213
|
const elapsed = now - this.loopState.createdAt;
|
|
1845
|
-
const
|
|
2214
|
+
const providedState = root.getState?.() ?? {};
|
|
1846
2215
|
const frameState = {
|
|
1847
|
-
...
|
|
2216
|
+
...providedState,
|
|
1848
2217
|
time: now,
|
|
1849
2218
|
delta,
|
|
1850
2219
|
elapsed,
|
|
@@ -1854,6 +2223,7 @@ const _Scheduler = class _Scheduler {
|
|
|
1854
2223
|
job.callback(frameState, delta);
|
|
1855
2224
|
} catch (error) {
|
|
1856
2225
|
console.error(`[Scheduler] Error in job "${job.id}":`, error);
|
|
2226
|
+
this.triggerError(error instanceof Error ? error : new Error(String(error)));
|
|
1857
2227
|
}
|
|
1858
2228
|
}
|
|
1859
2229
|
/**
|
|
@@ -1895,7 +2265,7 @@ const _Scheduler = class _Scheduler {
|
|
|
1895
2265
|
/**
|
|
1896
2266
|
* Execute all jobs for a single root in sorted order.
|
|
1897
2267
|
* Rebuilds sorted job list if needed, then dispatches each job.
|
|
1898
|
-
* Errors are caught and propagated
|
|
2268
|
+
* Errors are caught and propagated via triggerError.
|
|
1899
2269
|
* @param {RootEntry} root - The root entry to tick
|
|
1900
2270
|
* @param {number} timestamp - RAF timestamp in milliseconds
|
|
1901
2271
|
* @param {number} delta - Time since last frame in seconds
|
|
@@ -1907,10 +2277,9 @@ const _Scheduler = class _Scheduler {
|
|
|
1907
2277
|
root.sortedJobs = rebuildSortedJobs(root.jobs, this.phaseGraph);
|
|
1908
2278
|
root.needsRebuild = false;
|
|
1909
2279
|
}
|
|
1910
|
-
const
|
|
1911
|
-
if (!rootState) return;
|
|
2280
|
+
const providedState = root.getState?.() ?? {};
|
|
1912
2281
|
const frameState = {
|
|
1913
|
-
...
|
|
2282
|
+
...providedState,
|
|
1914
2283
|
time: timestamp,
|
|
1915
2284
|
delta,
|
|
1916
2285
|
elapsed: this.loopState.elapsedTime / 1e3,
|
|
@@ -1923,7 +2292,7 @@ const _Scheduler = class _Scheduler {
|
|
|
1923
2292
|
job.callback(frameState, delta);
|
|
1924
2293
|
} catch (error) {
|
|
1925
2294
|
console.error(`[Scheduler] Error in job "${job.id}":`, error);
|
|
1926
|
-
|
|
2295
|
+
this.triggerError(error instanceof Error ? error : new Error(String(error)));
|
|
1927
2296
|
}
|
|
1928
2297
|
}
|
|
1929
2298
|
}
|
|
@@ -2008,8 +2377,11 @@ const _Scheduler = class _Scheduler {
|
|
|
2008
2377
|
return /* @__PURE__ */ new Set([value]);
|
|
2009
2378
|
}
|
|
2010
2379
|
};
|
|
2011
|
-
//* Static State & Methods (
|
|
2012
|
-
|
|
2380
|
+
//* Static State & Methods (Singleton Usage) ================================
|
|
2381
|
+
//* Cross-Bundle Singleton Key ==============================
|
|
2382
|
+
// Use Symbol.for() to ensure scheduler is shared across bundle boundaries
|
|
2383
|
+
// This prevents issues when mixing imports from @react-three/fiber and @react-three/fiber/webgpu
|
|
2384
|
+
__publicField$1(_Scheduler, "INSTANCE_KEY", Symbol.for("@react-three/fiber.scheduler"));
|
|
2013
2385
|
let Scheduler = _Scheduler;
|
|
2014
2386
|
const getScheduler = () => Scheduler.get();
|
|
2015
2387
|
if (hmrData) {
|
|
@@ -2017,11 +2389,9 @@ if (hmrData) {
|
|
|
2017
2389
|
}
|
|
2018
2390
|
|
|
2019
2391
|
function useFrame(callback, priorityOrOptions) {
|
|
2020
|
-
const store =
|
|
2021
|
-
const
|
|
2022
|
-
|
|
2023
|
-
return state.internal.rootId;
|
|
2024
|
-
}, [store]);
|
|
2392
|
+
const store = React__namespace.useContext(context);
|
|
2393
|
+
const isInsideCanvas = store !== null;
|
|
2394
|
+
const scheduler = getScheduler();
|
|
2025
2395
|
const optionsKey = typeof priorityOrOptions === "number" ? `p:${priorityOrOptions}` : priorityOrOptions ? JSON.stringify({
|
|
2026
2396
|
id: priorityOrOptions.id,
|
|
2027
2397
|
phase: priorityOrOptions.phase,
|
|
@@ -2041,55 +2411,71 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
2041
2411
|
const isLegacyPriority = typeof priorityOrOptions === "number" && priorityOrOptions > 0;
|
|
2042
2412
|
useIsomorphicLayoutEffect(() => {
|
|
2043
2413
|
if (!callback) return;
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
if (isLegacyPriority) {
|
|
2048
|
-
state.internal.priority++;
|
|
2049
|
-
let parentRoot = state.previousRoot;
|
|
2050
|
-
while (parentRoot) {
|
|
2051
|
-
const parentState = parentRoot.getState();
|
|
2052
|
-
if (parentState?.internal) parentState.internal.priority++;
|
|
2053
|
-
parentRoot = parentState?.previousRoot;
|
|
2054
|
-
}
|
|
2055
|
-
notifyDepreciated({
|
|
2056
|
-
heading: "useFrame with numeric priority is deprecated",
|
|
2057
|
-
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 })',
|
|
2058
|
-
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
2059
|
-
});
|
|
2060
|
-
}
|
|
2061
|
-
const wrappedCallback = (frameState, delta) => {
|
|
2062
|
-
const localState = store.getState();
|
|
2063
|
-
const mergedState = {
|
|
2064
|
-
...localState,
|
|
2065
|
-
time: frameState.time,
|
|
2066
|
-
delta: frameState.delta,
|
|
2067
|
-
elapsed: frameState.elapsed,
|
|
2068
|
-
frame: frameState.frame
|
|
2069
|
-
};
|
|
2070
|
-
callbackRef.current?.(mergedState, delta);
|
|
2071
|
-
};
|
|
2072
|
-
const unregister = scheduler.register(wrappedCallback, {
|
|
2073
|
-
id,
|
|
2074
|
-
rootId,
|
|
2075
|
-
...options
|
|
2076
|
-
});
|
|
2077
|
-
return () => {
|
|
2078
|
-
unregister();
|
|
2414
|
+
if (isInsideCanvas) {
|
|
2415
|
+
const state = store.getState();
|
|
2416
|
+
const rootId = state.internal.rootId;
|
|
2079
2417
|
if (isLegacyPriority) {
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2418
|
+
state.internal.priority++;
|
|
2419
|
+
let parentRoot = state.previousRoot;
|
|
2420
|
+
while (parentRoot) {
|
|
2421
|
+
const parentState = parentRoot.getState();
|
|
2422
|
+
if (parentState?.internal) parentState.internal.priority++;
|
|
2423
|
+
parentRoot = parentState?.previousRoot;
|
|
2424
|
+
}
|
|
2425
|
+
notifyDepreciated({
|
|
2426
|
+
heading: "useFrame with numeric priority is deprecated",
|
|
2427
|
+
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 })',
|
|
2428
|
+
link: "https://docs.pmnd.rs/react-three-fiber/api/hooks#useframe"
|
|
2429
|
+
});
|
|
2430
|
+
}
|
|
2431
|
+
const wrappedCallback = (frameState, delta) => {
|
|
2432
|
+
const localState = store.getState();
|
|
2433
|
+
const mergedState = {
|
|
2434
|
+
...localState,
|
|
2435
|
+
time: frameState.time,
|
|
2436
|
+
delta: frameState.delta,
|
|
2437
|
+
elapsed: frameState.elapsed,
|
|
2438
|
+
frame: frameState.frame
|
|
2439
|
+
};
|
|
2440
|
+
callbackRef.current?.(mergedState, delta);
|
|
2441
|
+
};
|
|
2442
|
+
const unregister = scheduler.register(wrappedCallback, {
|
|
2443
|
+
id,
|
|
2444
|
+
rootId,
|
|
2445
|
+
...options
|
|
2446
|
+
});
|
|
2447
|
+
return () => {
|
|
2448
|
+
unregister();
|
|
2449
|
+
if (isLegacyPriority) {
|
|
2450
|
+
const currentState = store.getState();
|
|
2451
|
+
if (currentState.internal) {
|
|
2452
|
+
currentState.internal.priority--;
|
|
2453
|
+
let parentRoot = currentState.previousRoot;
|
|
2454
|
+
while (parentRoot) {
|
|
2455
|
+
const parentState = parentRoot.getState();
|
|
2456
|
+
if (parentState?.internal) parentState.internal.priority--;
|
|
2457
|
+
parentRoot = parentState?.previousRoot;
|
|
2458
|
+
}
|
|
2088
2459
|
}
|
|
2089
2460
|
}
|
|
2461
|
+
};
|
|
2462
|
+
} else {
|
|
2463
|
+
const registerOutside = () => {
|
|
2464
|
+
return scheduler.register((state, delta) => callbackRef.current?.(state, delta), { id, ...options });
|
|
2465
|
+
};
|
|
2466
|
+
if (scheduler.independent || scheduler.isReady) {
|
|
2467
|
+
return registerOutside();
|
|
2090
2468
|
}
|
|
2091
|
-
|
|
2092
|
-
|
|
2469
|
+
let unregisterJob = null;
|
|
2470
|
+
const unsubReady = scheduler.onRootReady(() => {
|
|
2471
|
+
unregisterJob = registerOutside();
|
|
2472
|
+
});
|
|
2473
|
+
return () => {
|
|
2474
|
+
unsubReady();
|
|
2475
|
+
unregisterJob?.();
|
|
2476
|
+
};
|
|
2477
|
+
}
|
|
2478
|
+
}, [store, scheduler, id, optionsKey, isLegacyPriority, isInsideCanvas]);
|
|
2093
2479
|
const isPaused = React__namespace.useSyncExternalStore(
|
|
2094
2480
|
// Subscribe function
|
|
2095
2481
|
React__namespace.useCallback(
|
|
@@ -2104,7 +2490,7 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
2104
2490
|
React__namespace.useCallback(() => false, [])
|
|
2105
2491
|
);
|
|
2106
2492
|
const controls = React__namespace.useMemo(() => {
|
|
2107
|
-
const
|
|
2493
|
+
const scheduler2 = getScheduler();
|
|
2108
2494
|
return {
|
|
2109
2495
|
/** The job's unique ID */
|
|
2110
2496
|
id,
|
|
@@ -2112,7 +2498,7 @@ function useFrame(callback, priorityOrOptions) {
|
|
|
2112
2498
|
* Access to the global scheduler for frame loop control.
|
|
2113
2499
|
* Use for controlling the entire frame loop, adding phases, etc.
|
|
2114
2500
|
*/
|
|
2115
|
-
scheduler,
|
|
2501
|
+
scheduler: scheduler2,
|
|
2116
2502
|
/**
|
|
2117
2503
|
* Manually step this job only.
|
|
2118
2504
|
* Bypasses FPS limiting - always runs.
|
|
@@ -2360,6 +2746,16 @@ function useTextures() {
|
|
|
2360
2746
|
}, [store]);
|
|
2361
2747
|
}
|
|
2362
2748
|
|
|
2749
|
+
function useRenderTarget(width, height, options) {
|
|
2750
|
+
const isLegacy = useThree((s) => s.isLegacy);
|
|
2751
|
+
const size = useThree((s) => s.size);
|
|
2752
|
+
return React.useMemo(() => {
|
|
2753
|
+
const w = width ?? size.width;
|
|
2754
|
+
const h = height ?? size.height;
|
|
2755
|
+
return new webgpu.RenderTarget(w, h, options);
|
|
2756
|
+
}, [width, height, size.width, size.height, options, isLegacy]);
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2363
2759
|
function useStore() {
|
|
2364
2760
|
const store = React.useContext(context);
|
|
2365
2761
|
if (!store) throw new Error("R3F: Hooks can only be used within the Canvas component!");
|
|
@@ -2411,24 +2807,14 @@ function advance(timestamp, runGlobalEffects = true, state, frame) {
|
|
|
2411
2807
|
getScheduler().step(timestamp);
|
|
2412
2808
|
}
|
|
2413
2809
|
|
|
2414
|
-
const version = "10.0.0-alpha.
|
|
2810
|
+
const version = "10.0.0-alpha.2";
|
|
2415
2811
|
const packageData = {
|
|
2416
2812
|
version: version};
|
|
2417
2813
|
|
|
2418
2814
|
function Xb(Tt) {
|
|
2419
2815
|
return Tt && Tt.__esModule && Object.prototype.hasOwnProperty.call(Tt, "default") ? Tt.default : Tt;
|
|
2420
2816
|
}
|
|
2421
|
-
var Rm = { exports: {} }, Og = { exports: {} };
|
|
2422
|
-
/**
|
|
2423
|
-
* @license React
|
|
2424
|
-
* react-reconciler.production.js
|
|
2425
|
-
*
|
|
2426
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2427
|
-
*
|
|
2428
|
-
* This source code is licensed under the MIT license found in the
|
|
2429
|
-
* LICENSE file in the root directory of this source tree.
|
|
2430
|
-
*/
|
|
2431
|
-
var _b;
|
|
2817
|
+
var Rm = { exports: {} }, Og = { exports: {} }, _b;
|
|
2432
2818
|
function Kb() {
|
|
2433
2819
|
return _b || (_b = 1, (function(Tt) {
|
|
2434
2820
|
Tt.exports = function(m) {
|
|
@@ -3500,7 +3886,6 @@ Error generating stack: ` + l.message + `
|
|
|
3500
3886
|
if (J === cl || J === jc) throw J;
|
|
3501
3887
|
var Ge = Yn(29, J, null, P.mode);
|
|
3502
3888
|
return Ge.lanes = H, Ge.return = P, Ge;
|
|
3503
|
-
} finally {
|
|
3504
3889
|
}
|
|
3505
3890
|
};
|
|
3506
3891
|
}
|
|
@@ -4154,7 +4539,6 @@ Error generating stack: ` + l.message + `
|
|
|
4154
4539
|
var h = r.lastRenderedState, y = d(h, a);
|
|
4155
4540
|
if (c.hasEagerState = true, c.eagerState = y, jn(y, h)) return go(t, r, c, 0), Ne === null && Bn(), false;
|
|
4156
4541
|
} catch {
|
|
4157
|
-
} finally {
|
|
4158
4542
|
}
|
|
4159
4543
|
if (a = yo(t, r, c, l), a !== null) return nt(a, t, l), ns(a, r, l), true;
|
|
4160
4544
|
}
|
|
@@ -6575,10 +6959,7 @@ Error generating stack: ` + l.message + `
|
|
|
6575
6959
|
function vr(t, r) {
|
|
6576
6960
|
Sf(t, r), (t = t.alternate) && Sf(t, r);
|
|
6577
6961
|
}
|
|
6578
|
-
var ie = {}, Fm = React__default, tt = Tb__default, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy");
|
|
6579
|
-
var gc = Symbol.for("react.activity");
|
|
6580
|
-
var $r = Symbol.for("react.memo_cache_sentinel");
|
|
6581
|
-
var Pf = Symbol.iterator, xf = Symbol.for("react.client.reference"), ca = Array.isArray, M = Fm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Yp = m.rendererVersion, zf = m.rendererPackageName, Cf = m.extraDevToolsConfig, Ts = m.getPublicInstance, Hm = m.getRootHostContext, Xp = m.getChildHostContext, Am = m.prepareForCommit, _s = m.resetAfterCommit, Vr = m.createInstance;
|
|
6962
|
+
var ie = {}, Fm = React__default, tt = Tb__default, Lt = Object.assign, hc = Symbol.for("react.element"), zs = Symbol.for("react.transitional.element"), sa = Symbol.for("react.portal"), $a = Symbol.for("react.fragment"), kf = Symbol.for("react.strict_mode"), Cs = Symbol.for("react.profiler"), mc = Symbol.for("react.consumer"), Io = Symbol.for("react.context"), Zi = Symbol.for("react.forward_ref"), Va = Symbol.for("react.suspense"), Te = Symbol.for("react.suspense_list"), wf = Symbol.for("react.memo"), ua = Symbol.for("react.lazy"), gc = Symbol.for("react.activity"), $r = Symbol.for("react.memo_cache_sentinel"), Pf = Symbol.iterator, xf = Symbol.for("react.client.reference"), ca = Array.isArray, M = Fm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Yp = m.rendererVersion, zf = m.rendererPackageName, Cf = m.extraDevToolsConfig, Ts = m.getPublicInstance, Hm = m.getRootHostContext, Xp = m.getChildHostContext, Am = m.prepareForCommit, _s = m.resetAfterCommit, Vr = m.createInstance;
|
|
6582
6963
|
m.cloneMutableInstance;
|
|
6583
6964
|
var yc = m.appendInitialChild, Kp = m.finalizeInitialChildren, Rs = m.shouldSetTextContent, bc = m.createTextInstance;
|
|
6584
6965
|
m.cloneMutableTextInstance;
|
|
@@ -6947,17 +7328,7 @@ No matching component was found for:
|
|
|
6947
7328
|
}, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true });
|
|
6948
7329
|
})(Og)), Og.exports;
|
|
6949
7330
|
}
|
|
6950
|
-
var Mg = { exports: {} };
|
|
6951
|
-
/**
|
|
6952
|
-
* @license React
|
|
6953
|
-
* react-reconciler.development.js
|
|
6954
|
-
*
|
|
6955
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
6956
|
-
*
|
|
6957
|
-
* This source code is licensed under the MIT license found in the
|
|
6958
|
-
* LICENSE file in the root directory of this source tree.
|
|
6959
|
-
*/
|
|
6960
|
-
var Rb;
|
|
7331
|
+
var Mg = { exports: {} }, Rb;
|
|
6961
7332
|
function e0() {
|
|
6962
7333
|
return Rb || (Rb = 1, (function(Tt) {
|
|
6963
7334
|
process.env.NODE_ENV !== "production" && (Tt.exports = function(m) {
|
|
@@ -12724,10 +13095,7 @@ Check the render method of %s.`, G(di) || "Unknown")), i = zo(n), i.payload = {
|
|
|
12724
13095
|
function Ic() {
|
|
12725
13096
|
return di;
|
|
12726
13097
|
}
|
|
12727
|
-
var le = {}, qm = React__default, St = Tb__default, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy");
|
|
12728
|
-
var Ds = Symbol.for("react.activity");
|
|
12729
|
-
var Bh = Symbol.for("react.memo_cache_sentinel");
|
|
12730
|
-
var ni = Symbol.iterator, il = Symbol.for("react.client.reference"), fn = Array.isArray, x = qm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Jt = m.rendererVersion, Zt = m.rendererPackageName, jo = m.extraDevToolsConfig, ot = m.getPublicInstance, Zr = m.getRootHostContext, Dn = m.getChildHostContext, Ws = m.prepareForCommit, pa = m.resetAfterCommit, Fc = m.createInstance;
|
|
13098
|
+
var le = {}, qm = React__default, St = Tb__default, ze = Object.assign, Uh = Symbol.for("react.element"), Ho = Symbol.for("react.transitional.element"), Ao = Symbol.for("react.portal"), ol = Symbol.for("react.fragment"), Lc = Symbol.for("react.strict_mode"), Uf = Symbol.for("react.profiler"), ei = Symbol.for("react.consumer"), on = Symbol.for("react.context"), jn = Symbol.for("react.forward_ref"), Nc = Symbol.for("react.suspense"), Bf = Symbol.for("react.suspense_list"), al = Symbol.for("react.memo"), kt = Symbol.for("react.lazy"), Ds = Symbol.for("react.activity"), Bh = Symbol.for("react.memo_cache_sentinel"), ni = Symbol.iterator, il = Symbol.for("react.client.reference"), fn = Array.isArray, x = qm.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Jt = m.rendererVersion, Zt = m.rendererPackageName, jo = m.extraDevToolsConfig, ot = m.getPublicInstance, Zr = m.getRootHostContext, Dn = m.getChildHostContext, Ws = m.prepareForCommit, pa = m.resetAfterCommit, Fc = m.createInstance;
|
|
12731
13099
|
m.cloneMutableInstance;
|
|
12732
13100
|
var bn = m.appendInitialChild, Ue = m.finalizeInitialChildren, ue = m.shouldSetTextContent, Do = m.createTextInstance;
|
|
12733
13101
|
m.cloneMutableTextInstance;
|
|
@@ -13695,15 +14063,6 @@ function n0() {
|
|
|
13695
14063
|
var t0 = n0();
|
|
13696
14064
|
const r0 = Xb(t0);
|
|
13697
14065
|
|
|
13698
|
-
/**
|
|
13699
|
-
* @license React
|
|
13700
|
-
* react-reconciler-constants.production.js
|
|
13701
|
-
*
|
|
13702
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13703
|
-
*
|
|
13704
|
-
* This source code is licensed under the MIT license found in the
|
|
13705
|
-
* LICENSE file in the root directory of this source tree.
|
|
13706
|
-
*/
|
|
13707
14066
|
const t = 1, o = 8, r = 32, e = 2;
|
|
13708
14067
|
|
|
13709
14068
|
function createReconciler(config) {
|
|
@@ -13712,7 +14071,8 @@ function createReconciler(config) {
|
|
|
13712
14071
|
return reconciler2;
|
|
13713
14072
|
}
|
|
13714
14073
|
const NoEventPriority = 0;
|
|
13715
|
-
const
|
|
14074
|
+
const R3F_CATALOGUE = Symbol.for("@react-three/fiber.catalogue");
|
|
14075
|
+
const catalogue = globalThis[R3F_CATALOGUE] ?? (globalThis[R3F_CATALOGUE] = {});
|
|
13716
14076
|
const PREFIX_REGEX = /^three(?=[A-Z])/;
|
|
13717
14077
|
const toPascalCase = (type) => `${type[0].toUpperCase()}${type.slice(1)}`;
|
|
13718
14078
|
let i = 0;
|
|
@@ -13729,10 +14089,11 @@ function extend(objects) {
|
|
|
13729
14089
|
function validateInstance(type, props) {
|
|
13730
14090
|
const name = toPascalCase(type);
|
|
13731
14091
|
const target = catalogue[name];
|
|
13732
|
-
if (type !== "primitive" && !target)
|
|
14092
|
+
if (type !== "primitive" && !target) {
|
|
13733
14093
|
throw new Error(
|
|
13734
14094
|
`R3F: ${name} is not part of the THREE namespace! Did you forget to extend? See: https://docs.pmnd.rs/react-three-fiber/api/objects#using-3rd-party-objects-declaratively`
|
|
13735
14095
|
);
|
|
14096
|
+
}
|
|
13736
14097
|
if (type === "primitive" && !props.object) throw new Error(`R3F: Primitives without 'object' are invalid!`);
|
|
13737
14098
|
if (props.args !== void 0 && !Array.isArray(props.args)) throw new Error("R3F: The args prop must be an array!");
|
|
13738
14099
|
}
|
|
@@ -14183,14 +14544,14 @@ function createRoot(canvas) {
|
|
|
14183
14544
|
if (!prevRoot) _roots.set(canvas, { fiber, store });
|
|
14184
14545
|
let onCreated;
|
|
14185
14546
|
let lastCamera;
|
|
14186
|
-
|
|
14547
|
+
const lastConfiguredProps = {};
|
|
14187
14548
|
let configured = false;
|
|
14188
14549
|
let pending = null;
|
|
14189
14550
|
return {
|
|
14190
14551
|
async configure(props = {}) {
|
|
14191
14552
|
let resolve;
|
|
14192
14553
|
pending = new Promise((_resolve) => resolve = _resolve);
|
|
14193
|
-
|
|
14554
|
+
const {
|
|
14194
14555
|
gl: glConfig,
|
|
14195
14556
|
renderer: rendererConfig,
|
|
14196
14557
|
size: propsSize,
|
|
@@ -14210,9 +14571,12 @@ function createRoot(canvas) {
|
|
|
14210
14571
|
camera: cameraOptions,
|
|
14211
14572
|
onPointerMissed,
|
|
14212
14573
|
onDragOverMissed,
|
|
14213
|
-
onDropMissed
|
|
14574
|
+
onDropMissed,
|
|
14575
|
+
autoUpdateFrustum = true,
|
|
14576
|
+
occlusion = false,
|
|
14577
|
+
_sizeProps
|
|
14214
14578
|
} = props;
|
|
14215
|
-
|
|
14579
|
+
const state = store.getState();
|
|
14216
14580
|
const defaultGPUProps = {
|
|
14217
14581
|
canvas
|
|
14218
14582
|
};
|
|
@@ -14227,7 +14591,9 @@ function createRoot(canvas) {
|
|
|
14227
14591
|
let renderer = state.internal.actualRenderer;
|
|
14228
14592
|
if (!state.internal.actualRenderer) {
|
|
14229
14593
|
renderer = await resolveRenderer(rendererConfig, defaultGPUProps, webgpu.WebGPURenderer);
|
|
14230
|
-
|
|
14594
|
+
if (!renderer.hasInitialized?.()) {
|
|
14595
|
+
await renderer.init();
|
|
14596
|
+
}
|
|
14231
14597
|
const backend = renderer.backend;
|
|
14232
14598
|
const isWebGPUBackend = backend && "isWebGPUBackend" in backend;
|
|
14233
14599
|
state.internal.actualRenderer = renderer;
|
|
@@ -14237,8 +14603,9 @@ function createRoot(canvas) {
|
|
|
14237
14603
|
if (!raycaster) state.set({ raycaster: raycaster = new webgpu.Raycaster() });
|
|
14238
14604
|
const { params, ...options } = raycastOptions || {};
|
|
14239
14605
|
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options });
|
|
14240
|
-
if (!is.equ(params, raycaster.params, shallowLoose))
|
|
14606
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) {
|
|
14241
14607
|
applyProps(raycaster, { params: { ...raycaster.params, ...params } });
|
|
14608
|
+
}
|
|
14242
14609
|
if (!state.camera || state.camera === lastCamera && !is.equ(lastCamera, cameraOptions, shallowLoose)) {
|
|
14243
14610
|
lastCamera = cameraOptions;
|
|
14244
14611
|
const isCamera = cameraOptions?.isCamera;
|
|
@@ -14275,6 +14642,8 @@ function createRoot(canvas) {
|
|
|
14275
14642
|
rootScene: scene,
|
|
14276
14643
|
internal: { ...prev.internal, container: scene }
|
|
14277
14644
|
}));
|
|
14645
|
+
const camera = state.camera;
|
|
14646
|
+
if (camera && !camera.parent) scene.add(camera);
|
|
14278
14647
|
}
|
|
14279
14648
|
if (events && !state.events.handlers) {
|
|
14280
14649
|
state.set({ events: events(store) });
|
|
@@ -14287,9 +14656,14 @@ function createRoot(canvas) {
|
|
|
14287
14656
|
wasEnabled = enabled;
|
|
14288
14657
|
});
|
|
14289
14658
|
}
|
|
14659
|
+
if (_sizeProps !== void 0) {
|
|
14660
|
+
state.set({ _sizeProps });
|
|
14661
|
+
}
|
|
14290
14662
|
const size = computeInitialSize(canvas, propsSize);
|
|
14291
|
-
if (!is.equ(size, state.size, shallowLoose)) {
|
|
14663
|
+
if (!state._sizeImperative && !is.equ(size, state.size, shallowLoose)) {
|
|
14664
|
+
const wasImperative = state._sizeImperative;
|
|
14292
14665
|
state.setSize(size.width, size.height, size.top, size.left);
|
|
14666
|
+
if (!wasImperative) state.set({ _sizeImperative: false });
|
|
14293
14667
|
}
|
|
14294
14668
|
if (dpr !== void 0 && !is.equ(dpr, lastConfiguredProps.dpr, shallowLoose)) {
|
|
14295
14669
|
state.setDpr(dpr);
|
|
@@ -14302,6 +14676,10 @@ function createRoot(canvas) {
|
|
|
14302
14676
|
if (!state.onPointerMissed) state.set({ onPointerMissed });
|
|
14303
14677
|
if (!state.onDragOverMissed) state.set({ onDragOverMissed });
|
|
14304
14678
|
if (!state.onDropMissed) state.set({ onDropMissed });
|
|
14679
|
+
if (state.autoUpdateFrustum !== autoUpdateFrustum) state.set({ autoUpdateFrustum });
|
|
14680
|
+
if (occlusion && !state.internal.occlusionEnabled) {
|
|
14681
|
+
enableOcclusion(store);
|
|
14682
|
+
}
|
|
14305
14683
|
if (performance && !is.equ(performance, lastConfiguredProps.performance, shallowLoose)) {
|
|
14306
14684
|
state.set((state2) => ({ performance: { ...state2.performance, ...performance } }));
|
|
14307
14685
|
lastConfiguredProps.performance = performance;
|
|
@@ -14355,15 +14733,17 @@ function createRoot(canvas) {
|
|
|
14355
14733
|
} else if (is.obj(shadows)) {
|
|
14356
14734
|
Object.assign(renderer.shadowMap, shadows);
|
|
14357
14735
|
}
|
|
14358
|
-
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type)
|
|
14736
|
+
if (oldEnabled !== renderer.shadowMap.enabled || oldType !== renderer.shadowMap.type) {
|
|
14359
14737
|
renderer.shadowMap.needsUpdate = true;
|
|
14738
|
+
}
|
|
14360
14739
|
}
|
|
14361
14740
|
if (textureColorSpace !== lastConfiguredProps.textureColorSpace) {
|
|
14362
14741
|
if (state.textureColorSpace !== textureColorSpace) state.set(() => ({ textureColorSpace }));
|
|
14363
14742
|
lastConfiguredProps.textureColorSpace = textureColorSpace;
|
|
14364
14743
|
}
|
|
14365
|
-
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose))
|
|
14744
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, renderer, shallowLoose)) {
|
|
14366
14745
|
applyProps(renderer, glConfig);
|
|
14746
|
+
}
|
|
14367
14747
|
if (rendererConfig && !is.fun(rendererConfig) && !isRenderer(rendererConfig) && state.renderer) {
|
|
14368
14748
|
const currentRenderer = state.renderer;
|
|
14369
14749
|
if (!is.equ(rendererConfig, currentRenderer, shallowLoose)) {
|
|
@@ -14374,7 +14754,37 @@ function createRoot(canvas) {
|
|
|
14374
14754
|
const rootId = state.internal.rootId;
|
|
14375
14755
|
if (!rootId) {
|
|
14376
14756
|
const newRootId = scheduler.generateRootId();
|
|
14377
|
-
const unregisterRoot = scheduler.registerRoot(newRootId,
|
|
14757
|
+
const unregisterRoot = scheduler.registerRoot(newRootId, {
|
|
14758
|
+
getState: () => store.getState(),
|
|
14759
|
+
onError: (err) => store.getState().setError(err)
|
|
14760
|
+
});
|
|
14761
|
+
const unregisterFrustum = scheduler.register(
|
|
14762
|
+
() => {
|
|
14763
|
+
const state2 = store.getState();
|
|
14764
|
+
if (state2.autoUpdateFrustum && state2.camera) {
|
|
14765
|
+
updateFrustum(state2.camera, state2.frustum);
|
|
14766
|
+
}
|
|
14767
|
+
},
|
|
14768
|
+
{
|
|
14769
|
+
id: `${newRootId}_frustum`,
|
|
14770
|
+
rootId: newRootId,
|
|
14771
|
+
phase: "preRender",
|
|
14772
|
+
system: true
|
|
14773
|
+
}
|
|
14774
|
+
);
|
|
14775
|
+
const unregisterVisibility = scheduler.register(
|
|
14776
|
+
() => {
|
|
14777
|
+
const state2 = store.getState();
|
|
14778
|
+
checkVisibility(state2);
|
|
14779
|
+
},
|
|
14780
|
+
{
|
|
14781
|
+
id: `${newRootId}_visibility`,
|
|
14782
|
+
rootId: newRootId,
|
|
14783
|
+
phase: "preRender",
|
|
14784
|
+
system: true,
|
|
14785
|
+
after: `${newRootId}_frustum`
|
|
14786
|
+
}
|
|
14787
|
+
);
|
|
14378
14788
|
const unregisterRender = scheduler.register(
|
|
14379
14789
|
() => {
|
|
14380
14790
|
const state2 = store.getState();
|
|
@@ -14402,6 +14812,8 @@ function createRoot(canvas) {
|
|
|
14402
14812
|
rootId: newRootId,
|
|
14403
14813
|
unregisterRoot: () => {
|
|
14404
14814
|
unregisterRoot();
|
|
14815
|
+
unregisterFrustum();
|
|
14816
|
+
unregisterVisibility();
|
|
14405
14817
|
unregisterRender();
|
|
14406
14818
|
},
|
|
14407
14819
|
scheduler
|
|
@@ -14459,6 +14871,7 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
14459
14871
|
const unregisterRoot = state.internal.unregisterRoot;
|
|
14460
14872
|
if (unregisterRoot) unregisterRoot();
|
|
14461
14873
|
state.events.disconnect?.();
|
|
14874
|
+
cleanupHelperGroup(root.store);
|
|
14462
14875
|
renderer?.renderLists?.dispose?.();
|
|
14463
14876
|
renderer?.forceContextLoss?.();
|
|
14464
14877
|
if (renderer?.xr) state.xr.disconnect();
|
|
@@ -14598,6 +15011,9 @@ function CanvasImpl({
|
|
|
14598
15011
|
onDragOverMissed,
|
|
14599
15012
|
onDropMissed,
|
|
14600
15013
|
onCreated,
|
|
15014
|
+
hmr,
|
|
15015
|
+
width,
|
|
15016
|
+
height,
|
|
14601
15017
|
...props
|
|
14602
15018
|
}) {
|
|
14603
15019
|
React__namespace.useMemo(() => extend(THREE), []);
|
|
@@ -14618,7 +15034,16 @@ function CanvasImpl({
|
|
|
14618
15034
|
};
|
|
14619
15035
|
}, [resize, hasInitialSizeRef.current]);
|
|
14620
15036
|
const [containerRef, containerRect] = useMeasure__default(measureConfig);
|
|
14621
|
-
|
|
15037
|
+
const effectiveSize = React__namespace.useMemo(
|
|
15038
|
+
() => ({
|
|
15039
|
+
width: width ?? containerRect.width,
|
|
15040
|
+
height: height ?? containerRect.height,
|
|
15041
|
+
top: containerRect.top,
|
|
15042
|
+
left: containerRect.left
|
|
15043
|
+
}),
|
|
15044
|
+
[width, height, containerRect]
|
|
15045
|
+
);
|
|
15046
|
+
if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
|
|
14622
15047
|
hasInitialSizeRef.current = true;
|
|
14623
15048
|
}
|
|
14624
15049
|
const canvasRef = React__namespace.useRef(null);
|
|
@@ -14637,8 +15062,23 @@ function CanvasImpl({
|
|
|
14637
15062
|
useIsomorphicLayoutEffect(() => {
|
|
14638
15063
|
effectActiveRef.current = true;
|
|
14639
15064
|
const canvas = canvasRef.current;
|
|
14640
|
-
if (
|
|
14641
|
-
if (!root.current)
|
|
15065
|
+
if (effectiveSize.width > 0 && effectiveSize.height > 0 && canvas) {
|
|
15066
|
+
if (!root.current) {
|
|
15067
|
+
root.current = createRoot(canvas);
|
|
15068
|
+
notifyAlpha({
|
|
15069
|
+
message: "React Three Fiber v10 is in ALPHA - expect breaking changes",
|
|
15070
|
+
link: "https://github.com/pmndrs/react-three-fiber/discussions"
|
|
15071
|
+
});
|
|
15072
|
+
const rootEntry = _roots.get(canvas);
|
|
15073
|
+
if (rootEntry?.store) {
|
|
15074
|
+
if (unsubscribeErrorRef.current) unsubscribeErrorRef.current();
|
|
15075
|
+
unsubscribeErrorRef.current = rootEntry.store.subscribe((state) => {
|
|
15076
|
+
if (state.error && effectActiveRef.current) {
|
|
15077
|
+
setError(state.error);
|
|
15078
|
+
}
|
|
15079
|
+
});
|
|
15080
|
+
}
|
|
15081
|
+
}
|
|
14642
15082
|
async function run() {
|
|
14643
15083
|
if (!effectActiveRef.current || !root.current) return;
|
|
14644
15084
|
await root.current.configure({
|
|
@@ -14656,7 +15096,9 @@ function CanvasImpl({
|
|
|
14656
15096
|
performance,
|
|
14657
15097
|
raycaster,
|
|
14658
15098
|
camera,
|
|
14659
|
-
size:
|
|
15099
|
+
size: effectiveSize,
|
|
15100
|
+
// Store size props for reset functionality
|
|
15101
|
+
_sizeProps: width !== void 0 || height !== void 0 ? { width, height } : null,
|
|
14660
15102
|
// Pass mutable reference to onPointerMissed so it's free to update
|
|
14661
15103
|
onPointerMissed: (...args) => handlePointerMissed.current?.(...args),
|
|
14662
15104
|
onDragOverMissed: (...args) => handleDragOverMissed.current?.(...args),
|
|
@@ -14679,15 +15121,9 @@ function CanvasImpl({
|
|
|
14679
15121
|
}
|
|
14680
15122
|
});
|
|
14681
15123
|
if (!effectActiveRef.current || !root.current) return;
|
|
14682
|
-
|
|
15124
|
+
root.current.render(
|
|
14683
15125
|
/* @__PURE__ */ jsxRuntime.jsx(Bridge, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { set: setError, children: /* @__PURE__ */ jsxRuntime.jsx(React__namespace.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(Block, { set: setBlock }), children: children ?? null }) }) })
|
|
14684
15126
|
);
|
|
14685
|
-
if (unsubscribeErrorRef.current) unsubscribeErrorRef.current();
|
|
14686
|
-
unsubscribeErrorRef.current = store.subscribe((state) => {
|
|
14687
|
-
if (state.error && effectActiveRef.current) {
|
|
14688
|
-
setError(state.error);
|
|
14689
|
-
}
|
|
14690
|
-
});
|
|
14691
15127
|
}
|
|
14692
15128
|
run();
|
|
14693
15129
|
}
|
|
@@ -14708,6 +15144,33 @@ function CanvasImpl({
|
|
|
14708
15144
|
};
|
|
14709
15145
|
}
|
|
14710
15146
|
}, []);
|
|
15147
|
+
React__namespace.useEffect(() => {
|
|
15148
|
+
if (hmr === false) return;
|
|
15149
|
+
const canvas = canvasRef.current;
|
|
15150
|
+
if (!canvas) return;
|
|
15151
|
+
const handleHMR = () => {
|
|
15152
|
+
const rootEntry = _roots.get(canvas);
|
|
15153
|
+
if (rootEntry?.store) {
|
|
15154
|
+
rootEntry.store.setState((state) => ({
|
|
15155
|
+
nodes: {},
|
|
15156
|
+
uniforms: {},
|
|
15157
|
+
_hmrVersion: state._hmrVersion + 1
|
|
15158
|
+
}));
|
|
15159
|
+
}
|
|
15160
|
+
};
|
|
15161
|
+
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== "undefined" && undefined) {
|
|
15162
|
+
const hot = undefined;
|
|
15163
|
+
hot.on("vite:afterUpdate", handleHMR);
|
|
15164
|
+
return () => hot.dispose?.(() => {
|
|
15165
|
+
});
|
|
15166
|
+
}
|
|
15167
|
+
if (typeof module !== "undefined" && module.hot) {
|
|
15168
|
+
const hot = module.hot;
|
|
15169
|
+
hot.addStatusHandler((status) => {
|
|
15170
|
+
if (status === "idle") handleHMR();
|
|
15171
|
+
});
|
|
15172
|
+
}
|
|
15173
|
+
}, [hmr]);
|
|
14711
15174
|
const pointerEvents = eventSource ? "none" : "auto";
|
|
14712
15175
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
14713
15176
|
"div",
|
|
@@ -14730,6 +15193,72 @@ function Canvas(props) {
|
|
|
14730
15193
|
return /* @__PURE__ */ jsxRuntime.jsx(itsFine.FiberProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(CanvasImpl, { ...props }) });
|
|
14731
15194
|
}
|
|
14732
15195
|
|
|
15196
|
+
var __defProp = Object.defineProperty;
|
|
15197
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
15198
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
15199
|
+
var _a;
|
|
15200
|
+
const INTERNAL_DATA = Symbol("ScopedStore.data");
|
|
15201
|
+
_a = INTERNAL_DATA;
|
|
15202
|
+
const _ScopedStore = class _ScopedStore {
|
|
15203
|
+
constructor(data) {
|
|
15204
|
+
__publicField(this, _a);
|
|
15205
|
+
this[INTERNAL_DATA] = data;
|
|
15206
|
+
return new Proxy(this, {
|
|
15207
|
+
get(target, prop, receiver) {
|
|
15208
|
+
if (typeof prop === "string") {
|
|
15209
|
+
if (prop === "scope" || prop === "has" || prop === "keys") {
|
|
15210
|
+
return Reflect.get(target, prop, receiver);
|
|
15211
|
+
}
|
|
15212
|
+
return target[INTERNAL_DATA][prop];
|
|
15213
|
+
}
|
|
15214
|
+
return Reflect.get(target, prop, receiver);
|
|
15215
|
+
},
|
|
15216
|
+
has(target, prop) {
|
|
15217
|
+
return typeof prop === "string" ? prop in target[INTERNAL_DATA] : Reflect.has(target, prop);
|
|
15218
|
+
},
|
|
15219
|
+
ownKeys(target) {
|
|
15220
|
+
return Reflect.ownKeys(target[INTERNAL_DATA]);
|
|
15221
|
+
},
|
|
15222
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
15223
|
+
if (typeof prop === "string" && prop in target[INTERNAL_DATA]) {
|
|
15224
|
+
return {
|
|
15225
|
+
configurable: true,
|
|
15226
|
+
enumerable: true,
|
|
15227
|
+
value: target[INTERNAL_DATA][prop]
|
|
15228
|
+
};
|
|
15229
|
+
}
|
|
15230
|
+
return void 0;
|
|
15231
|
+
}
|
|
15232
|
+
});
|
|
15233
|
+
}
|
|
15234
|
+
/**
|
|
15235
|
+
* Access a nested scope by key.
|
|
15236
|
+
* If the key doesn't exist or isn't a scope object, returns an empty ScopedStore.
|
|
15237
|
+
*/
|
|
15238
|
+
scope(key) {
|
|
15239
|
+
const data = this[INTERNAL_DATA][key];
|
|
15240
|
+
return new _ScopedStore(
|
|
15241
|
+
data && typeof data === "object" ? data : {}
|
|
15242
|
+
);
|
|
15243
|
+
}
|
|
15244
|
+
/**
|
|
15245
|
+
* Check if a key exists in the store.
|
|
15246
|
+
*/
|
|
15247
|
+
has(key) {
|
|
15248
|
+
return key in this[INTERNAL_DATA];
|
|
15249
|
+
}
|
|
15250
|
+
/**
|
|
15251
|
+
* Get all keys in the store.
|
|
15252
|
+
*/
|
|
15253
|
+
keys() {
|
|
15254
|
+
return Object.keys(this[INTERNAL_DATA]);
|
|
15255
|
+
}
|
|
15256
|
+
};
|
|
15257
|
+
let ScopedStore = _ScopedStore;
|
|
15258
|
+
function createScopedStore(data) {
|
|
15259
|
+
return new ScopedStore(data);
|
|
15260
|
+
}
|
|
15261
|
+
|
|
14733
15262
|
function addTexture(set, key, value) {
|
|
14734
15263
|
set((state) => {
|
|
14735
15264
|
const newMap = new Map(state.textures);
|
|
@@ -14808,21 +15337,87 @@ function useCompareMemoize(value, deep) {
|
|
|
14808
15337
|
const isUniformNode$1 = (value) => value !== null && typeof value === "object" && "value" in value && "uuid" in value;
|
|
14809
15338
|
function useUniforms(creatorOrScope, scope) {
|
|
14810
15339
|
const store = useStore();
|
|
15340
|
+
const removeUniforms2 = React.useCallback(
|
|
15341
|
+
(names, targetScope) => {
|
|
15342
|
+
const nameArray = Array.isArray(names) ? names : [names];
|
|
15343
|
+
store.setState((state) => {
|
|
15344
|
+
if (targetScope) {
|
|
15345
|
+
const currentScope = { ...state.uniforms[targetScope] };
|
|
15346
|
+
for (const name of nameArray) delete currentScope[name];
|
|
15347
|
+
return { uniforms: { ...state.uniforms, [targetScope]: currentScope } };
|
|
15348
|
+
}
|
|
15349
|
+
const uniforms2 = { ...state.uniforms };
|
|
15350
|
+
for (const name of nameArray) if (isUniformNode$1(uniforms2[name])) delete uniforms2[name];
|
|
15351
|
+
return { uniforms: uniforms2 };
|
|
15352
|
+
});
|
|
15353
|
+
},
|
|
15354
|
+
[store]
|
|
15355
|
+
);
|
|
15356
|
+
const clearUniforms = React.useCallback(
|
|
15357
|
+
(targetScope) => {
|
|
15358
|
+
store.setState((state) => {
|
|
15359
|
+
if (targetScope && targetScope !== "root") {
|
|
15360
|
+
const { [targetScope]: _, ...rest } = state.uniforms;
|
|
15361
|
+
return { uniforms: rest };
|
|
15362
|
+
}
|
|
15363
|
+
if (targetScope === "root") {
|
|
15364
|
+
const uniforms2 = {};
|
|
15365
|
+
for (const [key, value] of Object.entries(state.uniforms)) {
|
|
15366
|
+
if (!isUniformNode$1(value)) uniforms2[key] = value;
|
|
15367
|
+
}
|
|
15368
|
+
return { uniforms: uniforms2 };
|
|
15369
|
+
}
|
|
15370
|
+
return { uniforms: {} };
|
|
15371
|
+
});
|
|
15372
|
+
},
|
|
15373
|
+
[store]
|
|
15374
|
+
);
|
|
15375
|
+
const rebuildUniforms = React.useCallback(
|
|
15376
|
+
(targetScope) => {
|
|
15377
|
+
store.setState((state) => {
|
|
15378
|
+
let newUniforms = state.uniforms;
|
|
15379
|
+
if (targetScope && targetScope !== "root") {
|
|
15380
|
+
const { [targetScope]: _, ...rest } = state.uniforms;
|
|
15381
|
+
newUniforms = rest;
|
|
15382
|
+
} else if (targetScope === "root") {
|
|
15383
|
+
newUniforms = {};
|
|
15384
|
+
for (const [key, value] of Object.entries(state.uniforms)) {
|
|
15385
|
+
if (!isUniformNode$1(value)) newUniforms[key] = value;
|
|
15386
|
+
}
|
|
15387
|
+
} else {
|
|
15388
|
+
newUniforms = {};
|
|
15389
|
+
}
|
|
15390
|
+
return { uniforms: newUniforms, _hmrVersion: state._hmrVersion + 1 };
|
|
15391
|
+
});
|
|
15392
|
+
},
|
|
15393
|
+
[store]
|
|
15394
|
+
);
|
|
14811
15395
|
const inputForMemoization = React.useMemo(() => {
|
|
14812
|
-
|
|
15396
|
+
if (is.fun(creatorOrScope)) {
|
|
15397
|
+
const state = store.getState();
|
|
15398
|
+
const wrappedState = {
|
|
15399
|
+
...state,
|
|
15400
|
+
uniforms: createScopedStore(state.uniforms),
|
|
15401
|
+
nodes: createScopedStore(state.nodes)
|
|
15402
|
+
};
|
|
15403
|
+
return creatorOrScope(wrappedState);
|
|
15404
|
+
}
|
|
15405
|
+
return creatorOrScope;
|
|
14813
15406
|
}, [creatorOrScope, store]);
|
|
14814
15407
|
const memoizedInput = useCompareMemoize(inputForMemoization);
|
|
14815
|
-
|
|
14816
|
-
|
|
14817
|
-
|
|
15408
|
+
const isReader = memoizedInput === void 0 || typeof memoizedInput === "string";
|
|
15409
|
+
const storeUniforms = useThree((s) => s.uniforms);
|
|
15410
|
+
const uniforms = React.useMemo(() => {
|
|
14818
15411
|
if (memoizedInput === void 0) {
|
|
14819
|
-
return
|
|
15412
|
+
return storeUniforms;
|
|
14820
15413
|
}
|
|
14821
15414
|
if (typeof memoizedInput === "string") {
|
|
14822
|
-
const scopeData =
|
|
15415
|
+
const scopeData = storeUniforms[memoizedInput];
|
|
14823
15416
|
if (scopeData && !isUniformNode$1(scopeData)) return scopeData;
|
|
14824
15417
|
return {};
|
|
14825
15418
|
}
|
|
15419
|
+
const state = store.getState();
|
|
15420
|
+
const set = store.setState;
|
|
14826
15421
|
if (typeof memoizedInput !== "object" || memoizedInput === null) {
|
|
14827
15422
|
throw new Error("Invalid uniform input");
|
|
14828
15423
|
}
|
|
@@ -14858,44 +15453,49 @@ function useUniforms(creatorOrScope, scope) {
|
|
|
14858
15453
|
set((s) => ({
|
|
14859
15454
|
uniforms: {
|
|
14860
15455
|
...s.uniforms,
|
|
14861
|
-
[scope]: {
|
|
14862
|
-
...s.uniforms[scope],
|
|
14863
|
-
...result
|
|
14864
|
-
}
|
|
15456
|
+
[scope]: { ...s.uniforms[scope], ...result }
|
|
14865
15457
|
}
|
|
14866
15458
|
}));
|
|
14867
15459
|
} else {
|
|
14868
|
-
set((s) => ({
|
|
14869
|
-
uniforms: {
|
|
14870
|
-
...s.uniforms,
|
|
14871
|
-
...result
|
|
14872
|
-
}
|
|
14873
|
-
}));
|
|
15460
|
+
set((s) => ({ uniforms: { ...s.uniforms, ...result } }));
|
|
14874
15461
|
}
|
|
14875
15462
|
}
|
|
14876
15463
|
return result;
|
|
14877
|
-
}, [
|
|
15464
|
+
}, [
|
|
15465
|
+
store,
|
|
15466
|
+
memoizedInput,
|
|
15467
|
+
scope,
|
|
15468
|
+
// Only include storeUniforms in deps for reader modes to enable reactivity
|
|
15469
|
+
isReader ? storeUniforms : null
|
|
15470
|
+
]);
|
|
15471
|
+
return { ...uniforms, removeUniforms: removeUniforms2, clearUniforms, rebuildUniforms };
|
|
15472
|
+
}
|
|
15473
|
+
function rebuildAllUniforms(store, scope) {
|
|
15474
|
+
store.setState((state) => {
|
|
15475
|
+
let newUniforms = state.uniforms;
|
|
15476
|
+
if (scope && scope !== "root") {
|
|
15477
|
+
const { [scope]: _, ...rest } = state.uniforms;
|
|
15478
|
+
newUniforms = rest;
|
|
15479
|
+
} else if (scope === "root") {
|
|
15480
|
+
newUniforms = {};
|
|
15481
|
+
for (const [key, value] of Object.entries(state.uniforms)) {
|
|
15482
|
+
if (!isUniformNode$1(value)) newUniforms[key] = value;
|
|
15483
|
+
}
|
|
15484
|
+
} else {
|
|
15485
|
+
newUniforms = {};
|
|
15486
|
+
}
|
|
15487
|
+
return { uniforms: newUniforms, _hmrVersion: state._hmrVersion + 1 };
|
|
15488
|
+
});
|
|
14878
15489
|
}
|
|
14879
15490
|
function removeUniforms(set, names, scope) {
|
|
14880
15491
|
set((state) => {
|
|
14881
15492
|
if (scope) {
|
|
14882
15493
|
const currentScope = { ...state.uniforms[scope] };
|
|
14883
|
-
for (const name of names)
|
|
14884
|
-
|
|
14885
|
-
}
|
|
14886
|
-
return {
|
|
14887
|
-
uniforms: {
|
|
14888
|
-
...state.uniforms,
|
|
14889
|
-
[scope]: currentScope
|
|
14890
|
-
}
|
|
14891
|
-
};
|
|
15494
|
+
for (const name of names) delete currentScope[name];
|
|
15495
|
+
return { uniforms: { ...state.uniforms, [scope]: currentScope } };
|
|
14892
15496
|
}
|
|
14893
15497
|
const uniforms = { ...state.uniforms };
|
|
14894
|
-
for (const name of names)
|
|
14895
|
-
if (isUniformNode$1(uniforms[name])) {
|
|
14896
|
-
delete uniforms[name];
|
|
14897
|
-
}
|
|
14898
|
-
}
|
|
15498
|
+
for (const name of names) if (isUniformNode$1(uniforms[name])) delete uniforms[name];
|
|
14899
15499
|
return { uniforms };
|
|
14900
15500
|
});
|
|
14901
15501
|
}
|
|
@@ -14909,9 +15509,7 @@ function clearRootUniforms(set) {
|
|
|
14909
15509
|
set((state) => {
|
|
14910
15510
|
const uniforms = {};
|
|
14911
15511
|
for (const [key, value] of Object.entries(state.uniforms)) {
|
|
14912
|
-
if (!isUniformNode$1(value))
|
|
14913
|
-
uniforms[key] = value;
|
|
14914
|
-
}
|
|
15512
|
+
if (!isUniformNode$1(value)) uniforms[key] = value;
|
|
14915
15513
|
}
|
|
14916
15514
|
return { uniforms };
|
|
14917
15515
|
});
|
|
@@ -14986,21 +15584,82 @@ function useUniform(name, value) {
|
|
|
14986
15584
|
const isTSLNode = (value) => value !== null && typeof value === "object" && ("uuid" in value || "nodeType" in value);
|
|
14987
15585
|
function useNodes(creatorOrScope, scope) {
|
|
14988
15586
|
const store = useStore();
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
|
|
15587
|
+
const removeNodes2 = React.useCallback(
|
|
15588
|
+
(names, targetScope) => {
|
|
15589
|
+
const nameArray = Array.isArray(names) ? names : [names];
|
|
15590
|
+
store.setState((state) => {
|
|
15591
|
+
if (targetScope) {
|
|
15592
|
+
const currentScope = { ...state.nodes[targetScope] };
|
|
15593
|
+
for (const name of nameArray) delete currentScope[name];
|
|
15594
|
+
return { nodes: { ...state.nodes, [targetScope]: currentScope } };
|
|
15595
|
+
}
|
|
15596
|
+
const nodes2 = { ...state.nodes };
|
|
15597
|
+
for (const name of nameArray) if (isTSLNode(nodes2[name])) delete nodes2[name];
|
|
15598
|
+
return { nodes: nodes2 };
|
|
15599
|
+
});
|
|
15600
|
+
},
|
|
15601
|
+
[store]
|
|
15602
|
+
);
|
|
15603
|
+
const clearNodes = React.useCallback(
|
|
15604
|
+
(targetScope) => {
|
|
15605
|
+
store.setState((state) => {
|
|
15606
|
+
if (targetScope && targetScope !== "root") {
|
|
15607
|
+
const { [targetScope]: _, ...rest } = state.nodes;
|
|
15608
|
+
return { nodes: rest };
|
|
15609
|
+
}
|
|
15610
|
+
if (targetScope === "root") {
|
|
15611
|
+
const nodes2 = {};
|
|
15612
|
+
for (const [key, value] of Object.entries(state.nodes)) {
|
|
15613
|
+
if (!isTSLNode(value)) nodes2[key] = value;
|
|
15614
|
+
}
|
|
15615
|
+
return { nodes: nodes2 };
|
|
15616
|
+
}
|
|
15617
|
+
return { nodes: {} };
|
|
15618
|
+
});
|
|
15619
|
+
},
|
|
15620
|
+
[store]
|
|
15621
|
+
);
|
|
15622
|
+
const rebuildNodes = React.useCallback(
|
|
15623
|
+
(targetScope) => {
|
|
15624
|
+
store.setState((state) => {
|
|
15625
|
+
let newNodes = state.nodes;
|
|
15626
|
+
if (targetScope && targetScope !== "root") {
|
|
15627
|
+
const { [targetScope]: _, ...rest } = state.nodes;
|
|
15628
|
+
newNodes = rest;
|
|
15629
|
+
} else if (targetScope === "root") {
|
|
15630
|
+
newNodes = {};
|
|
15631
|
+
for (const [key, value] of Object.entries(state.nodes)) {
|
|
15632
|
+
if (!isTSLNode(value)) newNodes[key] = value;
|
|
15633
|
+
}
|
|
15634
|
+
} else {
|
|
15635
|
+
newNodes = {};
|
|
15636
|
+
}
|
|
15637
|
+
return { nodes: newNodes, _hmrVersion: state._hmrVersion + 1 };
|
|
15638
|
+
});
|
|
15639
|
+
},
|
|
15640
|
+
[store]
|
|
15641
|
+
);
|
|
15642
|
+
const isReader = creatorOrScope === void 0 || typeof creatorOrScope === "string";
|
|
15643
|
+
const storeNodes = useThree((s) => s.nodes);
|
|
15644
|
+
const hmrVersion = useThree((s) => s._hmrVersion);
|
|
15645
|
+
const nodes = React.useMemo(() => {
|
|
14992
15646
|
if (creatorOrScope === void 0) {
|
|
14993
|
-
return
|
|
15647
|
+
return storeNodes;
|
|
14994
15648
|
}
|
|
14995
15649
|
if (typeof creatorOrScope === "string") {
|
|
14996
|
-
const scopeData =
|
|
14997
|
-
if (scopeData && !isTSLNode(scopeData))
|
|
14998
|
-
return scopeData;
|
|
14999
|
-
}
|
|
15650
|
+
const scopeData = storeNodes[creatorOrScope];
|
|
15651
|
+
if (scopeData && !isTSLNode(scopeData)) return scopeData;
|
|
15000
15652
|
return {};
|
|
15001
15653
|
}
|
|
15654
|
+
const state = store.getState();
|
|
15655
|
+
const set = store.setState;
|
|
15002
15656
|
const creator = creatorOrScope;
|
|
15003
|
-
const
|
|
15657
|
+
const wrappedState = {
|
|
15658
|
+
...state,
|
|
15659
|
+
uniforms: createScopedStore(state.uniforms),
|
|
15660
|
+
nodes: createScopedStore(state.nodes)
|
|
15661
|
+
};
|
|
15662
|
+
const created = creator(wrappedState);
|
|
15004
15663
|
const result = {};
|
|
15005
15664
|
let hasNewNodes = false;
|
|
15006
15665
|
if (scope) {
|
|
@@ -15009,9 +15668,7 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15009
15668
|
if (currentScope[name]) {
|
|
15010
15669
|
result[name] = currentScope[name];
|
|
15011
15670
|
} else {
|
|
15012
|
-
if (typeof node.label === "function") {
|
|
15013
|
-
node.setName(`${scope}.${name}`);
|
|
15014
|
-
}
|
|
15671
|
+
if (typeof node.label === "function") node.setName(`${scope}.${name}`);
|
|
15015
15672
|
result[name] = node;
|
|
15016
15673
|
hasNewNodes = true;
|
|
15017
15674
|
}
|
|
@@ -15020,10 +15677,7 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15020
15677
|
set((s) => ({
|
|
15021
15678
|
nodes: {
|
|
15022
15679
|
...s.nodes,
|
|
15023
|
-
[scope]: {
|
|
15024
|
-
...s.nodes[scope],
|
|
15025
|
-
...result
|
|
15026
|
-
}
|
|
15680
|
+
[scope]: { ...s.nodes[scope], ...result }
|
|
15027
15681
|
}
|
|
15028
15682
|
}));
|
|
15029
15683
|
}
|
|
@@ -15034,44 +15688,52 @@ function useNodes(creatorOrScope, scope) {
|
|
|
15034
15688
|
if (existing && isTSLNode(existing)) {
|
|
15035
15689
|
result[name] = existing;
|
|
15036
15690
|
} else {
|
|
15037
|
-
if (typeof node.label === "function")
|
|
15038
|
-
node.setName(name);
|
|
15039
|
-
}
|
|
15691
|
+
if (typeof node.label === "function") node.setName(name);
|
|
15040
15692
|
result[name] = node;
|
|
15041
15693
|
hasNewNodes = true;
|
|
15042
15694
|
}
|
|
15043
15695
|
}
|
|
15044
15696
|
if (hasNewNodes) {
|
|
15045
|
-
set((s) => ({
|
|
15046
|
-
nodes: {
|
|
15047
|
-
...s.nodes,
|
|
15048
|
-
...result
|
|
15049
|
-
}
|
|
15050
|
-
}));
|
|
15697
|
+
set((s) => ({ nodes: { ...s.nodes, ...result } }));
|
|
15051
15698
|
}
|
|
15052
15699
|
return result;
|
|
15053
|
-
}, [
|
|
15700
|
+
}, [
|
|
15701
|
+
store,
|
|
15702
|
+
typeof creatorOrScope === "string" ? creatorOrScope : scope,
|
|
15703
|
+
// Only include storeNodes in deps for reader modes to enable reactivity
|
|
15704
|
+
// Creator mode intentionally excludes it to avoid re-running creator on unrelated changes
|
|
15705
|
+
isReader ? storeNodes : null,
|
|
15706
|
+
// Include hmrVersion for creator modes to allow rebuildNodes() to bust the cache
|
|
15707
|
+
isReader ? null : hmrVersion
|
|
15708
|
+
]);
|
|
15709
|
+
return { ...nodes, removeNodes: removeNodes2, clearNodes, rebuildNodes };
|
|
15710
|
+
}
|
|
15711
|
+
function rebuildAllNodes(store, scope) {
|
|
15712
|
+
store.setState((state) => {
|
|
15713
|
+
let newNodes = state.nodes;
|
|
15714
|
+
if (scope && scope !== "root") {
|
|
15715
|
+
const { [scope]: _, ...rest } = state.nodes;
|
|
15716
|
+
newNodes = rest;
|
|
15717
|
+
} else if (scope === "root") {
|
|
15718
|
+
newNodes = {};
|
|
15719
|
+
for (const [key, value] of Object.entries(state.nodes)) {
|
|
15720
|
+
if (!isTSLNode(value)) newNodes[key] = value;
|
|
15721
|
+
}
|
|
15722
|
+
} else {
|
|
15723
|
+
newNodes = {};
|
|
15724
|
+
}
|
|
15725
|
+
return { nodes: newNodes, _hmrVersion: state._hmrVersion + 1 };
|
|
15726
|
+
});
|
|
15054
15727
|
}
|
|
15055
15728
|
function removeNodes(set, names, scope) {
|
|
15056
15729
|
set((state) => {
|
|
15057
15730
|
if (scope) {
|
|
15058
15731
|
const currentScope = { ...state.nodes[scope] };
|
|
15059
|
-
for (const name of names)
|
|
15060
|
-
|
|
15061
|
-
}
|
|
15062
|
-
return {
|
|
15063
|
-
nodes: {
|
|
15064
|
-
...state.nodes,
|
|
15065
|
-
[scope]: currentScope
|
|
15066
|
-
}
|
|
15067
|
-
};
|
|
15732
|
+
for (const name of names) delete currentScope[name];
|
|
15733
|
+
return { nodes: { ...state.nodes, [scope]: currentScope } };
|
|
15068
15734
|
}
|
|
15069
15735
|
const nodes = { ...state.nodes };
|
|
15070
|
-
for (const name of names)
|
|
15071
|
-
if (isTSLNode(nodes[name])) {
|
|
15072
|
-
delete nodes[name];
|
|
15073
|
-
}
|
|
15074
|
-
}
|
|
15736
|
+
for (const name of names) if (isTSLNode(nodes[name])) delete nodes[name];
|
|
15075
15737
|
return { nodes };
|
|
15076
15738
|
});
|
|
15077
15739
|
}
|
|
@@ -15085,9 +15747,7 @@ function clearRootNodes(set) {
|
|
|
15085
15747
|
set((state) => {
|
|
15086
15748
|
const nodes = {};
|
|
15087
15749
|
for (const [key, value] of Object.entries(state.nodes)) {
|
|
15088
|
-
if (!isTSLNode(value))
|
|
15089
|
-
nodes[key] = value;
|
|
15090
|
-
}
|
|
15750
|
+
if (!isTSLNode(value)) nodes[key] = value;
|
|
15091
15751
|
}
|
|
15092
15752
|
return { nodes };
|
|
15093
15753
|
});
|
|
@@ -15099,7 +15759,12 @@ function useLocalNodes(creator) {
|
|
|
15099
15759
|
const textures = useThree((s) => s.textures);
|
|
15100
15760
|
return React.useMemo(() => {
|
|
15101
15761
|
const state = store.getState();
|
|
15102
|
-
|
|
15762
|
+
const wrappedState = {
|
|
15763
|
+
...state,
|
|
15764
|
+
uniforms: createScopedStore(state.uniforms),
|
|
15765
|
+
nodes: createScopedStore(state.nodes)
|
|
15766
|
+
};
|
|
15767
|
+
return creator(wrappedState);
|
|
15103
15768
|
}, [store, creator, uniforms, nodes, textures]);
|
|
15104
15769
|
}
|
|
15105
15770
|
|
|
@@ -15113,6 +15778,10 @@ function usePostProcessing(mainCB, setupCB) {
|
|
|
15113
15778
|
mainCBRef.current = mainCB;
|
|
15114
15779
|
setupCBRef.current = setupCB;
|
|
15115
15780
|
const [rebuildVersion, setRebuildVersion] = React.useState(0);
|
|
15781
|
+
React.useEffect(() => {
|
|
15782
|
+
callbacksRanRef.current = false;
|
|
15783
|
+
scenePassCacheRef.current = null;
|
|
15784
|
+
}, []);
|
|
15116
15785
|
const clearPasses = React.useCallback(() => {
|
|
15117
15786
|
store.setState({ passes: {} });
|
|
15118
15787
|
}, [store]);
|
|
@@ -15223,6 +15892,7 @@ exports.createEvents = createEvents;
|
|
|
15223
15892
|
exports.createPointerEvents = createPointerEvents;
|
|
15224
15893
|
exports.createPortal = createPortal;
|
|
15225
15894
|
exports.createRoot = createRoot;
|
|
15895
|
+
exports.createScopedStore = createScopedStore;
|
|
15226
15896
|
exports.createStore = createStore;
|
|
15227
15897
|
exports.createTextureOperations = createTextureOperations;
|
|
15228
15898
|
exports.detach = detach;
|
|
@@ -15249,6 +15919,8 @@ exports.isRenderer = isRenderer;
|
|
|
15249
15919
|
exports.isTexture = isTexture;
|
|
15250
15920
|
exports.isVectorLike = isVectorLike;
|
|
15251
15921
|
exports.prepare = prepare;
|
|
15922
|
+
exports.rebuildAllNodes = rebuildAllNodes;
|
|
15923
|
+
exports.rebuildAllUniforms = rebuildAllUniforms;
|
|
15252
15924
|
exports.reconciler = reconciler;
|
|
15253
15925
|
exports.removeInteractivity = removeInteractivity;
|
|
15254
15926
|
exports.removeNodes = removeNodes;
|
|
@@ -15256,6 +15928,7 @@ exports.removeUniforms = removeUniforms;
|
|
|
15256
15928
|
exports.resolve = resolve;
|
|
15257
15929
|
exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
15258
15930
|
exports.updateCamera = updateCamera;
|
|
15931
|
+
exports.updateFrustum = updateFrustum;
|
|
15259
15932
|
exports.useBridge = useBridge;
|
|
15260
15933
|
exports.useFrame = useFrame;
|
|
15261
15934
|
exports.useGraph = useGraph;
|
|
@@ -15266,6 +15939,7 @@ exports.useLocalNodes = useLocalNodes;
|
|
|
15266
15939
|
exports.useMutableCallback = useMutableCallback;
|
|
15267
15940
|
exports.useNodes = useNodes;
|
|
15268
15941
|
exports.usePostProcessing = usePostProcessing;
|
|
15942
|
+
exports.useRenderTarget = useRenderTarget;
|
|
15269
15943
|
exports.useStore = useStore;
|
|
15270
15944
|
exports.useTexture = useTexture;
|
|
15271
15945
|
exports.useTextures = useTextures;
|