@react-three/fiber 8.0.0-beta-05 → 8.0.0-beta.10
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/CHANGELOG.md +6 -0
- 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 +23 -13
- package/dist/declarations/src/core/loop.d.ts +1 -1
- package/dist/declarations/src/core/renderer.d.ts +7 -6
- package/dist/declarations/src/core/store.d.ts +20 -33
- package/dist/declarations/src/core/utils.d.ts +10 -3
- package/dist/declarations/src/index.d.ts +1 -0
- package/dist/declarations/src/native/Canvas.d.ts +2 -2
- package/dist/declarations/src/native/events.d.ts +2 -2
- package/dist/declarations/src/native.d.ts +1 -0
- package/dist/declarations/src/three-types.d.ts +18 -0
- package/dist/declarations/src/web/Canvas.d.ts +2 -2
- package/dist/declarations/src/web/events.d.ts +2 -2
- package/dist/{index-95c17855.cjs.dev.js → index-012f96fe.cjs.dev.js} +507 -414
- package/dist/{index-3f4e5f46.esm.js → index-56b68682.esm.js} +505 -414
- package/dist/{index-ff8b5912.cjs.prod.js → index-8d2b9a82.cjs.prod.js} +507 -414
- package/dist/react-three-fiber.cjs.dev.js +37 -12
- package/dist/react-three-fiber.cjs.prod.js +37 -12
- package/dist/react-three-fiber.esm.js +36 -13
- package/native/dist/react-three-fiber-native.cjs.dev.js +39 -14
- package/native/dist/react-three-fiber-native.cjs.prod.js +39 -14
- package/native/dist/react-three-fiber-native.esm.js +37 -15
- package/package.json +10 -11
|
@@ -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
|
}
|
|
@@ -70,31 +75,46 @@ const pick = (obj, keys) => filterKeys(obj, false, ...keys);
|
|
|
70
75
|
* Clones an object and prunes or omits keys.
|
|
71
76
|
*/
|
|
72
77
|
|
|
73
|
-
const omit = (obj, keys) => filterKeys(obj, true, ...keys);
|
|
74
|
-
|
|
78
|
+
const omit = (obj, keys) => filterKeys(obj, true, ...keys);
|
|
79
|
+
// A collection of compare functions
|
|
75
80
|
const is = {
|
|
76
81
|
obj: a => a === Object(a) && !is.arr(a) && typeof a !== 'function',
|
|
77
82
|
fun: a => typeof a === 'function',
|
|
78
83
|
str: a => typeof a === 'string',
|
|
79
84
|
num: a => typeof a === 'number',
|
|
85
|
+
boo: a => typeof a === 'boolean',
|
|
80
86
|
und: a => a === void 0,
|
|
81
87
|
arr: a => Array.isArray(a),
|
|
82
88
|
|
|
83
|
-
equ(a, b
|
|
89
|
+
equ(a, b, {
|
|
90
|
+
arrays = 'shallow',
|
|
91
|
+
objects = 'reference',
|
|
92
|
+
strict = true
|
|
93
|
+
} = {}) {
|
|
84
94
|
// Wrong type or one of the two undefined, doesn't match
|
|
85
95
|
if (typeof a !== typeof b || !!a !== !!b) return false; // Atomic, just compare a against b
|
|
86
96
|
|
|
87
|
-
if (is.str(a) || is.num(a)
|
|
97
|
+
if (is.str(a) || is.num(a)) return a === b;
|
|
98
|
+
const isObj = is.obj(a);
|
|
99
|
+
if (isObj && objects === 'reference') return a === b;
|
|
100
|
+
const isArr = is.arr(a);
|
|
101
|
+
if (isArr && arrays === 'reference') return a === b; // Array or Object, shallow compare first to see if it's a match
|
|
88
102
|
|
|
89
|
-
if (
|
|
103
|
+
if ((isArr || isObj) && a === b) return true; // Last resort, go through keys
|
|
90
104
|
|
|
91
105
|
let i;
|
|
92
106
|
|
|
93
107
|
for (i in a) if (!(i in b)) return false;
|
|
94
108
|
|
|
95
|
-
for (i in b) if (a[i] !== b[i]) return false;
|
|
109
|
+
for (i in strict ? b : a) if (a[i] !== b[i]) return false;
|
|
110
|
+
|
|
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
|
+
}
|
|
96
116
|
|
|
97
|
-
return
|
|
117
|
+
return true;
|
|
98
118
|
}
|
|
99
119
|
|
|
100
120
|
}; // Collects nodes and materials from a THREE.Object3D
|
|
@@ -129,7 +149,9 @@ function prepare(object, state) {
|
|
|
129
149
|
|
|
130
150
|
if (state != null && state.primitive || !instance.__r3f) {
|
|
131
151
|
instance.__r3f = {
|
|
152
|
+
type: '',
|
|
132
153
|
root: null,
|
|
154
|
+
previousAttach: null,
|
|
133
155
|
memoizedProps: {},
|
|
134
156
|
eventCount: 0,
|
|
135
157
|
handlers: {},
|
|
@@ -157,41 +179,44 @@ function resolve(instance, key) {
|
|
|
157
179
|
target,
|
|
158
180
|
key
|
|
159
181
|
};
|
|
160
|
-
}
|
|
182
|
+
} // Checks if a dash-cased string ends with an integer
|
|
183
|
+
|
|
161
184
|
|
|
185
|
+
const INDEX_REGEX = /-\d+$/;
|
|
162
186
|
function attach(parent, child, type) {
|
|
163
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
|
+
|
|
164
198
|
const {
|
|
165
199
|
target,
|
|
166
200
|
key
|
|
167
201
|
} = resolve(parent, type);
|
|
168
|
-
|
|
202
|
+
child.__r3f.previousAttach = target[key];
|
|
169
203
|
target[key] = child;
|
|
170
|
-
} else
|
|
171
|
-
const [attach] = type;
|
|
172
|
-
if (is.str(attach)) parent[attach](child);else if (is.fun(attach)) attach(parent, child);
|
|
173
|
-
}
|
|
204
|
+
} else child.__r3f.previousAttach = type(parent, child);
|
|
174
205
|
}
|
|
175
206
|
function detach(parent, child, type) {
|
|
207
|
+
var _child$__r3f, _child$__r3f2;
|
|
208
|
+
|
|
176
209
|
if (is.str(type)) {
|
|
177
210
|
const {
|
|
178
211
|
target,
|
|
179
212
|
key
|
|
180
213
|
} = resolve(parent, type);
|
|
181
|
-
target[key] =
|
|
182
|
-
} else
|
|
183
|
-
const [, detach] = type;
|
|
184
|
-
if (is.str(detach)) parent[detach](child);else if (is.fun(detach)) detach(parent, child);
|
|
185
|
-
}
|
|
186
|
-
} // Shallow check arrays, but check objects atomically
|
|
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);
|
|
187
216
|
|
|
188
|
-
|
|
189
|
-
if (is.arr(a) && is.equ(a, b)) return true;
|
|
190
|
-
if (a === b) return true;
|
|
191
|
-
return false;
|
|
217
|
+
(_child$__r3f2 = child.__r3f) == null ? true : delete _child$__r3f2.previousAttach;
|
|
192
218
|
} // This function prepares a set of changes to be applied to the instance
|
|
193
219
|
|
|
194
|
-
|
|
195
220
|
function diffProps(instance, {
|
|
196
221
|
children: cN,
|
|
197
222
|
key: kN,
|
|
@@ -223,7 +248,7 @@ function diffProps(instance, {
|
|
|
223
248
|
// Bail out on primitive object
|
|
224
249
|
if ((_instance$__r3f2 = instance.__r3f) != null && _instance$__r3f2.primitive && key === 'object') return; // When props match bail out
|
|
225
250
|
|
|
226
|
-
if (
|
|
251
|
+
if (is.equ(value, previous[key])) return; // Collect handlers and bail out
|
|
227
252
|
|
|
228
253
|
if (/^on(Pointer|Click|DoubleClick|ContextMenu|Wheel)/.test(key)) return changes.push([key, value, true, []]); // Split dashed props
|
|
229
254
|
|
|
@@ -277,11 +302,11 @@ function applyProps$1(instance, data) {
|
|
|
277
302
|
if (value === DEFAULT + 'remove') {
|
|
278
303
|
if (targetProp && targetProp.constructor) {
|
|
279
304
|
// use the prop constructor to find the default it should be
|
|
280
|
-
value = new targetProp.constructor(memoized.args);
|
|
305
|
+
value = new targetProp.constructor(...memoized.args);
|
|
281
306
|
} else if (currentInstance.constructor) {
|
|
282
307
|
// create a blank slate of the instance and copy the particular parameter.
|
|
283
308
|
// @ts-ignore
|
|
284
|
-
const defaultClassCall = new currentInstance.constructor(currentInstance.__r3f.memoizedProps.args);
|
|
309
|
+
const defaultClassCall = new currentInstance.constructor(...currentInstance.__r3f.memoizedProps.args);
|
|
285
310
|
value = defaultClassCall[targetProp]; // destory the instance
|
|
286
311
|
|
|
287
312
|
if (defaultClassCall.dispose) defaultClassCall.dispose(); // instance does not have constructor, just set it to 0
|
|
@@ -309,23 +334,12 @@ function applyProps$1(instance, data) {
|
|
|
309
334
|
|
|
310
335
|
if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
|
|
311
336
|
else if (targetProp instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) targetProp.mask = value.mask; // Otherwise just set ...
|
|
312
|
-
else targetProp.set(value);
|
|
313
|
-
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
314
|
-
|
|
315
|
-
if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
|
|
337
|
+
else targetProp.set(value);
|
|
316
338
|
} // Else, just overwrite the value
|
|
317
339
|
|
|
318
|
-
} else
|
|
319
|
-
currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
|
|
320
|
-
// https://github.com/pmndrs/react-three-fiber/issues/344
|
|
321
|
-
|
|
322
|
-
if (!rootState.linear && currentInstance[key] instanceof THREE__namespace.Texture) {
|
|
323
|
-
currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
340
|
+
} else currentInstance[key] = value;
|
|
326
341
|
|
|
327
342
|
invalidateInstance(instance);
|
|
328
|
-
return instance;
|
|
329
343
|
});
|
|
330
344
|
|
|
331
345
|
if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
|
|
@@ -338,6 +352,7 @@ function applyProps$1(instance, data) {
|
|
|
338
352
|
|
|
339
353
|
|
|
340
354
|
if (changes.length && instance.parent) updateInstance(instance);
|
|
355
|
+
return instance;
|
|
341
356
|
}
|
|
342
357
|
function invalidateInstance(instance) {
|
|
343
358
|
var _instance$__r3f4, _instance$__r3f4$root;
|
|
@@ -401,6 +416,7 @@ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
|
|
|
401
416
|
|
|
402
417
|
function removeInteractivity(store, object) {
|
|
403
418
|
const {
|
|
419
|
+
events,
|
|
404
420
|
internal
|
|
405
421
|
} = store.getState(); // Removes every trace of an object from the data store
|
|
406
422
|
|
|
@@ -408,6 +424,7 @@ function removeInteractivity(store, object) {
|
|
|
408
424
|
internal.initialHits = internal.initialHits.filter(o => o !== object);
|
|
409
425
|
internal.hovered.forEach((value, key) => {
|
|
410
426
|
if (value.eventObject === object || value.object === object) {
|
|
427
|
+
// Clear out intersects, they are outdated by now
|
|
411
428
|
internal.hovered.delete(key);
|
|
412
429
|
}
|
|
413
430
|
});
|
|
@@ -417,31 +434,8 @@ function removeInteractivity(store, object) {
|
|
|
417
434
|
}
|
|
418
435
|
function createEvents(store) {
|
|
419
436
|
const temp = new THREE__namespace.Vector3();
|
|
420
|
-
/** Sets up defaultRaycaster */
|
|
421
|
-
|
|
422
|
-
function prepareRay(event) {
|
|
423
|
-
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
424
|
-
|
|
425
|
-
const state = store.getState();
|
|
426
|
-
const {
|
|
427
|
-
raycaster,
|
|
428
|
-
mouse,
|
|
429
|
-
camera,
|
|
430
|
-
size
|
|
431
|
-
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
432
|
-
// Events trigger outside of canvas when moved
|
|
433
|
-
|
|
434
|
-
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
435
|
-
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
436
|
-
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
437
|
-
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
438
|
-
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
439
|
-
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
440
|
-
raycaster.setFromCamera(mouse, camera);
|
|
441
|
-
}
|
|
442
437
|
/** Calculates delta */
|
|
443
438
|
|
|
444
|
-
|
|
445
439
|
function calculateDistance(event) {
|
|
446
440
|
const {
|
|
447
441
|
internal
|
|
@@ -461,55 +455,70 @@ function createEvents(store) {
|
|
|
461
455
|
}));
|
|
462
456
|
}
|
|
463
457
|
|
|
464
|
-
function intersect(filter) {
|
|
458
|
+
function intersect(event, filter) {
|
|
465
459
|
const state = store.getState();
|
|
466
|
-
const
|
|
467
|
-
raycaster,
|
|
468
|
-
internal
|
|
469
|
-
} = state; // Skip event handling when noEvents is set
|
|
470
|
-
|
|
471
|
-
if (!raycaster.enabled) return [];
|
|
472
|
-
const seen = new Set();
|
|
460
|
+
const duplicates = new Set();
|
|
473
461
|
const intersections = []; // Allow callers to eliminate event objects
|
|
474
462
|
|
|
475
|
-
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
|
|
476
|
+
|
|
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;
|
|
476
481
|
|
|
477
|
-
|
|
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 => {
|
|
478
497
|
const id = makeId(item);
|
|
479
|
-
if (
|
|
480
|
-
|
|
498
|
+
if (duplicates.has(id)) return false;
|
|
499
|
+
duplicates.add(id);
|
|
481
500
|
return true;
|
|
482
501
|
}); // https://github.com/mrdoob/three.js/issues/16031
|
|
483
|
-
// Allow custom userland intersect sort order
|
|
502
|
+
// Allow custom userland intersect sort order, this likely only makes sense on the root filter
|
|
484
503
|
|
|
485
|
-
if (
|
|
504
|
+
if (state.events.filter) hits = state.events.filter(hits, state); // Bubble up the events, find the event source (eventObject)
|
|
486
505
|
|
|
487
|
-
for (const
|
|
488
|
-
let eventObject =
|
|
506
|
+
for (const hit of hits) {
|
|
507
|
+
let eventObject = hit.object; // Bubble event up
|
|
489
508
|
|
|
490
509
|
while (eventObject) {
|
|
491
510
|
var _r3f2;
|
|
492
511
|
|
|
493
|
-
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...
|
|
512
|
+
if ((_r3f2 = eventObject.__r3f) != null && _r3f2.eventCount) intersections.push({ ...hit,
|
|
494
513
|
eventObject
|
|
495
514
|
});
|
|
496
515
|
eventObject = eventObject.parent;
|
|
497
516
|
}
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
return intersections;
|
|
501
|
-
}
|
|
502
|
-
/** Creates filtered intersects and returns an array of positive hits */
|
|
517
|
+
} // If the interaction is captured, make all capturing targets part of the intersect.
|
|
503
518
|
|
|
504
519
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
internal
|
|
508
|
-
} = store.getState(); // If the interaction is captured, make all capturing targets part of the
|
|
509
|
-
// intersect.
|
|
510
|
-
|
|
511
|
-
if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
|
|
512
|
-
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()) {
|
|
513
522
|
intersections.push(captureData.intersection);
|
|
514
523
|
}
|
|
515
524
|
}
|
|
@@ -522,13 +531,13 @@ function createEvents(store) {
|
|
|
522
531
|
function handleIntersects(intersections, event, delta, callback) {
|
|
523
532
|
const {
|
|
524
533
|
raycaster,
|
|
525
|
-
|
|
534
|
+
pointer,
|
|
526
535
|
camera,
|
|
527
536
|
internal
|
|
528
537
|
} = store.getState(); // If anything has been found, forward it to the event listeners
|
|
529
538
|
|
|
530
539
|
if (intersections.length) {
|
|
531
|
-
const unprojectedPoint = temp.set(
|
|
540
|
+
const unprojectedPoint = temp.set(pointer.x, pointer.y, 0).unproject(camera);
|
|
532
541
|
const localState = {
|
|
533
542
|
stopped: false
|
|
534
543
|
};
|
|
@@ -579,8 +588,7 @@ function createEvents(store) {
|
|
|
579
588
|
|
|
580
589
|
let raycastEvent = { ...hit,
|
|
581
590
|
...extractEventProps,
|
|
582
|
-
|
|
583
|
-
spaceY: mouse.y,
|
|
591
|
+
pointer,
|
|
584
592
|
intersections,
|
|
585
593
|
stopped: localState.stopped,
|
|
586
594
|
delta,
|
|
@@ -617,8 +625,6 @@ function createEvents(store) {
|
|
|
617
625
|
setPointerCapture,
|
|
618
626
|
releasePointerCapture
|
|
619
627
|
},
|
|
620
|
-
sourceEvent: event,
|
|
621
|
-
// deprecated
|
|
622
628
|
nativeEvent: event
|
|
623
629
|
}; // Call subscribers
|
|
624
630
|
|
|
@@ -683,14 +689,15 @@ function createEvents(store) {
|
|
|
683
689
|
const {
|
|
684
690
|
onPointerMissed,
|
|
685
691
|
internal
|
|
686
|
-
} = store.getState();
|
|
687
|
-
|
|
692
|
+
} = store.getState(); //prepareRay(event)
|
|
693
|
+
|
|
688
694
|
internal.lastEvent.current = event; // Get fresh intersects
|
|
689
695
|
|
|
690
696
|
const isPointerMove = name === 'onPointerMove';
|
|
691
697
|
const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
|
|
692
|
-
const filter = isPointerMove ? filterPointerEvents : undefined;
|
|
693
|
-
|
|
698
|
+
const filter = isPointerMove ? filterPointerEvents : undefined; //const hits = patchIntersects(intersect(filter), event)
|
|
699
|
+
|
|
700
|
+
const hits = intersect(event, filter);
|
|
694
701
|
const delta = isClickEvent ? calculateDistance(event) : 0; // Save initial coordinates on pointer-down
|
|
695
702
|
|
|
696
703
|
if (name === 'onPointerDown') {
|
|
@@ -773,23 +780,6 @@ function createEvents(store) {
|
|
|
773
780
|
};
|
|
774
781
|
}
|
|
775
782
|
|
|
776
|
-
// Type guard to tell a store from a portal
|
|
777
|
-
const isStore = def => def && !!def.getState;
|
|
778
|
-
|
|
779
|
-
const getContainer = (container, child) => {
|
|
780
|
-
var _container$__r3f$root, _container$__r3f;
|
|
781
|
-
|
|
782
|
-
return {
|
|
783
|
-
// If the container is not a root-store then it must be a THREE.Object3D into which part of the
|
|
784
|
-
// scene is portalled into. Now there can be two variants of this, either that object is part of
|
|
785
|
-
// the regular jsx tree, in which case it already has __r3f with a valid root attached, or it lies
|
|
786
|
-
// outside react, in which case we must take the root of the child that is about to be attached to it.
|
|
787
|
-
root: isStore(container) ? container : (_container$__r3f$root = (_container$__r3f = container.__r3f) == null ? void 0 : _container$__r3f.root) != null ? _container$__r3f$root : child.__r3f.root,
|
|
788
|
-
// The container is the eventual target into which objects are mounted, it has to be a THREE.Object3D
|
|
789
|
-
container: isStore(container) ? container.getState().scene : container
|
|
790
|
-
};
|
|
791
|
-
};
|
|
792
|
-
|
|
793
783
|
let catalogue = {};
|
|
794
784
|
|
|
795
785
|
let extend = objects => void (catalogue = { ...catalogue,
|
|
@@ -801,22 +791,9 @@ function createRenderer(roots, getEventPriority) {
|
|
|
801
791
|
args = [],
|
|
802
792
|
attach,
|
|
803
793
|
...props
|
|
804
|
-
}, root
|
|
794
|
+
}, root) {
|
|
805
795
|
let name = `${type[0].toUpperCase()}${type.slice(1)}`;
|
|
806
|
-
let instance; //
|
|
807
|
-
// Portals do not give us a root, they are themselves treated as a root by the reconciler
|
|
808
|
-
// In order to figure out the actual root we have to climb through fiber internals :(
|
|
809
|
-
|
|
810
|
-
if (!isStore(root) && internalInstanceHandle) {
|
|
811
|
-
const fn = node => {
|
|
812
|
-
if (!node.return) return node.stateNode && node.stateNode.containerInfo;else return fn(node.return);
|
|
813
|
-
};
|
|
814
|
-
|
|
815
|
-
root = fn(internalInstanceHandle);
|
|
816
|
-
} // Assert that by now we have a valid root
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
if (!root || !isStore(root)) throw `No valid root for ${name}!`; // Auto-attach geometries and materials
|
|
796
|
+
let instance; // Auto-attach geometries and materials
|
|
820
797
|
|
|
821
798
|
if (attach === undefined) {
|
|
822
799
|
if (name.endsWith('Geometry')) attach = 'geometry';else if (name.endsWith('Material')) attach = 'material';
|
|
@@ -826,6 +803,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
826
803
|
if (props.object === undefined) throw `Primitives without 'object' are invalid!`;
|
|
827
804
|
const object = props.object;
|
|
828
805
|
instance = prepare(object, {
|
|
806
|
+
type,
|
|
829
807
|
root,
|
|
830
808
|
attach,
|
|
831
809
|
primitive: true
|
|
@@ -842,19 +820,21 @@ function createRenderer(roots, getEventPriority) {
|
|
|
842
820
|
// Append memoized props with args so it's not forgotten
|
|
843
821
|
|
|
844
822
|
instance = prepare(new target(...args), {
|
|
823
|
+
type,
|
|
845
824
|
root,
|
|
846
825
|
attach,
|
|
847
826
|
// TODO: Figure out what this is for
|
|
848
827
|
memoizedProps: {
|
|
849
|
-
args
|
|
828
|
+
args
|
|
850
829
|
}
|
|
851
830
|
});
|
|
852
831
|
} // It should NOT call onUpdate on object instanciation, because it hasn't been added to the
|
|
853
832
|
// view yet. If the callback relies on references for instance, they won't be ready yet, this is
|
|
854
833
|
// why it passes "true" here
|
|
834
|
+
// There is no reason to apply props to injects
|
|
855
835
|
|
|
856
836
|
|
|
857
|
-
applyProps$1(instance, props);
|
|
837
|
+
if (name !== 'inject') applyProps$1(instance, props);
|
|
858
838
|
return instance;
|
|
859
839
|
}
|
|
860
840
|
|
|
@@ -976,11 +956,11 @@ function createRenderer(roots, getEventPriority) {
|
|
|
976
956
|
}
|
|
977
957
|
|
|
978
958
|
function switchInstance(instance, type, newProps, fiber) {
|
|
979
|
-
var _instance$__r3f;
|
|
959
|
+
var _instance$__r3f, _instance$__r3f2;
|
|
980
960
|
|
|
981
961
|
const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
|
|
982
962
|
if (!parent) return;
|
|
983
|
-
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
|
|
984
964
|
// When args change the instance has to be re-constructed, which then
|
|
985
965
|
// forces r3f to re-parent the children and non-scene objects
|
|
986
966
|
// This can not include primitives, which should not have declarative children
|
|
@@ -1013,19 +993,38 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1013
993
|
}
|
|
1014
994
|
|
|
1015
995
|
const reconciler = Reconciler__default['default']({
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
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
|
|
1008
|
+
|
|
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,
|
|
1021
1016
|
|
|
1022
|
-
|
|
1023
|
-
|
|
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;
|
|
1024
1024
|
},
|
|
1025
|
-
removeChildFromContainer: (parentInstance, child) => removeChild(getContainer(parentInstance, child).container, child),
|
|
1026
|
-
insertInContainerBefore: (parentInstance, child, beforeChild) => insertBefore(getContainer(parentInstance, child).container, child, beforeChild),
|
|
1027
1025
|
|
|
1028
1026
|
prepareUpdate(instance, type, oldProps, newProps) {
|
|
1027
|
+
// Create diff-sets
|
|
1029
1028
|
if (instance.__r3f.primitive && newProps.object && newProps.object !== instance) {
|
|
1030
1029
|
return [true];
|
|
1031
1030
|
} else {
|
|
@@ -1058,40 +1057,58 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1058
1057
|
else applyProps$1(instance, diff);
|
|
1059
1058
|
},
|
|
1060
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
|
+
|
|
1061
1082
|
hideInstance(instance) {
|
|
1062
|
-
var _instance$
|
|
1083
|
+
var _instance$__r3f5;
|
|
1063
1084
|
|
|
1064
1085
|
// Deatch while the instance is hidden
|
|
1065
1086
|
const {
|
|
1066
1087
|
attach: type,
|
|
1067
1088
|
parent
|
|
1068
|
-
} = (_instance$
|
|
1089
|
+
} = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
|
|
1069
1090
|
if (type && parent) detach(parent, instance, type);
|
|
1070
1091
|
if (instance.isObject3D) instance.visible = false;
|
|
1071
1092
|
invalidateInstance(instance);
|
|
1072
1093
|
},
|
|
1073
1094
|
|
|
1074
1095
|
unhideInstance(instance, props) {
|
|
1075
|
-
var _instance$
|
|
1096
|
+
var _instance$__r3f6;
|
|
1076
1097
|
|
|
1077
1098
|
// Re-attach when the instance is unhidden
|
|
1078
1099
|
const {
|
|
1079
1100
|
attach: type,
|
|
1080
1101
|
parent
|
|
1081
|
-
} = (_instance$
|
|
1102
|
+
} = (_instance$__r3f6 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f6 : {};
|
|
1082
1103
|
if (type && parent) attach(parent, instance, type);
|
|
1083
1104
|
if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
|
|
1084
1105
|
invalidateInstance(instance);
|
|
1085
1106
|
},
|
|
1086
1107
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
insertBefore,
|
|
1092
|
-
warnsIfNotActing: true,
|
|
1093
|
-
supportsMutation: true,
|
|
1094
|
-
isPrimaryRenderer: false,
|
|
1108
|
+
hideTextInstance: () => {
|
|
1109
|
+
throw new Error('Text is not allowed in the R3F tree.');
|
|
1110
|
+
},
|
|
1111
|
+
// prettier-ignore
|
|
1095
1112
|
getCurrentEventPriority: () => getEventPriority ? getEventPriority() : constants.DefaultEventPriority,
|
|
1096
1113
|
// @ts-ignore
|
|
1097
1114
|
now: typeof performance !== 'undefined' && is.fun(performance.now) ? performance.now : is.fun(Date.now) ? Date.now : undefined,
|
|
@@ -1100,47 +1117,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1100
1117
|
// @ts-ignore
|
|
1101
1118
|
cancelTimeout: is.fun(clearTimeout) ? clearTimeout : undefined,
|
|
1102
1119
|
setTimeout: is.fun(setTimeout) ? setTimeout : undefined,
|
|
1103
|
-
clearTimeout: is.fun(clearTimeout) ? clearTimeout : undefined
|
|
1104
|
-
noTimeout: -1,
|
|
1105
|
-
hideTextInstance: () => {
|
|
1106
|
-
throw new Error('Text is not allowed in the R3F tree.');
|
|
1107
|
-
},
|
|
1108
|
-
// prettier-ignore
|
|
1109
|
-
getPublicInstance: instance => instance,
|
|
1110
|
-
getRootHostContext: () => null,
|
|
1111
|
-
getChildHostContext: parentHostContext => parentHostContext,
|
|
1112
|
-
createTextInstance: () => {},
|
|
1113
|
-
|
|
1114
|
-
finalizeInitialChildren(instance) {
|
|
1115
|
-
var _instance$__r3f4;
|
|
1116
|
-
|
|
1117
|
-
// https://github.com/facebook/react/issues/20271
|
|
1118
|
-
// Returning true will trigger commitMount
|
|
1119
|
-
const localState = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
|
|
1120
|
-
return !!localState.handlers;
|
|
1121
|
-
},
|
|
1122
|
-
|
|
1123
|
-
commitMount(instance)
|
|
1124
|
-
/*, type, props*/
|
|
1125
|
-
{
|
|
1126
|
-
var _instance$__r3f5;
|
|
1127
|
-
|
|
1128
|
-
// https://github.com/facebook/react/issues/20271
|
|
1129
|
-
// This will make sure events are only added once to the central container
|
|
1130
|
-
const localState = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
|
|
1131
|
-
|
|
1132
|
-
if (instance.raycast && localState.handlers && localState.eventCount) {
|
|
1133
|
-
instance.__r3f.root.getState().internal.interaction.push(instance);
|
|
1134
|
-
}
|
|
1135
|
-
},
|
|
1136
|
-
|
|
1137
|
-
shouldDeprioritizeSubtree: () => false,
|
|
1138
|
-
prepareForCommit: () => null,
|
|
1139
|
-
preparePortalMount: containerInfo => prepare(containerInfo),
|
|
1140
|
-
resetAfterCommit: () => {},
|
|
1141
|
-
shouldSetTextContent: () => false,
|
|
1142
|
-
clearContainer: () => false,
|
|
1143
|
-
detachDeletedInstance: () => {}
|
|
1120
|
+
clearTimeout: is.fun(clearTimeout) ? clearTimeout : undefined
|
|
1144
1121
|
});
|
|
1145
1122
|
return {
|
|
1146
1123
|
reconciler,
|
|
@@ -1152,63 +1129,8 @@ const isRenderer = def => !!(def != null && def.render);
|
|
|
1152
1129
|
const isOrthographicCamera = def => def && def.isOrthographicCamera;
|
|
1153
1130
|
const context = /*#__PURE__*/React__namespace.createContext(null);
|
|
1154
1131
|
|
|
1155
|
-
const createStore = (
|
|
1156
|
-
const {
|
|
1157
|
-
gl,
|
|
1158
|
-
size,
|
|
1159
|
-
shadows = false,
|
|
1160
|
-
linear = false,
|
|
1161
|
-
flat = false,
|
|
1162
|
-
orthographic = false,
|
|
1163
|
-
frameloop = 'always',
|
|
1164
|
-
dpr = [1, 2],
|
|
1165
|
-
performance,
|
|
1166
|
-
clock = new THREE__namespace.Clock(),
|
|
1167
|
-
raycaster: raycastOptions,
|
|
1168
|
-
camera: cameraOptions,
|
|
1169
|
-
onPointerMissed
|
|
1170
|
-
} = props; // Set shadowmap
|
|
1171
|
-
|
|
1172
|
-
if (shadows) {
|
|
1173
|
-
gl.shadowMap.enabled = true;
|
|
1174
|
-
if (typeof shadows === 'object') Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE__namespace.PCFSoftShadowMap;
|
|
1175
|
-
} // Set color preferences
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
if (linear) gl.outputEncoding = THREE__namespace.LinearEncoding;
|
|
1179
|
-
if (flat) gl.toneMapping = THREE__namespace.NoToneMapping; // clock.elapsedTime is updated using advance(timestamp)
|
|
1180
|
-
|
|
1181
|
-
if (frameloop === 'never') {
|
|
1182
|
-
clock.stop();
|
|
1183
|
-
clock.elapsedTime = 0;
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1132
|
+
const createStore = (invalidate, advance) => {
|
|
1186
1133
|
const rootState = create__default['default']((set, get) => {
|
|
1187
|
-
// Create custom raycaster
|
|
1188
|
-
const raycaster = new THREE__namespace.Raycaster();
|
|
1189
|
-
const {
|
|
1190
|
-
params,
|
|
1191
|
-
...options
|
|
1192
|
-
} = raycastOptions || {};
|
|
1193
|
-
applyProps(raycaster, {
|
|
1194
|
-
enabled: true,
|
|
1195
|
-
...options,
|
|
1196
|
-
params: { ...raycaster.params,
|
|
1197
|
-
...params
|
|
1198
|
-
}
|
|
1199
|
-
}); // Create default camera
|
|
1200
|
-
|
|
1201
|
-
const isCamera = cameraOptions instanceof THREE__namespace.Camera;
|
|
1202
|
-
const camera = isCamera ? cameraOptions : orthographic ? new THREE__namespace.OrthographicCamera(0, 0, 0, 0, 0.1, 1000) : new THREE__namespace.PerspectiveCamera(75, 0, 0.1, 1000);
|
|
1203
|
-
|
|
1204
|
-
if (!isCamera) {
|
|
1205
|
-
camera.position.z = 5;
|
|
1206
|
-
if (cameraOptions) applyProps(camera, cameraOptions); // Always look at center by default
|
|
1207
|
-
|
|
1208
|
-
if (!(cameraOptions != null && cameraOptions.rotation)) camera.lookAt(0, 0, 0);
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
const initialDpr = calculateDpr(dpr);
|
|
1212
1134
|
const position = new THREE__namespace.Vector3();
|
|
1213
1135
|
const defaultTarget = new THREE__namespace.Vector3();
|
|
1214
1136
|
const tempTarget = new THREE__namespace.Vector3();
|
|
@@ -1252,61 +1174,38 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1252
1174
|
performance: { ...state.performance,
|
|
1253
1175
|
current
|
|
1254
1176
|
}
|
|
1255
|
-
}));
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
const handleXRFrame = (timestamp, frame) => {
|
|
1259
|
-
const state = get();
|
|
1260
|
-
if (state.frameloop === 'never') return;
|
|
1261
|
-
advance(timestamp, true, state, frame);
|
|
1262
|
-
}; // Toggle render switching on session
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
const handleSessionChange = () => {
|
|
1266
|
-
gl.xr.enabled = gl.xr.isPresenting; // @ts-expect-error
|
|
1267
|
-
// WebXRManager's signature is incorrect.
|
|
1268
|
-
// See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
|
|
1269
|
-
|
|
1270
|
-
gl.xr.setAnimationLoop(gl.xr.isPresenting ? handleXRFrame : null);
|
|
1271
|
-
}; // WebXR session manager
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
const xr = {
|
|
1275
|
-
connect() {
|
|
1276
|
-
gl.xr.addEventListener('sessionstart', handleSessionChange);
|
|
1277
|
-
gl.xr.addEventListener('sessionend', handleSessionChange);
|
|
1278
|
-
},
|
|
1279
|
-
|
|
1280
|
-
disconnect() {
|
|
1281
|
-
gl.xr.removeEventListener('sessionstart', handleSessionChange);
|
|
1282
|
-
gl.xr.removeEventListener('sessionend', handleSessionChange);
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
}; // Subscribe to WebXR session events
|
|
1177
|
+
}));
|
|
1286
1178
|
|
|
1287
|
-
|
|
1179
|
+
const pointer = new THREE__namespace.Vector2();
|
|
1288
1180
|
return {
|
|
1289
|
-
gl,
|
|
1290
1181
|
set,
|
|
1291
1182
|
get,
|
|
1183
|
+
// Mock objects that have to be configured
|
|
1184
|
+
gl: null,
|
|
1185
|
+
camera: null,
|
|
1186
|
+
raycaster: null,
|
|
1187
|
+
events: {
|
|
1188
|
+
priority: 1,
|
|
1189
|
+
enabled: true,
|
|
1190
|
+
connected: false
|
|
1191
|
+
},
|
|
1192
|
+
xr: null,
|
|
1292
1193
|
invalidate: () => invalidate(get()),
|
|
1293
1194
|
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1294
|
-
linear,
|
|
1295
|
-
flat,
|
|
1195
|
+
linear: false,
|
|
1196
|
+
flat: false,
|
|
1296
1197
|
scene: prepare(new THREE__namespace.Scene()),
|
|
1297
|
-
camera,
|
|
1298
1198
|
controls: null,
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
mouse:
|
|
1302
|
-
frameloop,
|
|
1303
|
-
onPointerMissed,
|
|
1199
|
+
clock: new THREE__namespace.Clock(),
|
|
1200
|
+
pointer,
|
|
1201
|
+
mouse: pointer,
|
|
1202
|
+
frameloop: 'always',
|
|
1203
|
+
onPointerMissed: undefined,
|
|
1304
1204
|
performance: {
|
|
1305
1205
|
current: 1,
|
|
1306
1206
|
min: 0.5,
|
|
1307
1207
|
max: 1,
|
|
1308
1208
|
debounce: 200,
|
|
1309
|
-
...performance,
|
|
1310
1209
|
regress: () => {
|
|
1311
1210
|
const state = get(); // Clear timeout
|
|
1312
1211
|
|
|
@@ -1322,8 +1221,8 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1322
1221
|
height: 0
|
|
1323
1222
|
},
|
|
1324
1223
|
viewport: {
|
|
1325
|
-
initialDpr,
|
|
1326
|
-
dpr:
|
|
1224
|
+
initialDpr: 0,
|
|
1225
|
+
dpr: 0,
|
|
1327
1226
|
width: 0,
|
|
1328
1227
|
height: 0,
|
|
1329
1228
|
aspect: 0,
|
|
@@ -1331,7 +1230,13 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1331
1230
|
factor: 0,
|
|
1332
1231
|
getCurrentViewport
|
|
1333
1232
|
},
|
|
1233
|
+
setEvents: events => set(state => ({ ...state,
|
|
1234
|
+
events: { ...state.events,
|
|
1235
|
+
events
|
|
1236
|
+
}
|
|
1237
|
+
})),
|
|
1334
1238
|
setSize: (width, height) => {
|
|
1239
|
+
const camera = get().camera;
|
|
1335
1240
|
const size = {
|
|
1336
1241
|
width,
|
|
1337
1242
|
height
|
|
@@ -1343,22 +1248,35 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1343
1248
|
}
|
|
1344
1249
|
}));
|
|
1345
1250
|
},
|
|
1346
|
-
setDpr: dpr => set(state =>
|
|
1347
|
-
|
|
1348
|
-
|
|
1251
|
+
setDpr: dpr => set(state => {
|
|
1252
|
+
const resolved = calculateDpr(dpr);
|
|
1253
|
+
return {
|
|
1254
|
+
viewport: { ...state.viewport,
|
|
1255
|
+
dpr: resolved,
|
|
1256
|
+
initialDpr: state.viewport.initialDpr || resolved
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
1259
|
+
}),
|
|
1260
|
+
setFrameloop: (frameloop = 'always') => {
|
|
1261
|
+
const clock = get().clock; // if frameloop === "never" clock.elapsedTime is updated using advance(timestamp)
|
|
1262
|
+
|
|
1263
|
+
clock.stop();
|
|
1264
|
+
clock.elapsedTime = 0;
|
|
1265
|
+
|
|
1266
|
+
if (frameloop !== 'never') {
|
|
1267
|
+
clock.start();
|
|
1268
|
+
clock.elapsedTime = 0;
|
|
1349
1269
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
events: {
|
|
1355
|
-
connected: false
|
|
1270
|
+
|
|
1271
|
+
set(() => ({
|
|
1272
|
+
frameloop
|
|
1273
|
+
}));
|
|
1356
1274
|
},
|
|
1275
|
+
previousRoot: undefined,
|
|
1357
1276
|
internal: {
|
|
1358
1277
|
active: false,
|
|
1359
1278
|
priority: 0,
|
|
1360
1279
|
frames: 0,
|
|
1361
|
-
lastProps: props,
|
|
1362
1280
|
lastEvent: /*#__PURE__*/React__namespace.createRef(),
|
|
1363
1281
|
interaction: [],
|
|
1364
1282
|
hovered: new Map(),
|
|
@@ -1366,7 +1284,6 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1366
1284
|
initialClick: [0, 0],
|
|
1367
1285
|
initialHits: [],
|
|
1368
1286
|
capturedMap: new Map(),
|
|
1369
|
-
xr,
|
|
1370
1287
|
subscribe: (ref, priority = 0) => {
|
|
1371
1288
|
set(({
|
|
1372
1289
|
internal
|
|
@@ -1410,13 +1327,13 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1410
1327
|
camera,
|
|
1411
1328
|
size,
|
|
1412
1329
|
viewport,
|
|
1413
|
-
|
|
1330
|
+
gl
|
|
1414
1331
|
} = rootState.getState();
|
|
1415
1332
|
|
|
1416
1333
|
if (size !== oldSize || viewport.dpr !== oldDpr) {
|
|
1417
1334
|
// https://github.com/pmndrs/react-three-fiber/issues/92
|
|
1418
1335
|
// Do not mess with the camera if it belongs to the user
|
|
1419
|
-
if (!camera.manual
|
|
1336
|
+
if (!camera.manual) {
|
|
1420
1337
|
if (isOrthographicCamera(camera)) {
|
|
1421
1338
|
camera.left = size.width / -2;
|
|
1422
1339
|
camera.right = size.width / 2;
|
|
@@ -1438,9 +1355,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1438
1355
|
oldSize = size;
|
|
1439
1356
|
oldDpr = viewport.dpr;
|
|
1440
1357
|
}
|
|
1441
|
-
}); //
|
|
1442
|
-
|
|
1443
|
-
if (size) state.setSize(size.width, size.height); // Invalidate on any change
|
|
1358
|
+
}); // Invalidate on any change
|
|
1444
1359
|
|
|
1445
1360
|
rootState.subscribe(state => invalidate(state)); // Return root state
|
|
1446
1361
|
|
|
@@ -1465,6 +1380,8 @@ function run(effects, timestamp) {
|
|
|
1465
1380
|
for (i = 0; i < effects.length; i++) effects[i](timestamp);
|
|
1466
1381
|
}
|
|
1467
1382
|
|
|
1383
|
+
let subscribers;
|
|
1384
|
+
|
|
1468
1385
|
function render$1(timestamp, state, frame) {
|
|
1469
1386
|
// Run local effects
|
|
1470
1387
|
let delta = state.clock.getDelta(); // In frameloop='never' mode, clock times are updated using the provided timestamp
|
|
@@ -1476,7 +1393,9 @@ function render$1(timestamp, state, frame) {
|
|
|
1476
1393
|
} // Call subscribers (useFrame)
|
|
1477
1394
|
|
|
1478
1395
|
|
|
1479
|
-
|
|
1396
|
+
subscribers = state.internal.subscribers;
|
|
1397
|
+
|
|
1398
|
+
for (i = 0; i < subscribers.length; i++) subscribers[i].ref.current(state, delta, frame); // Render content
|
|
1480
1399
|
|
|
1481
1400
|
|
|
1482
1401
|
if (!state.internal.priority && state.gl.render) state.gl.render(state.scene, state.camera); // Decrease frame count
|
|
@@ -1488,29 +1407,35 @@ function render$1(timestamp, state, frame) {
|
|
|
1488
1407
|
function createLoop(roots) {
|
|
1489
1408
|
let running = false;
|
|
1490
1409
|
let repeat;
|
|
1410
|
+
let frame;
|
|
1411
|
+
let state;
|
|
1491
1412
|
|
|
1492
1413
|
function loop(timestamp) {
|
|
1414
|
+
frame = requestAnimationFrame(loop);
|
|
1493
1415
|
running = true;
|
|
1494
1416
|
repeat = 0; // Run effects
|
|
1495
1417
|
|
|
1496
|
-
run(globalEffects, timestamp); // Render all roots
|
|
1418
|
+
if (globalEffects.length) run(globalEffects, timestamp); // Render all roots
|
|
1497
1419
|
|
|
1498
1420
|
roots.forEach(root => {
|
|
1499
1421
|
var _state$gl$xr;
|
|
1500
1422
|
|
|
1501
|
-
|
|
1423
|
+
state = root.store.getState(); // If the frameloop is invalidated, do not run another frame
|
|
1502
1424
|
|
|
1503
1425
|
if (state.internal.active && (state.frameloop === 'always' || state.internal.frames > 0) && !((_state$gl$xr = state.gl.xr) != null && _state$gl$xr.isPresenting)) {
|
|
1504
1426
|
repeat += render$1(timestamp, state);
|
|
1505
1427
|
}
|
|
1506
1428
|
}); // Run after-effects
|
|
1507
1429
|
|
|
1508
|
-
run(globalAfterEffects, timestamp); //
|
|
1430
|
+
if (globalAfterEffects.length) run(globalAfterEffects, timestamp); // Stop the loop if nothing invalidates it
|
|
1509
1431
|
|
|
1510
|
-
if (repeat
|
|
1511
|
-
|
|
1432
|
+
if (repeat === 0) {
|
|
1433
|
+
// Tail call effects, they are called when rendering stops
|
|
1434
|
+
if (globalTailEffects.length) run(globalTailEffects, timestamp); // Flag end of operation
|
|
1512
1435
|
|
|
1513
|
-
|
|
1436
|
+
running = false;
|
|
1437
|
+
return cancelAnimationFrame(frame);
|
|
1438
|
+
}
|
|
1514
1439
|
}
|
|
1515
1440
|
|
|
1516
1441
|
function invalidate(state) {
|
|
@@ -1574,6 +1499,11 @@ function loadingFn(extensions, onProgress) {
|
|
|
1574
1499
|
};
|
|
1575
1500
|
}
|
|
1576
1501
|
|
|
1502
|
+
function useMemoizedFn(fn) {
|
|
1503
|
+
const fnRef = React__namespace.useRef(fn);
|
|
1504
|
+
React__namespace.useLayoutEffect(() => void (fnRef.current = fn), [fn]);
|
|
1505
|
+
return (...args) => fnRef.current == null ? void 0 : fnRef.current(...args);
|
|
1506
|
+
}
|
|
1577
1507
|
function useLoader(Proto, input, extensions, onProgress) {
|
|
1578
1508
|
// Use suspense to load async assets
|
|
1579
1509
|
const keys = Array.isArray(input) ? input : [input];
|
|
@@ -1603,137 +1533,240 @@ const {
|
|
|
1603
1533
|
reconciler,
|
|
1604
1534
|
applyProps
|
|
1605
1535
|
} = createRenderer(roots, getEventPriority);
|
|
1536
|
+
const shallowLoose = {
|
|
1537
|
+
objects: 'shallow',
|
|
1538
|
+
strict: false
|
|
1539
|
+
};
|
|
1606
1540
|
|
|
1607
1541
|
const createRendererInstance = (gl, canvas) => {
|
|
1608
1542
|
const customRenderer = typeof gl === 'function' ? gl(canvas) : gl;
|
|
1609
|
-
if (isRenderer(customRenderer)) return customRenderer;
|
|
1610
|
-
const renderer = new THREE__namespace.WebGLRenderer({
|
|
1543
|
+
if (isRenderer(customRenderer)) return customRenderer;else return new THREE__namespace.WebGLRenderer({
|
|
1611
1544
|
powerPreference: 'high-performance',
|
|
1612
1545
|
canvas: canvas,
|
|
1613
1546
|
antialias: true,
|
|
1614
1547
|
alpha: true,
|
|
1615
1548
|
...gl
|
|
1616
|
-
});
|
|
1549
|
+
});
|
|
1550
|
+
};
|
|
1617
1551
|
|
|
1618
|
-
|
|
1619
|
-
|
|
1552
|
+
function createRoot(canvas) {
|
|
1553
|
+
// Check against mistaken use of createRoot
|
|
1554
|
+
let prevRoot = roots.get(canvas);
|
|
1555
|
+
let prevFiber = prevRoot == null ? void 0 : prevRoot.fiber;
|
|
1556
|
+
let prevStore = prevRoot == null ? void 0 : prevRoot.store;
|
|
1557
|
+
if (prevRoot) console.warn('R3F.createRoot should only be called once!'); // Create store
|
|
1620
1558
|
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1559
|
+
const store = prevStore || createStore(invalidate, advance); // Create renderer
|
|
1560
|
+
|
|
1561
|
+
const fiber = prevFiber || reconciler.createContainer(store, constants.ConcurrentRoot, false, null); // Map it
|
|
1624
1562
|
|
|
1625
|
-
|
|
1563
|
+
if (!prevRoot) roots.set(canvas, {
|
|
1564
|
+
fiber,
|
|
1565
|
+
store
|
|
1566
|
+
}); // Locals
|
|
1567
|
+
|
|
1568
|
+
let onCreated;
|
|
1569
|
+
let configured = false;
|
|
1626
1570
|
return {
|
|
1627
|
-
|
|
1628
|
-
var
|
|
1571
|
+
configure(props = {}) {
|
|
1572
|
+
var _canvas$parentElement, _canvas$parentElement2, _canvas$parentElement3, _canvas$parentElement4;
|
|
1629
1573
|
|
|
1630
1574
|
let {
|
|
1631
|
-
gl,
|
|
1575
|
+
gl: glConfig,
|
|
1632
1576
|
size,
|
|
1633
1577
|
events,
|
|
1634
|
-
onCreated,
|
|
1635
|
-
|
|
1636
|
-
|
|
1578
|
+
onCreated: onCreatedCallback,
|
|
1579
|
+
shadows = false,
|
|
1580
|
+
linear = false,
|
|
1581
|
+
flat = false,
|
|
1582
|
+
orthographic = false,
|
|
1583
|
+
frameloop = 'always',
|
|
1584
|
+
dpr = [1, 2],
|
|
1585
|
+
performance,
|
|
1586
|
+
raycaster: raycastOptions,
|
|
1587
|
+
camera: cameraOptions,
|
|
1588
|
+
onPointerMissed
|
|
1589
|
+
} = props;
|
|
1590
|
+
let state = store.getState(); // Set up renderer (one time only!)
|
|
1591
|
+
|
|
1592
|
+
let gl = state.gl;
|
|
1593
|
+
if (!state.gl) state.set({
|
|
1594
|
+
gl: gl = createRendererInstance(glConfig, canvas)
|
|
1595
|
+
}); // Set up raycaster (one time only!)
|
|
1596
|
+
|
|
1597
|
+
let raycaster = state.raycaster;
|
|
1598
|
+
if (!raycaster) state.set({
|
|
1599
|
+
raycaster: raycaster = new THREE__namespace.Raycaster()
|
|
1600
|
+
}); // Set raycaster options
|
|
1601
|
+
|
|
1602
|
+
const {
|
|
1603
|
+
params,
|
|
1604
|
+
...options
|
|
1605
|
+
} = raycastOptions || {};
|
|
1606
|
+
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, { ...options
|
|
1607
|
+
});
|
|
1608
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) applyProps(raycaster, {
|
|
1609
|
+
params: { ...raycaster.params,
|
|
1610
|
+
...params
|
|
1611
|
+
}
|
|
1612
|
+
}); // Create default camera (one time only!)
|
|
1637
1613
|
|
|
1638
|
-
if (!
|
|
1639
|
-
|
|
1614
|
+
if (!state.camera) {
|
|
1615
|
+
const isCamera = cameraOptions instanceof THREE__namespace.Camera;
|
|
1616
|
+
const camera = isCamera ? cameraOptions : orthographic ? new THREE__namespace.OrthographicCamera(0, 0, 0, 0, 0.1, 1000) : new THREE__namespace.PerspectiveCamera(75, 0, 0.1, 1000);
|
|
1640
1617
|
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1618
|
+
if (!isCamera) {
|
|
1619
|
+
camera.position.z = 5;
|
|
1620
|
+
if (cameraOptions) applyProps(camera, cameraOptions); // Always look at center by default
|
|
1621
|
+
|
|
1622
|
+
if (!(cameraOptions != null && cameraOptions.rotation)) camera.lookAt(0, 0, 0);
|
|
1623
|
+
}
|
|
1646
1624
|
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1625
|
+
state.set({
|
|
1626
|
+
camera
|
|
1627
|
+
});
|
|
1628
|
+
} // Set up XR (one time only!)
|
|
1651
1629
|
|
|
1652
|
-
if (fiber && state) {
|
|
1653
|
-
// When a root was found, see if any fundamental props must be changed or exchanged
|
|
1654
|
-
// Check pixelratio
|
|
1655
|
-
if (props.dpr !== undefined && state.viewport.dpr !== calculateDpr(props.dpr)) state.setDpr(props.dpr); // Check size
|
|
1656
1630
|
|
|
1657
|
-
|
|
1631
|
+
if (!state.xr) {
|
|
1632
|
+
// Handle frame behavior in WebXR
|
|
1633
|
+
const handleXRFrame = (timestamp, frame) => {
|
|
1634
|
+
const state = store.getState();
|
|
1635
|
+
if (state.frameloop === 'never') return;
|
|
1636
|
+
advance(timestamp, true, state, frame);
|
|
1637
|
+
}; // Toggle render switching on session
|
|
1658
1638
|
|
|
1659
|
-
if (state.frameloop !== props.frameloop) state.setFrameloop(props.frameloop); // For some props we want to reset the entire root
|
|
1660
|
-
// Changes to the color-space
|
|
1661
1639
|
|
|
1662
|
-
const
|
|
1640
|
+
const handleSessionChange = () => {
|
|
1641
|
+
const gl = store.getState().gl;
|
|
1642
|
+
gl.xr.enabled = gl.xr.isPresenting; // @ts-ignore
|
|
1643
|
+
// WebXRManager's signature is incorrect.
|
|
1644
|
+
// See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
|
|
1663
1645
|
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
fiber = undefined;
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1646
|
+
gl.xr.setAnimationLoop(gl.xr.isPresenting ? handleXRFrame : null);
|
|
1647
|
+
}; // WebXR session manager
|
|
1669
1648
|
|
|
1670
|
-
if (!fiber) {
|
|
1671
|
-
// If no root has been found, make one
|
|
1672
|
-
// Create gl
|
|
1673
|
-
const glRenderer = createRendererInstance(gl, canvas); // Create store
|
|
1674
1649
|
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1650
|
+
const xr = {
|
|
1651
|
+
connect() {
|
|
1652
|
+
const gl = store.getState().gl;
|
|
1653
|
+
gl.xr.addEventListener('sessionstart', handleSessionChange);
|
|
1654
|
+
gl.xr.addEventListener('sessionend', handleSessionChange);
|
|
1655
|
+
},
|
|
1681
1656
|
|
|
1682
|
-
|
|
1657
|
+
disconnect() {
|
|
1658
|
+
const gl = store.getState().gl;
|
|
1659
|
+
gl.xr.removeEventListener('sessionstart', handleSessionChange);
|
|
1660
|
+
gl.xr.removeEventListener('sessionend', handleSessionChange);
|
|
1661
|
+
}
|
|
1683
1662
|
|
|
1684
|
-
|
|
1685
|
-
fiber,
|
|
1686
|
-
store
|
|
1687
|
-
}); // Store events internally
|
|
1663
|
+
}; // Subscribe to WebXR session events
|
|
1688
1664
|
|
|
1689
|
-
if (
|
|
1690
|
-
|
|
1665
|
+
if (gl.xr) xr.connect();
|
|
1666
|
+
state.set({
|
|
1667
|
+
xr
|
|
1691
1668
|
});
|
|
1692
|
-
}
|
|
1669
|
+
} // Set shadowmap
|
|
1693
1670
|
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
}
|
|
1671
|
+
|
|
1672
|
+
if (gl.shadowMap) {
|
|
1673
|
+
const isBoolean = is.boo(shadows);
|
|
1674
|
+
|
|
1675
|
+
if (isBoolean && gl.shadowMap.enabled !== shadows || !is.equ(shadows, gl.shadowMap, shallowLoose)) {
|
|
1676
|
+
const old = gl.shadowMap.enabled;
|
|
1677
|
+
gl.shadowMap.enabled = !!shadows;
|
|
1678
|
+
if (!isBoolean) Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE__namespace.PCFSoftShadowMap;
|
|
1679
|
+
if (old !== gl.shadowMap.enabled) gl.shadowMap.needsUpdate = true;
|
|
1680
|
+
}
|
|
1681
|
+
} // Set color management
|
|
1682
|
+
|
|
1683
|
+
|
|
1684
|
+
if (THREE__namespace.ColorManagement) THREE__namespace.ColorManagement.legacyMode = false;
|
|
1685
|
+
const outputEncoding = linear ? THREE__namespace.LinearEncoding : THREE__namespace.sRGBEncoding;
|
|
1686
|
+
const toneMapping = flat ? THREE__namespace.NoToneMapping : THREE__namespace.ACESFilmicToneMapping;
|
|
1687
|
+
if (gl.outputEncoding !== outputEncoding) gl.outputEncoding = outputEncoding;
|
|
1688
|
+
if (gl.toneMapping !== toneMapping) gl.toneMapping = toneMapping; // Set gl props
|
|
1689
|
+
|
|
1690
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, gl, shallowLoose)) applyProps(gl, glConfig); // Store events internally
|
|
1691
|
+
|
|
1692
|
+
if (events && !state.events.handlers) state.set({
|
|
1693
|
+
events: events(store)
|
|
1694
|
+
}); // Check pixelratio
|
|
1695
|
+
|
|
1696
|
+
if (dpr && state.viewport.dpr !== calculateDpr(dpr)) state.setDpr(dpr); // Check size, allow it to take on container bounds initially
|
|
1697
|
+
|
|
1698
|
+
size = size || {
|
|
1699
|
+
width: (_canvas$parentElement = (_canvas$parentElement2 = canvas.parentElement) == null ? void 0 : _canvas$parentElement2.clientWidth) != null ? _canvas$parentElement : 0,
|
|
1700
|
+
height: (_canvas$parentElement3 = (_canvas$parentElement4 = canvas.parentElement) == null ? void 0 : _canvas$parentElement4.clientHeight) != null ? _canvas$parentElement3 : 0
|
|
1701
|
+
};
|
|
1702
|
+
if (!is.equ(size, state.size, shallowLoose)) state.setSize(size.width, size.height); // Check frameloop
|
|
1703
|
+
|
|
1704
|
+
if (state.frameloop !== frameloop) state.setFrameloop(frameloop); // Check pointer missed
|
|
1705
|
+
|
|
1706
|
+
if (!state.onPointerMissed) state.set({
|
|
1707
|
+
onPointerMissed
|
|
1708
|
+
}); // Check performance
|
|
1709
|
+
|
|
1710
|
+
if (performance && !is.equ(performance, state.performance, shallowLoose)) state.set(state => ({
|
|
1711
|
+
performance: { ...state.performance,
|
|
1712
|
+
...performance
|
|
1713
|
+
}
|
|
1714
|
+
})); // Set locals
|
|
1715
|
+
|
|
1716
|
+
onCreated = onCreatedCallback;
|
|
1717
|
+
configured = true;
|
|
1718
|
+
return this;
|
|
1705
1719
|
},
|
|
1706
|
-
|
|
1720
|
+
|
|
1721
|
+
render(children) {
|
|
1722
|
+
// The root has to be configured before it can be rendered
|
|
1723
|
+
if (!configured) this.configure();
|
|
1724
|
+
reconciler.updateContainer( /*#__PURE__*/React__namespace.createElement(Provider, {
|
|
1725
|
+
store: store,
|
|
1726
|
+
children: children,
|
|
1727
|
+
onCreated: onCreated,
|
|
1728
|
+
rootElement: canvas
|
|
1729
|
+
}), fiber, null, () => undefined);
|
|
1730
|
+
return store;
|
|
1731
|
+
},
|
|
1732
|
+
|
|
1733
|
+
unmount() {
|
|
1734
|
+
unmountComponentAtNode(canvas);
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1707
1737
|
};
|
|
1708
1738
|
}
|
|
1709
1739
|
|
|
1710
|
-
function render(
|
|
1740
|
+
function render(children, canvas, config) {
|
|
1711
1741
|
console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!');
|
|
1712
|
-
|
|
1742
|
+
const root = createRoot(canvas);
|
|
1743
|
+
root.configure(config);
|
|
1744
|
+
return root.render(children);
|
|
1713
1745
|
}
|
|
1714
1746
|
|
|
1715
1747
|
function Provider({
|
|
1716
1748
|
store,
|
|
1717
|
-
|
|
1749
|
+
children,
|
|
1718
1750
|
onCreated,
|
|
1719
|
-
|
|
1751
|
+
rootElement
|
|
1720
1752
|
}) {
|
|
1721
|
-
React__namespace.
|
|
1753
|
+
React__namespace.useLayoutEffect(() => {
|
|
1722
1754
|
const state = store.getState(); // Flag the canvas active, rendering will now begin
|
|
1723
1755
|
|
|
1724
1756
|
state.set(state => ({
|
|
1725
1757
|
internal: { ...state.internal,
|
|
1726
1758
|
active: true
|
|
1727
1759
|
}
|
|
1728
|
-
})); //
|
|
1760
|
+
})); // Notifiy that init is completed, the scene graph exists, but nothing has yet rendered
|
|
1729
1761
|
|
|
1730
|
-
|
|
1762
|
+
if (onCreated) onCreated(state); // Connect events to the targets parent, this is done to ensure events are registered on
|
|
1763
|
+
// a shared target, and not on the canvas itself
|
|
1731
1764
|
|
|
1732
|
-
if (
|
|
1765
|
+
if (!store.getState().events.connected) state.events.connect == null ? void 0 : state.events.connect(rootElement); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1733
1766
|
}, []);
|
|
1734
1767
|
return /*#__PURE__*/React__namespace.createElement(context.Provider, {
|
|
1735
1768
|
value: store
|
|
1736
|
-
},
|
|
1769
|
+
}, children);
|
|
1737
1770
|
}
|
|
1738
1771
|
|
|
1739
1772
|
function unmountComponentAtNode(canvas, callback) {
|
|
@@ -1752,7 +1785,7 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
1752
1785
|
state.events.disconnect == null ? void 0 : state.events.disconnect();
|
|
1753
1786
|
(_state$gl = state.gl) == null ? void 0 : (_state$gl$renderLists = _state$gl.renderLists) == null ? void 0 : _state$gl$renderLists.dispose == null ? void 0 : _state$gl$renderLists.dispose();
|
|
1754
1787
|
(_state$gl2 = state.gl) == null ? void 0 : _state$gl2.forceContextLoss == null ? void 0 : _state$gl2.forceContextLoss();
|
|
1755
|
-
if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.
|
|
1788
|
+
if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.xr.disconnect();
|
|
1756
1789
|
dispose(state);
|
|
1757
1790
|
roots.delete(canvas);
|
|
1758
1791
|
if (callback) callback(canvas);
|
|
@@ -1765,10 +1798,67 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
1765
1798
|
}
|
|
1766
1799
|
}
|
|
1767
1800
|
|
|
1768
|
-
|
|
1801
|
+
function createPortal(children, container, state) {
|
|
1802
|
+
return /*#__PURE__*/React__namespace.createElement(Portal, {
|
|
1803
|
+
children: children,
|
|
1804
|
+
container: container,
|
|
1805
|
+
state: state
|
|
1806
|
+
});
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
function Portal({
|
|
1810
|
+
state = {},
|
|
1811
|
+
children,
|
|
1812
|
+
container
|
|
1813
|
+
}) {
|
|
1814
|
+
/** This has to be a component because it would not be able to call useThree/useStore otherwise since
|
|
1815
|
+
* if this is our environment, then we are not in r3f's renderer but in react-dom, it would trigger
|
|
1816
|
+
* the "R3F hooks can only be used within the Canvas component!" warning:
|
|
1817
|
+
* <Canvas>
|
|
1818
|
+
* {createPortal(...)} */
|
|
1819
|
+
const {
|
|
1820
|
+
events,
|
|
1821
|
+
...rest
|
|
1822
|
+
} = state;
|
|
1823
|
+
const previousRoot = useStore();
|
|
1824
|
+
const [raycaster] = React__namespace.useState(() => new THREE__namespace.Raycaster());
|
|
1825
|
+
const inject = React__namespace.useCallback((state, injectState) => {
|
|
1826
|
+
const intersect = { ...state
|
|
1827
|
+
};
|
|
1828
|
+
|
|
1829
|
+
if (injectState) {
|
|
1830
|
+
// Only the fields of "state" that do not differ from injectState
|
|
1831
|
+
Object.keys(state).forEach(key => {
|
|
1832
|
+
if ( // Some props should be off-limits
|
|
1833
|
+
!['size', 'viewport', 'internal', 'performance'].includes(key) && // Otherwise filter out the props that are different and let the inject layer take precedence
|
|
1834
|
+
state[key] !== injectState[key]) delete intersect[key];
|
|
1835
|
+
});
|
|
1836
|
+
}
|
|
1769
1837
|
|
|
1770
|
-
|
|
1771
|
-
|
|
1838
|
+
return { ...intersect,
|
|
1839
|
+
scene: container,
|
|
1840
|
+
previousRoot,
|
|
1841
|
+
raycaster,
|
|
1842
|
+
events: { ...state.events,
|
|
1843
|
+
...events
|
|
1844
|
+
},
|
|
1845
|
+
...rest
|
|
1846
|
+
};
|
|
1847
|
+
}, [state]);
|
|
1848
|
+
const [useInjectStore] = React__namespace.useState(() => {
|
|
1849
|
+
const store = create__default['default']((set, get) => ({ ...inject(previousRoot.getState()),
|
|
1850
|
+
set,
|
|
1851
|
+
get
|
|
1852
|
+
}));
|
|
1853
|
+
previousRoot.subscribe(state => useInjectStore.setState(injectState => inject(state, injectState)));
|
|
1854
|
+
return store;
|
|
1855
|
+
});
|
|
1856
|
+
React__namespace.useEffect(() => {
|
|
1857
|
+
useInjectStore.setState(injectState => inject(previousRoot.getState(), injectState));
|
|
1858
|
+
}, [inject]);
|
|
1859
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, reconciler.createPortal( /*#__PURE__*/React__namespace.createElement(context.Provider, {
|
|
1860
|
+
value: useInjectStore
|
|
1861
|
+
}, children), useInjectStore, null));
|
|
1772
1862
|
}
|
|
1773
1863
|
|
|
1774
1864
|
reconciler.injectIntoDevTools({
|
|
@@ -1776,6 +1866,7 @@ reconciler.injectIntoDevTools({
|
|
|
1776
1866
|
rendererPackageName: '@react-three/fiber',
|
|
1777
1867
|
version: '18.0.0'
|
|
1778
1868
|
});
|
|
1869
|
+
const act = React__namespace.unstable_act;
|
|
1779
1870
|
|
|
1780
1871
|
exports.act = act;
|
|
1781
1872
|
exports.addAfterEffect = addAfterEffect;
|
|
@@ -1789,6 +1880,7 @@ exports.createPortal = createPortal;
|
|
|
1789
1880
|
exports.createRoot = createRoot;
|
|
1790
1881
|
exports.dispose = dispose;
|
|
1791
1882
|
exports.extend = extend;
|
|
1883
|
+
exports.getRootState = getRootState;
|
|
1792
1884
|
exports.invalidate = invalidate;
|
|
1793
1885
|
exports.omit = omit;
|
|
1794
1886
|
exports.pick = pick;
|
|
@@ -1800,5 +1892,6 @@ exports.unmountComponentAtNode = unmountComponentAtNode;
|
|
|
1800
1892
|
exports.useFrame = useFrame;
|
|
1801
1893
|
exports.useGraph = useGraph;
|
|
1802
1894
|
exports.useLoader = useLoader;
|
|
1895
|
+
exports.useMemoizedFn = useMemoizedFn;
|
|
1803
1896
|
exports.useStore = useStore;
|
|
1804
1897
|
exports.useThree = useThree;
|