@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,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var React = require('react');
|
|
4
|
-
var suspendReact = require('suspend-react');
|
|
5
3
|
var THREE = require('three');
|
|
4
|
+
var React = require('react');
|
|
6
5
|
var constants = require('react-reconciler/constants');
|
|
7
6
|
var create = require('zustand');
|
|
8
7
|
var Reconciler = require('react-reconciler');
|
|
9
8
|
var scheduler = require('scheduler');
|
|
9
|
+
var suspendReact = require('suspend-react');
|
|
10
10
|
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
12
12
|
|
|
@@ -30,8 +30,8 @@ function _interopNamespace(e) {
|
|
|
30
30
|
return Object.freeze(n);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
34
33
|
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
34
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
35
35
|
var create__default = /*#__PURE__*/_interopDefault(create);
|
|
36
36
|
var Reconciler__default = /*#__PURE__*/_interopDefault(Reconciler);
|
|
37
37
|
|
|
@@ -44,6 +44,15 @@ const isDiffSet = def => def && !!def.memoized && !!def.changes;
|
|
|
44
44
|
function calculateDpr(dpr) {
|
|
45
45
|
return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], window.devicePixelRatio), dpr[1]) : dpr;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Returns instance root state
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
const getRootState = obj => {
|
|
52
|
+
var _r3f;
|
|
53
|
+
|
|
54
|
+
return (_r3f = obj.__r3f) == null ? void 0 : _r3f.root.getState();
|
|
55
|
+
};
|
|
47
56
|
/**
|
|
48
57
|
* Picks or omits keys from an object
|
|
49
58
|
* `omit` will filter out keys, and otherwise cherry-pick them.
|
|
@@ -53,11 +62,7 @@ function filterKeys(obj, omit, ...keys) {
|
|
|
53
62
|
const keysToSelect = new Set(keys);
|
|
54
63
|
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
55
64
|
const shouldInclude = !omit;
|
|
56
|
-
|
|
57
|
-
if (keysToSelect.has(key) === shouldInclude) {
|
|
58
|
-
acc[key] = value;
|
|
59
|
-
}
|
|
60
|
-
|
|
65
|
+
if (keysToSelect.has(key) === shouldInclude) acc[key] = value;
|
|
61
66
|
return acc;
|
|
62
67
|
}, {});
|
|
63
68
|
}
|
|
@@ -95,7 +100,7 @@ const is = {
|
|
|
95
100
|
const isArr = is.arr(a);
|
|
96
101
|
if (isArr && arrays === 'reference') return a === b; // Array or Object, shallow compare first to see if it's a match
|
|
97
102
|
|
|
98
|
-
if ((isArr || isObj) && a
|
|
103
|
+
if ((isArr || isObj) && a === b) return true; // Last resort, go through keys
|
|
99
104
|
|
|
100
105
|
let i;
|
|
101
106
|
|
|
@@ -103,7 +108,13 @@ const is = {
|
|
|
103
108
|
|
|
104
109
|
for (i in strict ? b : a) if (a[i] !== b[i]) return false;
|
|
105
110
|
|
|
106
|
-
|
|
111
|
+
if (is.und(i)) {
|
|
112
|
+
if (isArr && a.length === 0 && b.length === 0) return true;
|
|
113
|
+
if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
|
|
114
|
+
if (a !== b) return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return true;
|
|
107
118
|
}
|
|
108
119
|
|
|
109
120
|
}; // Collects nodes and materials from a THREE.Object3D
|
|
@@ -138,7 +149,9 @@ function prepare(object, state) {
|
|
|
138
149
|
|
|
139
150
|
if (state != null && state.primitive || !instance.__r3f) {
|
|
140
151
|
instance.__r3f = {
|
|
152
|
+
type: '',
|
|
141
153
|
root: null,
|
|
154
|
+
previousAttach: null,
|
|
142
155
|
memoizedProps: {},
|
|
143
156
|
eventCount: 0,
|
|
144
157
|
handlers: {},
|
|
@@ -166,32 +179,42 @@ function resolve(instance, key) {
|
|
|
166
179
|
target,
|
|
167
180
|
key
|
|
168
181
|
};
|
|
169
|
-
}
|
|
182
|
+
} // Checks if a dash-cased string ends with an integer
|
|
183
|
+
|
|
170
184
|
|
|
185
|
+
const INDEX_REGEX = /-\d+$/;
|
|
171
186
|
function attach(parent, child, type) {
|
|
172
187
|
if (is.str(type)) {
|
|
188
|
+
// If attaching into an array (foo-0), create one
|
|
189
|
+
if (INDEX_REGEX.test(type)) {
|
|
190
|
+
const root = type.replace(INDEX_REGEX, '');
|
|
191
|
+
const {
|
|
192
|
+
target,
|
|
193
|
+
key
|
|
194
|
+
} = resolve(parent, root);
|
|
195
|
+
if (!Array.isArray(target[key])) target[key] = [];
|
|
196
|
+
}
|
|
197
|
+
|
|
173
198
|
const {
|
|
174
199
|
target,
|
|
175
200
|
key
|
|
176
201
|
} = resolve(parent, type);
|
|
177
|
-
|
|
202
|
+
child.__r3f.previousAttach = target[key];
|
|
178
203
|
target[key] = child;
|
|
179
|
-
} else
|
|
180
|
-
const [attach] = type;
|
|
181
|
-
if (is.str(attach)) parent[attach](child);else if (is.fun(attach)) attach(parent, child);
|
|
182
|
-
}
|
|
204
|
+
} else child.__r3f.previousAttach = type(parent, child);
|
|
183
205
|
}
|
|
184
206
|
function detach(parent, child, type) {
|
|
207
|
+
var _child$__r3f, _child$__r3f2;
|
|
208
|
+
|
|
185
209
|
if (is.str(type)) {
|
|
186
210
|
const {
|
|
187
211
|
target,
|
|
188
212
|
key
|
|
189
213
|
} = resolve(parent, type);
|
|
190
|
-
target[key] =
|
|
191
|
-
} else
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
214
|
+
target[key] = child.__r3f.previousAttach;
|
|
215
|
+
} else (_child$__r3f = child.__r3f) == null ? void 0 : _child$__r3f.previousAttach == null ? void 0 : _child$__r3f.previousAttach(parent, child);
|
|
216
|
+
|
|
217
|
+
(_child$__r3f2 = child.__r3f) == null ? true : delete _child$__r3f2.previousAttach;
|
|
195
218
|
} // This function prepares a set of changes to be applied to the instance
|
|
196
219
|
|
|
197
220
|
function diffProps(instance, {
|
|
@@ -279,11 +302,11 @@ function applyProps$1(instance, data) {
|
|
|
279
302
|
if (value === DEFAULT + 'remove') {
|
|
280
303
|
if (targetProp && targetProp.constructor) {
|
|
281
304
|
// use the prop constructor to find the default it should be
|
|
282
|
-
value = new targetProp.constructor(memoized.args);
|
|
305
|
+
value = new targetProp.constructor(...memoized.args);
|
|
283
306
|
} else if (currentInstance.constructor) {
|
|
284
307
|
// create a blank slate of the instance and copy the particular parameter.
|
|
285
308
|
// @ts-ignore
|
|
286
|
-
const defaultClassCall = new currentInstance.constructor(currentInstance.__r3f.memoizedProps.args);
|
|
309
|
+
const defaultClassCall = new currentInstance.constructor(...currentInstance.__r3f.memoizedProps.args);
|
|
287
310
|
value = defaultClassCall[targetProp]; // destory the instance
|
|
288
311
|
|
|
289
312
|
if (defaultClassCall.dispose) defaultClassCall.dispose(); // instance does not have constructor, just set it to 0
|
|
@@ -311,20 +334,10 @@ function applyProps$1(instance, data) {
|
|
|
311
334
|
|
|
312
335
|
if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
|
|
313
336
|
else if (targetProp instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) targetProp.mask = value.mask; // Otherwise just set ...
|
|
314
|
-
else targetProp.set(value);
|
|
315
|
-
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
316
|
-
|
|
317
|
-
if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
|
|
337
|
+
else targetProp.set(value);
|
|
318
338
|
} // Else, just overwrite the value
|
|
319
339
|
|
|
320
|
-
} else
|
|
321
|
-
currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
|
|
322
|
-
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
323
|
-
|
|
324
|
-
if (!rootState.linear && currentInstance[key] instanceof THREE__namespace.Texture) {
|
|
325
|
-
currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
340
|
+
} else currentInstance[key] = value;
|
|
328
341
|
|
|
329
342
|
invalidateInstance(instance);
|
|
330
343
|
return instance;
|
|
@@ -403,6 +416,7 @@ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
|
|
|
403
416
|
|
|
404
417
|
function removeInteractivity(store, object) {
|
|
405
418
|
const {
|
|
419
|
+
events,
|
|
406
420
|
internal
|
|
407
421
|
} = store.getState(); // Removes every trace of an object from the data store
|
|
408
422
|
|
|
@@ -410,6 +424,7 @@ function removeInteractivity(store, object) {
|
|
|
410
424
|
internal.initialHits = internal.initialHits.filter(o => o !== object);
|
|
411
425
|
internal.hovered.forEach((value, key) => {
|
|
412
426
|
if (value.eventObject === object || value.object === object) {
|
|
427
|
+
// Clear out intersects, they are outdated by now
|
|
413
428
|
internal.hovered.delete(key);
|
|
414
429
|
}
|
|
415
430
|
});
|
|
@@ -419,31 +434,8 @@ function removeInteractivity(store, object) {
|
|
|
419
434
|
}
|
|
420
435
|
function createEvents(store) {
|
|
421
436
|
const temp = new THREE__namespace.Vector3();
|
|
422
|
-
/** Sets up defaultRaycaster */
|
|
423
|
-
|
|
424
|
-
function prepareRay(event) {
|
|
425
|
-
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
426
|
-
|
|
427
|
-
const state = store.getState();
|
|
428
|
-
const {
|
|
429
|
-
raycaster,
|
|
430
|
-
mouse,
|
|
431
|
-
camera,
|
|
432
|
-
size
|
|
433
|
-
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
434
|
-
// Events trigger outside of canvas when moved
|
|
435
|
-
|
|
436
|
-
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
437
|
-
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
438
|
-
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
439
|
-
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
440
|
-
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
441
|
-
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
442
|
-
raycaster.setFromCamera(mouse, camera);
|
|
443
|
-
}
|
|
444
437
|
/** Calculates delta */
|
|
445
438
|
|
|
446
|
-
|
|
447
439
|
function calculateDistance(event) {
|
|
448
440
|
const {
|
|
449
441
|
internal
|
|
@@ -463,55 +455,70 @@ function createEvents(store) {
|
|
|
463
455
|
}));
|
|
464
456
|
}
|
|
465
457
|
|
|
466
|
-
function intersect(filter) {
|
|
458
|
+
function intersect(event, filter) {
|
|
467
459
|
const state = store.getState();
|
|
468
|
-
const
|
|
469
|
-
raycaster,
|
|
470
|
-
internal
|
|
471
|
-
} = state; // Skip event handling when noEvents is set
|
|
472
|
-
|
|
473
|
-
if (!raycaster.enabled) return [];
|
|
474
|
-
const seen = new Set();
|
|
460
|
+
const duplicates = new Set();
|
|
475
461
|
const intersections = []; // Allow callers to eliminate event objects
|
|
476
462
|
|
|
477
|
-
const eventsObjects = filter ? filter(internal.interaction) : internal.interaction; //
|
|
463
|
+
const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction; // Reset all raycaster cameras to undefined
|
|
464
|
+
|
|
465
|
+
eventsObjects.forEach(obj => {
|
|
466
|
+
const state = getRootState(obj);
|
|
467
|
+
|
|
468
|
+
if (state) {
|
|
469
|
+
state.raycaster.camera = undefined;
|
|
470
|
+
}
|
|
471
|
+
}); // Collect events
|
|
472
|
+
|
|
473
|
+
let hits = eventsObjects // Intersect objects
|
|
474
|
+
.flatMap(obj => {
|
|
475
|
+
const state = getRootState(obj); // Skip event handling when noEvents is set, or when the raycasters camera is null
|
|
478
476
|
|
|
479
|
-
|
|
477
|
+
if (!state || !state.events.enabled || state.raycaster.camera === null) return []; // When the camera is undefined we have to call the event layers update function
|
|
478
|
+
|
|
479
|
+
if (state.raycaster.camera === undefined) {
|
|
480
|
+
var _state$previousRoot;
|
|
481
|
+
|
|
482
|
+
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
|
|
483
|
+
|
|
484
|
+
if (state.raycaster.camera === undefined) state.raycaster.camera = null;
|
|
485
|
+
} // Intersect object by object
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
return state.raycaster.camera ? state.raycaster.intersectObject(obj, true) : [];
|
|
489
|
+
}) // Sort by event priority and distance
|
|
490
|
+
.sort((a, b) => {
|
|
491
|
+
const aState = getRootState(a.object);
|
|
492
|
+
const bState = getRootState(b.object);
|
|
493
|
+
if (!aState || !bState) return 0;
|
|
494
|
+
return bState.events.priority - aState.events.priority || a.distance - b.distance;
|
|
495
|
+
}) // Filter out duplicates
|
|
496
|
+
.filter(item => {
|
|
480
497
|
const id = makeId(item);
|
|
481
|
-
if (
|
|
482
|
-
|
|
498
|
+
if (duplicates.has(id)) return false;
|
|
499
|
+
duplicates.add(id);
|
|
483
500
|
return true;
|
|
484
501
|
}); // https://github.com/mrdoob/three.js/issues/16031
|
|
485
|
-
// Allow custom userland intersect sort order
|
|
502
|
+
// Allow custom userland intersect sort order, this likely only makes sense on the root filter
|
|
486
503
|
|
|
487
|
-
if (
|
|
504
|
+
if (state.events.filter) hits = state.events.filter(hits, state); // Bubble up the events, find the event source (eventObject)
|
|
488
505
|
|
|
489
|
-
for (const
|
|
490
|
-
let eventObject =
|
|
506
|
+
for (const hit of hits) {
|
|
507
|
+
let eventObject = hit.object; // Bubble event up
|
|
491
508
|
|
|
492
509
|
while (eventObject) {
|
|
493
510
|
var _r3f2;
|
|
494
511
|
|
|
495
|
-
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...
|
|
512
|
+
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...hit,
|
|
496
513
|
eventObject
|
|
497
514
|
});
|
|
498
515
|
eventObject = eventObject.parent;
|
|
499
516
|
}
|
|
500
|
-
}
|
|
517
|
+
} // If the interaction is captured, make all capturing targets part of the intersect.
|
|
501
518
|
|
|
502
|
-
return intersections;
|
|
503
|
-
}
|
|
504
|
-
/** Creates filtered intersects and returns an array of positive hits */
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
function patchIntersects(intersections, event) {
|
|
508
|
-
const {
|
|
509
|
-
internal
|
|
510
|
-
} = store.getState(); // If the interaction is captured, make all capturing targets part of the
|
|
511
|
-
// intersect.
|
|
512
519
|
|
|
513
|
-
if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
|
|
514
|
-
for (let captureData of internal.capturedMap.get(event.pointerId).values()) {
|
|
520
|
+
if ('pointerId' in event && state.internal.capturedMap.has(event.pointerId)) {
|
|
521
|
+
for (let captureData of state.internal.capturedMap.get(event.pointerId).values()) {
|
|
515
522
|
intersections.push(captureData.intersection);
|
|
516
523
|
}
|
|
517
524
|
}
|
|
@@ -524,13 +531,13 @@ function createEvents(store) {
|
|
|
524
531
|
function handleIntersects(intersections, event, delta, callback) {
|
|
525
532
|
const {
|
|
526
533
|
raycaster,
|
|
527
|
-
|
|
534
|
+
pointer,
|
|
528
535
|
camera,
|
|
529
536
|
internal
|
|
530
537
|
} = store.getState(); // If anything has been found, forward it to the event listeners
|
|
531
538
|
|
|
532
539
|
if (intersections.length) {
|
|
533
|
-
const unprojectedPoint = temp.set(
|
|
540
|
+
const unprojectedPoint = temp.set(pointer.x, pointer.y, 0).unproject(camera);
|
|
534
541
|
const localState = {
|
|
535
542
|
stopped: false
|
|
536
543
|
};
|
|
@@ -581,8 +588,7 @@ function createEvents(store) {
|
|
|
581
588
|
|
|
582
589
|
let raycastEvent = { ...hit,
|
|
583
590
|
...extractEventProps,
|
|
584
|
-
|
|
585
|
-
spaceY: mouse.y,
|
|
591
|
+
pointer,
|
|
586
592
|
intersections,
|
|
587
593
|
stopped: localState.stopped,
|
|
588
594
|
delta,
|
|
@@ -619,8 +625,6 @@ function createEvents(store) {
|
|
|
619
625
|
setPointerCapture,
|
|
620
626
|
releasePointerCapture
|
|
621
627
|
},
|
|
622
|
-
sourceEvent: event,
|
|
623
|
-
// deprecated
|
|
624
628
|
nativeEvent: event
|
|
625
629
|
}; // Call subscribers
|
|
626
630
|
|
|
@@ -685,14 +689,15 @@ function createEvents(store) {
|
|
|
685
689
|
const {
|
|
686
690
|
onPointerMissed,
|
|
687
691
|
internal
|
|
688
|
-
} = store.getState();
|
|
689
|
-
|
|
692
|
+
} = store.getState(); //prepareRay(event)
|
|
693
|
+
|
|
690
694
|
internal.lastEvent.current = event; // Get fresh intersects
|
|
691
695
|
|
|
692
696
|
const isPointerMove = name === 'onPointerMove';
|
|
693
697
|
const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
|
|
694
|
-
const filter = isPointerMove ? filterPointerEvents : undefined;
|
|
695
|
-
|
|
698
|
+
const filter = isPointerMove ? filterPointerEvents : undefined; //const hits = patchIntersects(intersect(filter), event)
|
|
699
|
+
|
|
700
|
+
const hits = intersect(event, filter);
|
|
696
701
|
const delta = isClickEvent ? calculateDistance(event) : 0; // Save initial coordinates on pointer-down
|
|
697
702
|
|
|
698
703
|
if (name === 'onPointerDown') {
|
|
@@ -775,23 +780,6 @@ function createEvents(store) {
|
|
|
775
780
|
};
|
|
776
781
|
}
|
|
777
782
|
|
|
778
|
-
// Type guard to tell a store from a portal
|
|
779
|
-
const isStore = def => def && !!def.getState;
|
|
780
|
-
|
|
781
|
-
const getContainer = (container, child) => {
|
|
782
|
-
var _container$__r3f$root, _container$__r3f;
|
|
783
|
-
|
|
784
|
-
return {
|
|
785
|
-
// If the container is not a root-store then it must be a THREE.Object3D into which part of the
|
|
786
|
-
// scene is portalled into. Now there can be two variants of this, either that object is part of
|
|
787
|
-
// the regular jsx tree, in which case it already has __r3f with a valid root attached, or it lies
|
|
788
|
-
// outside react, in which case we must take the root of the child that is about to be attached to it.
|
|
789
|
-
root: isStore(container) ? container : (_container$__r3f$root = (_container$__r3f = container.__r3f) == null ? void 0 : _container$__r3f.root) != null ? _container$__r3f$root : child.__r3f.root,
|
|
790
|
-
// The container is the eventual target into which objects are mounted, it has to be a THREE.Object3D
|
|
791
|
-
container: isStore(container) ? container.getState().scene : container
|
|
792
|
-
};
|
|
793
|
-
};
|
|
794
|
-
|
|
795
783
|
let catalogue = {};
|
|
796
784
|
|
|
797
785
|
let extend = objects => void (catalogue = { ...catalogue,
|
|
@@ -803,22 +791,9 @@ function createRenderer(roots, getEventPriority) {
|
|
|
803
791
|
args = [],
|
|
804
792
|
attach,
|
|
805
793
|
...props
|
|
806
|
-
}, root
|
|
794
|
+
}, root) {
|
|
807
795
|
let name = `${type[0].toUpperCase()}${type.slice(1)}`;
|
|
808
|
-
let instance; //
|
|
809
|
-
// Portals do not give us a root, they are themselves treated as a root by the reconciler
|
|
810
|
-
// In order to figure out the actual root we have to climb through fiber internals :(
|
|
811
|
-
|
|
812
|
-
if (!isStore(root) && internalInstanceHandle) {
|
|
813
|
-
const fn = node => {
|
|
814
|
-
if (!node.return) return node.stateNode && node.stateNode.containerInfo;else return fn(node.return);
|
|
815
|
-
};
|
|
816
|
-
|
|
817
|
-
root = fn(internalInstanceHandle);
|
|
818
|
-
} // Assert that by now we have a valid root
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
if (!root || !isStore(root)) throw `No valid root for ${name}!`; // Auto-attach geometries and materials
|
|
796
|
+
let instance; // Auto-attach geometries and materials
|
|
822
797
|
|
|
823
798
|
if (attach === undefined) {
|
|
824
799
|
if (name.endsWith('Geometry')) attach = 'geometry';else if (name.endsWith('Material')) attach = 'material';
|
|
@@ -828,6 +803,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
828
803
|
if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
|
|
829
804
|
const object = props.object;
|
|
830
805
|
instance = prepare(object, {
|
|
806
|
+
type,
|
|
831
807
|
root,
|
|
832
808
|
attach,
|
|
833
809
|
primitive: true
|
|
@@ -844,19 +820,21 @@ function createRenderer(roots, getEventPriority) {
|
|
|
844
820
|
// Append memoized props with args so it's not forgotten
|
|
845
821
|
|
|
846
822
|
instance = prepare(new target(...args), {
|
|
823
|
+
type,
|
|
847
824
|
root,
|
|
848
825
|
attach,
|
|
849
826
|
// TODO: Figure out what this is for
|
|
850
827
|
memoizedProps: {
|
|
851
|
-
args
|
|
828
|
+
args
|
|
852
829
|
}
|
|
853
830
|
});
|
|
854
831
|
} // It should NOT call onUpdate on object instanciation, because it hasn't been added to the
|
|
855
832
|
// view yet. If the callback relies on references for instance, they won't be ready yet, this is
|
|
856
833
|
// why it passes "true" here
|
|
834
|
+
// There is no reason to apply props to injects
|
|
857
835
|
|
|
858
836
|
|
|
859
|
-
applyProps$1(instance, props);
|
|
837
|
+
if (name !== 'inject') applyProps$1(instance, props);
|
|
860
838
|
return instance;
|
|
861
839
|
}
|
|
862
840
|
|
|
@@ -978,11 +956,11 @@ function createRenderer(roots, getEventPriority) {
|
|
|
978
956
|
}
|
|
979
957
|
|
|
980
958
|
function switchInstance(instance, type, newProps, fiber) {
|
|
981
|
-
var _instance$__r3f;
|
|
959
|
+
var _instance$__r3f, _instance$__r3f2;
|
|
982
960
|
|
|
983
961
|
const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
|
|
984
962
|
if (!parent) return;
|
|
985
|
-
const newInstance = createInstance(type, newProps, instance.__r3f.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
|
|
963
|
+
const newInstance = createInstance(type, newProps, (_instance$__r3f2 = instance.__r3f) == null ? void 0 : _instance$__r3f2.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
|
|
986
964
|
// When args change the instance has to be re-constructed, which then
|
|
987
965
|
// forces r3f to re-parent the children and non-scene objects
|
|
988
966
|
// This can not include primitives, which should not have declarative children
|
|
@@ -1015,19 +993,38 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1015
993
|
}
|
|
1016
994
|
|
|
1017
995
|
const reconciler = Reconciler__default['default']({
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
996
|
+
createInstance,
|
|
997
|
+
removeChild,
|
|
998
|
+
appendChild,
|
|
999
|
+
appendInitialChild: appendChild,
|
|
1000
|
+
insertBefore,
|
|
1001
|
+
supportsMicrotask: true,
|
|
1002
|
+
warnsIfNotActing: true,
|
|
1003
|
+
supportsMutation: true,
|
|
1004
|
+
isPrimaryRenderer: false,
|
|
1005
|
+
noTimeout: -1,
|
|
1006
|
+
appendChildToContainer: (container, child) => {
|
|
1007
|
+
const scene = container.getState().scene; // Link current root to the default scene
|
|
1023
1008
|
|
|
1024
|
-
|
|
1025
|
-
appendChild(
|
|
1009
|
+
scene.__r3f.root = container;
|
|
1010
|
+
appendChild(scene, child);
|
|
1011
|
+
},
|
|
1012
|
+
removeChildFromContainer: (container, child) => removeChild(container.getState().scene, child),
|
|
1013
|
+
insertInContainerBefore: (container, child, beforeChild) => insertBefore(container.getState().scene, child, beforeChild),
|
|
1014
|
+
getRootHostContext: () => null,
|
|
1015
|
+
getChildHostContext: parentHostContext => parentHostContext,
|
|
1016
|
+
|
|
1017
|
+
finalizeInitialChildren(instance) {
|
|
1018
|
+
var _instance$__r3f3;
|
|
1019
|
+
|
|
1020
|
+
const localState = (_instance$__r3f3 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f3 : {}; // https://github.com/facebook/react/issues/20271
|
|
1021
|
+
// Returning true will trigger commitMount
|
|
1022
|
+
|
|
1023
|
+
return !!localState.handlers;
|
|
1026
1024
|
},
|
|
1027
|
-
removeChildFromContainer: (parentInstance, child) => removeChild(getContainer(parentInstance, child).container, child),
|
|
1028
|
-
insertInContainerBefore: (parentInstance, child, beforeChild) => insertBefore(getContainer(parentInstance, child).container, child, beforeChild),
|
|
1029
1025
|
|
|
1030
1026
|
prepareUpdate(instance, type, oldProps, newProps) {
|
|
1027
|
+
// Create diff-sets
|
|
1031
1028
|
if (instance.__r3f.primitive && newProps.object && newProps.object !== instance) {
|
|
1032
1029
|
return [true];
|
|
1033
1030
|
} else {
|
|
@@ -1060,40 +1057,58 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1060
1057
|
else applyProps$1(instance, diff);
|
|
1061
1058
|
},
|
|
1062
1059
|
|
|
1060
|
+
commitMount(instance, type, props, int) {
|
|
1061
|
+
var _instance$__r3f4;
|
|
1062
|
+
|
|
1063
|
+
// https://github.com/facebook/react/issues/20271
|
|
1064
|
+
// This will make sure events are only added once to the central container
|
|
1065
|
+
const localState = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
|
|
1066
|
+
|
|
1067
|
+
if (instance.raycast && localState.handlers && localState.eventCount) {
|
|
1068
|
+
instance.__r3f.root.getState().internal.interaction.push(instance);
|
|
1069
|
+
}
|
|
1070
|
+
},
|
|
1071
|
+
|
|
1072
|
+
getPublicInstance: instance => instance,
|
|
1073
|
+
shouldDeprioritizeSubtree: () => false,
|
|
1074
|
+
prepareForCommit: () => null,
|
|
1075
|
+
preparePortalMount: container => prepare(container.getState().scene),
|
|
1076
|
+
resetAfterCommit: () => {},
|
|
1077
|
+
shouldSetTextContent: () => false,
|
|
1078
|
+
clearContainer: () => false,
|
|
1079
|
+
detachDeletedInstance: () => {},
|
|
1080
|
+
createTextInstance: () => {},
|
|
1081
|
+
|
|
1063
1082
|
hideInstance(instance) {
|
|
1064
|
-
var _instance$
|
|
1083
|
+
var _instance$__r3f5;
|
|
1065
1084
|
|
|
1066
1085
|
// Deatch while the instance is hidden
|
|
1067
1086
|
const {
|
|
1068
1087
|
attach: type,
|
|
1069
1088
|
parent
|
|
1070
|
-
} = (_instance$
|
|
1089
|
+
} = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
|
|
1071
1090
|
if (type && parent) detach(parent, instance, type);
|
|
1072
1091
|
if (instance.isObject3D) instance.visible = false;
|
|
1073
1092
|
invalidateInstance(instance);
|
|
1074
1093
|
},
|
|
1075
1094
|
|
|
1076
1095
|
unhideInstance(instance, props) {
|
|
1077
|
-
var _instance$
|
|
1096
|
+
var _instance$__r3f6;
|
|
1078
1097
|
|
|
1079
1098
|
// Re-attach when the instance is unhidden
|
|
1080
1099
|
const {
|
|
1081
1100
|
attach: type,
|
|
1082
1101
|
parent
|
|
1083
|
-
} = (_instance$
|
|
1102
|
+
} = (_instance$__r3f6 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f6 : {};
|
|
1084
1103
|
if (type && parent) attach(parent, instance, type);
|
|
1085
1104
|
if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
|
|
1086
1105
|
invalidateInstance(instance);
|
|
1087
1106
|
},
|
|
1088
1107
|
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
insertBefore,
|
|
1094
|
-
warnsIfNotActing: true,
|
|
1095
|
-
supportsMutation: true,
|
|
1096
|
-
isPrimaryRenderer: false,
|
|
1108
|
+
hideTextInstance: () => {
|
|
1109
|
+
throw new Error('Text is not allowed in the R3F tree.');
|
|
1110
|
+
},
|
|
1111
|
+
// prettier-ignore
|
|
1097
1112
|
getCurrentEventPriority: () => getEventPriority ? getEventPriority() : constants.DefaultEventPriority,
|
|
1098
1113
|
// @ts-ignore
|
|
1099
1114
|
now: typeof performance !== 'undefined' && is.fun(performance.now) ? performance.now : is.fun(Date.now) ? Date.now : undefined,
|
|
@@ -1102,47 +1117,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1102
1117
|
// @ts-ignore
|
|
1103
1118
|
cancelTimeout: is.fun(clearTimeout) ? clearTimeout : undefined,
|
|
1104
1119
|
setTimeout: is.fun(setTimeout) ? setTimeout : undefined,
|
|
1105
|
-
clearTimeout: is.fun(clearTimeout) ? clearTimeout : undefined
|
|
1106
|
-
noTimeout: -1,
|
|
1107
|
-
hideTextInstance: () => {
|
|
1108
|
-
throw new Error('Text is not allowed in the R3F tree.');
|
|
1109
|
-
},
|
|
1110
|
-
// prettier-ignore
|
|
1111
|
-
getPublicInstance: instance => instance,
|
|
1112
|
-
getRootHostContext: () => null,
|
|
1113
|
-
getChildHostContext: parentHostContext => parentHostContext,
|
|
1114
|
-
createTextInstance: () => {},
|
|
1115
|
-
|
|
1116
|
-
finalizeInitialChildren(instance) {
|
|
1117
|
-
var _instance$__r3f4;
|
|
1118
|
-
|
|
1119
|
-
// https://github.com/facebook/react/issues/20271
|
|
1120
|
-
// Returning true will trigger commitMount
|
|
1121
|
-
const localState = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
|
|
1122
|
-
return !!localState.handlers;
|
|
1123
|
-
},
|
|
1124
|
-
|
|
1125
|
-
commitMount(instance)
|
|
1126
|
-
/*, type, props*/
|
|
1127
|
-
{
|
|
1128
|
-
var _instance$__r3f5;
|
|
1129
|
-
|
|
1130
|
-
// https://github.com/facebook/react/issues/20271
|
|
1131
|
-
// This will make sure events are only added once to the central container
|
|
1132
|
-
const localState = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
|
|
1133
|
-
|
|
1134
|
-
if (instance.raycast && localState.handlers && localState.eventCount) {
|
|
1135
|
-
instance.__r3f.root.getState().internal.interaction.push(instance);
|
|
1136
|
-
}
|
|
1137
|
-
},
|
|
1138
|
-
|
|
1139
|
-
shouldDeprioritizeSubtree: () => false,
|
|
1140
|
-
prepareForCommit: () => null,
|
|
1141
|
-
preparePortalMount: containerInfo => prepare(containerInfo),
|
|
1142
|
-
resetAfterCommit: () => {},
|
|
1143
|
-
shouldSetTextContent: () => false,
|
|
1144
|
-
clearContainer: () => false,
|
|
1145
|
-
detachDeletedInstance: () => {}
|
|
1120
|
+
clearTimeout: is.fun(clearTimeout) ? clearTimeout : undefined
|
|
1146
1121
|
});
|
|
1147
1122
|
return {
|
|
1148
1123
|
reconciler,
|
|
@@ -1202,16 +1177,18 @@ const createStore = (invalidate, advance) => {
|
|
|
1202
1177
|
}));
|
|
1203
1178
|
|
|
1204
1179
|
return {
|
|
1180
|
+
set,
|
|
1181
|
+
get,
|
|
1205
1182
|
// Mock objects that have to be configured
|
|
1206
1183
|
gl: null,
|
|
1207
1184
|
camera: null,
|
|
1208
1185
|
raycaster: null,
|
|
1209
1186
|
events: {
|
|
1187
|
+
priority: 1,
|
|
1188
|
+
enabled: true,
|
|
1210
1189
|
connected: false
|
|
1211
1190
|
},
|
|
1212
1191
|
xr: null,
|
|
1213
|
-
set,
|
|
1214
|
-
get,
|
|
1215
1192
|
invalidate: () => invalidate(get()),
|
|
1216
1193
|
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1217
1194
|
linear: false,
|
|
@@ -1219,7 +1196,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1219
1196
|
scene: prepare(new THREE__namespace.Scene()),
|
|
1220
1197
|
controls: null,
|
|
1221
1198
|
clock: new THREE__namespace.Clock(),
|
|
1222
|
-
|
|
1199
|
+
pointer: new THREE__namespace.Vector2(),
|
|
1223
1200
|
frameloop: 'always',
|
|
1224
1201
|
onPointerMissed: undefined,
|
|
1225
1202
|
performance: {
|
|
@@ -1288,6 +1265,7 @@ const createStore = (invalidate, advance) => {
|
|
|
1288
1265
|
frameloop
|
|
1289
1266
|
}));
|
|
1290
1267
|
},
|
|
1268
|
+
previousRoot: undefined,
|
|
1291
1269
|
internal: {
|
|
1292
1270
|
active: false,
|
|
1293
1271
|
priority: 0,
|
|
@@ -1515,6 +1493,11 @@ function loadingFn(extensions, onProgress) {
|
|
|
1515
1493
|
};
|
|
1516
1494
|
}
|
|
1517
1495
|
|
|
1496
|
+
function useMemoizedFn(fn) {
|
|
1497
|
+
const fnRef = React__namespace.useRef(fn);
|
|
1498
|
+
React__namespace.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
|
|
1499
|
+
return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
|
|
1500
|
+
}
|
|
1518
1501
|
function useLoader(Proto, input, extensions, onProgress) {
|
|
1519
1502
|
// Use suspense to load async assets
|
|
1520
1503
|
const keys = Array.isArray(input) ? input : [input];
|
|
@@ -1614,9 +1597,7 @@ function createRoot(canvas) {
|
|
|
1614
1597
|
params,
|
|
1615
1598
|
...options
|
|
1616
1599
|
} = raycastOptions || {};
|
|
1617
|
-
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, {
|
|
1618
|
-
enabled: true,
|
|
1619
|
-
...options
|
|
1600
|
+
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options
|
|
1620
1601
|
});
|
|
1621
1602
|
if (!is.equ(params, raycaster.params, shallowLoose)) applyProps(raycaster, {
|
|
1622
1603
|
params: { ...raycaster.params,
|
|
@@ -1652,7 +1633,7 @@ function createRoot(canvas) {
|
|
|
1652
1633
|
|
|
1653
1634
|
const handleSessionChange = () => {
|
|
1654
1635
|
const gl = store.getState().gl;
|
|
1655
|
-
gl.xr.enabled = gl.xr.isPresenting; // @ts-
|
|
1636
|
+
gl.xr.enabled = gl.xr.isPresenting; // @ts-ignore
|
|
1656
1637
|
// WebXRManager's signature is incorrect.
|
|
1657
1638
|
// See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
|
|
1658
1639
|
|
|
@@ -1694,6 +1675,7 @@ function createRoot(canvas) {
|
|
|
1694
1675
|
} // Set color management
|
|
1695
1676
|
|
|
1696
1677
|
|
|
1678
|
+
if (THREE__namespace.ColorManagement) THREE__namespace.ColorManagement.legacyMode = false;
|
|
1697
1679
|
const outputEncoding = linear ? THREE__namespace.LinearEncoding : THREE__namespace.sRGBEncoding;
|
|
1698
1680
|
const toneMapping = flat ? THREE__namespace.NoToneMapping : THREE__namespace.ACESFilmicToneMapping;
|
|
1699
1681
|
if (gl.outputEncoding !== outputEncoding) gl.outputEncoding = outputEncoding;
|
|
@@ -1769,9 +1751,10 @@ function Provider({
|
|
|
1769
1751
|
internal: { ...state.internal,
|
|
1770
1752
|
active: true
|
|
1771
1753
|
}
|
|
1772
|
-
})); // Connect events
|
|
1754
|
+
})); // Connect events to the targets parent, this is done to ensure events are registered on
|
|
1755
|
+
// a shared target, and not on the canvas itself
|
|
1773
1756
|
|
|
1774
|
-
state.events.connect == null ? void 0 : state.events.connect(target); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
|
|
1757
|
+
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
|
|
1775
1758
|
|
|
1776
1759
|
if (onCreated) onCreated(state); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1777
1760
|
}, []);
|
|
@@ -1809,10 +1792,65 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
1809
1792
|
}
|
|
1810
1793
|
}
|
|
1811
1794
|
|
|
1812
|
-
|
|
1795
|
+
function createPortal(children, container, state) {
|
|
1796
|
+
return /*#__PURE__*/React__namespace.createElement(Portal, {
|
|
1797
|
+
children: children,
|
|
1798
|
+
container: container,
|
|
1799
|
+
state: state
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
function Portal({
|
|
1804
|
+
state = {},
|
|
1805
|
+
children,
|
|
1806
|
+
container
|
|
1807
|
+
}) {
|
|
1808
|
+
/** This has to be a component because it would not be able to call useThree/useStore otherwise since
|
|
1809
|
+
* if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
|
|
1810
|
+
* the "R3F hooks can only be used within the Canvas component!" warning:
|
|
1811
|
+
* <Canvas>
|
|
1812
|
+
* {createPortal(...)} */
|
|
1813
|
+
const {
|
|
1814
|
+
events,
|
|
1815
|
+
...rest
|
|
1816
|
+
} = state;
|
|
1817
|
+
const previousRoot = useStore();
|
|
1818
|
+
const [raycaster] = React__namespace.useState(() => new THREE__namespace.Raycaster());
|
|
1819
|
+
const inject = React__namespace.useCallback((state, injectState) => {
|
|
1820
|
+
const intersect = { ...state
|
|
1821
|
+
};
|
|
1813
1822
|
|
|
1814
|
-
|
|
1815
|
-
|
|
1823
|
+
if (injectState) {
|
|
1824
|
+
// Only the fields of "state" that do not differ from injectState
|
|
1825
|
+
Object.keys(state).forEach(key => {
|
|
1826
|
+
if (state[key] !== injectState[key]) delete intersect[key];
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
return { ...intersect,
|
|
1831
|
+
scene: container,
|
|
1832
|
+
previousRoot,
|
|
1833
|
+
raycaster,
|
|
1834
|
+
events: { ...state.events,
|
|
1835
|
+
...events
|
|
1836
|
+
},
|
|
1837
|
+
...rest
|
|
1838
|
+
};
|
|
1839
|
+
}, [state]);
|
|
1840
|
+
const [useInjectStore] = React__namespace.useState(() => {
|
|
1841
|
+
const store = create__default['default']((set, get) => ({ ...inject(previousRoot.getState()),
|
|
1842
|
+
set,
|
|
1843
|
+
get
|
|
1844
|
+
}));
|
|
1845
|
+
previousRoot.subscribe(state => useInjectStore.setState(injectState => inject(state, injectState)));
|
|
1846
|
+
return store;
|
|
1847
|
+
});
|
|
1848
|
+
React__namespace.useEffect(() => {
|
|
1849
|
+
useInjectStore.setState(injectState => inject(previousRoot.getState(), injectState));
|
|
1850
|
+
}, [inject]);
|
|
1851
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, reconciler.createPortal( /*#__PURE__*/React__namespace.createElement(context.Provider, {
|
|
1852
|
+
value: useInjectStore
|
|
1853
|
+
}, children), useInjectStore, null));
|
|
1816
1854
|
}
|
|
1817
1855
|
|
|
1818
1856
|
reconciler.injectIntoDevTools({
|
|
@@ -1820,6 +1858,7 @@ reconciler.injectIntoDevTools({
|
|
|
1820
1858
|
rendererPackageName: '@react-three/fiber',
|
|
1821
1859
|
version: '18.0.0'
|
|
1822
1860
|
});
|
|
1861
|
+
const act = React__namespace.unstable_act;
|
|
1823
1862
|
|
|
1824
1863
|
exports.act = act;
|
|
1825
1864
|
exports.addAfterEffect = addAfterEffect;
|
|
@@ -1833,6 +1872,7 @@ exports.createPortal = createPortal;
|
|
|
1833
1872
|
exports.createRoot = createRoot;
|
|
1834
1873
|
exports.dispose = dispose;
|
|
1835
1874
|
exports.extend = extend;
|
|
1875
|
+
exports.getRootState = getRootState;
|
|
1836
1876
|
exports.invalidate = invalidate;
|
|
1837
1877
|
exports.omit = omit;
|
|
1838
1878
|
exports.pick = pick;
|
|
@@ -1844,5 +1884,6 @@ exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
|
1844
1884
|
exports.useFrame = useFrame;
|
|
1845
1885
|
exports.useGraph = useGraph;
|
|
1846
1886
|
exports.useLoader = useLoader;
|
|
1887
|
+
exports.useMemoizedFn = useMemoizedFn;
|
|
1847
1888
|
exports.useStore = useStore;
|
|
1848
1889
|
exports.useThree = useThree;
|