@react-three/fiber 8.0.0-beta.4 → 8.0.0-beta.7
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/declarations/src/core/events.d.ts +14 -9
- package/dist/declarations/src/core/hooks.d.ts +5 -1
- package/dist/declarations/src/core/index.d.ts +16 -8
- package/dist/declarations/src/core/renderer.d.ts +6 -15
- package/dist/declarations/src/core/store.d.ts +8 -19
- package/dist/declarations/src/core/utils.d.ts +2 -1
- package/dist/declarations/src/native/Canvas.d.ts +2 -2
- package/dist/declarations/src/native/events.d.ts +2 -2
- package/dist/declarations/src/three-types.d.ts +0 -5
- package/dist/declarations/src/web/Canvas.d.ts +2 -2
- package/dist/declarations/src/web/events.d.ts +2 -2
- package/dist/{index-a9d2810c.cjs.prod.js → index-2d224292.cjs.prod.js} +212 -227
- package/dist/{index-3d7af2b7.esm.js → index-6a8cc5a4.esm.js} +210 -227
- package/dist/{index-2b21ab4b.cjs.dev.js → index-8ce56249.cjs.dev.js} +212 -227
- package/dist/react-three-fiber.cjs.dev.js +29 -7
- package/dist/react-three-fiber.cjs.prod.js +29 -7
- package/dist/react-three-fiber.esm.js +28 -8
- package/native/dist/react-three-fiber-native.cjs.dev.js +29 -9
- package/native/dist/react-three-fiber-native.cjs.prod.js +29 -9
- package/native/dist/react-three-fiber-native.esm.js +27 -10
- package/package.json +2 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { suspend, preload, clear } from 'suspend-react';
|
|
3
1
|
import * as THREE from 'three';
|
|
2
|
+
import * as React from 'react';
|
|
4
3
|
import { DefaultEventPriority, ContinuousEventPriority, DiscreteEventPriority, ConcurrentRoot } from 'react-reconciler/constants';
|
|
5
4
|
import create from 'zustand';
|
|
6
5
|
import Reconciler from 'react-reconciler';
|
|
7
6
|
import { unstable_scheduleCallback, unstable_IdlePriority } from 'scheduler';
|
|
7
|
+
import { suspend, preload, clear } from 'suspend-react';
|
|
8
8
|
|
|
9
9
|
var threeTypes = /*#__PURE__*/Object.freeze({
|
|
10
10
|
__proto__: null
|
|
@@ -15,6 +15,15 @@ const isDiffSet = def => def && !!def.memoized && !!def.changes;
|
|
|
15
15
|
function calculateDpr(dpr) {
|
|
16
16
|
return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], window.devicePixelRatio), dpr[1]) : dpr;
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns instance root state
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const getRootState = obj => {
|
|
23
|
+
var _r3f;
|
|
24
|
+
|
|
25
|
+
return (_r3f = obj.__r3f) == null ? void 0 : _r3f.root.getState();
|
|
26
|
+
};
|
|
18
27
|
/**
|
|
19
28
|
* Picks or omits keys from an object
|
|
20
29
|
* `omit` will filter out keys, and otherwise cherry-pick them.
|
|
@@ -24,11 +33,7 @@ function filterKeys(obj, omit, ...keys) {
|
|
|
24
33
|
const keysToSelect = new Set(keys);
|
|
25
34
|
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
26
35
|
const shouldInclude = !omit;
|
|
27
|
-
|
|
28
|
-
if (keysToSelect.has(key) === shouldInclude) {
|
|
29
|
-
acc[key] = value;
|
|
30
|
-
}
|
|
31
|
-
|
|
36
|
+
if (keysToSelect.has(key) === shouldInclude) acc[key] = value;
|
|
32
37
|
return acc;
|
|
33
38
|
}, {});
|
|
34
39
|
}
|
|
@@ -66,7 +71,7 @@ const is = {
|
|
|
66
71
|
const isArr = is.arr(a);
|
|
67
72
|
if (isArr && arrays === 'reference') return a === b; // Array or Object, shallow compare first to see if it's a match
|
|
68
73
|
|
|
69
|
-
if ((isArr || isObj) && a
|
|
74
|
+
if ((isArr || isObj) && a === b) return true; // Last resort, go through keys
|
|
70
75
|
|
|
71
76
|
let i;
|
|
72
77
|
|
|
@@ -74,7 +79,13 @@ const is = {
|
|
|
74
79
|
|
|
75
80
|
for (i in strict ? b : a) if (a[i] !== b[i]) return false;
|
|
76
81
|
|
|
77
|
-
|
|
82
|
+
if (is.und(i)) {
|
|
83
|
+
if (isArr && a.length === 0 && b.length === 0) return true;
|
|
84
|
+
if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
|
|
85
|
+
if (a !== b) return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return true;
|
|
78
89
|
}
|
|
79
90
|
|
|
80
91
|
}; // Collects nodes and materials from a THREE.Object3D
|
|
@@ -110,30 +121,8 @@ function prepare(object, state) {
|
|
|
110
121
|
if (state != null && state.primitive || !instance.__r3f) {
|
|
111
122
|
instance.__r3f = {
|
|
112
123
|
type: '',
|
|
113
|
-
context: {
|
|
114
|
-
current: null
|
|
115
|
-
},
|
|
116
|
-
getContext: () => {
|
|
117
|
-
const injects = [];
|
|
118
|
-
let inject = instance.__r3f.context.current;
|
|
119
|
-
|
|
120
|
-
while (inject) {
|
|
121
|
-
var _inject$memoizedProps, _inject, _inject$context;
|
|
122
|
-
|
|
123
|
-
const {
|
|
124
|
-
children,
|
|
125
|
-
args,
|
|
126
|
-
...props
|
|
127
|
-
} = (_inject$memoizedProps = (_inject = inject) == null ? void 0 : _inject.memoizedProps) != null ? _inject$memoizedProps : {};
|
|
128
|
-
injects.push(props);
|
|
129
|
-
inject = (_inject$context = inject.context) == null ? void 0 : _inject$context.current;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return injects.reverse().reduce((prev, cur) => ({ ...prev,
|
|
133
|
-
...cur
|
|
134
|
-
}), {});
|
|
135
|
-
},
|
|
136
124
|
root: null,
|
|
125
|
+
previousAttach: null,
|
|
137
126
|
memoizedProps: {},
|
|
138
127
|
eventCount: 0,
|
|
139
128
|
handlers: {},
|
|
@@ -161,32 +150,42 @@ function resolve(instance, key) {
|
|
|
161
150
|
target,
|
|
162
151
|
key
|
|
163
152
|
};
|
|
164
|
-
}
|
|
153
|
+
} // Checks if a dash-cased string ends with an integer
|
|
165
154
|
|
|
155
|
+
|
|
156
|
+
const INDEX_REGEX = /-\d+$/;
|
|
166
157
|
function attach(parent, child, type) {
|
|
167
158
|
if (is.str(type)) {
|
|
159
|
+
// If attaching into an array (foo-0), create one
|
|
160
|
+
if (INDEX_REGEX.test(type)) {
|
|
161
|
+
const root = type.replace(INDEX_REGEX, '');
|
|
162
|
+
const {
|
|
163
|
+
target,
|
|
164
|
+
key
|
|
165
|
+
} = resolve(parent, root);
|
|
166
|
+
if (!Array.isArray(target[key])) target[key] = [];
|
|
167
|
+
}
|
|
168
|
+
|
|
168
169
|
const {
|
|
169
170
|
target,
|
|
170
171
|
key
|
|
171
172
|
} = resolve(parent, type);
|
|
172
|
-
|
|
173
|
+
child.__r3f.previousAttach = target[key];
|
|
173
174
|
target[key] = child;
|
|
174
|
-
} else
|
|
175
|
-
const [attach] = type;
|
|
176
|
-
if (is.str(attach)) parent[attach](child);else if (is.fun(attach)) attach(parent, child);
|
|
177
|
-
}
|
|
175
|
+
} else child.__r3f.previousAttach = type(parent, child);
|
|
178
176
|
}
|
|
179
177
|
function detach(parent, child, type) {
|
|
178
|
+
var _child$__r3f, _child$__r3f2;
|
|
179
|
+
|
|
180
180
|
if (is.str(type)) {
|
|
181
181
|
const {
|
|
182
182
|
target,
|
|
183
183
|
key
|
|
184
184
|
} = resolve(parent, type);
|
|
185
|
-
target[key] =
|
|
186
|
-
} else
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
185
|
+
target[key] = child.__r3f.previousAttach;
|
|
186
|
+
} else (_child$__r3f = child.__r3f) == null ? void 0 : _child$__r3f.previousAttach == null ? void 0 : _child$__r3f.previousAttach(parent, child);
|
|
187
|
+
|
|
188
|
+
(_child$__r3f2 = child.__r3f) == null ? true : delete _child$__r3f2.previousAttach;
|
|
190
189
|
} // This function prepares a set of changes to be applied to the instance
|
|
191
190
|
|
|
192
191
|
function diffProps(instance, {
|
|
@@ -306,20 +305,10 @@ function applyProps$1(instance, data) {
|
|
|
306
305
|
|
|
307
306
|
if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
|
|
308
307
|
else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask; // Otherwise just set ...
|
|
309
|
-
else targetProp.set(value);
|
|
310
|
-
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
311
|
-
|
|
312
|
-
if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
|
|
308
|
+
else targetProp.set(value);
|
|
313
309
|
} // Else, just overwrite the value
|
|
314
310
|
|
|
315
|
-
} else
|
|
316
|
-
currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
|
|
317
|
-
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
318
|
-
|
|
319
|
-
if (!rootState.linear && currentInstance[key] instanceof THREE.Texture) {
|
|
320
|
-
currentInstance[key].encoding = THREE.sRGBEncoding;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
311
|
+
} else currentInstance[key] = value;
|
|
323
312
|
|
|
324
313
|
invalidateInstance(instance);
|
|
325
314
|
return instance;
|
|
@@ -398,6 +387,7 @@ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
|
|
|
398
387
|
|
|
399
388
|
function removeInteractivity(store, object) {
|
|
400
389
|
const {
|
|
390
|
+
events,
|
|
401
391
|
internal
|
|
402
392
|
} = store.getState(); // Removes every trace of an object from the data store
|
|
403
393
|
|
|
@@ -405,6 +395,7 @@ function removeInteractivity(store, object) {
|
|
|
405
395
|
internal.initialHits = internal.initialHits.filter(o => o !== object);
|
|
406
396
|
internal.hovered.forEach((value, key) => {
|
|
407
397
|
if (value.eventObject === object || value.object === object) {
|
|
398
|
+
// Clear out intersects, they are outdated by now
|
|
408
399
|
internal.hovered.delete(key);
|
|
409
400
|
}
|
|
410
401
|
});
|
|
@@ -414,31 +405,8 @@ function removeInteractivity(store, object) {
|
|
|
414
405
|
}
|
|
415
406
|
function createEvents(store) {
|
|
416
407
|
const temp = new THREE.Vector3();
|
|
417
|
-
/** Sets up defaultRaycaster */
|
|
418
|
-
|
|
419
|
-
function prepareRay(event) {
|
|
420
|
-
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
421
|
-
|
|
422
|
-
const state = store.getState();
|
|
423
|
-
const {
|
|
424
|
-
raycaster,
|
|
425
|
-
mouse,
|
|
426
|
-
camera,
|
|
427
|
-
size
|
|
428
|
-
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
429
|
-
// Events trigger outside of canvas when moved
|
|
430
|
-
|
|
431
|
-
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
432
|
-
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
433
|
-
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
434
|
-
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
435
|
-
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
436
|
-
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
437
|
-
raycaster.setFromCamera(mouse, camera);
|
|
438
|
-
}
|
|
439
408
|
/** Calculates delta */
|
|
440
409
|
|
|
441
|
-
|
|
442
410
|
function calculateDistance(event) {
|
|
443
411
|
const {
|
|
444
412
|
internal
|
|
@@ -458,55 +426,70 @@ function createEvents(store) {
|
|
|
458
426
|
}));
|
|
459
427
|
}
|
|
460
428
|
|
|
461
|
-
function intersect(filter) {
|
|
429
|
+
function intersect(event, filter) {
|
|
462
430
|
const state = store.getState();
|
|
463
|
-
const
|
|
464
|
-
raycaster,
|
|
465
|
-
internal
|
|
466
|
-
} = state; // Skip event handling when noEvents is set
|
|
467
|
-
|
|
468
|
-
if (!raycaster.enabled) return [];
|
|
469
|
-
const seen = new Set();
|
|
431
|
+
const duplicates = new Set();
|
|
470
432
|
const intersections = []; // Allow callers to eliminate event objects
|
|
471
433
|
|
|
472
|
-
const eventsObjects = filter ? filter(internal.interaction) : internal.interaction; //
|
|
434
|
+
const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction; // Reset all raycaster cameras to undefined
|
|
435
|
+
|
|
436
|
+
eventsObjects.forEach(obj => {
|
|
437
|
+
const state = getRootState(obj);
|
|
438
|
+
|
|
439
|
+
if (state) {
|
|
440
|
+
state.raycaster.camera = undefined;
|
|
441
|
+
}
|
|
442
|
+
}); // Collect events
|
|
443
|
+
|
|
444
|
+
let hits = eventsObjects // Intersect objects
|
|
445
|
+
.flatMap(obj => {
|
|
446
|
+
const state = getRootState(obj); // Skip event handling when noEvents is set, or when the raycasters camera is null
|
|
447
|
+
|
|
448
|
+
if (!state || !state.events.enabled || state.raycaster.camera === null) return []; // When the camera is undefined we have to call the event layers update function
|
|
449
|
+
|
|
450
|
+
if (state.raycaster.camera === undefined) {
|
|
451
|
+
var _state$previousRoot;
|
|
473
452
|
|
|
474
|
-
|
|
453
|
+
state.events.compute == null ? void 0 : state.events.compute(event, state, (_state$previousRoot = state.previousRoot) == null ? void 0 : _state$previousRoot.getState()); // If the camera is still undefined we have to skip this layer entirely
|
|
454
|
+
|
|
455
|
+
if (state.raycaster.camera === undefined) state.raycaster.camera = null;
|
|
456
|
+
} // Intersect object by object
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
return state.raycaster.camera ? state.raycaster.intersectObject(obj, true) : [];
|
|
460
|
+
}) // Sort by event priority and distance
|
|
461
|
+
.sort((a, b) => {
|
|
462
|
+
const aState = getRootState(a.object);
|
|
463
|
+
const bState = getRootState(b.object);
|
|
464
|
+
if (!aState || !bState) return 0;
|
|
465
|
+
return bState.events.priority - aState.events.priority || a.distance - b.distance;
|
|
466
|
+
}) // Filter out duplicates
|
|
467
|
+
.filter(item => {
|
|
475
468
|
const id = makeId(item);
|
|
476
|
-
if (
|
|
477
|
-
|
|
469
|
+
if (duplicates.has(id)) return false;
|
|
470
|
+
duplicates.add(id);
|
|
478
471
|
return true;
|
|
479
472
|
}); // https://github.com/mrdoob/three.js/issues/16031
|
|
480
|
-
// Allow custom userland intersect sort order
|
|
473
|
+
// Allow custom userland intersect sort order, this likely only makes sense on the root filter
|
|
481
474
|
|
|
482
|
-
if (
|
|
475
|
+
if (state.events.filter) hits = state.events.filter(hits, state); // Bubble up the events, find the event source (eventObject)
|
|
483
476
|
|
|
484
|
-
for (const
|
|
485
|
-
let eventObject =
|
|
477
|
+
for (const hit of hits) {
|
|
478
|
+
let eventObject = hit.object; // Bubble event up
|
|
486
479
|
|
|
487
480
|
while (eventObject) {
|
|
488
481
|
var _r3f2;
|
|
489
482
|
|
|
490
|
-
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...
|
|
483
|
+
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...hit,
|
|
491
484
|
eventObject
|
|
492
485
|
});
|
|
493
486
|
eventObject = eventObject.parent;
|
|
494
487
|
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
return intersections;
|
|
498
|
-
}
|
|
499
|
-
/** Creates filtered intersects and returns an array of positive hits */
|
|
488
|
+
} // If the interaction is captured, make all capturing targets part of the intersect.
|
|
500
489
|
|
|
501
490
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
internal
|
|
505
|
-
} = store.getState(); // If the interaction is captured, make all capturing targets part of the
|
|
506
|
-
// intersect.
|
|
507
|
-
|
|
508
|
-
if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
|
|
509
|
-
for (let captureData of internal.capturedMap.get(event.pointerId).values()) {
|
|
491
|
+
if ('pointerId' in event && state.internal.capturedMap.has(event.pointerId)) {
|
|
492
|
+
for (let captureData of state.internal.capturedMap.get(event.pointerId).values()) {
|
|
510
493
|
intersections.push(captureData.intersection);
|
|
511
494
|
}
|
|
512
495
|
}
|
|
@@ -519,13 +502,13 @@ function createEvents(store) {
|
|
|
519
502
|
function handleIntersects(intersections, event, delta, callback) {
|
|
520
503
|
const {
|
|
521
504
|
raycaster,
|
|
522
|
-
|
|
505
|
+
pointer,
|
|
523
506
|
camera,
|
|
524
507
|
internal
|
|
525
508
|
} = store.getState(); // If anything has been found, forward it to the event listeners
|
|
526
509
|
|
|
527
510
|
if (intersections.length) {
|
|
528
|
-
const unprojectedPoint = temp.set(
|
|
511
|
+
const unprojectedPoint = temp.set(pointer.x, pointer.y, 0).unproject(camera);
|
|
529
512
|
const localState = {
|
|
530
513
|
stopped: false
|
|
531
514
|
};
|
|
@@ -576,8 +559,7 @@ function createEvents(store) {
|
|
|
576
559
|
|
|
577
560
|
let raycastEvent = { ...hit,
|
|
578
561
|
...extractEventProps,
|
|
579
|
-
|
|
580
|
-
spaceY: mouse.y,
|
|
562
|
+
pointer,
|
|
581
563
|
intersections,
|
|
582
564
|
stopped: localState.stopped,
|
|
583
565
|
delta,
|
|
@@ -614,8 +596,6 @@ function createEvents(store) {
|
|
|
614
596
|
setPointerCapture,
|
|
615
597
|
releasePointerCapture
|
|
616
598
|
},
|
|
617
|
-
sourceEvent: event,
|
|
618
|
-
// deprecated
|
|
619
599
|
nativeEvent: event
|
|
620
600
|
}; // Call subscribers
|
|
621
601
|
|
|
@@ -680,14 +660,15 @@ function createEvents(store) {
|
|
|
680
660
|
const {
|
|
681
661
|
onPointerMissed,
|
|
682
662
|
internal
|
|
683
|
-
} = store.getState();
|
|
684
|
-
|
|
663
|
+
} = store.getState(); //prepareRay(event)
|
|
664
|
+
|
|
685
665
|
internal.lastEvent.current = event; // Get fresh intersects
|
|
686
666
|
|
|
687
667
|
const isPointerMove = name === 'onPointerMove';
|
|
688
668
|
const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
|
|
689
|
-
const filter = isPointerMove ? filterPointerEvents : undefined;
|
|
690
|
-
|
|
669
|
+
const filter = isPointerMove ? filterPointerEvents : undefined; //const hits = patchIntersects(intersect(filter), event)
|
|
670
|
+
|
|
671
|
+
const hits = intersect(event, filter);
|
|
691
672
|
const delta = isClickEvent ? calculateDistance(event) : 0; // Save initial coordinates on pointer-down
|
|
692
673
|
|
|
693
674
|
if (name === 'onPointerDown') {
|
|
@@ -770,54 +751,20 @@ function createEvents(store) {
|
|
|
770
751
|
};
|
|
771
752
|
}
|
|
772
753
|
|
|
773
|
-
// Type guard to tell a store from a portal
|
|
774
|
-
const isStore = def => def && !!def.getState;
|
|
775
|
-
|
|
776
|
-
const getContainer = (container, child) => {
|
|
777
|
-
var _container$__r3f$root, _container$__r3f;
|
|
778
|
-
|
|
779
|
-
return {
|
|
780
|
-
// If the container is not a root-store then it must be a THREE.Object3D into which part of the
|
|
781
|
-
// scene is portalled into. Now there can be two variants of this, either that object is part of
|
|
782
|
-
// the regular jsx tree, in which case it already has __r3f with a valid root attached, or it lies
|
|
783
|
-
// outside react, in which case we must take the root of the child that is about to be attached to it.
|
|
784
|
-
root: isStore(container) ? container : (_container$__r3f$root = (_container$__r3f = container.__r3f) == null ? void 0 : _container$__r3f.root) != null ? _container$__r3f$root : child.__r3f.root,
|
|
785
|
-
// The container is the eventual target into which objects are mounted, it has to be a THREE.Object3D
|
|
786
|
-
container: isStore(container) ? container.getState().scene : container
|
|
787
|
-
};
|
|
788
|
-
};
|
|
789
|
-
|
|
790
754
|
let catalogue = {};
|
|
791
755
|
|
|
792
756
|
let extend = objects => void (catalogue = { ...catalogue,
|
|
793
757
|
...objects
|
|
794
758
|
});
|
|
795
759
|
|
|
796
|
-
extend({
|
|
797
|
-
Inject: THREE.Group
|
|
798
|
-
});
|
|
799
|
-
|
|
800
760
|
function createRenderer(roots, getEventPriority) {
|
|
801
761
|
function createInstance(type, {
|
|
802
762
|
args = [],
|
|
803
763
|
attach,
|
|
804
764
|
...props
|
|
805
|
-
}, root
|
|
765
|
+
}, root) {
|
|
806
766
|
let name = `${type[0].toUpperCase()}${type.slice(1)}`;
|
|
807
|
-
let instance; //
|
|
808
|
-
// Portals do not give us a root, they are themselves treated as a root by the reconciler
|
|
809
|
-
// In order to figure out the actual root we have to climb through fiber internals :(
|
|
810
|
-
|
|
811
|
-
if (!isStore(root) && internalInstanceHandle) {
|
|
812
|
-
const fn = node => {
|
|
813
|
-
if (!node.return) return node.stateNode && node.stateNode.containerInfo;else return fn(node.return);
|
|
814
|
-
};
|
|
815
|
-
|
|
816
|
-
root = fn(internalInstanceHandle);
|
|
817
|
-
} // Assert that by now we have a valid root
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
if (!root || !isStore(root)) throw `No valid root for ${name}!`; // Auto-attach geometries and materials
|
|
767
|
+
let instance; // Auto-attach geometries and materials
|
|
821
768
|
|
|
822
769
|
if (attach === undefined) {
|
|
823
770
|
if (name.endsWith('Geometry')) attach = 'geometry';else if (name.endsWith('Material')) attach = 'material';
|
|
@@ -829,7 +776,6 @@ function createRenderer(roots, getEventPriority) {
|
|
|
829
776
|
instance = prepare(object, {
|
|
830
777
|
type,
|
|
831
778
|
root,
|
|
832
|
-
context,
|
|
833
779
|
attach,
|
|
834
780
|
primitive: true
|
|
835
781
|
});
|
|
@@ -847,7 +793,6 @@ function createRenderer(roots, getEventPriority) {
|
|
|
847
793
|
instance = prepare(new target(...args), {
|
|
848
794
|
type,
|
|
849
795
|
root,
|
|
850
|
-
context,
|
|
851
796
|
attach,
|
|
852
797
|
// TODO: Figure out what this is for
|
|
853
798
|
memoizedProps: {
|
|
@@ -865,15 +810,6 @@ function createRenderer(roots, getEventPriority) {
|
|
|
865
810
|
}
|
|
866
811
|
|
|
867
812
|
function appendChild(parentInstance, child) {
|
|
868
|
-
// https://github.com/facebook/react/issues/24138
|
|
869
|
-
// Injects are special purpose "onion layers" that inject contextual information into the scene graph.
|
|
870
|
-
// Since react-reconciler does not allow us to access the current host context we trick it by leading
|
|
871
|
-
// back to it from the first child that is added to it. We just connect the inject to it's own host context.
|
|
872
|
-
if ((parentInstance == null ? void 0 : parentInstance.__r3f.type) === 'inject') {
|
|
873
|
-
const context = child == null ? void 0 : child.__r3f.context;
|
|
874
|
-
if (context) context.current = parentInstance.__r3f;
|
|
875
|
-
}
|
|
876
|
-
|
|
877
813
|
let added = false;
|
|
878
814
|
|
|
879
815
|
if (child) {
|
|
@@ -969,7 +905,6 @@ function createRenderer(roots, getEventPriority) {
|
|
|
969
905
|
|
|
970
906
|
if (child.__r3f) {
|
|
971
907
|
delete child.__r3f.root;
|
|
972
|
-
delete child.__r3f.context;
|
|
973
908
|
delete child.__r3f.objects;
|
|
974
909
|
delete child.__r3f.handlers;
|
|
975
910
|
delete child.__r3f.memoizedProps;
|
|
@@ -992,11 +927,11 @@ function createRenderer(roots, getEventPriority) {
|
|
|
992
927
|
}
|
|
993
928
|
|
|
994
929
|
function switchInstance(instance, type, newProps, fiber) {
|
|
995
|
-
var _instance$__r3f;
|
|
930
|
+
var _instance$__r3f, _instance$__r3f2;
|
|
996
931
|
|
|
997
932
|
const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
|
|
998
933
|
if (!parent) return;
|
|
999
|
-
const newInstance = createInstance(type, newProps, instance.__r3f.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
|
|
934
|
+
const newInstance = createInstance(type, newProps, (_instance$__r3f2 = instance.__r3f) == null ? void 0 : _instance$__r3f2.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
|
|
1000
935
|
// When args change the instance has to be re-constructed, which then
|
|
1001
936
|
// forces r3f to re-parent the children and non-scene objects
|
|
1002
937
|
// This can not include primitives, which should not have declarative children
|
|
@@ -1039,46 +974,28 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1039
974
|
supportsMutation: true,
|
|
1040
975
|
isPrimaryRenderer: false,
|
|
1041
976
|
noTimeout: -1,
|
|
1042
|
-
appendChildToContainer: (
|
|
1043
|
-
const
|
|
1044
|
-
container,
|
|
1045
|
-
root
|
|
1046
|
-
} = getContainer(parentInstance, child); // Link current root to the default scene
|
|
977
|
+
appendChildToContainer: (container, child) => {
|
|
978
|
+
const scene = container.getState().scene; // Link current root to the default scene
|
|
1047
979
|
|
|
1048
|
-
|
|
1049
|
-
appendChild(
|
|
1050
|
-
},
|
|
1051
|
-
removeChildFromContainer: (parentInstance, child) => removeChild(getContainer(parentInstance, child).container, child),
|
|
1052
|
-
insertInContainerBefore: (parentInstance, child, beforeChild) => insertBefore(getContainer(parentInstance, child).container, child, beforeChild),
|
|
1053
|
-
getRootHostContext: () => ({
|
|
1054
|
-
current: null
|
|
1055
|
-
}),
|
|
1056
|
-
getChildHostContext: (parentHostContext, type) => {
|
|
1057
|
-
// This is a little misleading, this function does not determine the host context for the element at hand,
|
|
1058
|
-
// but rather for all the children of it. The context for an inject is and will be the scene, everything
|
|
1059
|
-
// within an inject is contextual to it.
|
|
1060
|
-
if (type === 'inject') return {
|
|
1061
|
-
current: null
|
|
1062
|
-
};
|
|
1063
|
-
return parentHostContext;
|
|
980
|
+
scene.__r3f.root = container;
|
|
981
|
+
appendChild(scene, child);
|
|
1064
982
|
},
|
|
983
|
+
removeChildFromContainer: (container, child) => removeChild(container.getState().scene, child),
|
|
984
|
+
insertInContainerBefore: (container, child, beforeChild) => insertBefore(container.getState().scene, child, beforeChild),
|
|
985
|
+
getRootHostContext: () => null,
|
|
986
|
+
getChildHostContext: parentHostContext => parentHostContext,
|
|
1065
987
|
|
|
1066
988
|
finalizeInitialChildren(instance) {
|
|
1067
|
-
var _instance$
|
|
989
|
+
var _instance$__r3f3;
|
|
1068
990
|
|
|
1069
|
-
const localState = (_instance$
|
|
991
|
+
const localState = (_instance$__r3f3 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f3 : {}; // https://github.com/facebook/react/issues/20271
|
|
1070
992
|
// Returning true will trigger commitMount
|
|
1071
993
|
|
|
1072
994
|
return !!localState.handlers;
|
|
1073
995
|
},
|
|
1074
996
|
|
|
1075
997
|
prepareUpdate(instance, type, oldProps, newProps) {
|
|
1076
|
-
//
|
|
1077
|
-
// Because the context of an inject is still the scene we have to rely on children to give us the inject-context
|
|
1078
|
-
// so that we can set up props.
|
|
1079
|
-
if (type === 'inject' && instance.children.length) ; // Create diff-sets
|
|
1080
|
-
|
|
1081
|
-
|
|
998
|
+
// Create diff-sets
|
|
1082
999
|
if (instance.__r3f.primitive && newProps.object && newProps.object !== instance) {
|
|
1083
1000
|
return [true];
|
|
1084
1001
|
} else {
|
|
@@ -1112,11 +1029,11 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1112
1029
|
},
|
|
1113
1030
|
|
|
1114
1031
|
commitMount(instance, type, props, int) {
|
|
1115
|
-
var _instance$
|
|
1032
|
+
var _instance$__r3f4;
|
|
1116
1033
|
|
|
1117
1034
|
// https://github.com/facebook/react/issues/20271
|
|
1118
1035
|
// This will make sure events are only added once to the central container
|
|
1119
|
-
const localState = (_instance$
|
|
1036
|
+
const localState = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
|
|
1120
1037
|
|
|
1121
1038
|
if (instance.raycast && localState.handlers && localState.eventCount) {
|
|
1122
1039
|
instance.__r3f.root.getState().internal.interaction.push(instance);
|
|
@@ -1126,7 +1043,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1126
1043
|
getPublicInstance: instance => instance,
|
|
1127
1044
|
shouldDeprioritizeSubtree: () => false,
|
|
1128
1045
|
prepareForCommit: () => null,
|
|
1129
|
-
preparePortalMount:
|
|
1046
|
+
preparePortalMount: container => prepare(container.getState().scene),
|
|
1130
1047
|
resetAfterCommit: () => {},
|
|
1131
1048
|
shouldSetTextContent: () => false,
|
|
1132
1049
|
clearContainer: () => false,
|
|
@@ -1134,26 +1051,26 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1134
1051
|
createTextInstance: () => {},
|
|
1135
1052
|
|
|
1136
1053
|
hideInstance(instance) {
|
|
1137
|
-
var _instance$
|
|
1054
|
+
var _instance$__r3f5;
|
|
1138
1055
|
|
|
1139
1056
|
// Deatch while the instance is hidden
|
|
1140
1057
|
const {
|
|
1141
1058
|
attach: type,
|
|
1142
1059
|
parent
|
|
1143
|
-
} = (_instance$
|
|
1060
|
+
} = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
|
|
1144
1061
|
if (type && parent) detach(parent, instance, type);
|
|
1145
1062
|
if (instance.isObject3D) instance.visible = false;
|
|
1146
1063
|
invalidateInstance(instance);
|
|
1147
1064
|
},
|
|
1148
1065
|
|
|
1149
1066
|
unhideInstance(instance, props) {
|
|
1150
|
-
var _instance$
|
|
1067
|
+
var _instance$__r3f6;
|
|
1151
1068
|
|
|
1152
1069
|
// Re-attach when the instance is unhidden
|
|
1153
1070
|
const {
|
|
1154
1071
|
attach: type,
|
|
1155
1072
|
parent
|
|
1156
|
-
} = (_instance$
|
|
1073
|
+
} = (_instance$__r3f6 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f6 : {};
|
|
1157
1074
|
if (type && parent) attach(parent, instance, type);
|
|
1158
1075
|
if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
|
|
1159
1076
|
invalidateInstance(instance);
|
|
@@ -1231,16 +1148,18 @@ const createStore = (invalidate, advance) => {
|
|
|
1231
1148
|
}));
|
|
1232
1149
|
|
|
1233
1150
|
return {
|
|
1151
|
+
set,
|
|
1152
|
+
get,
|
|
1234
1153
|
// Mock objects that have to be configured
|
|
1235
1154
|
gl: null,
|
|
1236
1155
|
camera: null,
|
|
1237
1156
|
raycaster: null,
|
|
1238
1157
|
events: {
|
|
1158
|
+
priority: 1,
|
|
1159
|
+
enabled: true,
|
|
1239
1160
|
connected: false
|
|
1240
1161
|
},
|
|
1241
1162
|
xr: null,
|
|
1242
|
-
set,
|
|
1243
|
-
get,
|
|
1244
1163
|
invalidate: () => invalidate(get()),
|
|
1245
1164
|
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1246
1165
|
linear: false,
|
|
@@ -1248,7 +1167,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1248
1167
|
scene: prepare(new THREE.Scene()),
|
|
1249
1168
|
controls: null,
|
|
1250
1169
|
clock: new THREE.Clock(),
|
|
1251
|
-
|
|
1170
|
+
pointer: new THREE.Vector2(),
|
|
1252
1171
|
frameloop: 'always',
|
|
1253
1172
|
onPointerMissed: undefined,
|
|
1254
1173
|
performance: {
|
|
@@ -1317,6 +1236,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1317
1236
|
frameloop
|
|
1318
1237
|
}));
|
|
1319
1238
|
},
|
|
1239
|
+
previousRoot: undefined,
|
|
1320
1240
|
internal: {
|
|
1321
1241
|
active: false,
|
|
1322
1242
|
priority: 0,
|
|
@@ -1544,6 +1464,11 @@ function loadingFn(extensions, onProgress) {
|
|
|
1544
1464
|
};
|
|
1545
1465
|
}
|
|
1546
1466
|
|
|
1467
|
+
function useMemoizedFn(fn) {
|
|
1468
|
+
const fnRef = React.useRef(fn);
|
|
1469
|
+
React.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
|
|
1470
|
+
return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
|
|
1471
|
+
}
|
|
1547
1472
|
function useLoader(Proto, input, extensions, onProgress) {
|
|
1548
1473
|
// Use suspense to load async assets
|
|
1549
1474
|
const keys = Array.isArray(input) ? input : [input];
|
|
@@ -1643,9 +1568,7 @@ function createRoot(canvas) {
|
|
|
1643
1568
|
params,
|
|
1644
1569
|
...options
|
|
1645
1570
|
} = raycastOptions || {};
|
|
1646
|
-
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, {
|
|
1647
|
-
enabled: true,
|
|
1648
|
-
...options
|
|
1571
|
+
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options
|
|
1649
1572
|
});
|
|
1650
1573
|
if (!is.equ(params, raycaster.params, shallowLoose)) applyProps(raycaster, {
|
|
1651
1574
|
params: { ...raycaster.params,
|
|
@@ -1681,7 +1604,7 @@ function createRoot(canvas) {
|
|
|
1681
1604
|
|
|
1682
1605
|
const handleSessionChange = () => {
|
|
1683
1606
|
const gl = store.getState().gl;
|
|
1684
|
-
gl.xr.enabled = gl.xr.isPresenting; // @ts-
|
|
1607
|
+
gl.xr.enabled = gl.xr.isPresenting; // @ts-ignore
|
|
1685
1608
|
// WebXRManager's signature is incorrect.
|
|
1686
1609
|
// See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
|
|
1687
1610
|
|
|
@@ -1723,6 +1646,7 @@ function createRoot(canvas) {
|
|
|
1723
1646
|
} // Set color management
|
|
1724
1647
|
|
|
1725
1648
|
|
|
1649
|
+
if (THREE.ColorManagement) THREE.ColorManagement.legacyMode = false;
|
|
1726
1650
|
const outputEncoding = linear ? THREE.LinearEncoding : THREE.sRGBEncoding;
|
|
1727
1651
|
const toneMapping = flat ? THREE.NoToneMapping : THREE.ACESFilmicToneMapping;
|
|
1728
1652
|
if (gl.outputEncoding !== outputEncoding) gl.outputEncoding = outputEncoding;
|
|
@@ -1759,14 +1683,14 @@ function createRoot(canvas) {
|
|
|
1759
1683
|
return this;
|
|
1760
1684
|
},
|
|
1761
1685
|
|
|
1762
|
-
render(
|
|
1686
|
+
render(children) {
|
|
1763
1687
|
// The root has to be configured before it can be rendered
|
|
1764
1688
|
if (!configured) this.configure();
|
|
1765
1689
|
reconciler.updateContainer( /*#__PURE__*/React.createElement(Provider, {
|
|
1766
1690
|
store: store,
|
|
1767
|
-
|
|
1691
|
+
children: children,
|
|
1768
1692
|
onCreated: onCreated,
|
|
1769
|
-
|
|
1693
|
+
rootElement: canvas
|
|
1770
1694
|
}), fiber, null, () => undefined);
|
|
1771
1695
|
return store;
|
|
1772
1696
|
},
|
|
@@ -1778,35 +1702,36 @@ function createRoot(canvas) {
|
|
|
1778
1702
|
};
|
|
1779
1703
|
}
|
|
1780
1704
|
|
|
1781
|
-
function render(
|
|
1705
|
+
function render(children, canvas, config) {
|
|
1782
1706
|
console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!');
|
|
1783
1707
|
const root = createRoot(canvas);
|
|
1784
1708
|
root.configure(config);
|
|
1785
|
-
return root.render(
|
|
1709
|
+
return root.render(children);
|
|
1786
1710
|
}
|
|
1787
1711
|
|
|
1788
1712
|
function Provider({
|
|
1789
1713
|
store,
|
|
1790
|
-
|
|
1714
|
+
children,
|
|
1791
1715
|
onCreated,
|
|
1792
|
-
|
|
1716
|
+
rootElement
|
|
1793
1717
|
}) {
|
|
1794
|
-
React.
|
|
1718
|
+
React.useLayoutEffect(() => {
|
|
1795
1719
|
const state = store.getState(); // Flag the canvas active, rendering will now begin
|
|
1796
1720
|
|
|
1797
1721
|
state.set(state => ({
|
|
1798
1722
|
internal: { ...state.internal,
|
|
1799
1723
|
active: true
|
|
1800
1724
|
}
|
|
1801
|
-
})); //
|
|
1725
|
+
})); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
|
|
1802
1726
|
|
|
1803
|
-
|
|
1727
|
+
if (onCreated) onCreated(state); // Connect events to the targets parent, this is done to ensure events are registered on
|
|
1728
|
+
// a shared target, and not on the canvas itself
|
|
1804
1729
|
|
|
1805
|
-
if (
|
|
1730
|
+
if (!store.getState().events.connected) state.events.connect == null ? void 0 : state.events.connect(rootElement); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1806
1731
|
}, []);
|
|
1807
1732
|
return /*#__PURE__*/React.createElement(context.Provider, {
|
|
1808
1733
|
value: store
|
|
1809
|
-
},
|
|
1734
|
+
}, children);
|
|
1810
1735
|
}
|
|
1811
1736
|
|
|
1812
1737
|
function unmountComponentAtNode(canvas, callback) {
|
|
@@ -1838,10 +1763,67 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
1838
1763
|
}
|
|
1839
1764
|
}
|
|
1840
1765
|
|
|
1841
|
-
|
|
1766
|
+
function createPortal(children, container, state) {
|
|
1767
|
+
return /*#__PURE__*/React.createElement(Portal, {
|
|
1768
|
+
children: children,
|
|
1769
|
+
container: container,
|
|
1770
|
+
state: state
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1842
1773
|
|
|
1843
|
-
function
|
|
1844
|
-
|
|
1774
|
+
function Portal({
|
|
1775
|
+
state = {},
|
|
1776
|
+
children,
|
|
1777
|
+
container
|
|
1778
|
+
}) {
|
|
1779
|
+
/** This has to be a component because it would not be able to call useThree/useStore otherwise since
|
|
1780
|
+
* if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
|
|
1781
|
+
* the "R3F hooks can only be used within the Canvas component!" warning:
|
|
1782
|
+
* <Canvas>
|
|
1783
|
+
* {createPortal(...)} */
|
|
1784
|
+
const {
|
|
1785
|
+
events,
|
|
1786
|
+
...rest
|
|
1787
|
+
} = state;
|
|
1788
|
+
const previousRoot = useStore();
|
|
1789
|
+
const [raycaster] = React.useState(() => new THREE.Raycaster());
|
|
1790
|
+
const inject = React.useCallback((state, injectState) => {
|
|
1791
|
+
const intersect = { ...state
|
|
1792
|
+
};
|
|
1793
|
+
|
|
1794
|
+
if (injectState) {
|
|
1795
|
+
// Only the fields of "state" that do not differ from injectState
|
|
1796
|
+
Object.keys(state).forEach(key => {
|
|
1797
|
+
if ( // Some props should be off-limits
|
|
1798
|
+
!['size', 'viewport', 'internal', 'performance'].includes(key) && // Otherwise filter out the props that are different and let the inject layer take precedence
|
|
1799
|
+
state[key] !== injectState[key]) delete intersect[key];
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
return { ...intersect,
|
|
1804
|
+
scene: container,
|
|
1805
|
+
previousRoot,
|
|
1806
|
+
raycaster,
|
|
1807
|
+
events: { ...state.events,
|
|
1808
|
+
...events
|
|
1809
|
+
},
|
|
1810
|
+
...rest
|
|
1811
|
+
};
|
|
1812
|
+
}, [state]);
|
|
1813
|
+
const [useInjectStore] = React.useState(() => {
|
|
1814
|
+
const store = create((set, get) => ({ ...inject(previousRoot.getState()),
|
|
1815
|
+
set,
|
|
1816
|
+
get
|
|
1817
|
+
}));
|
|
1818
|
+
previousRoot.subscribe(state => useInjectStore.setState(injectState => inject(state, injectState)));
|
|
1819
|
+
return store;
|
|
1820
|
+
});
|
|
1821
|
+
React.useEffect(() => {
|
|
1822
|
+
useInjectStore.setState(injectState => inject(previousRoot.getState(), injectState));
|
|
1823
|
+
}, [inject]);
|
|
1824
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, reconciler.createPortal( /*#__PURE__*/React.createElement(context.Provider, {
|
|
1825
|
+
value: useInjectStore
|
|
1826
|
+
}, children), useInjectStore, null));
|
|
1845
1827
|
}
|
|
1846
1828
|
|
|
1847
1829
|
reconciler.injectIntoDevTools({
|
|
@@ -1849,5 +1831,6 @@ reconciler.injectIntoDevTools({
|
|
|
1849
1831
|
rendererPackageName: '@react-three/fiber',
|
|
1850
1832
|
version: '18.0.0'
|
|
1851
1833
|
});
|
|
1834
|
+
const act = React.unstable_act;
|
|
1852
1835
|
|
|
1853
|
-
export { createRoot as a,
|
|
1836
|
+
export { useLoader as A, createRoot as a, unmountComponentAtNode as b, createEvents as c, context as d, extend as e, createPortal as f, reconciler as g, applyProps as h, dispose as i, invalidate as j, advance as k, addEffect as l, addAfterEffect as m, addTail as n, omit as o, pick as p, getRootState as q, render as r, act as s, threeTypes as t, useMemoizedFn as u, roots as v, useStore as w, useThree as x, useFrame as y, useGraph as z };
|