@react-three/fiber 8.0.0-beta-04 → 8.0.0-beta.1
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 +18 -0
- package/dist/declarations/src/core/index.d.ts +10 -7
- package/dist/declarations/src/core/loop.d.ts +3 -2
- package/dist/declarations/src/core/store.d.ts +13 -15
- package/dist/declarations/src/core/utils.d.ts +7 -1
- package/dist/declarations/src/index.d.ts +1 -1
- package/dist/declarations/src/native.d.ts +1 -1
- package/dist/declarations/src/three-types.d.ts +7 -8
- package/dist/{index-ff3eb68b.cjs.dev.js → index-05ebefd3.cjs.dev.js} +322 -279
- package/dist/{index-eb414398.cjs.prod.js → index-85b2df17.cjs.prod.js} +322 -279
- package/dist/{index-fccd77b0.esm.js → index-e78dd2f0.esm.js} +323 -278
- package/dist/react-three-fiber.cjs.dev.js +9 -6
- package/dist/react-three-fiber.cjs.prod.js +9 -6
- package/dist/react-three-fiber.esm.js +10 -7
- package/native/dist/react-three-fiber-native.cjs.dev.js +100 -125
- package/native/dist/react-three-fiber-native.cjs.prod.js +100 -125
- package/native/dist/react-three-fiber-native.esm.js +101 -126
- package/package.json +14 -9
- package/dist/declarations/src/native/hooks.d.ts +0 -9
|
@@ -41,29 +41,38 @@ const pick = (obj, keys) => filterKeys(obj, false, ...keys);
|
|
|
41
41
|
* Clones an object and prunes or omits keys.
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
|
-
const omit = (obj, keys) => filterKeys(obj, true, ...keys);
|
|
45
|
-
|
|
44
|
+
const omit = (obj, keys) => filterKeys(obj, true, ...keys);
|
|
45
|
+
// A collection of compare functions
|
|
46
46
|
const is = {
|
|
47
47
|
obj: a => a === Object(a) && !is.arr(a) && typeof a !== 'function',
|
|
48
48
|
fun: a => typeof a === 'function',
|
|
49
49
|
str: a => typeof a === 'string',
|
|
50
50
|
num: a => typeof a === 'number',
|
|
51
|
+
boo: a => typeof a === 'boolean',
|
|
51
52
|
und: a => a === void 0,
|
|
52
53
|
arr: a => Array.isArray(a),
|
|
53
54
|
|
|
54
|
-
equ(a, b
|
|
55
|
+
equ(a, b, {
|
|
56
|
+
arrays = 'shallow',
|
|
57
|
+
objects = 'reference',
|
|
58
|
+
strict = true
|
|
59
|
+
} = {}) {
|
|
55
60
|
// Wrong type or one of the two undefined, doesn't match
|
|
56
61
|
if (typeof a !== typeof b || !!a !== !!b) return false; // Atomic, just compare a against b
|
|
57
62
|
|
|
58
|
-
if (is.str(a) || is.num(a)
|
|
63
|
+
if (is.str(a) || is.num(a)) return a === b;
|
|
64
|
+
const isObj = is.obj(a);
|
|
65
|
+
if (isObj && objects === 'reference') return a === b;
|
|
66
|
+
const isArr = is.arr(a);
|
|
67
|
+
if (isArr && arrays === 'reference') return a === b; // Array or Object, shallow compare first to see if it's a match
|
|
59
68
|
|
|
60
|
-
if (
|
|
69
|
+
if ((isArr || isObj) && a == b) return true; // Last resort, go through keys
|
|
61
70
|
|
|
62
71
|
let i;
|
|
63
72
|
|
|
64
73
|
for (i in a) if (!(i in b)) return false;
|
|
65
74
|
|
|
66
|
-
for (i in b) if (a[i] !== b[i]) return false;
|
|
75
|
+
for (i in strict ? b : a) if (a[i] !== b[i]) return false;
|
|
67
76
|
|
|
68
77
|
return is.und(i) ? a === b : true;
|
|
69
78
|
}
|
|
@@ -154,15 +163,8 @@ function detach(parent, child, type) {
|
|
|
154
163
|
const [, detach] = type;
|
|
155
164
|
if (is.str(detach)) parent[detach](child);else if (is.fun(detach)) detach(parent, child);
|
|
156
165
|
}
|
|
157
|
-
} // Shallow check arrays, but check objects atomically
|
|
158
|
-
|
|
159
|
-
function checkShallow(a, b) {
|
|
160
|
-
if (is.arr(a) && is.equ(a, b)) return true;
|
|
161
|
-
if (a === b) return true;
|
|
162
|
-
return false;
|
|
163
166
|
} // This function prepares a set of changes to be applied to the instance
|
|
164
167
|
|
|
165
|
-
|
|
166
168
|
function diffProps(instance, {
|
|
167
169
|
children: cN,
|
|
168
170
|
key: kN,
|
|
@@ -194,7 +196,7 @@ function diffProps(instance, {
|
|
|
194
196
|
// Bail out on primitive object
|
|
195
197
|
if ((_instance$__r3f2 = instance.__r3f) != null && _instance$__r3f2.primitive && key === 'object') return; // When props match bail out
|
|
196
198
|
|
|
197
|
-
if (
|
|
199
|
+
if (is.equ(value, previous[key])) return; // Collect handlers and bail out
|
|
198
200
|
|
|
199
201
|
if (/^on(Pointer|Click|DoubleClick|ContextMenu|Wheel)/.test(key)) return changes.push([key, value, true, []]); // Split dashed props
|
|
200
202
|
|
|
@@ -391,7 +393,7 @@ function createEvents(store) {
|
|
|
391
393
|
/** Sets up defaultRaycaster */
|
|
392
394
|
|
|
393
395
|
function prepareRay(event) {
|
|
394
|
-
var
|
|
396
|
+
var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
|
|
395
397
|
|
|
396
398
|
const state = store.getState();
|
|
397
399
|
const {
|
|
@@ -402,14 +404,11 @@ function createEvents(store) {
|
|
|
402
404
|
} = state; // https://github.com/pmndrs/react-three-fiber/pull/782
|
|
403
405
|
// Events trigger outside of canvas when moved
|
|
404
406
|
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
const
|
|
410
|
-
width,
|
|
411
|
-
height
|
|
412
|
-
} = size;
|
|
407
|
+
const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
|
|
408
|
+
const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
|
|
409
|
+
const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
|
|
410
|
+
const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
|
|
411
|
+
const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
|
|
413
412
|
mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
414
413
|
raycaster.setFromCamera(mouse, camera);
|
|
415
414
|
}
|
|
@@ -968,10 +967,13 @@ function createRenderer(roots, getEventPriority) {
|
|
|
968
967
|
|
|
969
968
|
instance.__r3f.objects = [];
|
|
970
969
|
removeChild(parent, instance);
|
|
971
|
-
appendChild(parent, newInstance) //
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
970
|
+
appendChild(parent, newInstance); // Re-bind event handlers
|
|
971
|
+
|
|
972
|
+
if (newInstance.raycast && newInstance.__r3f.eventCount) {
|
|
973
|
+
const rootState = newInstance.__r3f.root.getState();
|
|
974
|
+
|
|
975
|
+
rootState.internal.interaction.push(newInstance);
|
|
976
|
+
} // This evil hack switches the react-internal fiber node
|
|
975
977
|
[fiber, fiber.alternate].forEach(fiber => {
|
|
976
978
|
if (fiber !== null) {
|
|
977
979
|
fiber.stateNode = newInstance;
|
|
@@ -1065,7 +1067,7 @@ function createRenderer(roots, getEventPriority) {
|
|
|
1065
1067
|
isPrimaryRenderer: false,
|
|
1066
1068
|
getCurrentEventPriority: () => getEventPriority ? getEventPriority() : DefaultEventPriority,
|
|
1067
1069
|
// @ts-ignore
|
|
1068
|
-
now: is.fun(performance.now) ? performance.now : is.fun(Date.now) ? Date.now : undefined,
|
|
1070
|
+
now: typeof performance !== 'undefined' && is.fun(performance.now) ? performance.now : is.fun(Date.now) ? Date.now : undefined,
|
|
1069
1071
|
// @ts-ignore
|
|
1070
1072
|
scheduleTimeout: is.fun(setTimeout) ? setTimeout : undefined,
|
|
1071
1073
|
// @ts-ignore
|
|
@@ -1123,63 +1125,8 @@ const isRenderer = def => !!(def != null && def.render);
|
|
|
1123
1125
|
const isOrthographicCamera = def => def && def.isOrthographicCamera;
|
|
1124
1126
|
const context = /*#__PURE__*/React.createContext(null);
|
|
1125
1127
|
|
|
1126
|
-
const createStore = (
|
|
1127
|
-
const {
|
|
1128
|
-
gl,
|
|
1129
|
-
size,
|
|
1130
|
-
shadows = false,
|
|
1131
|
-
linear = false,
|
|
1132
|
-
flat = false,
|
|
1133
|
-
orthographic = false,
|
|
1134
|
-
frameloop = 'always',
|
|
1135
|
-
dpr = [1, 2],
|
|
1136
|
-
performance,
|
|
1137
|
-
clock = new THREE.Clock(),
|
|
1138
|
-
raycaster: raycastOptions,
|
|
1139
|
-
camera: cameraOptions,
|
|
1140
|
-
onPointerMissed
|
|
1141
|
-
} = props; // Set shadowmap
|
|
1142
|
-
|
|
1143
|
-
if (shadows) {
|
|
1144
|
-
gl.shadowMap.enabled = true;
|
|
1145
|
-
if (typeof shadows === 'object') Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
1146
|
-
} // Set color preferences
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
if (linear) gl.outputEncoding = THREE.LinearEncoding;
|
|
1150
|
-
if (flat) gl.toneMapping = THREE.NoToneMapping; // clock.elapsedTime is updated using advance(timestamp)
|
|
1151
|
-
|
|
1152
|
-
if (frameloop === 'never') {
|
|
1153
|
-
clock.stop();
|
|
1154
|
-
clock.elapsedTime = 0;
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1128
|
+
const createStore = (invalidate, advance) => {
|
|
1157
1129
|
const rootState = create((set, get) => {
|
|
1158
|
-
// Create custom raycaster
|
|
1159
|
-
const raycaster = new THREE.Raycaster();
|
|
1160
|
-
const {
|
|
1161
|
-
params,
|
|
1162
|
-
...options
|
|
1163
|
-
} = raycastOptions || {};
|
|
1164
|
-
applyProps(raycaster, {
|
|
1165
|
-
enabled: true,
|
|
1166
|
-
...options,
|
|
1167
|
-
params: { ...raycaster.params,
|
|
1168
|
-
...params
|
|
1169
|
-
}
|
|
1170
|
-
}); // Create default camera
|
|
1171
|
-
|
|
1172
|
-
const isCamera = cameraOptions instanceof THREE.Camera;
|
|
1173
|
-
const camera = isCamera ? cameraOptions : orthographic ? new THREE.OrthographicCamera(0, 0, 0, 0, 0.1, 1000) : new THREE.PerspectiveCamera(75, 0, 0.1, 1000);
|
|
1174
|
-
|
|
1175
|
-
if (!isCamera) {
|
|
1176
|
-
camera.position.z = 5;
|
|
1177
|
-
if (cameraOptions) applyProps(camera, cameraOptions); // Always look at center by default
|
|
1178
|
-
|
|
1179
|
-
if (!(cameraOptions != null && cameraOptions.rotation)) camera.lookAt(0, 0, 0);
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
|
-
const initialDpr = calculateDpr(dpr);
|
|
1183
1130
|
const position = new THREE.Vector3();
|
|
1184
1131
|
const defaultTarget = new THREE.Vector3();
|
|
1185
1132
|
const tempTarget = new THREE.Vector3();
|
|
@@ -1223,60 +1170,34 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1223
1170
|
performance: { ...state.performance,
|
|
1224
1171
|
current
|
|
1225
1172
|
}
|
|
1226
|
-
}));
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
const handleXRFrame = timestamp => {
|
|
1230
|
-
const state = get();
|
|
1231
|
-
if (state.frameloop === 'never') return;
|
|
1232
|
-
advance(timestamp, true);
|
|
1233
|
-
}; // Toggle render switching on session
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
const handleSessionChange = () => {
|
|
1237
|
-
gl.xr.enabled = gl.xr.isPresenting;
|
|
1238
|
-
gl.setAnimationLoop(gl.xr.isPresenting ? handleXRFrame : null); // If exiting session, request frame
|
|
1239
|
-
|
|
1240
|
-
if (!gl.xr.isPresenting) invalidate(get());
|
|
1241
|
-
}; // WebXR session manager
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
const xr = {
|
|
1245
|
-
connect() {
|
|
1246
|
-
gl.xr.addEventListener('sessionstart', handleSessionChange);
|
|
1247
|
-
gl.xr.addEventListener('sessionend', handleSessionChange);
|
|
1248
|
-
},
|
|
1249
|
-
|
|
1250
|
-
disconnect() {
|
|
1251
|
-
gl.xr.removeEventListener('sessionstart', handleSessionChange);
|
|
1252
|
-
gl.xr.removeEventListener('sessionend', handleSessionChange);
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
}; // Subscribe to WebXR session events
|
|
1173
|
+
}));
|
|
1256
1174
|
|
|
1257
|
-
if (gl.xr) xr.connect();
|
|
1258
1175
|
return {
|
|
1259
|
-
|
|
1176
|
+
// Mock objects that have to be configured
|
|
1177
|
+
gl: null,
|
|
1178
|
+
camera: null,
|
|
1179
|
+
raycaster: null,
|
|
1180
|
+
events: {
|
|
1181
|
+
connected: false
|
|
1182
|
+
},
|
|
1183
|
+
xr: null,
|
|
1260
1184
|
set,
|
|
1261
1185
|
get,
|
|
1262
1186
|
invalidate: () => invalidate(get()),
|
|
1263
1187
|
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1264
|
-
linear,
|
|
1265
|
-
flat,
|
|
1188
|
+
linear: false,
|
|
1189
|
+
flat: false,
|
|
1266
1190
|
scene: prepare(new THREE.Scene()),
|
|
1267
|
-
camera,
|
|
1268
1191
|
controls: null,
|
|
1269
|
-
|
|
1270
|
-
clock,
|
|
1192
|
+
clock: new THREE.Clock(),
|
|
1271
1193
|
mouse: new THREE.Vector2(),
|
|
1272
|
-
frameloop,
|
|
1273
|
-
onPointerMissed,
|
|
1194
|
+
frameloop: 'always',
|
|
1195
|
+
onPointerMissed: undefined,
|
|
1274
1196
|
performance: {
|
|
1275
1197
|
current: 1,
|
|
1276
1198
|
min: 0.5,
|
|
1277
1199
|
max: 1,
|
|
1278
1200
|
debounce: 200,
|
|
1279
|
-
...performance,
|
|
1280
1201
|
regress: () => {
|
|
1281
1202
|
const state = get(); // Clear timeout
|
|
1282
1203
|
|
|
@@ -1292,8 +1213,8 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1292
1213
|
height: 0
|
|
1293
1214
|
},
|
|
1294
1215
|
viewport: {
|
|
1295
|
-
initialDpr,
|
|
1296
|
-
dpr:
|
|
1216
|
+
initialDpr: 0,
|
|
1217
|
+
dpr: 0,
|
|
1297
1218
|
width: 0,
|
|
1298
1219
|
height: 0,
|
|
1299
1220
|
aspect: 0,
|
|
@@ -1302,6 +1223,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1302
1223
|
getCurrentViewport
|
|
1303
1224
|
},
|
|
1304
1225
|
setSize: (width, height) => {
|
|
1226
|
+
const camera = get().camera;
|
|
1305
1227
|
const size = {
|
|
1306
1228
|
width,
|
|
1307
1229
|
height
|
|
@@ -1313,22 +1235,34 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1313
1235
|
}
|
|
1314
1236
|
}));
|
|
1315
1237
|
},
|
|
1316
|
-
setDpr: dpr => set(state =>
|
|
1317
|
-
|
|
1318
|
-
|
|
1238
|
+
setDpr: dpr => set(state => {
|
|
1239
|
+
const resolved = calculateDpr(dpr);
|
|
1240
|
+
return {
|
|
1241
|
+
viewport: { ...state.viewport,
|
|
1242
|
+
dpr: resolved,
|
|
1243
|
+
initialDpr: state.viewport.initialDpr || resolved
|
|
1244
|
+
}
|
|
1245
|
+
};
|
|
1246
|
+
}),
|
|
1247
|
+
setFrameloop: (frameloop = 'always') => {
|
|
1248
|
+
const clock = get().clock; // if frameloop === "never" clock.elapsedTime is updated using advance(timestamp)
|
|
1249
|
+
|
|
1250
|
+
clock.stop();
|
|
1251
|
+
clock.elapsedTime = 0;
|
|
1252
|
+
|
|
1253
|
+
if (frameloop !== 'never') {
|
|
1254
|
+
clock.start();
|
|
1255
|
+
clock.elapsedTime = 0;
|
|
1319
1256
|
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
events: {
|
|
1325
|
-
connected: false
|
|
1257
|
+
|
|
1258
|
+
set(() => ({
|
|
1259
|
+
frameloop
|
|
1260
|
+
}));
|
|
1326
1261
|
},
|
|
1327
1262
|
internal: {
|
|
1328
1263
|
active: false,
|
|
1329
1264
|
priority: 0,
|
|
1330
1265
|
frames: 0,
|
|
1331
|
-
lastProps: props,
|
|
1332
1266
|
lastEvent: /*#__PURE__*/React.createRef(),
|
|
1333
1267
|
interaction: [],
|
|
1334
1268
|
hovered: new Map(),
|
|
@@ -1336,7 +1270,6 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1336
1270
|
initialClick: [0, 0],
|
|
1337
1271
|
initialHits: [],
|
|
1338
1272
|
capturedMap: new Map(),
|
|
1339
|
-
xr,
|
|
1340
1273
|
subscribe: (ref, priority = 0) => {
|
|
1341
1274
|
set(({
|
|
1342
1275
|
internal
|
|
@@ -1380,13 +1313,14 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1380
1313
|
camera,
|
|
1381
1314
|
size,
|
|
1382
1315
|
viewport,
|
|
1383
|
-
internal
|
|
1316
|
+
internal,
|
|
1317
|
+
gl
|
|
1384
1318
|
} = rootState.getState();
|
|
1385
1319
|
|
|
1386
1320
|
if (size !== oldSize || viewport.dpr !== oldDpr) {
|
|
1387
1321
|
// https://github.com/pmndrs/react-three-fiber/issues/92
|
|
1388
1322
|
// Do not mess with the camera if it belongs to the user
|
|
1389
|
-
if (!camera.manual
|
|
1323
|
+
if (!camera.manual) {
|
|
1390
1324
|
if (isOrthographicCamera(camera)) {
|
|
1391
1325
|
camera.left = size.width / -2;
|
|
1392
1326
|
camera.right = size.width / 2;
|
|
@@ -1408,69 +1342,13 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1408
1342
|
oldSize = size;
|
|
1409
1343
|
oldDpr = viewport.dpr;
|
|
1410
1344
|
}
|
|
1411
|
-
}); //
|
|
1412
|
-
|
|
1413
|
-
if (size) state.setSize(size.width, size.height); // Invalidate on any change
|
|
1345
|
+
}); // Invalidate on any change
|
|
1414
1346
|
|
|
1415
1347
|
rootState.subscribe(state => invalidate(state)); // Return root state
|
|
1416
1348
|
|
|
1417
1349
|
return rootState;
|
|
1418
1350
|
};
|
|
1419
1351
|
|
|
1420
|
-
function useStore() {
|
|
1421
|
-
const store = React.useContext(context);
|
|
1422
|
-
if (!store) throw `R3F hooks can only be used within the Canvas component!`;
|
|
1423
|
-
return store;
|
|
1424
|
-
}
|
|
1425
|
-
function useThree(selector = state => state, equalityFn) {
|
|
1426
|
-
return useStore()(selector, equalityFn);
|
|
1427
|
-
}
|
|
1428
|
-
function useFrame(callback, renderPriority = 0) {
|
|
1429
|
-
const subscribe = useStore().getState().internal.subscribe; // Update ref
|
|
1430
|
-
|
|
1431
|
-
const ref = React.useRef(callback);
|
|
1432
|
-
React.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
|
|
1433
|
-
|
|
1434
|
-
React.useLayoutEffect(() => subscribe(ref, renderPriority), [renderPriority, subscribe]);
|
|
1435
|
-
return null;
|
|
1436
|
-
}
|
|
1437
|
-
function useGraph(object) {
|
|
1438
|
-
return React.useMemo(() => buildGraph(object), [object]);
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
function loadingFn(extensions, onProgress) {
|
|
1442
|
-
return function (Proto, ...input) {
|
|
1443
|
-
// Construct new loader and run extensions
|
|
1444
|
-
const loader = new Proto();
|
|
1445
|
-
if (extensions) extensions(loader); // Go through the urls and load them
|
|
1446
|
-
|
|
1447
|
-
return Promise.all(input.map(input => new Promise((res, reject) => loader.load(input, data => {
|
|
1448
|
-
if (data.scene) Object.assign(data, buildGraph(data.scene));
|
|
1449
|
-
res(data);
|
|
1450
|
-
}, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
|
|
1451
|
-
};
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
|
-
function useLoader(Proto, input, extensions, onProgress) {
|
|
1455
|
-
// Use suspense to load async assets
|
|
1456
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1457
|
-
const results = suspend(loadingFn(extensions, onProgress), [Proto, ...keys], {
|
|
1458
|
-
equal: is.equ
|
|
1459
|
-
}); // Return the object/s
|
|
1460
|
-
|
|
1461
|
-
return Array.isArray(input) ? results : results[0];
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
useLoader.preload = function (Proto, input, extensions) {
|
|
1465
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1466
|
-
return preload(loadingFn(extensions), [Proto, ...keys]);
|
|
1467
|
-
};
|
|
1468
|
-
|
|
1469
|
-
useLoader.clear = function (Proto, input) {
|
|
1470
|
-
const keys = Array.isArray(input) ? input : [input];
|
|
1471
|
-
return clear([Proto, ...keys]);
|
|
1472
|
-
};
|
|
1473
|
-
|
|
1474
1352
|
function createSubs(callback, subs) {
|
|
1475
1353
|
const index = subs.length;
|
|
1476
1354
|
subs.push(callback);
|
|
@@ -1489,7 +1367,9 @@ function run(effects, timestamp) {
|
|
|
1489
1367
|
for (i = 0; i < effects.length; i++) effects[i](timestamp);
|
|
1490
1368
|
}
|
|
1491
1369
|
|
|
1492
|
-
|
|
1370
|
+
let subscribers;
|
|
1371
|
+
|
|
1372
|
+
function render$1(timestamp, state, frame) {
|
|
1493
1373
|
// Run local effects
|
|
1494
1374
|
let delta = state.clock.getDelta(); // In frameloop='never' mode, clock times are updated using the provided timestamp
|
|
1495
1375
|
|
|
@@ -1500,7 +1380,9 @@ function render$1(timestamp, state) {
|
|
|
1500
1380
|
} // Call subscribers (useFrame)
|
|
1501
1381
|
|
|
1502
1382
|
|
|
1503
|
-
|
|
1383
|
+
subscribers = state.internal.subscribers;
|
|
1384
|
+
|
|
1385
|
+
for (i = 0; i < subscribers.length; i++) subscribers[i].ref.current(state, delta, frame); // Render content
|
|
1504
1386
|
|
|
1505
1387
|
|
|
1506
1388
|
if (!state.internal.priority && state.gl.render) state.gl.render(state.scene, state.camera); // Decrease frame count
|
|
@@ -1512,29 +1394,35 @@ function render$1(timestamp, state) {
|
|
|
1512
1394
|
function createLoop(roots) {
|
|
1513
1395
|
let running = false;
|
|
1514
1396
|
let repeat;
|
|
1397
|
+
let frame;
|
|
1398
|
+
let state;
|
|
1515
1399
|
|
|
1516
1400
|
function loop(timestamp) {
|
|
1401
|
+
frame = requestAnimationFrame(loop);
|
|
1517
1402
|
running = true;
|
|
1518
1403
|
repeat = 0; // Run effects
|
|
1519
1404
|
|
|
1520
|
-
run(globalEffects, timestamp); // Render all roots
|
|
1405
|
+
if (globalEffects.length) run(globalEffects, timestamp); // Render all roots
|
|
1521
1406
|
|
|
1522
1407
|
roots.forEach(root => {
|
|
1523
1408
|
var _state$gl$xr;
|
|
1524
1409
|
|
|
1525
|
-
|
|
1410
|
+
state = root.store.getState(); // If the frameloop is invalidated, do not run another frame
|
|
1526
1411
|
|
|
1527
1412
|
if (state.internal.active && (state.frameloop === 'always' || state.internal.frames > 0) && !((_state$gl$xr = state.gl.xr) != null && _state$gl$xr.isPresenting)) {
|
|
1528
1413
|
repeat += render$1(timestamp, state);
|
|
1529
1414
|
}
|
|
1530
1415
|
}); // Run after-effects
|
|
1531
1416
|
|
|
1532
|
-
run(globalAfterEffects, timestamp); //
|
|
1417
|
+
if (globalAfterEffects.length) run(globalAfterEffects, timestamp); // Stop the loop if nothing invalidates it
|
|
1533
1418
|
|
|
1534
|
-
if (repeat
|
|
1535
|
-
|
|
1419
|
+
if (repeat === 0) {
|
|
1420
|
+
// Tail call effects, they are called when rendering stops
|
|
1421
|
+
if (globalTailEffects.length) run(globalTailEffects, timestamp); // Flag end of operation
|
|
1536
1422
|
|
|
1537
|
-
|
|
1423
|
+
running = false;
|
|
1424
|
+
return cancelAnimationFrame(frame);
|
|
1425
|
+
}
|
|
1538
1426
|
}
|
|
1539
1427
|
|
|
1540
1428
|
function invalidate(state) {
|
|
@@ -1551,9 +1439,9 @@ function createLoop(roots) {
|
|
|
1551
1439
|
}
|
|
1552
1440
|
}
|
|
1553
1441
|
|
|
1554
|
-
function advance(timestamp, runGlobalEffects = true, state) {
|
|
1442
|
+
function advance(timestamp, runGlobalEffects = true, state, frame) {
|
|
1555
1443
|
if (runGlobalEffects) run(globalEffects, timestamp);
|
|
1556
|
-
if (!state) roots.forEach(root => render$1(timestamp, root.store.getState()));else render$1(timestamp, state);
|
|
1444
|
+
if (!state) roots.forEach(root => render$1(timestamp, root.store.getState()));else render$1(timestamp, state, frame);
|
|
1557
1445
|
if (runGlobalEffects) run(globalAfterEffects, timestamp);
|
|
1558
1446
|
}
|
|
1559
1447
|
|
|
@@ -1564,6 +1452,60 @@ function createLoop(roots) {
|
|
|
1564
1452
|
};
|
|
1565
1453
|
}
|
|
1566
1454
|
|
|
1455
|
+
function useStore() {
|
|
1456
|
+
const store = React.useContext(context);
|
|
1457
|
+
if (!store) throw `R3F hooks can only be used within the Canvas component!`;
|
|
1458
|
+
return store;
|
|
1459
|
+
}
|
|
1460
|
+
function useThree(selector = state => state, equalityFn) {
|
|
1461
|
+
return useStore()(selector, equalityFn);
|
|
1462
|
+
}
|
|
1463
|
+
function useFrame(callback, renderPriority = 0) {
|
|
1464
|
+
const subscribe = useStore().getState().internal.subscribe; // Update ref
|
|
1465
|
+
|
|
1466
|
+
const ref = React.useRef(callback);
|
|
1467
|
+
React.useLayoutEffect(() => void (ref.current = callback), [callback]); // Subscribe on mount, unsubscribe on unmount
|
|
1468
|
+
|
|
1469
|
+
React.useLayoutEffect(() => subscribe(ref, renderPriority), [renderPriority, subscribe]);
|
|
1470
|
+
return null;
|
|
1471
|
+
}
|
|
1472
|
+
function useGraph(object) {
|
|
1473
|
+
return React.useMemo(() => buildGraph(object), [object]);
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
function loadingFn(extensions, onProgress) {
|
|
1477
|
+
return function (Proto, ...input) {
|
|
1478
|
+
// Construct new loader and run extensions
|
|
1479
|
+
const loader = new Proto();
|
|
1480
|
+
if (extensions) extensions(loader); // Go through the urls and load them
|
|
1481
|
+
|
|
1482
|
+
return Promise.all(input.map(input => new Promise((res, reject) => loader.load(input, data => {
|
|
1483
|
+
if (data.scene) Object.assign(data, buildGraph(data.scene));
|
|
1484
|
+
res(data);
|
|
1485
|
+
}, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
function useLoader(Proto, input, extensions, onProgress) {
|
|
1490
|
+
// Use suspense to load async assets
|
|
1491
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
1492
|
+
const results = suspend(loadingFn(extensions, onProgress), [Proto, ...keys], {
|
|
1493
|
+
equal: is.equ
|
|
1494
|
+
}); // Return the object/s
|
|
1495
|
+
|
|
1496
|
+
return Array.isArray(input) ? results : results[0];
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
useLoader.preload = function (Proto, input, extensions) {
|
|
1500
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
1501
|
+
return preload(loadingFn(extensions), [Proto, ...keys]);
|
|
1502
|
+
};
|
|
1503
|
+
|
|
1504
|
+
useLoader.clear = function (Proto, input) {
|
|
1505
|
+
const keys = Array.isArray(input) ? input : [input];
|
|
1506
|
+
return clear([Proto, ...keys]);
|
|
1507
|
+
};
|
|
1508
|
+
|
|
1567
1509
|
const roots = new Map();
|
|
1568
1510
|
const {
|
|
1569
1511
|
invalidate,
|
|
@@ -1573,113 +1515,216 @@ const {
|
|
|
1573
1515
|
reconciler,
|
|
1574
1516
|
applyProps
|
|
1575
1517
|
} = createRenderer(roots, getEventPriority);
|
|
1518
|
+
const shallowLoose = {
|
|
1519
|
+
objects: 'shallow',
|
|
1520
|
+
strict: false
|
|
1521
|
+
};
|
|
1576
1522
|
|
|
1577
1523
|
const createRendererInstance = (gl, canvas) => {
|
|
1578
1524
|
const customRenderer = typeof gl === 'function' ? gl(canvas) : gl;
|
|
1579
|
-
if (isRenderer(customRenderer)) return customRenderer;
|
|
1580
|
-
const renderer = new THREE.WebGLRenderer({
|
|
1525
|
+
if (isRenderer(customRenderer)) return customRenderer;else return new THREE.WebGLRenderer({
|
|
1581
1526
|
powerPreference: 'high-performance',
|
|
1582
1527
|
canvas: canvas,
|
|
1583
1528
|
antialias: true,
|
|
1584
1529
|
alpha: true,
|
|
1585
1530
|
...gl
|
|
1586
|
-
});
|
|
1531
|
+
});
|
|
1532
|
+
};
|
|
1587
1533
|
|
|
1588
|
-
|
|
1589
|
-
|
|
1534
|
+
function createRoot(canvas) {
|
|
1535
|
+
// Check against mistaken use of createRoot
|
|
1536
|
+
let prevRoot = roots.get(canvas);
|
|
1537
|
+
let prevFiber = prevRoot == null ? void 0 : prevRoot.fiber;
|
|
1538
|
+
let prevStore = prevRoot == null ? void 0 : prevRoot.store;
|
|
1539
|
+
if (prevRoot) console.warn('R3F.createRoot should only be called once!'); // Create store
|
|
1590
1540
|
|
|
1591
|
-
|
|
1592
|
-
return renderer;
|
|
1593
|
-
};
|
|
1541
|
+
const store = prevStore || createStore(invalidate, advance); // Create renderer
|
|
1594
1542
|
|
|
1595
|
-
|
|
1543
|
+
const fiber = prevFiber || reconciler.createContainer(store, ConcurrentRoot, false, null); // Map it
|
|
1544
|
+
|
|
1545
|
+
if (!prevRoot) roots.set(canvas, {
|
|
1546
|
+
fiber,
|
|
1547
|
+
store
|
|
1548
|
+
}); // Locals
|
|
1549
|
+
|
|
1550
|
+
let onCreated;
|
|
1551
|
+
let configured = false;
|
|
1596
1552
|
return {
|
|
1597
|
-
|
|
1598
|
-
var
|
|
1553
|
+
configure(props = {}) {
|
|
1554
|
+
var _canvas$parentElement, _canvas$parentElement2, _canvas$parentElement3, _canvas$parentElement4;
|
|
1599
1555
|
|
|
1600
1556
|
let {
|
|
1601
|
-
gl,
|
|
1557
|
+
gl: glConfig,
|
|
1602
1558
|
size,
|
|
1603
1559
|
events,
|
|
1604
|
-
onCreated,
|
|
1605
|
-
|
|
1606
|
-
|
|
1560
|
+
onCreated: onCreatedCallback,
|
|
1561
|
+
shadows = false,
|
|
1562
|
+
linear = false,
|
|
1563
|
+
flat = false,
|
|
1564
|
+
orthographic = false,
|
|
1565
|
+
frameloop = 'always',
|
|
1566
|
+
dpr = [1, 2],
|
|
1567
|
+
performance,
|
|
1568
|
+
raycaster: raycastOptions,
|
|
1569
|
+
camera: cameraOptions,
|
|
1570
|
+
onPointerMissed
|
|
1571
|
+
} = props;
|
|
1572
|
+
let state = store.getState(); // Set up renderer (one time only!)
|
|
1573
|
+
|
|
1574
|
+
let gl = state.gl;
|
|
1575
|
+
if (!state.gl) state.set({
|
|
1576
|
+
gl: gl = createRendererInstance(glConfig, canvas)
|
|
1577
|
+
}); // Set up raycaster (one time only!)
|
|
1578
|
+
|
|
1579
|
+
let raycaster = state.raycaster;
|
|
1580
|
+
if (!raycaster) state.set({
|
|
1581
|
+
raycaster: raycaster = new THREE.Raycaster()
|
|
1582
|
+
}); // Set raycaster options
|
|
1607
1583
|
|
|
1608
|
-
|
|
1609
|
-
|
|
1584
|
+
const {
|
|
1585
|
+
params,
|
|
1586
|
+
...options
|
|
1587
|
+
} = raycastOptions || {};
|
|
1588
|
+
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, {
|
|
1589
|
+
enabled: true,
|
|
1590
|
+
...options
|
|
1591
|
+
});
|
|
1592
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) applyProps(raycaster, {
|
|
1593
|
+
params: { ...raycaster.params,
|
|
1594
|
+
...params
|
|
1595
|
+
}
|
|
1596
|
+
}); // Create default camera (one time only!)
|
|
1610
1597
|
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1598
|
+
if (!state.camera) {
|
|
1599
|
+
const isCamera = cameraOptions instanceof THREE.Camera;
|
|
1600
|
+
const camera = isCamera ? cameraOptions : orthographic ? new THREE.OrthographicCamera(0, 0, 0, 0, 0.1, 1000) : new THREE.PerspectiveCamera(75, 0, 0.1, 1000);
|
|
1601
|
+
|
|
1602
|
+
if (!isCamera) {
|
|
1603
|
+
camera.position.z = 5;
|
|
1604
|
+
if (cameraOptions) applyProps(camera, cameraOptions); // Always look at center by default
|
|
1605
|
+
|
|
1606
|
+
if (!(cameraOptions != null && cameraOptions.rotation)) camera.lookAt(0, 0, 0);
|
|
1607
|
+
}
|
|
1616
1608
|
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1609
|
+
state.set({
|
|
1610
|
+
camera
|
|
1611
|
+
});
|
|
1612
|
+
} // Set up XR (one time only!)
|
|
1621
1613
|
|
|
1622
|
-
if (fiber && state) {
|
|
1623
|
-
// When a root was found, see if any fundamental props must be changed or exchanged
|
|
1624
|
-
// Check pixelratio
|
|
1625
|
-
if (props.dpr !== undefined && state.viewport.dpr !== calculateDpr(props.dpr)) state.setDpr(props.dpr); // Check size
|
|
1626
1614
|
|
|
1627
|
-
|
|
1615
|
+
if (!state.xr) {
|
|
1616
|
+
// Handle frame behavior in WebXR
|
|
1617
|
+
const handleXRFrame = (timestamp, frame) => {
|
|
1618
|
+
const state = store.getState();
|
|
1619
|
+
if (state.frameloop === 'never') return;
|
|
1620
|
+
advance(timestamp, true, state, frame);
|
|
1621
|
+
}; // Toggle render switching on session
|
|
1628
1622
|
|
|
1629
|
-
if (state.frameloop !== props.frameloop) state.setFrameloop(props.frameloop); // For some props we want to reset the entire root
|
|
1630
|
-
// Changes to the color-space
|
|
1631
1623
|
|
|
1632
|
-
const
|
|
1624
|
+
const handleSessionChange = () => {
|
|
1625
|
+
const gl = store.getState().gl;
|
|
1626
|
+
gl.xr.enabled = gl.xr.isPresenting; // @ts-expect-error
|
|
1627
|
+
// WebXRManager's signature is incorrect.
|
|
1628
|
+
// See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
|
|
1633
1629
|
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
fiber = undefined;
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1630
|
+
gl.xr.setAnimationLoop(gl.xr.isPresenting ? handleXRFrame : null);
|
|
1631
|
+
}; // WebXR session manager
|
|
1639
1632
|
|
|
1640
|
-
if (!fiber) {
|
|
1641
|
-
// If no root has been found, make one
|
|
1642
|
-
// Create gl
|
|
1643
|
-
const glRenderer = createRendererInstance(gl, canvas); // Create store
|
|
1644
1633
|
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1634
|
+
const xr = {
|
|
1635
|
+
connect() {
|
|
1636
|
+
const gl = store.getState().gl;
|
|
1637
|
+
gl.xr.addEventListener('sessionstart', handleSessionChange);
|
|
1638
|
+
gl.xr.addEventListener('sessionend', handleSessionChange);
|
|
1639
|
+
},
|
|
1651
1640
|
|
|
1652
|
-
|
|
1641
|
+
disconnect() {
|
|
1642
|
+
const gl = store.getState().gl;
|
|
1643
|
+
gl.xr.removeEventListener('sessionstart', handleSessionChange);
|
|
1644
|
+
gl.xr.removeEventListener('sessionend', handleSessionChange);
|
|
1645
|
+
}
|
|
1653
1646
|
|
|
1654
|
-
|
|
1655
|
-
fiber,
|
|
1656
|
-
store
|
|
1657
|
-
}); // Store events internally
|
|
1647
|
+
}; // Subscribe to WebXR session events
|
|
1658
1648
|
|
|
1659
|
-
if (
|
|
1660
|
-
|
|
1649
|
+
if (gl.xr) xr.connect();
|
|
1650
|
+
state.set({
|
|
1651
|
+
xr
|
|
1661
1652
|
});
|
|
1662
|
-
}
|
|
1653
|
+
} // Set shadowmap
|
|
1663
1654
|
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
}
|
|
1655
|
+
|
|
1656
|
+
if (gl.shadowMap) {
|
|
1657
|
+
const isBoolean = is.boo(shadows);
|
|
1658
|
+
|
|
1659
|
+
if (isBoolean && gl.shadowMap.enabled !== shadows || !is.equ(shadows, gl.shadowMap, shallowLoose)) {
|
|
1660
|
+
const old = gl.shadowMap.enabled;
|
|
1661
|
+
gl.shadowMap.enabled = !!shadows;
|
|
1662
|
+
if (!isBoolean) Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
1663
|
+
if (old !== gl.shadowMap.enabled) gl.shadowMap.needsUpdate = true;
|
|
1664
|
+
}
|
|
1665
|
+
} // Set color management
|
|
1666
|
+
|
|
1667
|
+
|
|
1668
|
+
const outputEncoding = linear ? THREE.LinearEncoding : THREE.sRGBEncoding;
|
|
1669
|
+
const toneMapping = flat ? THREE.NoToneMapping : THREE.ACESFilmicToneMapping;
|
|
1670
|
+
if (gl.outputEncoding !== outputEncoding) gl.outputEncoding = outputEncoding;
|
|
1671
|
+
if (gl.toneMapping !== toneMapping) gl.toneMapping = toneMapping; // Set gl props
|
|
1672
|
+
|
|
1673
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, gl, shallowLoose)) applyProps(gl, glConfig); // Store events internally
|
|
1674
|
+
|
|
1675
|
+
if (events && !state.events.handlers) state.set({
|
|
1676
|
+
events: events(store)
|
|
1677
|
+
}); // Check pixelratio
|
|
1678
|
+
|
|
1679
|
+
if (dpr && state.viewport.dpr !== calculateDpr(dpr)) state.setDpr(dpr); // Check size, allow it to take on container bounds initially
|
|
1680
|
+
|
|
1681
|
+
size = size || {
|
|
1682
|
+
width: (_canvas$parentElement = (_canvas$parentElement2 = canvas.parentElement) == null ? void 0 : _canvas$parentElement2.clientWidth) != null ? _canvas$parentElement : 0,
|
|
1683
|
+
height: (_canvas$parentElement3 = (_canvas$parentElement4 = canvas.parentElement) == null ? void 0 : _canvas$parentElement4.clientHeight) != null ? _canvas$parentElement3 : 0
|
|
1684
|
+
};
|
|
1685
|
+
if (!is.equ(size, state.size, shallowLoose)) state.setSize(size.width, size.height); // Check frameloop
|
|
1686
|
+
|
|
1687
|
+
if (state.frameloop !== frameloop) state.setFrameloop(frameloop); // Check pointer missed
|
|
1688
|
+
|
|
1689
|
+
if (!state.onPointerMissed) state.set({
|
|
1690
|
+
onPointerMissed
|
|
1691
|
+
}); // Check performance
|
|
1692
|
+
|
|
1693
|
+
if (performance && !is.equ(performance, state.performance, shallowLoose)) state.set(state => ({
|
|
1694
|
+
performance: { ...state.performance,
|
|
1695
|
+
...performance
|
|
1696
|
+
}
|
|
1697
|
+
})); // Set locals
|
|
1698
|
+
|
|
1699
|
+
onCreated = onCreatedCallback;
|
|
1700
|
+
configured = true;
|
|
1701
|
+
return this;
|
|
1702
|
+
},
|
|
1703
|
+
|
|
1704
|
+
render(element) {
|
|
1705
|
+
// The root has to be configured before it can be rendered
|
|
1706
|
+
if (!configured) this.configure();
|
|
1707
|
+
reconciler.updateContainer( /*#__PURE__*/React.createElement(Provider, {
|
|
1708
|
+
store: store,
|
|
1709
|
+
element: element,
|
|
1710
|
+
onCreated: onCreated,
|
|
1711
|
+
target: canvas
|
|
1712
|
+
}), fiber, null, () => undefined);
|
|
1713
|
+
return store;
|
|
1675
1714
|
},
|
|
1676
|
-
|
|
1715
|
+
|
|
1716
|
+
unmount() {
|
|
1717
|
+
unmountComponentAtNode(canvas);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1677
1720
|
};
|
|
1678
1721
|
}
|
|
1679
1722
|
|
|
1680
1723
|
function render(element, canvas, config = {}) {
|
|
1681
1724
|
console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!');
|
|
1682
|
-
|
|
1725
|
+
const root = createRoot(canvas);
|
|
1726
|
+
root.configure(config);
|
|
1727
|
+
return root.render(element);
|
|
1683
1728
|
}
|
|
1684
1729
|
|
|
1685
1730
|
function Provider({
|
|
@@ -1722,7 +1767,7 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
1722
1767
|
state.events.disconnect == null ? void 0 : state.events.disconnect();
|
|
1723
1768
|
(_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();
|
|
1724
1769
|
(_state$gl2 = state.gl) == null ? void 0 : _state$gl2.forceContextLoss == null ? void 0 : _state$gl2.forceContextLoss();
|
|
1725
|
-
if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.
|
|
1770
|
+
if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.xr.disconnect();
|
|
1726
1771
|
dispose(state);
|
|
1727
1772
|
roots.delete(canvas);
|
|
1728
1773
|
if (callback) callback(canvas);
|
|
@@ -1747,4 +1792,4 @@ reconciler.injectIntoDevTools({
|
|
|
1747
1792
|
version: '18.0.0'
|
|
1748
1793
|
});
|
|
1749
1794
|
|
|
1750
|
-
export {
|
|
1795
|
+
export { createRoot as a, context as b, createEvents as c, createPortal as d, extend as e, reconciler as f, applyProps as g, dispose as h, invalidate as i, advance as j, addEffect as k, addAfterEffect as l, addTail as m, act as n, omit as o, pick as p, roots as q, render as r, useStore as s, threeTypes as t, unmountComponentAtNode as u, useThree as v, useFrame as w, useGraph as x, useLoader as y };
|