@react-three/fiber 8.0.0-beta.0 → 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/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 +10 -14
- package/dist/declarations/src/core/utils.d.ts +7 -1
- 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 +1 -1
|
@@ -70,29 +70,38 @@ const pick = (obj, keys) => filterKeys(obj, false, ...keys);
|
|
|
70
70
|
* Clones an object and prunes or omits keys.
|
|
71
71
|
*/
|
|
72
72
|
|
|
73
|
-
const omit = (obj, keys) => filterKeys(obj, true, ...keys);
|
|
74
|
-
|
|
73
|
+
const omit = (obj, keys) => filterKeys(obj, true, ...keys);
|
|
74
|
+
// A collection of compare functions
|
|
75
75
|
const is = {
|
|
76
76
|
obj: a => a === Object(a) && !is.arr(a) && typeof a !== 'function',
|
|
77
77
|
fun: a => typeof a === 'function',
|
|
78
78
|
str: a => typeof a === 'string',
|
|
79
79
|
num: a => typeof a === 'number',
|
|
80
|
+
boo: a => typeof a === 'boolean',
|
|
80
81
|
und: a => a === void 0,
|
|
81
82
|
arr: a => Array.isArray(a),
|
|
82
83
|
|
|
83
|
-
equ(a, b
|
|
84
|
+
equ(a, b, {
|
|
85
|
+
arrays = 'shallow',
|
|
86
|
+
objects = 'reference',
|
|
87
|
+
strict = true
|
|
88
|
+
} = {}) {
|
|
84
89
|
// Wrong type or one of the two undefined, doesn't match
|
|
85
90
|
if (typeof a !== typeof b || !!a !== !!b) return false; // Atomic, just compare a against b
|
|
86
91
|
|
|
87
|
-
if (is.str(a) || is.num(a)
|
|
92
|
+
if (is.str(a) || is.num(a)) return a === b;
|
|
93
|
+
const isObj = is.obj(a);
|
|
94
|
+
if (isObj && objects === 'reference') return a === b;
|
|
95
|
+
const isArr = is.arr(a);
|
|
96
|
+
if (isArr && arrays === 'reference') return a === b; // Array or Object, shallow compare first to see if it's a match
|
|
88
97
|
|
|
89
|
-
if (
|
|
98
|
+
if ((isArr || isObj) && a == b) return true; // Last resort, go through keys
|
|
90
99
|
|
|
91
100
|
let i;
|
|
92
101
|
|
|
93
102
|
for (i in a) if (!(i in b)) return false;
|
|
94
103
|
|
|
95
|
-
for (i in b) if (a[i] !== b[i]) return false;
|
|
104
|
+
for (i in strict ? b : a) if (a[i] !== b[i]) return false;
|
|
96
105
|
|
|
97
106
|
return is.und(i) ? a === b : true;
|
|
98
107
|
}
|
|
@@ -183,15 +192,8 @@ function detach(parent, child, type) {
|
|
|
183
192
|
const [, detach] = type;
|
|
184
193
|
if (is.str(detach)) parent[detach](child);else if (is.fun(detach)) detach(parent, child);
|
|
185
194
|
}
|
|
186
|
-
} // Shallow check arrays, but check objects atomically
|
|
187
|
-
|
|
188
|
-
function checkShallow(a, b) {
|
|
189
|
-
if (is.arr(a) && is.equ(a, b)) return true;
|
|
190
|
-
if (a === b) return true;
|
|
191
|
-
return false;
|
|
192
195
|
} // This function prepares a set of changes to be applied to the instance
|
|
193
196
|
|
|
194
|
-
|
|
195
197
|
function diffProps(instance, {
|
|
196
198
|
children: cN,
|
|
197
199
|
key: kN,
|
|
@@ -223,7 +225,7 @@ function diffProps(instance, {
|
|
|
223
225
|
// Bail out on primitive object
|
|
224
226
|
if ((_instance$__r3f2 = instance.__r3f) != null && _instance$__r3f2.primitive && key === 'object') return; // When props match bail out
|
|
225
227
|
|
|
226
|
-
if (
|
|
228
|
+
if (is.equ(value, previous[key])) return; // Collect handlers and bail out
|
|
227
229
|
|
|
228
230
|
if (/^on(Pointer|Click|DoubleClick|ContextMenu|Wheel)/.test(key)) return changes.push([key, value, true, []]); // Split dashed props
|
|
229
231
|
|
|
@@ -1152,63 +1154,8 @@ const isRenderer = def => !!(def != null && def.render);
|
|
|
1152
1154
|
const isOrthographicCamera = def => def && def.isOrthographicCamera;
|
|
1153
1155
|
const context = /*#__PURE__*/React__namespace.createContext(null);
|
|
1154
1156
|
|
|
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
|
-
|
|
1157
|
+
const createStore = (invalidate, advance) => {
|
|
1186
1158
|
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
1159
|
const position = new THREE__namespace.Vector3();
|
|
1213
1160
|
const defaultTarget = new THREE__namespace.Vector3();
|
|
1214
1161
|
const tempTarget = new THREE__namespace.Vector3();
|
|
@@ -1252,61 +1199,34 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1252
1199
|
performance: { ...state.performance,
|
|
1253
1200
|
current
|
|
1254
1201
|
}
|
|
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
|
|
1202
|
+
}));
|
|
1286
1203
|
|
|
1287
|
-
if (gl.xr) xr.connect();
|
|
1288
1204
|
return {
|
|
1289
|
-
|
|
1205
|
+
// Mock objects that have to be configured
|
|
1206
|
+
gl: null,
|
|
1207
|
+
camera: null,
|
|
1208
|
+
raycaster: null,
|
|
1209
|
+
events: {
|
|
1210
|
+
connected: false
|
|
1211
|
+
},
|
|
1212
|
+
xr: null,
|
|
1290
1213
|
set,
|
|
1291
1214
|
get,
|
|
1292
1215
|
invalidate: () => invalidate(get()),
|
|
1293
1216
|
advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, get()),
|
|
1294
|
-
linear,
|
|
1295
|
-
flat,
|
|
1217
|
+
linear: false,
|
|
1218
|
+
flat: false,
|
|
1296
1219
|
scene: prepare(new THREE__namespace.Scene()),
|
|
1297
|
-
camera,
|
|
1298
1220
|
controls: null,
|
|
1299
|
-
|
|
1300
|
-
clock,
|
|
1221
|
+
clock: new THREE__namespace.Clock(),
|
|
1301
1222
|
mouse: new THREE__namespace.Vector2(),
|
|
1302
|
-
frameloop,
|
|
1303
|
-
onPointerMissed,
|
|
1223
|
+
frameloop: 'always',
|
|
1224
|
+
onPointerMissed: undefined,
|
|
1304
1225
|
performance: {
|
|
1305
1226
|
current: 1,
|
|
1306
1227
|
min: 0.5,
|
|
1307
1228
|
max: 1,
|
|
1308
1229
|
debounce: 200,
|
|
1309
|
-
...performance,
|
|
1310
1230
|
regress: () => {
|
|
1311
1231
|
const state = get(); // Clear timeout
|
|
1312
1232
|
|
|
@@ -1322,8 +1242,8 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1322
1242
|
height: 0
|
|
1323
1243
|
},
|
|
1324
1244
|
viewport: {
|
|
1325
|
-
initialDpr,
|
|
1326
|
-
dpr:
|
|
1245
|
+
initialDpr: 0,
|
|
1246
|
+
dpr: 0,
|
|
1327
1247
|
width: 0,
|
|
1328
1248
|
height: 0,
|
|
1329
1249
|
aspect: 0,
|
|
@@ -1332,6 +1252,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1332
1252
|
getCurrentViewport
|
|
1333
1253
|
},
|
|
1334
1254
|
setSize: (width, height) => {
|
|
1255
|
+
const camera = get().camera;
|
|
1335
1256
|
const size = {
|
|
1336
1257
|
width,
|
|
1337
1258
|
height
|
|
@@ -1343,22 +1264,34 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1343
1264
|
}
|
|
1344
1265
|
}));
|
|
1345
1266
|
},
|
|
1346
|
-
setDpr: dpr => set(state =>
|
|
1347
|
-
|
|
1348
|
-
|
|
1267
|
+
setDpr: dpr => set(state => {
|
|
1268
|
+
const resolved = calculateDpr(dpr);
|
|
1269
|
+
return {
|
|
1270
|
+
viewport: { ...state.viewport,
|
|
1271
|
+
dpr: resolved,
|
|
1272
|
+
initialDpr: state.viewport.initialDpr || resolved
|
|
1273
|
+
}
|
|
1274
|
+
};
|
|
1275
|
+
}),
|
|
1276
|
+
setFrameloop: (frameloop = 'always') => {
|
|
1277
|
+
const clock = get().clock; // if frameloop === "never" clock.elapsedTime is updated using advance(timestamp)
|
|
1278
|
+
|
|
1279
|
+
clock.stop();
|
|
1280
|
+
clock.elapsedTime = 0;
|
|
1281
|
+
|
|
1282
|
+
if (frameloop !== 'never') {
|
|
1283
|
+
clock.start();
|
|
1284
|
+
clock.elapsedTime = 0;
|
|
1349
1285
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
events: {
|
|
1355
|
-
connected: false
|
|
1286
|
+
|
|
1287
|
+
set(() => ({
|
|
1288
|
+
frameloop
|
|
1289
|
+
}));
|
|
1356
1290
|
},
|
|
1357
1291
|
internal: {
|
|
1358
1292
|
active: false,
|
|
1359
1293
|
priority: 0,
|
|
1360
1294
|
frames: 0,
|
|
1361
|
-
lastProps: props,
|
|
1362
1295
|
lastEvent: /*#__PURE__*/React__namespace.createRef(),
|
|
1363
1296
|
interaction: [],
|
|
1364
1297
|
hovered: new Map(),
|
|
@@ -1366,7 +1299,6 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1366
1299
|
initialClick: [0, 0],
|
|
1367
1300
|
initialHits: [],
|
|
1368
1301
|
capturedMap: new Map(),
|
|
1369
|
-
xr,
|
|
1370
1302
|
subscribe: (ref, priority = 0) => {
|
|
1371
1303
|
set(({
|
|
1372
1304
|
internal
|
|
@@ -1410,13 +1342,14 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1410
1342
|
camera,
|
|
1411
1343
|
size,
|
|
1412
1344
|
viewport,
|
|
1413
|
-
internal
|
|
1345
|
+
internal,
|
|
1346
|
+
gl
|
|
1414
1347
|
} = rootState.getState();
|
|
1415
1348
|
|
|
1416
1349
|
if (size !== oldSize || viewport.dpr !== oldDpr) {
|
|
1417
1350
|
// https://github.com/pmndrs/react-three-fiber/issues/92
|
|
1418
1351
|
// Do not mess with the camera if it belongs to the user
|
|
1419
|
-
if (!camera.manual
|
|
1352
|
+
if (!camera.manual) {
|
|
1420
1353
|
if (isOrthographicCamera(camera)) {
|
|
1421
1354
|
camera.left = size.width / -2;
|
|
1422
1355
|
camera.right = size.width / 2;
|
|
@@ -1438,9 +1371,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
|
|
|
1438
1371
|
oldSize = size;
|
|
1439
1372
|
oldDpr = viewport.dpr;
|
|
1440
1373
|
}
|
|
1441
|
-
}); //
|
|
1442
|
-
|
|
1443
|
-
if (size) state.setSize(size.width, size.height); // Invalidate on any change
|
|
1374
|
+
}); // Invalidate on any change
|
|
1444
1375
|
|
|
1445
1376
|
rootState.subscribe(state => invalidate(state)); // Return root state
|
|
1446
1377
|
|
|
@@ -1465,6 +1396,8 @@ function run(effects, timestamp) {
|
|
|
1465
1396
|
for (i = 0; i < effects.length; i++) effects[i](timestamp);
|
|
1466
1397
|
}
|
|
1467
1398
|
|
|
1399
|
+
let subscribers;
|
|
1400
|
+
|
|
1468
1401
|
function render$1(timestamp, state, frame) {
|
|
1469
1402
|
// Run local effects
|
|
1470
1403
|
let delta = state.clock.getDelta(); // In frameloop='never' mode, clock times are updated using the provided timestamp
|
|
@@ -1476,7 +1409,9 @@ function render$1(timestamp, state, frame) {
|
|
|
1476
1409
|
} // Call subscribers (useFrame)
|
|
1477
1410
|
|
|
1478
1411
|
|
|
1479
|
-
|
|
1412
|
+
subscribers = state.internal.subscribers;
|
|
1413
|
+
|
|
1414
|
+
for (i = 0; i < subscribers.length; i++) subscribers[i].ref.current(state, delta, frame); // Render content
|
|
1480
1415
|
|
|
1481
1416
|
|
|
1482
1417
|
if (!state.internal.priority && state.gl.render) state.gl.render(state.scene, state.camera); // Decrease frame count
|
|
@@ -1488,29 +1423,35 @@ function render$1(timestamp, state, frame) {
|
|
|
1488
1423
|
function createLoop(roots) {
|
|
1489
1424
|
let running = false;
|
|
1490
1425
|
let repeat;
|
|
1426
|
+
let frame;
|
|
1427
|
+
let state;
|
|
1491
1428
|
|
|
1492
1429
|
function loop(timestamp) {
|
|
1430
|
+
frame = requestAnimationFrame(loop);
|
|
1493
1431
|
running = true;
|
|
1494
1432
|
repeat = 0; // Run effects
|
|
1495
1433
|
|
|
1496
|
-
run(globalEffects, timestamp); // Render all roots
|
|
1434
|
+
if (globalEffects.length) run(globalEffects, timestamp); // Render all roots
|
|
1497
1435
|
|
|
1498
1436
|
roots.forEach(root => {
|
|
1499
1437
|
var _state$gl$xr;
|
|
1500
1438
|
|
|
1501
|
-
|
|
1439
|
+
state = root.store.getState(); // If the frameloop is invalidated, do not run another frame
|
|
1502
1440
|
|
|
1503
1441
|
if (state.internal.active && (state.frameloop === 'always' || state.internal.frames > 0) && !((_state$gl$xr = state.gl.xr) != null && _state$gl$xr.isPresenting)) {
|
|
1504
1442
|
repeat += render$1(timestamp, state);
|
|
1505
1443
|
}
|
|
1506
1444
|
}); // Run after-effects
|
|
1507
1445
|
|
|
1508
|
-
run(globalAfterEffects, timestamp); //
|
|
1446
|
+
if (globalAfterEffects.length) run(globalAfterEffects, timestamp); // Stop the loop if nothing invalidates it
|
|
1509
1447
|
|
|
1510
|
-
if (repeat
|
|
1511
|
-
|
|
1448
|
+
if (repeat === 0) {
|
|
1449
|
+
// Tail call effects, they are called when rendering stops
|
|
1450
|
+
if (globalTailEffects.length) run(globalTailEffects, timestamp); // Flag end of operation
|
|
1512
1451
|
|
|
1513
|
-
|
|
1452
|
+
running = false;
|
|
1453
|
+
return cancelAnimationFrame(frame);
|
|
1454
|
+
}
|
|
1514
1455
|
}
|
|
1515
1456
|
|
|
1516
1457
|
function invalidate(state) {
|
|
@@ -1603,113 +1544,216 @@ const {
|
|
|
1603
1544
|
reconciler,
|
|
1604
1545
|
applyProps
|
|
1605
1546
|
} = createRenderer(roots, getEventPriority);
|
|
1547
|
+
const shallowLoose = {
|
|
1548
|
+
objects: 'shallow',
|
|
1549
|
+
strict: false
|
|
1550
|
+
};
|
|
1606
1551
|
|
|
1607
1552
|
const createRendererInstance = (gl, canvas) => {
|
|
1608
1553
|
const customRenderer = typeof gl === 'function' ? gl(canvas) : gl;
|
|
1609
|
-
if (isRenderer(customRenderer)) return customRenderer;
|
|
1610
|
-
const renderer = new THREE__namespace.WebGLRenderer({
|
|
1554
|
+
if (isRenderer(customRenderer)) return customRenderer;else return new THREE__namespace.WebGLRenderer({
|
|
1611
1555
|
powerPreference: 'high-performance',
|
|
1612
1556
|
canvas: canvas,
|
|
1613
1557
|
antialias: true,
|
|
1614
1558
|
alpha: true,
|
|
1615
1559
|
...gl
|
|
1616
|
-
});
|
|
1560
|
+
});
|
|
1561
|
+
};
|
|
1617
1562
|
|
|
1618
|
-
|
|
1619
|
-
|
|
1563
|
+
function createRoot(canvas) {
|
|
1564
|
+
// Check against mistaken use of createRoot
|
|
1565
|
+
let prevRoot = roots.get(canvas);
|
|
1566
|
+
let prevFiber = prevRoot == null ? void 0 : prevRoot.fiber;
|
|
1567
|
+
let prevStore = prevRoot == null ? void 0 : prevRoot.store;
|
|
1568
|
+
if (prevRoot) console.warn('R3F.createRoot should only be called once!'); // Create store
|
|
1620
1569
|
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1570
|
+
const store = prevStore || createStore(invalidate, advance); // Create renderer
|
|
1571
|
+
|
|
1572
|
+
const fiber = prevFiber || reconciler.createContainer(store, constants.ConcurrentRoot, false, null); // Map it
|
|
1573
|
+
|
|
1574
|
+
if (!prevRoot) roots.set(canvas, {
|
|
1575
|
+
fiber,
|
|
1576
|
+
store
|
|
1577
|
+
}); // Locals
|
|
1624
1578
|
|
|
1625
|
-
|
|
1579
|
+
let onCreated;
|
|
1580
|
+
let configured = false;
|
|
1626
1581
|
return {
|
|
1627
|
-
|
|
1628
|
-
var
|
|
1582
|
+
configure(props = {}) {
|
|
1583
|
+
var _canvas$parentElement, _canvas$parentElement2, _canvas$parentElement3, _canvas$parentElement4;
|
|
1629
1584
|
|
|
1630
1585
|
let {
|
|
1631
|
-
gl,
|
|
1586
|
+
gl: glConfig,
|
|
1632
1587
|
size,
|
|
1633
1588
|
events,
|
|
1634
|
-
onCreated,
|
|
1635
|
-
|
|
1636
|
-
|
|
1589
|
+
onCreated: onCreatedCallback,
|
|
1590
|
+
shadows = false,
|
|
1591
|
+
linear = false,
|
|
1592
|
+
flat = false,
|
|
1593
|
+
orthographic = false,
|
|
1594
|
+
frameloop = 'always',
|
|
1595
|
+
dpr = [1, 2],
|
|
1596
|
+
performance,
|
|
1597
|
+
raycaster: raycastOptions,
|
|
1598
|
+
camera: cameraOptions,
|
|
1599
|
+
onPointerMissed
|
|
1600
|
+
} = props;
|
|
1601
|
+
let state = store.getState(); // Set up renderer (one time only!)
|
|
1602
|
+
|
|
1603
|
+
let gl = state.gl;
|
|
1604
|
+
if (!state.gl) state.set({
|
|
1605
|
+
gl: gl = createRendererInstance(glConfig, canvas)
|
|
1606
|
+
}); // Set up raycaster (one time only!)
|
|
1607
|
+
|
|
1608
|
+
let raycaster = state.raycaster;
|
|
1609
|
+
if (!raycaster) state.set({
|
|
1610
|
+
raycaster: raycaster = new THREE__namespace.Raycaster()
|
|
1611
|
+
}); // Set raycaster options
|
|
1637
1612
|
|
|
1638
|
-
|
|
1639
|
-
|
|
1613
|
+
const {
|
|
1614
|
+
params,
|
|
1615
|
+
...options
|
|
1616
|
+
} = raycastOptions || {};
|
|
1617
|
+
if (!is.equ(options, raycaster, shallowLoose)) applyProps(raycaster, {
|
|
1618
|
+
enabled: true,
|
|
1619
|
+
...options
|
|
1620
|
+
});
|
|
1621
|
+
if (!is.equ(params, raycaster.params, shallowLoose)) applyProps(raycaster, {
|
|
1622
|
+
params: { ...raycaster.params,
|
|
1623
|
+
...params
|
|
1624
|
+
}
|
|
1625
|
+
}); // Create default camera (one time only!)
|
|
1640
1626
|
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
};
|
|
1645
|
-
}
|
|
1627
|
+
if (!state.camera) {
|
|
1628
|
+
const isCamera = cameraOptions instanceof THREE__namespace.Camera;
|
|
1629
|
+
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);
|
|
1646
1630
|
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
let state = (_store = store) == null ? void 0 : _store.getState();
|
|
1631
|
+
if (!isCamera) {
|
|
1632
|
+
camera.position.z = 5;
|
|
1633
|
+
if (cameraOptions) applyProps(camera, cameraOptions); // Always look at center by default
|
|
1651
1634
|
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
// Check pixelratio
|
|
1655
|
-
if (props.dpr !== undefined && state.viewport.dpr !== calculateDpr(props.dpr)) state.setDpr(props.dpr); // Check size
|
|
1635
|
+
if (!(cameraOptions != null && cameraOptions.rotation)) camera.lookAt(0, 0, 0);
|
|
1636
|
+
}
|
|
1656
1637
|
|
|
1657
|
-
|
|
1638
|
+
state.set({
|
|
1639
|
+
camera
|
|
1640
|
+
});
|
|
1641
|
+
} // Set up XR (one time only!)
|
|
1658
1642
|
|
|
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
1643
|
|
|
1662
|
-
|
|
1644
|
+
if (!state.xr) {
|
|
1645
|
+
// Handle frame behavior in WebXR
|
|
1646
|
+
const handleXRFrame = (timestamp, frame) => {
|
|
1647
|
+
const state = store.getState();
|
|
1648
|
+
if (state.frameloop === 'never') return;
|
|
1649
|
+
advance(timestamp, true, state, frame);
|
|
1650
|
+
}; // Toggle render switching on session
|
|
1663
1651
|
|
|
1664
|
-
if (linearChanged) {
|
|
1665
|
-
unmountComponentAtNode(canvas);
|
|
1666
|
-
fiber = undefined;
|
|
1667
|
-
}
|
|
1668
|
-
}
|
|
1669
1652
|
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1653
|
+
const handleSessionChange = () => {
|
|
1654
|
+
const gl = store.getState().gl;
|
|
1655
|
+
gl.xr.enabled = gl.xr.isPresenting; // @ts-expect-error
|
|
1656
|
+
// WebXRManager's signature is incorrect.
|
|
1657
|
+
// See: https://github.com/pmndrs/react-three-fiber/pull/2017#discussion_r790134505
|
|
1674
1658
|
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
size,
|
|
1678
|
-
...props
|
|
1679
|
-
});
|
|
1680
|
-
const state = store.getState(); // Create renderer
|
|
1659
|
+
gl.xr.setAnimationLoop(gl.xr.isPresenting ? handleXRFrame : null);
|
|
1660
|
+
}; // WebXR session manager
|
|
1681
1661
|
|
|
1682
|
-
fiber = reconciler.createContainer(store, constants.ConcurrentRoot, false, null); // Map it
|
|
1683
1662
|
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1663
|
+
const xr = {
|
|
1664
|
+
connect() {
|
|
1665
|
+
const gl = store.getState().gl;
|
|
1666
|
+
gl.xr.addEventListener('sessionstart', handleSessionChange);
|
|
1667
|
+
gl.xr.addEventListener('sessionend', handleSessionChange);
|
|
1668
|
+
},
|
|
1669
|
+
|
|
1670
|
+
disconnect() {
|
|
1671
|
+
const gl = store.getState().gl;
|
|
1672
|
+
gl.xr.removeEventListener('sessionstart', handleSessionChange);
|
|
1673
|
+
gl.xr.removeEventListener('sessionend', handleSessionChange);
|
|
1674
|
+
}
|
|
1688
1675
|
|
|
1689
|
-
|
|
1690
|
-
|
|
1676
|
+
}; // Subscribe to WebXR session events
|
|
1677
|
+
|
|
1678
|
+
if (gl.xr) xr.connect();
|
|
1679
|
+
state.set({
|
|
1680
|
+
xr
|
|
1691
1681
|
});
|
|
1692
|
-
}
|
|
1682
|
+
} // Set shadowmap
|
|
1693
1683
|
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
}
|
|
1684
|
+
|
|
1685
|
+
if (gl.shadowMap) {
|
|
1686
|
+
const isBoolean = is.boo(shadows);
|
|
1687
|
+
|
|
1688
|
+
if (isBoolean && gl.shadowMap.enabled !== shadows || !is.equ(shadows, gl.shadowMap, shallowLoose)) {
|
|
1689
|
+
const old = gl.shadowMap.enabled;
|
|
1690
|
+
gl.shadowMap.enabled = !!shadows;
|
|
1691
|
+
if (!isBoolean) Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE__namespace.PCFSoftShadowMap;
|
|
1692
|
+
if (old !== gl.shadowMap.enabled) gl.shadowMap.needsUpdate = true;
|
|
1693
|
+
}
|
|
1694
|
+
} // Set color management
|
|
1695
|
+
|
|
1696
|
+
|
|
1697
|
+
const outputEncoding = linear ? THREE__namespace.LinearEncoding : THREE__namespace.sRGBEncoding;
|
|
1698
|
+
const toneMapping = flat ? THREE__namespace.NoToneMapping : THREE__namespace.ACESFilmicToneMapping;
|
|
1699
|
+
if (gl.outputEncoding !== outputEncoding) gl.outputEncoding = outputEncoding;
|
|
1700
|
+
if (gl.toneMapping !== toneMapping) gl.toneMapping = toneMapping; // Set gl props
|
|
1701
|
+
|
|
1702
|
+
if (glConfig && !is.fun(glConfig) && !isRenderer(glConfig) && !is.equ(glConfig, gl, shallowLoose)) applyProps(gl, glConfig); // Store events internally
|
|
1703
|
+
|
|
1704
|
+
if (events && !state.events.handlers) state.set({
|
|
1705
|
+
events: events(store)
|
|
1706
|
+
}); // Check pixelratio
|
|
1707
|
+
|
|
1708
|
+
if (dpr && state.viewport.dpr !== calculateDpr(dpr)) state.setDpr(dpr); // Check size, allow it to take on container bounds initially
|
|
1709
|
+
|
|
1710
|
+
size = size || {
|
|
1711
|
+
width: (_canvas$parentElement = (_canvas$parentElement2 = canvas.parentElement) == null ? void 0 : _canvas$parentElement2.clientWidth) != null ? _canvas$parentElement : 0,
|
|
1712
|
+
height: (_canvas$parentElement3 = (_canvas$parentElement4 = canvas.parentElement) == null ? void 0 : _canvas$parentElement4.clientHeight) != null ? _canvas$parentElement3 : 0
|
|
1713
|
+
};
|
|
1714
|
+
if (!is.equ(size, state.size, shallowLoose)) state.setSize(size.width, size.height); // Check frameloop
|
|
1715
|
+
|
|
1716
|
+
if (state.frameloop !== frameloop) state.setFrameloop(frameloop); // Check pointer missed
|
|
1717
|
+
|
|
1718
|
+
if (!state.onPointerMissed) state.set({
|
|
1719
|
+
onPointerMissed
|
|
1720
|
+
}); // Check performance
|
|
1721
|
+
|
|
1722
|
+
if (performance && !is.equ(performance, state.performance, shallowLoose)) state.set(state => ({
|
|
1723
|
+
performance: { ...state.performance,
|
|
1724
|
+
...performance
|
|
1725
|
+
}
|
|
1726
|
+
})); // Set locals
|
|
1727
|
+
|
|
1728
|
+
onCreated = onCreatedCallback;
|
|
1729
|
+
configured = true;
|
|
1730
|
+
return this;
|
|
1705
1731
|
},
|
|
1706
|
-
|
|
1732
|
+
|
|
1733
|
+
render(element) {
|
|
1734
|
+
// The root has to be configured before it can be rendered
|
|
1735
|
+
if (!configured) this.configure();
|
|
1736
|
+
reconciler.updateContainer( /*#__PURE__*/React__namespace.createElement(Provider, {
|
|
1737
|
+
store: store,
|
|
1738
|
+
element: element,
|
|
1739
|
+
onCreated: onCreated,
|
|
1740
|
+
target: canvas
|
|
1741
|
+
}), fiber, null, () => undefined);
|
|
1742
|
+
return store;
|
|
1743
|
+
},
|
|
1744
|
+
|
|
1745
|
+
unmount() {
|
|
1746
|
+
unmountComponentAtNode(canvas);
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1707
1749
|
};
|
|
1708
1750
|
}
|
|
1709
1751
|
|
|
1710
1752
|
function render(element, canvas, config = {}) {
|
|
1711
1753
|
console.warn('R3F.render is no longer supported in React 18. Use createRoot instead!');
|
|
1712
|
-
|
|
1754
|
+
const root = createRoot(canvas);
|
|
1755
|
+
root.configure(config);
|
|
1756
|
+
return root.render(element);
|
|
1713
1757
|
}
|
|
1714
1758
|
|
|
1715
1759
|
function Provider({
|
|
@@ -1752,7 +1796,7 @@ function unmountComponentAtNode(canvas, callback) {
|
|
|
1752
1796
|
state.events.disconnect == null ? void 0 : state.events.disconnect();
|
|
1753
1797
|
(_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
1798
|
(_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.
|
|
1799
|
+
if ((_state$gl3 = state.gl) != null && _state$gl3.xr) state.xr.disconnect();
|
|
1756
1800
|
dispose(state);
|
|
1757
1801
|
roots.delete(canvas);
|
|
1758
1802
|
if (callback) callback(canvas);
|