@react-three/fiber 8.0.0-beta.3 → 8.0.0-beta.6
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 +7 -6
- 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 -1
- package/dist/declarations/src/web/Canvas.d.ts +2 -2
- package/dist/declarations/src/web/events.d.ts +2 -2
- package/dist/{index-85b2df17.cjs.prod.js → index-45f5b2a2.cjs.prod.js} +249 -208
- package/dist/{index-05ebefd3.cjs.dev.js → index-4782ba04.cjs.dev.js} +249 -208
- package/dist/{index-e78dd2f0.esm.js → index-74b1fd6b.esm.js} +247 -208
- package/dist/react-three-fiber.cjs.dev.js +23 -6
- package/dist/react-three-fiber.cjs.prod.js +23 -6
- package/dist/react-three-fiber.esm.js +22 -7
- package/native/dist/react-three-fiber-native.cjs.dev.js +24 -7
- package/native/dist/react-three-fiber-native.cjs.prod.js +24 -7
- package/native/dist/react-three-fiber-native.esm.js +23 -8
- package/package.json +3 -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
|
|
@@ -109,7 +120,9 @@ function prepare(object, state) {
|
|
|
109
120
|
|
|
110
121
|
if (state != null && state.primitive || !instance.__r3f) {
|
|
111
122
|
instance.__r3f = {
|
|
123
|
+
type: '',
|
|
112
124
|
root: null,
|
|
125
|
+
previousAttach: null,
|
|
113
126
|
memoizedProps: {},
|
|
114
127
|
eventCount: 0,
|
|
115
128
|
handlers: {},
|
|
@@ -137,32 +150,42 @@ function resolve(instance, key) {
|
|
|
137
150
|
target,
|
|
138
151
|
key
|
|
139
152
|
};
|
|
140
|
-
}
|
|
153
|
+
} // Checks if a dash-cased string ends with an integer
|
|
141
154
|
|
|
155
|
+
|
|
156
|
+
const INDEX_REGEX = /-\d+$/;
|
|
142
157
|
function attach(parent, child, type) {
|
|
143
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
|
+
|
|
144
169
|
const {
|
|
145
170
|
target,
|
|
146
171
|
key
|
|
147
172
|
} = resolve(parent, type);
|
|
148
|
-
|
|
173
|
+
child.__r3f.previousAttach = target[key];
|
|
149
174
|
target[key] = child;
|
|
150
|
-
} else
|
|
151
|
-
const [attach] = type;
|
|
152
|
-
if (is.str(attach)) parent[attach](child);else if (is.fun(attach)) attach(parent, child);
|
|
153
|
-
}
|
|
175
|
+
} else child.__r3f.previousAttach = type(parent, child);
|
|
154
176
|
}
|
|
155
177
|
function detach(parent, child, type) {
|
|
178
|
+
var _child$__r3f, _child$__r3f2;
|
|
179
|
+
|
|
156
180
|
if (is.str(type)) {
|
|
157
181
|
const {
|
|
158
182
|
target,
|
|
159
183
|
key
|
|
160
184
|
} = resolve(parent, type);
|
|
161
|
-
target[key] =
|
|
162
|
-
} else
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
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;
|
|
166
189
|
} // This function prepares a set of changes to be applied to the instance
|
|
167
190
|
|
|
168
191
|
function diffProps(instance, {
|
|
@@ -250,11 +273,11 @@ function applyProps$1(instance, data) {
|
|
|
250
273
|
if (value === DEFAULT + 'remove') {
|
|
251
274
|
if (targetProp && targetProp.constructor) {
|
|
252
275
|
// use the prop constructor to find the default it should be
|
|
253
|
-
value = new targetProp.constructor(memoized.args);
|
|
276
|
+
value = new targetProp.constructor(...memoized.args);
|
|
254
277
|
} else if (currentInstance.constructor) {
|
|
255
278
|
// create a blank slate of the instance and copy the particular parameter.
|
|
256
279
|
// @ts-ignore
|
|
257
|
-
const defaultClassCall = new currentInstance.constructor(currentInstance.__r3f.memoizedProps.args);
|
|
280
|
+
const defaultClassCall = new currentInstance.constructor(...currentInstance.__r3f.memoizedProps.args);
|
|
258
281
|
value = defaultClassCall[targetProp]; // destory the instance
|
|
259
282
|
|
|
260
283
|
if (defaultClassCall.dispose) defaultClassCall.dispose(); // instance does not have constructor, just set it to 0
|
|
@@ -282,20 +305,10 @@ function applyProps$1(instance, data) {
|
|
|
282
305
|
|
|
283
306
|
if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
|
|
284
307
|
else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask; // Otherwise just set ...
|
|
285
|
-
else targetProp.set(value);
|
|
286
|
-
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
287
|
-
|
|
288
|
-
if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
|
|
308
|
+
else targetProp.set(value);
|
|
289
309
|
} // Else, just overwrite the value
|
|
290
310
|
|
|
291
|
-
} else
|
|
292
|
-
currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
|
|
293
|
-
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
294
|
-
|
|
295
|
-
if (!rootState.linear && currentInstance[key] instanceof THREE.Texture) {
|
|
296
|
-
currentInstance[key].encoding = THREE.sRGBEncoding;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
311
|
+
} else currentInstance[key] = value;
|
|
299
312
|
|
|
300
313
|
invalidateInstance(instance);
|
|
301
314
|
return instance;
|
|
@@ -374,6 +387,7 @@ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
|
|
|
374
387
|
|
|
375
388
|
function removeInteractivity(store, object) {
|
|
376
389
|
const {
|
|
390
|
+
events,
|
|
377
391
|
internal
|
|
378
392
|
} = store.getState(); // Removes every trace of an object from the data store
|
|
379
393
|
|
|
@@ -381,6 +395,7 @@ function removeInteractivity(store, object) {
|
|
|
381
395
|
internal.initialHits = internal.initialHits.filter(o => o !== object);
|
|
382
396
|
internal.hovered.forEach((value, key) => {
|
|
383
397
|
if (value.eventObject === object || value.object === object) {
|
|
398
|
+
// Clear out intersects, they are outdated by now
|
|
384
399
|
internal.hovered.delete(key);
|
|
385
400
|
}
|
|
386
401
|
});
|
|
@@ -390,31 +405,8 @@ function removeInteractivity(store, object) {
|
|
|
390
405
|
}
|
|
391
406
|
function createEvents(store) {
|
|
392
407
|
const temp = new THREE.Vector3();
|
|
393
|
-
/** Sets up defaultRaycaster */
|
|
394
|
-
|
|
395
|
-
function prepareRay(event) {
|
|
396
|
-
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
397
|
-
|
|
398
|
-
const state = store.getState();
|
|
399
|
-
const {
|
|
400
|
-
raycaster,
|
|
401
|
-
mouse,
|
|
402
|
-
camera,
|
|
403
|
-
size
|
|
404
|
-
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
405
|
-
// Events trigger outside of canvas when moved
|
|
406
|
-
|
|
407
|
-
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
408
|
-
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
409
|
-
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
410
|
-
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
411
|
-
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
412
|
-
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
413
|
-
raycaster.setFromCamera(mouse, camera);
|
|
414
|
-
}
|
|
415
408
|
/** Calculates delta */
|
|
416
409
|
|
|
417
|
-
|
|
418
410
|
function calculateDistance(event) {
|
|
419
411
|
const {
|
|
420
412
|
internal
|
|
@@ -434,55 +426,70 @@ function createEvents(store) {
|
|
|
434
426
|
}));
|
|
435
427
|
}
|
|
436
428
|
|
|
437
|
-
function intersect(filter) {
|
|
429
|
+
function intersect(event, filter) {
|
|
438
430
|
const state = store.getState();
|
|
439
|
-
const
|
|
440
|
-
raycaster,
|
|
441
|
-
internal
|
|
442
|
-
} = state; // Skip event handling when noEvents is set
|
|
443
|
-
|
|
444
|
-
if (!raycaster.enabled) return [];
|
|
445
|
-
const seen = new Set();
|
|
431
|
+
const duplicates = new Set();
|
|
446
432
|
const intersections = []; // Allow callers to eliminate event objects
|
|
447
433
|
|
|
448
|
-
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
449
|
|
|
450
|
-
|
|
450
|
+
if (state.raycaster.camera === undefined) {
|
|
451
|
+
var _state$previousRoot;
|
|
452
|
+
|
|
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 => {
|
|
451
468
|
const id = makeId(item);
|
|
452
|
-
if (
|
|
453
|
-
|
|
469
|
+
if (duplicates.has(id)) return false;
|
|
470
|
+
duplicates.add(id);
|
|
454
471
|
return true;
|
|
455
472
|
}); // https://github.com/mrdoob/three.js/issues/16031
|
|
456
|
-
// Allow custom userland intersect sort order
|
|
473
|
+
// Allow custom userland intersect sort order, this likely only makes sense on the root filter
|
|
457
474
|
|
|
458
|
-
if (
|
|
475
|
+
if (state.events.filter) hits = state.events.filter(hits, state); // Bubble up the events, find the event source (eventObject)
|
|
459
476
|
|
|
460
|
-
for (const
|
|
461
|
-
let eventObject =
|
|
477
|
+
for (const hit of hits) {
|
|
478
|
+
let eventObject = hit.object; // Bubble event up
|
|
462
479
|
|
|
463
480
|
while (eventObject) {
|
|
464
481
|
var _r3f2;
|
|
465
482
|
|
|
466
|
-
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...
|
|
483
|
+
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...hit,
|
|
467
484
|
eventObject
|
|
468
485
|
});
|
|
469
486
|
eventObject = eventObject.parent;
|
|
470
487
|
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
return intersections;
|
|
474
|
-
}
|
|
475
|
-
/** Creates filtered intersects and returns an array of positive hits */
|
|
476
|
-
|
|
488
|
+
} // If the interaction is captured, make all capturing targets part of the intersect.
|
|
477
489
|
|
|
478
|
-
function patchIntersects(intersections, event) {
|
|
479
|
-
const {
|
|
480
|
-
internal
|
|
481
|
-
} = store.getState(); // If the interaction is captured, make all capturing targets part of the
|
|
482
|
-
// intersect.
|
|
483
490
|
|
|
484
|
-
if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
|
|
485
|
-
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()) {
|
|
486
493
|
intersections.push(captureData.intersection);
|
|
487
494
|
}
|
|
488
495
|
}
|
|
@@ -495,13 +502,13 @@ function createEvents(store) {
|
|
|
495
502
|
function handleIntersects(intersections, event, delta, callback) {
|
|
496
503
|
const {
|
|
497
504
|
raycaster,
|
|
498
|
-
|
|
505
|
+
pointer,
|
|
499
506
|
camera,
|
|
500
507
|
internal
|
|
501
508
|
} = store.getState(); // If anything has been found, forward it to the event listeners
|
|
502
509
|
|
|
503
510
|
if (intersections.length) {
|
|
504
|
-
const unprojectedPoint = temp.set(
|
|
511
|
+
const unprojectedPoint = temp.set(pointer.x, pointer.y, 0).unproject(camera);
|
|
505
512
|
const localState = {
|
|
506
513
|
stopped: false
|
|
507
514
|
};
|
|
@@ -552,8 +559,7 @@ function createEvents(store) {
|
|
|
552
559
|
|
|
553
560
|
let raycastEvent = { ...hit,
|
|
554
561
|
...extractEventProps,
|
|
555
|
-
|
|
556
|
-
spaceY: mouse.y,
|
|
562
|
+
pointer,
|
|
557
563
|
intersections,
|
|
558
564
|
stopped: localState.stopped,
|
|
559
565
|
delta,
|
|
@@ -590,8 +596,6 @@ function createEvents(store) {
|
|
|
590
596
|
setPointerCapture,
|
|
591
597
|
releasePointerCapture
|
|
592
598
|
},
|
|
593
|
-
sourceEvent: event,
|
|
594
|
-
// deprecated
|
|
595
599
|
nativeEvent: event
|
|
596
600
|
}; // Call subscribers
|
|
597
601
|
|
|
@@ -656,14 +660,15 @@ function createEvents(store) {
|
|
|
656
660
|
const {
|
|
657
661
|
onPointerMissed,
|
|
658
662
|
internal
|
|
659
|
-
} = store.getState();
|
|
660
|
-
|
|
663
|
+
} = store.getState(); //prepareRay(event)
|
|
664
|
+
|
|
661
665
|
internal.lastEvent.current = event; // Get fresh intersects
|
|
662
666
|
|
|
663
667
|
const isPointerMove = name === 'onPointerMove';
|
|
664
668
|
const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
|
|
665
|
-
const filter = isPointerMove ? filterPointerEvents : undefined;
|
|
666
|
-
|
|
669
|
+
const filter = isPointerMove ? filterPointerEvents : undefined; //const hits = patchIntersects(intersect(filter), event)
|
|
670
|
+
|
|
671
|
+
const hits = intersect(event, filter);
|
|
667
672
|
const delta = isClickEvent ? calculateDistance(event) : 0; // Save initial coordinates on pointer-down
|
|
668
673
|
|
|
669
674
|
if (name === 'onPointerDown') {
|
|
@@ -746,23 +751,6 @@ function createEvents(store) {
|
|
|
746
751
|
};
|
|
747
752
|
}
|
|
748
753
|
|
|
749
|
-
// Type guard to tell a store from a portal
|
|
750
|
-
const isStore = def => def && !!def.getState;
|
|
751
|
-
|
|
752
|
-
const getContainer = (container, child) => {
|
|
753
|
-
var _container$__r3f$root, _container$__r3f;
|
|
754
|
-
|
|
755
|
-
return {
|
|
756
|
-
// If the container is not a root-store then it must be a THREE.Object3D into which part of the
|
|
757
|
-
// scene is portalled into. Now there can be two variants of this, either that object is part of
|
|
758
|
-
// the regular jsx tree, in which case it already has __r3f with a valid root attached, or it lies
|
|
759
|
-
// outside react, in which case we must take the root of the child that is about to be attached to it.
|
|
760
|
-
root: isStore(container) ? container : (_container$__r3f$root = (_container$__r3f = container.__r3f) == null ? void 0 : _container$__r3f.root) != null ? _container$__r3f$root : child.__r3f.root,
|
|
761
|
-
// The container is the eventual target into which objects are mounted, it has to be a THREE.Object3D
|
|
762
|
-
container: isStore(container) ? container.getState().scene : container
|
|
763
|
-
};
|
|
764
|
-
};
|
|
765
|
-
|
|
766
754
|
let catalogue = {};
|
|
767
755
|
|
|
768
756
|
let extend = objects => void (catalogue = { ...catalogue,
|
|
@@ -774,22 +762,9 @@ function createRenderer(roots, getEventPriority) {
|
|
|
774
762
|
args = [],
|
|
775
763
|
attach,
|
|
776
764
|
...props
|
|
777
|
-
}, root
|
|
765
|
+
}, root) {
|
|
778
766
|
let name = `${type[0].toUpperCase()}${type.slice(1)}`;
|
|
779
|
-
let instance; //
|
|
780
|
-
// Portals do not give us a root, they are themselves treated as a root by the reconciler
|
|
781
|
-
// In order to figure out the actual root we have to climb through fiber internals :(
|
|
782
|
-
|
|
783
|
-
if (!isStore(root) && internalInstanceHandle) {
|
|
784
|
-
const fn = node => {
|
|
785
|
-
if (!node.return) return node.stateNode && node.stateNode.containerInfo;else return fn(node.return);
|
|
786
|
-
};
|
|
787
|
-
|
|
788
|
-
root = fn(internalInstanceHandle);
|
|
789
|
-
} // Assert that by now we have a valid root
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
if (!root || !isStore(root)) throw `No valid root for ${name}!`; // Auto-attach geometries and materials
|
|
767
|
+
let instance; // Auto-attach geometries and materials
|
|
793
768
|
|
|
794
769
|
if (attach === undefined) {
|
|
795
770
|
if (name.endsWith('Geometry')) attach = 'geometry';else if (name.endsWith('Material')) attach = 'material';
|
|
@@ -799,6 +774,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
799
774
|
if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
|
|
800
775
|
const object = props.object;
|
|
801
776
|
instance = prepare(object, {
|
|
777
|
+
type,
|
|
802
778
|
root,
|
|
803
779
|
attach,
|
|
804
780
|
primitive: true
|
|
@@ -815,19 +791,21 @@ function createRenderer(roots, getEventPriority) {
|
|
|
815
791
|
// Append memoized props with args so it's not forgotten
|
|
816
792
|
|
|
817
793
|
instance = prepare(new target(...args), {
|
|
794
|
+
type,
|
|
818
795
|
root,
|
|
819
796
|
attach,
|
|
820
797
|
// TODO: Figure out what this is for
|
|
821
798
|
memoizedProps: {
|
|
822
|
-
args
|
|
799
|
+
args
|
|
823
800
|
}
|
|
824
801
|
});
|
|
825
802
|
} // It should NOT call onUpdate on object instanciation, because it hasn't been added to the
|
|
826
803
|
// view yet. If the callback relies on references for instance, they won't be ready yet, this is
|
|
827
804
|
// why it passes "true" here
|
|
805
|
+
// There is no reason to apply props to injects
|
|
828
806
|
|
|
829
807
|
|
|
830
|
-
applyProps$1(instance, props);
|
|
808
|
+
if (name !== 'inject') applyProps$1(instance, props);
|
|
831
809
|
return instance;
|
|
832
810
|
}
|
|
833
811
|
|
|
@@ -949,11 +927,11 @@ function createRenderer(roots, getEventPriority) {
|
|
|
949
927
|
}
|
|
950
928
|
|
|
951
929
|
function switchInstance(instance, type, newProps, fiber) {
|
|
952
|
-
var _instance$__r3f;
|
|
930
|
+
var _instance$__r3f, _instance$__r3f2;
|
|
953
931
|
|
|
954
932
|
const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
|
|
955
933
|
if (!parent) return;
|
|
956
|
-
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
|
|
957
935
|
// When args change the instance has to be re-constructed, which then
|
|
958
936
|
// forces r3f to re-parent the children and non-scene objects
|
|
959
937
|
// This can not include primitives, which should not have declarative children
|
|
@@ -986,19 +964,38 @@ function createRenderer(roots, getEventPriority) {
|
|
|
986
964
|
}
|
|
987
965
|
|
|
988
966
|
const reconciler = Reconciler({
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
967
|
+
createInstance,
|
|
968
|
+
removeChild,
|
|
969
|
+
appendChild,
|
|
970
|
+
appendInitialChild: appendChild,
|
|
971
|
+
insertBefore,
|
|
972
|
+
supportsMicrotask: true,
|
|
973
|
+
warnsIfNotActing: true,
|
|
974
|
+
supportsMutation: true,
|
|
975
|
+
isPrimaryRenderer: false,
|
|
976
|
+
noTimeout: -1,
|
|
977
|
+
appendChildToContainer: (container, child) => {
|
|
978
|
+
const scene = container.getState().scene; // Link current root to the default scene
|
|
994
979
|
|
|
995
|
-
|
|
996
|
-
appendChild(
|
|
980
|
+
scene.__r3f.root = container;
|
|
981
|
+
appendChild(scene, child);
|
|
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,
|
|
987
|
+
|
|
988
|
+
finalizeInitialChildren(instance) {
|
|
989
|
+
var _instance$__r3f3;
|
|
990
|
+
|
|
991
|
+
const localState = (_instance$__r3f3 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f3 : {}; // https://github.com/facebook/react/issues/20271
|
|
992
|
+
// Returning true will trigger commitMount
|
|
993
|
+
|
|
994
|
+
return !!localState.handlers;
|
|
997
995
|
},
|
|
998
|
-
removeChildFromContainer: (parentInstance, child) => removeChild(getContainer(parentInstance, child).container, child),
|
|
999
|
-
insertInContainerBefore: (parentInstance, child, beforeChild) => insertBefore(getContainer(parentInstance, child).container, child, beforeChild),
|
|
1000
996
|
|
|
1001
997
|
prepareUpdate(instance, type, oldProps, newProps) {
|
|
998
|
+
// Create diff-sets
|
|
1002
999
|
if (instance.__r3f.primitive && newProps.object && newProps.object !== instance) {
|
|
1003
1000
|
return [true];
|
|
1004
1001
|
} else {
|
|
@@ -1031,40 +1028,58 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1031
1028
|
else applyProps$1(instance, diff);
|
|
1032
1029
|
},
|
|
1033
1030
|
|
|
1031
|
+
commitMount(instance, type, props, int) {
|
|
1032
|
+
var _instance$__r3f4;
|
|
1033
|
+
|
|
1034
|
+
// https://github.com/facebook/react/issues/20271
|
|
1035
|
+
// This will make sure events are only added once to the central container
|
|
1036
|
+
const localState = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
|
|
1037
|
+
|
|
1038
|
+
if (instance.raycast && localState.handlers && localState.eventCount) {
|
|
1039
|
+
instance.__r3f.root.getState().internal.interaction.push(instance);
|
|
1040
|
+
}
|
|
1041
|
+
},
|
|
1042
|
+
|
|
1043
|
+
getPublicInstance: instance => instance,
|
|
1044
|
+
shouldDeprioritizeSubtree: () => false,
|
|
1045
|
+
prepareForCommit: () => null,
|
|
1046
|
+
preparePortalMount: container => prepare(container.getState().scene),
|
|
1047
|
+
resetAfterCommit: () => {},
|
|
1048
|
+
shouldSetTextContent: () => false,
|
|
1049
|
+
clearContainer: () => false,
|
|
1050
|
+
detachDeletedInstance: () => {},
|
|
1051
|
+
createTextInstance: () => {},
|
|
1052
|
+
|
|
1034
1053
|
hideInstance(instance) {
|
|
1035
|
-
var _instance$
|
|
1054
|
+
var _instance$__r3f5;
|
|
1036
1055
|
|
|
1037
1056
|
// Deatch while the instance is hidden
|
|
1038
1057
|
const {
|
|
1039
1058
|
attach: type,
|
|
1040
1059
|
parent
|
|
1041
|
-
} = (_instance$
|
|
1060
|
+
} = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
|
|
1042
1061
|
if (type && parent) detach(parent, instance, type);
|
|
1043
1062
|
if (instance.isObject3D) instance.visible = false;
|
|
1044
1063
|
invalidateInstance(instance);
|
|
1045
1064
|
},
|
|
1046
1065
|
|
|
1047
1066
|
unhideInstance(instance, props) {
|
|
1048
|
-
var _instance$
|
|
1067
|
+
var _instance$__r3f6;
|
|
1049
1068
|
|
|
1050
1069
|
// Re-attach when the instance is unhidden
|
|
1051
1070
|
const {
|
|
1052
1071
|
attach: type,
|
|
1053
1072
|
parent
|
|
1054
|
-
} = (_instance$
|
|
1073
|
+
} = (_instance$__r3f6 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f6 : {};
|
|
1055
1074
|
if (type && parent) attach(parent, instance, type);
|
|
1056
1075
|
if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
|
|
1057
1076
|
invalidateInstance(instance);
|
|
1058
1077
|
},
|
|
1059
1078
|
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
insertBefore,
|
|
1065
|
-
warnsIfNotActing: true,
|
|
1066
|
-
supportsMutation: true,
|
|
1067
|
-
isPrimaryRenderer: false,
|
|
1079
|
+
hideTextInstance: () => {
|
|
1080
|
+
throw new Error('Text is not allowed in the R3F tree.');
|
|
1081
|
+
},
|
|
1082
|
+
// prettier-ignore
|
|
1068
1083
|
getCurrentEventPriority: () => getEventPriority ? getEventPriority() : DefaultEventPriority,
|
|
1069
1084
|
// @ts-ignore
|
|
1070
1085
|
now: typeof performance !== 'undefined' && is.fun(performance.now) ? performance.now : is.fun(Date.now) ? Date.now : undefined,
|
|
@@ -1073,47 +1088,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1073
1088
|
// @ts-ignore
|
|
1074
1089
|
cancelTimeout: is.fun(clearTimeout) ? clearTimeout : undefined,
|
|
1075
1090
|
setTimeout: is.fun(setTimeout) ? setTimeout : undefined,
|
|
1076
|
-
clearTimeout: is.fun(clearTimeout) ? clearTimeout : undefined
|
|
1077
|
-
noTimeout: -1,
|
|
1078
|
-
hideTextInstance: () => {
|
|
1079
|
-
throw new Error('Text is not allowed in the R3F tree.');
|
|
1080
|
-
},
|
|
1081
|
-
// prettier-ignore
|
|
1082
|
-
getPublicInstance: instance => instance,
|
|
1083
|
-
getRootHostContext: () => null,
|
|
1084
|
-
getChildHostContext: parentHostContext => parentHostContext,
|
|
1085
|
-
createTextInstance: () => {},
|
|
1086
|
-
|
|
1087
|
-
finalizeInitialChildren(instance) {
|
|
1088
|
-
var _instance$__r3f4;
|
|
1089
|
-
|
|
1090
|
-
// https://github.com/facebook/react/issues/20271
|
|
1091
|
-
// Returning true will trigger commitMount
|
|
1092
|
-
const localState = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
|
|
1093
|
-
return !!localState.handlers;
|
|
1094
|
-
},
|
|
1095
|
-
|
|
1096
|
-
commitMount(instance)
|
|
1097
|
-
/*, type, props*/
|
|
1098
|
-
{
|
|
1099
|
-
var _instance$__r3f5;
|
|
1100
|
-
|
|
1101
|
-
// https://github.com/facebook/react/issues/20271
|
|
1102
|
-
// This will make sure events are only added once to the central container
|
|
1103
|
-
const localState = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
|
|
1104
|
-
|
|
1105
|
-
if (instance.raycast && localState.handlers && localState.eventCount) {
|
|
1106
|
-
instance.__r3f.root.getState().internal.interaction.push(instance);
|
|
1107
|
-
}
|
|
1108
|
-
},
|
|
1109
|
-
|
|
1110
|
-
shouldDeprioritizeSubtree: () => false,
|
|
1111
|
-
prepareForCommit: () => null,
|
|
1112
|
-
preparePortalMount: containerInfo => prepare(containerInfo),
|
|
1113
|
-
resetAfterCommit: () => {},
|
|
1114
|
-
shouldSetTextContent: () => false,
|
|
1115
|
-
clearContainer: () => false,
|
|
1116
|
-
detachDeletedInstance: () => {}
|
|
1091
|
+
clearTimeout: is.fun(clearTimeout) ? clearTimeout : undefined
|
|
1117
1092
|
});
|
|
1118
1093
|
return {
|
|
1119
1094
|
reconciler,
|
|
@@ -1173,16 +1148,18 @@ const createStore = (invalidate, advance) => {
|
|
|
1173
1148
|
}));
|
|
1174
1149
|
|
|
1175
1150
|
return {
|
|
1151
|
+
set,
|
|
1152
|
+
get,
|
|
1176
1153
|
// Mock objects that have to be configured
|
|
1177
1154
|
gl: null,
|
|
1178
1155
|
camera: null,
|
|
1179
1156
|
raycaster: null,
|
|
1180
1157
|
events: {
|
|
1158
|
+
priority: 1,
|
|
1159
|
+
enabled: true,
|
|
1181
1160
|
connected: false
|
|
1182
1161
|
},
|
|
1183
1162
|
xr: null,
|
|
1184
|
-
set,
|
|
1185
|
-
get,
|
|
1186
1163
|
invalidate: () => invalidate(get()),
|
|
1187
1164
|
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1188
1165
|
linear: false,
|
|
@@ -1190,7 +1167,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1190
1167
|
scene: prepare(new THREE.Scene()),
|
|
1191
1168
|
controls: null,
|
|
1192
1169
|
clock: new THREE.Clock(),
|
|
1193
|
-
|
|
1170
|
+
pointer: new THREE.Vector2(),
|
|
1194
1171
|
frameloop: 'always',
|
|
1195
1172
|
onPointerMissed: undefined,
|
|
1196
1173
|
performance: {
|
|
@@ -1259,6 +1236,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1259
1236
|
frameloop
|
|
1260
1237
|
}));
|
|
1261
1238
|
},
|
|
1239
|
+
previousRoot: undefined,
|
|
1262
1240
|
internal: {
|
|
1263
1241
|
active: false,
|
|
1264
1242
|
priority: 0,
|
|
@@ -1486,6 +1464,11 @@ function loadingFn(extensions, onProgress) {
|
|
|
1486
1464
|
};
|
|
1487
1465
|
}
|
|
1488
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
|
+
}
|
|
1489
1472
|
function useLoader(Proto, input, extensions, onProgress) {
|
|
1490
1473
|
// Use suspense to load async assets
|
|
1491
1474
|
const keys = Array.isArray(input) ? input : [input];
|
|
@@ -1585,9 +1568,7 @@ function createRoot(canvas) {
|
|
|
1585
1568
|
params,
|
|
1586
1569
|
...options
|
|
1587
1570
|
} = raycastOptions || {};
|
|
1588
|
-
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, {
|
|
1589
|
-
enabled: true,
|
|
1590
|
-
...options
|
|
1571
|
+
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options
|
|
1591
1572
|
});
|
|
1592
1573
|
if (!is.equ(params, raycaster.params, shallowLoose)) applyProps(raycaster, {
|
|
1593
1574
|
params: { ...raycaster.params,
|
|
@@ -1623,7 +1604,7 @@ function createRoot(canvas) {
|
|
|
1623
1604
|
|
|
1624
1605
|
const handleSessionChange = () => {
|
|
1625
1606
|
const gl = store.getState().gl;
|
|
1626
|
-
gl.xr.enabled = gl.xr.isPresenting; // @ts-
|
|
1607
|
+
gl.xr.enabled = gl.xr.isPresenting; // @ts-ignore
|
|
1627
1608
|
// WebXRManager's signature is incorrect.
|
|
1628
1609
|
// See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
|
|
1629
1610
|
|
|
@@ -1665,6 +1646,7 @@ function createRoot(canvas) {
|
|
|
1665
1646
|
} // Set color management
|
|
1666
1647
|
|
|
1667
1648
|
|
|
1649
|
+
if (THREE.ColorManagement) THREE.ColorManagement.legacyMode = false;
|
|
1668
1650
|
const outputEncoding = linear ? THREE.LinearEncoding : THREE.sRGBEncoding;
|
|
1669
1651
|
const toneMapping = flat ? THREE.NoToneMapping : THREE.ACESFilmicToneMapping;
|
|
1670
1652
|
if (gl.outputEncoding !== outputEncoding) gl.outputEncoding = outputEncoding;
|
|
@@ -1740,9 +1722,10 @@ function Provider({
|
|
|
1740
1722
|
internal: { ...state.internal,
|
|
1741
1723
|
active: true
|
|
1742
1724
|
}
|
|
1743
|
-
})); // Connect events
|
|
1725
|
+
})); // Connect events to the targets parent, this is done to ensure events are registered on
|
|
1726
|
+
// a shared target, and not on the canvas itself
|
|
1744
1727
|
|
|
1745
|
-
state.events.connect == null ? void 0 : state.events.connect(target); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
|
|
1728
|
+
state.events.connect == null ? void 0 : state.events.connect(target.parentNode); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
|
|
1746
1729
|
|
|
1747
1730
|
if (onCreated) onCreated(state); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1748
1731
|
}, []);
|
|
@@ -1780,10 +1763,65 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
1780
1763
|
}
|
|
1781
1764
|
}
|
|
1782
1765
|
|
|
1783
|
-
|
|
1766
|
+
function createPortal(children, container, state) {
|
|
1767
|
+
return /*#__PURE__*/React.createElement(Portal, {
|
|
1768
|
+
children: children,
|
|
1769
|
+
container: container,
|
|
1770
|
+
state: state
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
|
|
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
|
+
};
|
|
1784
1793
|
|
|
1785
|
-
|
|
1786
|
-
|
|
1794
|
+
if (injectState) {
|
|
1795
|
+
// Only the fields of "state" that do not differ from injectState
|
|
1796
|
+
Object.keys(state).forEach(key => {
|
|
1797
|
+
if (state[key] !== injectState[key]) delete intersect[key];
|
|
1798
|
+
});
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
return { ...intersect,
|
|
1802
|
+
scene: container,
|
|
1803
|
+
previousRoot,
|
|
1804
|
+
raycaster,
|
|
1805
|
+
events: { ...state.events,
|
|
1806
|
+
...events
|
|
1807
|
+
},
|
|
1808
|
+
...rest
|
|
1809
|
+
};
|
|
1810
|
+
}, [state]);
|
|
1811
|
+
const [useInjectStore] = React.useState(() => {
|
|
1812
|
+
const store = create((set, get) => ({ ...inject(previousRoot.getState()),
|
|
1813
|
+
set,
|
|
1814
|
+
get
|
|
1815
|
+
}));
|
|
1816
|
+
previousRoot.subscribe(state => useInjectStore.setState(injectState => inject(state, injectState)));
|
|
1817
|
+
return store;
|
|
1818
|
+
});
|
|
1819
|
+
React.useEffect(() => {
|
|
1820
|
+
useInjectStore.setState(injectState => inject(previousRoot.getState(), injectState));
|
|
1821
|
+
}, [inject]);
|
|
1822
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, reconciler.createPortal( /*#__PURE__*/React.createElement(context.Provider, {
|
|
1823
|
+
value: useInjectStore
|
|
1824
|
+
}, children), useInjectStore, null));
|
|
1787
1825
|
}
|
|
1788
1826
|
|
|
1789
1827
|
reconciler.injectIntoDevTools({
|
|
@@ -1791,5 +1829,6 @@ reconciler.injectIntoDevTools({
|
|
|
1791
1829
|
rendererPackageName: '@react-three/fiber',
|
|
1792
1830
|
version: '18.0.0'
|
|
1793
1831
|
});
|
|
1832
|
+
const act = React.unstable_act;
|
|
1794
1833
|
|
|
1795
|
-
export { createRoot as a,
|
|
1834
|
+
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 };
|