@react-three/fiber 8.0.0-beta.0 → 8.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/declarations/src/core/hooks.d.ts +1 -1
- package/dist/declarations/src/core/index.d.ts +8 -6
- package/dist/declarations/src/core/loop.d.ts +1 -1
- package/dist/declarations/src/core/store.d.ts +11 -15
- package/dist/declarations/src/core/utils.d.ts +7 -1
- package/dist/declarations/src/three-types.d.ts +19 -0
- package/dist/{index-95c17855.cjs.dev.js → index-05ebefd3.cjs.dev.js} +251 -207
- package/dist/{index-ff8b5912.cjs.prod.js → index-85b2df17.cjs.prod.js} +251 -207
- package/dist/{index-3f4e5f46.esm.js → index-e78dd2f0.esm.js} +251 -207
- 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 +11 -6
- package/native/dist/react-three-fiber-native.cjs.prod.js +11 -6
- package/native/dist/react-three-fiber-native.esm.js +12 -7
- package/package.json +8 -8
|
@@ -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
|
|
|
@@ -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,61 +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, frame) => {
|
|
1230
|
-
const state = get();
|
|
1231
|
-
if (state.frameloop === 'never') return;
|
|
1232
|
-
advance(timestamp, true, state, frame);
|
|
1233
|
-
}; // Toggle render switching on session
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
const handleSessionChange = () => {
|
|
1237
|
-
gl.xr.enabled = gl.xr.isPresenting; // @ts-expect-error
|
|
1238
|
-
// WebXRManager's signature is incorrect.
|
|
1239
|
-
// See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
|
|
1240
|
-
|
|
1241
|
-
gl.xr.setAnimationLoop(gl.xr.isPresenting ? handleXRFrame : null);
|
|
1242
|
-
}; // WebXR session manager
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
const xr = {
|
|
1246
|
-
connect() {
|
|
1247
|
-
gl.xr.addEventListener('sessionstart', handleSessionChange);
|
|
1248
|
-
gl.xr.addEventListener('sessionend', handleSessionChange);
|
|
1249
|
-
},
|
|
1250
|
-
|
|
1251
|
-
disconnect() {
|
|
1252
|
-
gl.xr.removeEventListener('sessionstart', handleSessionChange);
|
|
1253
|
-
gl.xr.removeEventListener('sessionend', handleSessionChange);
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
}; // Subscribe to WebXR session events
|
|
1173
|
+
}));
|
|
1257
1174
|
|
|
1258
|
-
if (gl.xr) xr.connect();
|
|
1259
1175
|
return {
|
|
1260
|
-
|
|
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,
|
|
1261
1184
|
set,
|
|
1262
1185
|
get,
|
|
1263
1186
|
invalidate: () => invalidate(get()),
|
|
1264
1187
|
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1265
|
-
linear,
|
|
1266
|
-
flat,
|
|
1188
|
+
linear: false,
|
|
1189
|
+
flat: false,
|
|
1267
1190
|
scene: prepare(new THREE.Scene()),
|
|
1268
|
-
camera,
|
|
1269
1191
|
controls: null,
|
|
1270
|
-
|
|
1271
|
-
clock,
|
|
1192
|
+
clock: new THREE.Clock(),
|
|
1272
1193
|
mouse: new THREE.Vector2(),
|
|
1273
|
-
frameloop,
|
|
1274
|
-
onPointerMissed,
|
|
1194
|
+
frameloop: 'always',
|
|
1195
|
+
onPointerMissed: undefined,
|
|
1275
1196
|
performance: {
|
|
1276
1197
|
current: 1,
|
|
1277
1198
|
min: 0.5,
|
|
1278
1199
|
max: 1,
|
|
1279
1200
|
debounce: 200,
|
|
1280
|
-
...performance,
|
|
1281
1201
|
regress: () => {
|
|
1282
1202
|
const state = get(); // Clear timeout
|
|
1283
1203
|
|
|
@@ -1293,8 +1213,8 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1293
1213
|
height: 0
|
|
1294
1214
|
},
|
|
1295
1215
|
viewport: {
|
|
1296
|
-
initialDpr,
|
|
1297
|
-
dpr:
|
|
1216
|
+
initialDpr: 0,
|
|
1217
|
+
dpr: 0,
|
|
1298
1218
|
width: 0,
|
|
1299
1219
|
height: 0,
|
|
1300
1220
|
aspect: 0,
|
|
@@ -1303,6 +1223,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1303
1223
|
getCurrentViewport
|
|
1304
1224
|
},
|
|
1305
1225
|
setSize: (width, height) => {
|
|
1226
|
+
const camera = get().camera;
|
|
1306
1227
|
const size = {
|
|
1307
1228
|
width,
|
|
1308
1229
|
height
|
|
@@ -1314,22 +1235,34 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1314
1235
|
}
|
|
1315
1236
|
}));
|
|
1316
1237
|
},
|
|
1317
|
-
setDpr: dpr => set(state =>
|
|
1318
|
-
|
|
1319
|
-
|
|
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;
|
|
1320
1256
|
}
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
events: {
|
|
1326
|
-
connected: false
|
|
1257
|
+
|
|
1258
|
+
set(() => ({
|
|
1259
|
+
frameloop
|
|
1260
|
+
}));
|
|
1327
1261
|
},
|
|
1328
1262
|
internal: {
|
|
1329
1263
|
active: false,
|
|
1330
1264
|
priority: 0,
|
|
1331
1265
|
frames: 0,
|
|
1332
|
-
lastProps: props,
|
|
1333
1266
|
lastEvent: /*#__PURE__*/React.createRef(),
|
|
1334
1267
|
interaction: [],
|
|
1335
1268
|
hovered: new Map(),
|
|
@@ -1337,7 +1270,6 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1337
1270
|
initialClick: [0, 0],
|
|
1338
1271
|
initialHits: [],
|
|
1339
1272
|
capturedMap: new Map(),
|
|
1340
|
-
xr,
|
|
1341
1273
|
subscribe: (ref, priority = 0) => {
|
|
1342
1274
|
set(({
|
|
1343
1275
|
internal
|
|
@@ -1381,13 +1313,14 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1381
1313
|
camera,
|
|
1382
1314
|
size,
|
|
1383
1315
|
viewport,
|
|
1384
|
-
internal
|
|
1316
|
+
internal,
|
|
1317
|
+
gl
|
|
1385
1318
|
} = rootState.getState();
|
|
1386
1319
|
|
|
1387
1320
|
if (size !== oldSize || viewport.dpr !== oldDpr) {
|
|
1388
1321
|
// https://github.com/pmndrs/react-three-fiber/issues/92
|
|
1389
1322
|
// Do not mess with the camera if it belongs to the user
|
|
1390
|
-
if (!camera.manual
|
|
1323
|
+
if (!camera.manual) {
|
|
1391
1324
|
if (isOrthographicCamera(camera)) {
|
|
1392
1325
|
camera.left = size.width / -2;
|
|
1393
1326
|
camera.right = size.width / 2;
|
|
@@ -1409,9 +1342,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1409
1342
|
oldSize = size;
|
|
1410
1343
|
oldDpr = viewport.dpr;
|
|
1411
1344
|
}
|
|
1412
|
-
}); //
|
|
1413
|
-
|
|
1414
|
-
if (size) state.setSize(size.width, size.height); // Invalidate on any change
|
|
1345
|
+
}); // Invalidate on any change
|
|
1415
1346
|
|
|
1416
1347
|
rootState.subscribe(state => invalidate(state)); // Return root state
|
|
1417
1348
|
|
|
@@ -1436,6 +1367,8 @@ function run(effects, timestamp) {
|
|
|
1436
1367
|
for (i = 0; i < effects.length; i++) effects[i](timestamp);
|
|
1437
1368
|
}
|
|
1438
1369
|
|
|
1370
|
+
let subscribers;
|
|
1371
|
+
|
|
1439
1372
|
function render$1(timestamp, state, frame) {
|
|
1440
1373
|
// Run local effects
|
|
1441
1374
|
let delta = state.clock.getDelta(); // In frameloop='never' mode, clock times are updated using the provided timestamp
|
|
@@ -1447,7 +1380,9 @@ function render$1(timestamp, state, frame) {
|
|
|
1447
1380
|
} // Call subscribers (useFrame)
|
|
1448
1381
|
|
|
1449
1382
|
|
|
1450
|
-
|
|
1383
|
+
subscribers = state.internal.subscribers;
|
|
1384
|
+
|
|
1385
|
+
for (i = 0; i < subscribers.length; i++) subscribers[i].ref.current(state, delta, frame); // Render content
|
|
1451
1386
|
|
|
1452
1387
|
|
|
1453
1388
|
if (!state.internal.priority && state.gl.render) state.gl.render(state.scene, state.camera); // Decrease frame count
|
|
@@ -1459,29 +1394,35 @@ function render$1(timestamp, state, frame) {
|
|
|
1459
1394
|
function createLoop(roots) {
|
|
1460
1395
|
let running = false;
|
|
1461
1396
|
let repeat;
|
|
1397
|
+
let frame;
|
|
1398
|
+
let state;
|
|
1462
1399
|
|
|
1463
1400
|
function loop(timestamp) {
|
|
1401
|
+
frame = requestAnimationFrame(loop);
|
|
1464
1402
|
running = true;
|
|
1465
1403
|
repeat = 0; // Run effects
|
|
1466
1404
|
|
|
1467
|
-
run(globalEffects, timestamp); // Render all roots
|
|
1405
|
+
if (globalEffects.length) run(globalEffects, timestamp); // Render all roots
|
|
1468
1406
|
|
|
1469
1407
|
roots.forEach(root => {
|
|
1470
1408
|
var _state$gl$xr;
|
|
1471
1409
|
|
|
1472
|
-
|
|
1410
|
+
state = root.store.getState(); // If the frameloop is invalidated, do not run another frame
|
|
1473
1411
|
|
|
1474
1412
|
if (state.internal.active && (state.frameloop === 'always' || state.internal.frames > 0) && !((_state$gl$xr = state.gl.xr) != null && _state$gl$xr.isPresenting)) {
|
|
1475
1413
|
repeat += render$1(timestamp, state);
|
|
1476
1414
|
}
|
|
1477
1415
|
}); // Run after-effects
|
|
1478
1416
|
|
|
1479
|
-
run(globalAfterEffects, timestamp); //
|
|
1417
|
+
if (globalAfterEffects.length) run(globalAfterEffects, timestamp); // Stop the loop if nothing invalidates it
|
|
1480
1418
|
|
|
1481
|
-
if (repeat
|
|
1482
|
-
|
|
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
|
|
1483
1422
|
|
|
1484
|
-
|
|
1423
|
+
running = false;
|
|
1424
|
+
return cancelAnimationFrame(frame);
|
|
1425
|
+
}
|
|
1485
1426
|
}
|
|
1486
1427
|
|
|
1487
1428
|
function invalidate(state) {
|
|
@@ -1574,113 +1515,216 @@ const {
|
|
|
1574
1515
|
reconciler,
|
|
1575
1516
|
applyProps
|
|
1576
1517
|
} = createRenderer(roots, getEventPriority);
|
|
1518
|
+
const shallowLoose = {
|
|
1519
|
+
objects: 'shallow',
|
|
1520
|
+
strict: false
|
|
1521
|
+
};
|
|
1577
1522
|
|
|
1578
1523
|
const createRendererInstance = (gl, canvas) => {
|
|
1579
1524
|
const customRenderer = typeof gl === 'function' ? gl(canvas) : gl;
|
|
1580
|
-
if (isRenderer(customRenderer)) return customRenderer;
|
|
1581
|
-
const renderer = new THREE.WebGLRenderer({
|
|
1525
|
+
if (isRenderer(customRenderer)) return customRenderer;else return new THREE.WebGLRenderer({
|
|
1582
1526
|
powerPreference: 'high-performance',
|
|
1583
1527
|
canvas: canvas,
|
|
1584
1528
|
antialias: true,
|
|
1585
1529
|
alpha: true,
|
|
1586
1530
|
...gl
|
|
1587
|
-
});
|
|
1531
|
+
});
|
|
1532
|
+
};
|
|
1588
1533
|
|
|
1589
|
-
|
|
1590
|
-
|
|
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
|
|
1591
1540
|
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1541
|
+
const store = prevStore || createStore(invalidate, advance); // Create renderer
|
|
1542
|
+
|
|
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
|
|
1595
1549
|
|
|
1596
|
-
|
|
1550
|
+
let onCreated;
|
|
1551
|
+
let configured = false;
|
|
1597
1552
|
return {
|
|
1598
|
-
|
|
1599
|
-
var
|
|
1553
|
+
configure(props = {}) {
|
|
1554
|
+
var _canvas$parentElement, _canvas$parentElement2, _canvas$parentElement3, _canvas$parentElement4;
|
|
1600
1555
|
|
|
1601
1556
|
let {
|
|
1602
|
-
gl,
|
|
1557
|
+
gl: glConfig,
|
|
1603
1558
|
size,
|
|
1604
1559
|
events,
|
|
1605
|
-
onCreated,
|
|
1606
|
-
|
|
1607
|
-
|
|
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
|
|
1608
1583
|
|
|
1609
|
-
|
|
1610
|
-
|
|
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!)
|
|
1611
1597
|
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
};
|
|
1616
|
-
}
|
|
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);
|
|
1617
1601
|
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
let state = (_store = store) == null ? void 0 : _store.getState();
|
|
1602
|
+
if (!isCamera) {
|
|
1603
|
+
camera.position.z = 5;
|
|
1604
|
+
if (cameraOptions) applyProps(camera, cameraOptions); // Always look at center by default
|
|
1622
1605
|
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
// Check pixelratio
|
|
1626
|
-
if (props.dpr !== undefined && state.viewport.dpr !== calculateDpr(props.dpr)) state.setDpr(props.dpr); // Check size
|
|
1606
|
+
if (!(cameraOptions != null && cameraOptions.rotation)) camera.lookAt(0, 0, 0);
|
|
1607
|
+
}
|
|
1627
1608
|
|
|
1628
|
-
|
|
1609
|
+
state.set({
|
|
1610
|
+
camera
|
|
1611
|
+
});
|
|
1612
|
+
} // Set up XR (one time only!)
|
|
1629
1613
|
|
|
1630
|
-
if (state.frameloop !== props.frameloop) state.setFrameloop(props.frameloop); // For some props we want to reset the entire root
|
|
1631
|
-
// Changes to the color-space
|
|
1632
1614
|
|
|
1633
|
-
|
|
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
|
|
1634
1622
|
|
|
1635
|
-
if (linearChanged) {
|
|
1636
|
-
unmountComponentAtNode(canvas);
|
|
1637
|
-
fiber = undefined;
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
1623
|
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
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
|
|
1645
1629
|
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
size,
|
|
1649
|
-
...props
|
|
1650
|
-
});
|
|
1651
|
-
const state = store.getState(); // Create renderer
|
|
1630
|
+
gl.xr.setAnimationLoop(gl.xr.isPresenting ? handleXRFrame : null);
|
|
1631
|
+
}; // WebXR session manager
|
|
1652
1632
|
|
|
1653
|
-
fiber = reconciler.createContainer(store, ConcurrentRoot, false, null); // Map it
|
|
1654
1633
|
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1634
|
+
const xr = {
|
|
1635
|
+
connect() {
|
|
1636
|
+
const gl = store.getState().gl;
|
|
1637
|
+
gl.xr.addEventListener('sessionstart', handleSessionChange);
|
|
1638
|
+
gl.xr.addEventListener('sessionend', handleSessionChange);
|
|
1639
|
+
},
|
|
1640
|
+
|
|
1641
|
+
disconnect() {
|
|
1642
|
+
const gl = store.getState().gl;
|
|
1643
|
+
gl.xr.removeEventListener('sessionstart', handleSessionChange);
|
|
1644
|
+
gl.xr.removeEventListener('sessionend', handleSessionChange);
|
|
1645
|
+
}
|
|
1659
1646
|
|
|
1660
|
-
|
|
1661
|
-
|
|
1647
|
+
}; // Subscribe to WebXR session events
|
|
1648
|
+
|
|
1649
|
+
if (gl.xr) xr.connect();
|
|
1650
|
+
state.set({
|
|
1651
|
+
xr
|
|
1662
1652
|
});
|
|
1663
|
-
}
|
|
1653
|
+
} // Set shadowmap
|
|
1664
1654
|
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
}
|
|
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;
|
|
1676
1702
|
},
|
|
1677
|
-
|
|
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;
|
|
1714
|
+
},
|
|
1715
|
+
|
|
1716
|
+
unmount() {
|
|
1717
|
+
unmountComponentAtNode(canvas);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1678
1720
|
};
|
|
1679
1721
|
}
|
|
1680
1722
|
|
|
1681
1723
|
function render(element, canvas, config = {}) {
|
|
1682
1724
|
console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!');
|
|
1683
|
-
|
|
1725
|
+
const root = createRoot(canvas);
|
|
1726
|
+
root.configure(config);
|
|
1727
|
+
return root.render(element);
|
|
1684
1728
|
}
|
|
1685
1729
|
|
|
1686
1730
|
function Provider({
|
|
@@ -1723,7 +1767,7 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
1723
1767
|
state.events.disconnect == null ? void 0 : state.events.disconnect();
|
|
1724
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();
|
|
1725
1769
|
(_state$gl2 = state.gl) == null ? void 0 : _state$gl2.forceContextLoss == null ? void 0 : _state$gl2.forceContextLoss();
|
|
1726
|
-
if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.
|
|
1770
|
+
if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.xr.disconnect();
|
|
1727
1771
|
dispose(state);
|
|
1728
1772
|
roots.delete(canvas);
|
|
1729
1773
|
if (callback) callback(canvas);
|