@react-three/fiber 7.0.17 → 7.0.21

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 CHANGED
@@ -1,5 +1,29 @@
1
1
  # @react-three/fiber
2
2
 
3
+ ## 7.0.21
4
+
5
+ ### Patch Changes
6
+
7
+ - 65e4147: up usemeasure, add last event to internals"
8
+
9
+ ## 7.0.20
10
+
11
+ ### Patch Changes
12
+
13
+ - 54cb0fd: update react-use-measure, allow it to use the offsetSize
14
+
15
+ ## 7.0.19
16
+
17
+ ### Patch Changes
18
+
19
+ - 7aa2eab: fix: remove zustand subcribe selector
20
+
21
+ ## 7.0.18
22
+
23
+ ### Patch Changes
24
+
25
+ - 6780f58: fix unmount pointer capture
26
+
3
27
  ## 7.0.17
4
28
 
5
29
  ### Patch Changes
@@ -53,6 +53,10 @@ export interface EventManager<TTarget> {
53
53
  connect?: (target: TTarget) => void;
54
54
  disconnect?: () => void;
55
55
  }
56
+ export interface PointerCaptureTarget {
57
+ intersection: Intersection;
58
+ target: Element;
59
+ }
56
60
  export declare function removeInteractivity(store: UseStore<RootState>, object: THREE.Object3D): void;
57
61
  export declare function createEvents(store: UseStore<RootState>): {
58
62
  handlePointer: (name: string) => (event: DomEvent) => void;
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import * as ReactThreeFiber from '../three-types';
4
4
  import { GetState, SetState, UseStore } from 'zustand';
5
5
  import { Instance, InstanceProps } from './renderer';
6
- import { DomEvent, EventManager, ThreeEvent } from './events';
6
+ import { DomEvent, EventManager, PointerCaptureTarget, ThreeEvent } from './events';
7
7
  export interface Intersection extends THREE.Intersection {
8
8
  eventObject: THREE.Object3D;
9
9
  }
@@ -47,10 +47,11 @@ export declare type InternalState = {
47
47
  priority: number;
48
48
  frames: number;
49
49
  lastProps: StoreProps;
50
+ lastEvent: React.MutableRefObject<DomEvent>;
50
51
  interaction: THREE.Object3D[];
51
52
  hovered: Map<string, DomEvent>;
52
53
  subscribers: Subscription[];
53
- capturedMap: Map<number, Map<THREE.Object3D, Intersection>>;
54
+ capturedMap: Map<number, Map<THREE.Object3D, PointerCaptureTarget>>;
54
55
  initialClick: [x: number, y: number];
55
56
  initialHits: THREE.Object3D[];
56
57
  subscribe: (callback: React.MutableRefObject<RenderCallback>, priority?: number) => () => void;
@@ -59,7 +59,6 @@ export declare type LineSegmentsProps = Object3DNode<THREE.LineSegments, typeof
59
59
  export declare type LineLoopProps = Object3DNode<THREE.LineLoop, typeof THREE.LineLoop>;
60
60
  export declare type PointsProps = Object3DNode<THREE.Points, typeof THREE.Points>;
61
61
  export declare type GroupProps = Object3DNode<THREE.Group, typeof THREE.Group>;
62
- export declare type ImmediateRenderObjectProps = Object3DNode<THREE.ImmediateRenderObject, typeof THREE.ImmediateRenderObject>;
63
62
  export declare type CameraProps = Object3DNode<THREE.Camera, typeof THREE.Camera>;
64
63
  export declare type PerspectiveCameraProps = Object3DNode<THREE.PerspectiveCamera, typeof THREE.PerspectiveCamera>;
65
64
  export declare type OrthographicCameraProps = Object3DNode<THREE.OrthographicCamera, typeof THREE.OrthographicCamera>;
@@ -197,7 +196,6 @@ declare global {
197
196
  lineLoop: LineLoopProps;
198
197
  points: PointsProps;
199
198
  group: GroupProps;
200
- immediateRenderObject: ImmediateRenderObjectProps;
201
199
  camera: CameraProps;
202
200
  perspectiveCamera: PerspectiveCameraProps;
203
201
  orthographicCamera: OrthographicCameraProps;
@@ -5,7 +5,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var THREE = require('three');
6
6
  var React = require('react');
7
7
  var create = require('zustand');
8
- var shallow = require('zustand/shallow');
9
8
  var Reconciler = require('react-reconciler');
10
9
  var scheduler = require('scheduler');
11
10
  var useAsset = require('use-asset');
@@ -37,7 +36,6 @@ function _interopNamespace(e) {
37
36
  var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
38
37
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
39
38
  var create__default = /*#__PURE__*/_interopDefault(create);
40
- var shallow__default = /*#__PURE__*/_interopDefault(shallow);
41
39
  var Reconciler__default = /*#__PURE__*/_interopDefault(Reconciler);
42
40
  var mergeRefs__default = /*#__PURE__*/_interopDefault(mergeRefs);
43
41
  var useMeasure__default = /*#__PURE__*/_interopDefault(useMeasure);
@@ -76,6 +74,23 @@ const is = {
76
74
  function makeId(event) {
77
75
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
78
76
  }
77
+ /** Release pointer captures.
78
+ * This is called by releasePointerCapture in the API, and when an object is removed.
79
+ */
80
+
81
+
82
+ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
83
+ const captureData = captures.get(obj);
84
+
85
+ if (captureData) {
86
+ captures.delete(obj); // If this was the last capturing object for this pointer
87
+
88
+ if (captures.size === 0) {
89
+ capturedMap.delete(pointerId);
90
+ captureData.target.releasePointerCapture(pointerId);
91
+ }
92
+ }
93
+ }
79
94
 
80
95
  function removeInteractivity(store, object) {
81
96
  const {
@@ -89,6 +104,9 @@ function removeInteractivity(store, object) {
89
104
  internal.hovered.delete(key);
90
105
  }
91
106
  });
107
+ internal.capturedMap.forEach((captures, pointerId) => {
108
+ releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
109
+ });
92
110
  }
93
111
  function createEvents(store) {
94
112
  const temp = new THREE__namespace.Vector3();
@@ -187,7 +205,9 @@ function createEvents(store) {
187
205
  // intersect.
188
206
 
189
207
  if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
190
- intersections.push(...internal.capturedMap.get(event.pointerId).values());
208
+ for (let captureData of internal.capturedMap.get(event.pointerId).values()) {
209
+ intersections.push(captureData.intersection);
210
+ }
191
211
  }
192
212
 
193
213
  return intersections;
@@ -205,9 +225,6 @@ function createEvents(store) {
205
225
 
206
226
  if (intersections.length) {
207
227
  const unprojectedPoint = temp.set(mouse.x, mouse.y, 0).unproject(camera);
208
-
209
- const releasePointerCapture = id => event.target.releasePointerCapture(id);
210
-
211
228
  const localState = {
212
229
  stopped: false
213
230
  };
@@ -220,23 +237,36 @@ function createEvents(store) {
220
237
  };
221
238
 
222
239
  const setPointerCapture = id => {
240
+ const captureData = {
241
+ intersection: hit,
242
+ target: event.target
243
+ };
244
+
223
245
  if (internal.capturedMap.has(id)) {
224
246
  // if the pointerId was previously captured, we add the hit to the
225
247
  // event capturedMap.
226
- internal.capturedMap.get(id).set(hit.eventObject, hit);
248
+ internal.capturedMap.get(id).set(hit.eventObject, captureData);
227
249
  } else {
228
250
  // if the pointerId was not previously captured, we create a map
229
251
  // containing the hitObject, and the hit. hitObject is used for
230
252
  // faster access.
231
- internal.capturedMap.set(id, new Map([[hit.eventObject, hit]]));
253
+ internal.capturedMap.set(id, new Map([[hit.eventObject, captureData]]));
232
254
  } // Call the original event now
233
255
  event.target.setPointerCapture(id);
256
+ };
257
+
258
+ const releasePointerCapture = id => {
259
+ const captures = internal.capturedMap.get(id);
260
+
261
+ if (captures) {
262
+ releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
263
+ }
234
264
  }; // Add native event props
235
265
 
236
266
 
237
- let extractEventProps = {};
267
+ let extractEventProps = {}; // This iterates over the event's properties including the inherited ones. Native PointerEvents have most of their props as getters which are inherited, but polyfilled PointerEvents have them all as their own properties (i.e. not inherited). We can't use Object.keys() or Object.entries() as they only return "own" properties; nor Object.getPrototypeOf(event) as that *doesn't* return "own" properties, only inherited ones.
238
268
 
239
- for (let prop in Object.getPrototypeOf(event)) {
269
+ for (let prop in event) {
240
270
  let property = event[prop]; // Only copy over atomics, leave functions alone as these should be
241
271
  // called as event.nativeEvent.fn()
242
272
 
@@ -332,9 +362,8 @@ function createEvents(store) {
332
362
  case 'onLostPointerCapture':
333
363
  return event => {
334
364
  if ('pointerId' in event) {
335
- // this will be a problem if one target releases the pointerId
336
- // and another one is still keeping it, as the line below
337
- // indifferently deletes all capturing references.
365
+ // If the object event interface had onLostPointerCapture, we'd call it here on every
366
+ // object that's getting removed.
338
367
  store.getState().internal.capturedMap.delete(event.pointerId);
339
368
  }
340
369
 
@@ -348,7 +377,8 @@ function createEvents(store) {
348
377
  onPointerMissed,
349
378
  internal
350
379
  } = store.getState();
351
- prepareRay(event); // Get fresh intersects
380
+ prepareRay(event);
381
+ internal.lastEvent.current = event; // Get fresh intersects
352
382
 
353
383
  const isPointerMove = name === 'onPointerMove';
354
384
  const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
@@ -592,21 +622,21 @@ function createRenderer(roots) {
592
622
  if (targetProp.fromArray) targetProp.fromArray(value);else targetProp.set(...value);
593
623
  } // Test again target.copy(class) next ...
594
624
  else if (targetProp.copy && value && value.constructor && targetProp.constructor.name === value.constructor.name) targetProp.copy(value); // If nothing else fits, just set the single value, ignore undefined
595
- // https://github.com/react-spring/react-three-fiber/issues/274
625
+ // https://github.com/pmndrs/react-three-fiber/issues/274
596
626
  else if (value !== undefined) {
597
627
  const isColor = targetProp instanceof THREE__namespace.Color; // Allow setting array scalars
598
628
 
599
629
  if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
600
630
  else if (targetProp instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) targetProp.mask = value.mask; // Otherwise just set ...
601
631
  else targetProp.set(value); // Auto-convert sRGB colors, for now ...
602
- // https://github.com/react-spring/react-three-fiber/issues/344
632
+ // https://github.com/pmndrs/react-three-fiber/issues/344
603
633
 
604
634
  if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
605
635
  } // Else, just overwrite the value
606
636
 
607
637
  } else {
608
638
  currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
609
- // https://github.com/react-spring/react-three-fiber/issues/344
639
+ // https://github.com/pmndrs/react-three-fiber/issues/344
610
640
 
611
641
  if (!rootState.linear && currentInstance[key] instanceof THREE__namespace.Texture) currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
612
642
  }
@@ -810,7 +840,7 @@ function createRenderer(roots) {
810
840
  } else if (is.fun(detachFn)) {
811
841
  detachFn(child, parentInstance);
812
842
  }
813
- } else if (child.isObject3D) {
843
+ } else if (child.isObject3D && parentInstance.isObject3D) {
814
844
  var _child$__r3f;
815
845
 
816
846
  parentInstance.remove(child); // Remove interactivity
@@ -1056,11 +1086,11 @@ const createStore = (applyProps, invalidate, advance, props) => {
1056
1086
  if (shadows) {
1057
1087
  gl.shadowMap.enabled = true;
1058
1088
  if (typeof shadows === 'object') Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE__namespace.PCFSoftShadowMap;
1059
- } // Set color management
1089
+ } // Set color preferences
1060
1090
 
1061
1091
 
1062
- if (!linear) gl.outputEncoding = THREE__namespace.sRGBEncoding;
1063
- if (!flat) gl.toneMapping = THREE__namespace.ACESFilmicToneMapping; // clock.elapsedTime is updated using advance(timestamp)
1092
+ if (linear) gl.outputEncoding = THREE__namespace.LinearEncoding;
1093
+ if (flat) gl.toneMapping = THREE__namespace.NoToneMapping; // clock.elapsedTime is updated using advance(timestamp)
1064
1094
 
1065
1095
  if (frameloop === 'never') {
1066
1096
  clock.stop();
@@ -1210,6 +1240,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
1210
1240
  priority: 0,
1211
1241
  frames: 0,
1212
1242
  lastProps: props,
1243
+ lastEvent: /*#__PURE__*/React__namespace.createRef(null),
1213
1244
  interaction: [],
1214
1245
  hovered: new Map(),
1215
1246
  subscribers: [],
@@ -1249,38 +1280,45 @@ const createStore = (applyProps, invalidate, advance, props) => {
1249
1280
  }
1250
1281
  }
1251
1282
  };
1252
- }); // Resize camera and renderer on changes to size and pixelratio
1283
+ });
1284
+ const state = rootState.getState(); // Resize camera and renderer on changes to size and pixelratio
1253
1285
 
1286
+ let oldSize = state.size;
1287
+ let oldDpr = state.viewport.dpr;
1254
1288
  rootState.subscribe(() => {
1255
1289
  const {
1256
1290
  camera,
1257
1291
  size,
1258
1292
  viewport,
1259
1293
  internal
1260
- } = rootState.getState(); // https://github.com/pmndrs/react-three-fiber/issues/92
1261
- // Do not mess with the camera if it belongs to the user
1262
-
1263
- if (!(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1264
- if (isOrthographicCamera(camera)) {
1265
- camera.left = size.width / -2;
1266
- camera.right = size.width / 2;
1267
- camera.top = size.height / 2;
1268
- camera.bottom = size.height / -2;
1269
- } else {
1270
- camera.aspect = size.width / size.height;
1271
- }
1294
+ } = rootState.getState();
1295
+
1296
+ if (size !== oldSize || viewport.dpr !== oldDpr) {
1297
+ // https://github.com/pmndrs/react-three-fiber/issues/92
1298
+ // Do not mess with the camera if it belongs to the user
1299
+ if (!(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1300
+ if (isOrthographicCamera(camera)) {
1301
+ camera.left = size.width / -2;
1302
+ camera.right = size.width / 2;
1303
+ camera.top = size.height / 2;
1304
+ camera.bottom = size.height / -2;
1305
+ } else {
1306
+ camera.aspect = size.width / size.height;
1307
+ }
1272
1308
 
1273
- camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1274
- // Update matrix world since the renderer is a frame late
1309
+ camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1310
+ // Update matrix world since the renderer is a frame late
1275
1311
 
1276
- camera.updateMatrixWorld();
1277
- } // Update renderer
1312
+ camera.updateMatrixWorld();
1313
+ } // Update renderer
1278
1314
 
1279
1315
 
1280
- gl.setPixelRatio(viewport.dpr);
1281
- gl.setSize(size.width, size.height);
1282
- }, state => [state.viewport.dpr, state.size], shallow__default['default']);
1283
- const state = rootState.getState(); // Update size
1316
+ gl.setPixelRatio(viewport.dpr);
1317
+ gl.setSize(size.width, size.height);
1318
+ oldSize = size;
1319
+ oldDpr = viewport.dpr;
1320
+ }
1321
+ }); // Update size
1284
1322
 
1285
1323
  if (size) state.setSize(size.width, size.height); // Invalidate on any change
1286
1324
 
@@ -1644,7 +1682,11 @@ const createRendererInstance = (gl, canvas) => {
1644
1682
  antialias: true,
1645
1683
  alpha: true,
1646
1684
  ...gl
1647
- });
1685
+ }); // Set color management
1686
+
1687
+ renderer.outputEncoding = THREE__namespace.sRGBEncoding;
1688
+ renderer.toneMapping = THREE__namespace.ACESFilmicToneMapping; // Set gl props
1689
+
1648
1690
  if (gl) applyProps(renderer, gl);
1649
1691
  return renderer;
1650
1692
  };
@@ -5,7 +5,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var THREE = require('three');
6
6
  var React = require('react');
7
7
  var create = require('zustand');
8
- var shallow = require('zustand/shallow');
9
8
  var Reconciler = require('react-reconciler');
10
9
  var scheduler = require('scheduler');
11
10
  var useAsset = require('use-asset');
@@ -37,7 +36,6 @@ function _interopNamespace(e) {
37
36
  var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
38
37
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
39
38
  var create__default = /*#__PURE__*/_interopDefault(create);
40
- var shallow__default = /*#__PURE__*/_interopDefault(shallow);
41
39
  var Reconciler__default = /*#__PURE__*/_interopDefault(Reconciler);
42
40
  var mergeRefs__default = /*#__PURE__*/_interopDefault(mergeRefs);
43
41
  var useMeasure__default = /*#__PURE__*/_interopDefault(useMeasure);
@@ -76,6 +74,23 @@ const is = {
76
74
  function makeId(event) {
77
75
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
78
76
  }
77
+ /** Release pointer captures.
78
+ * This is called by releasePointerCapture in the API, and when an object is removed.
79
+ */
80
+
81
+
82
+ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
83
+ const captureData = captures.get(obj);
84
+
85
+ if (captureData) {
86
+ captures.delete(obj); // If this was the last capturing object for this pointer
87
+
88
+ if (captures.size === 0) {
89
+ capturedMap.delete(pointerId);
90
+ captureData.target.releasePointerCapture(pointerId);
91
+ }
92
+ }
93
+ }
79
94
 
80
95
  function removeInteractivity(store, object) {
81
96
  const {
@@ -89,6 +104,9 @@ function removeInteractivity(store, object) {
89
104
  internal.hovered.delete(key);
90
105
  }
91
106
  });
107
+ internal.capturedMap.forEach((captures, pointerId) => {
108
+ releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
109
+ });
92
110
  }
93
111
  function createEvents(store) {
94
112
  const temp = new THREE__namespace.Vector3();
@@ -187,7 +205,9 @@ function createEvents(store) {
187
205
  // intersect.
188
206
 
189
207
  if ('pointerId' in event && internal.capturedMap.has(event.pointerId)) {
190
- intersections.push(...internal.capturedMap.get(event.pointerId).values());
208
+ for (let captureData of internal.capturedMap.get(event.pointerId).values()) {
209
+ intersections.push(captureData.intersection);
210
+ }
191
211
  }
192
212
 
193
213
  return intersections;
@@ -205,9 +225,6 @@ function createEvents(store) {
205
225
 
206
226
  if (intersections.length) {
207
227
  const unprojectedPoint = temp.set(mouse.x, mouse.y, 0).unproject(camera);
208
-
209
- const releasePointerCapture = id => event.target.releasePointerCapture(id);
210
-
211
228
  const localState = {
212
229
  stopped: false
213
230
  };
@@ -220,23 +237,36 @@ function createEvents(store) {
220
237
  };
221
238
 
222
239
  const setPointerCapture = id => {
240
+ const captureData = {
241
+ intersection: hit,
242
+ target: event.target
243
+ };
244
+
223
245
  if (internal.capturedMap.has(id)) {
224
246
  // if the pointerId was previously captured, we add the hit to the
225
247
  // event capturedMap.
226
- internal.capturedMap.get(id).set(hit.eventObject, hit);
248
+ internal.capturedMap.get(id).set(hit.eventObject, captureData);
227
249
  } else {
228
250
  // if the pointerId was not previously captured, we create a map
229
251
  // containing the hitObject, and the hit. hitObject is used for
230
252
  // faster access.
231
- internal.capturedMap.set(id, new Map([[hit.eventObject, hit]]));
253
+ internal.capturedMap.set(id, new Map([[hit.eventObject, captureData]]));
232
254
  } // Call the original event now
233
255
  event.target.setPointerCapture(id);
256
+ };
257
+
258
+ const releasePointerCapture = id => {
259
+ const captures = internal.capturedMap.get(id);
260
+
261
+ if (captures) {
262
+ releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
263
+ }
234
264
  }; // Add native event props
235
265
 
236
266
 
237
- let extractEventProps = {};
267
+ let extractEventProps = {}; // This iterates over the event's properties including the inherited ones. Native PointerEvents have most of their props as getters which are inherited, but polyfilled PointerEvents have them all as their own properties (i.e. not inherited). We can't use Object.keys() or Object.entries() as they only return "own" properties; nor Object.getPrototypeOf(event) as that *doesn't* return "own" properties, only inherited ones.
238
268
 
239
- for (let prop in Object.getPrototypeOf(event)) {
269
+ for (let prop in event) {
240
270
  let property = event[prop]; // Only copy over atomics, leave functions alone as these should be
241
271
  // called as event.nativeEvent.fn()
242
272
 
@@ -332,9 +362,8 @@ function createEvents(store) {
332
362
  case 'onLostPointerCapture':
333
363
  return event => {
334
364
  if ('pointerId' in event) {
335
- // this will be a problem if one target releases the pointerId
336
- // and another one is still keeping it, as the line below
337
- // indifferently deletes all capturing references.
365
+ // If the object event interface had onLostPointerCapture, we'd call it here on every
366
+ // object that's getting removed.
338
367
  store.getState().internal.capturedMap.delete(event.pointerId);
339
368
  }
340
369
 
@@ -348,7 +377,8 @@ function createEvents(store) {
348
377
  onPointerMissed,
349
378
  internal
350
379
  } = store.getState();
351
- prepareRay(event); // Get fresh intersects
380
+ prepareRay(event);
381
+ internal.lastEvent.current = event; // Get fresh intersects
352
382
 
353
383
  const isPointerMove = name === 'onPointerMove';
354
384
  const isClickEvent = name === 'onClick' || name === 'onContextMenu' || name === 'onDoubleClick';
@@ -592,21 +622,21 @@ function createRenderer(roots) {
592
622
  if (targetProp.fromArray) targetProp.fromArray(value);else targetProp.set(...value);
593
623
  } // Test again target.copy(class) next ...
594
624
  else if (targetProp.copy && value && value.constructor && targetProp.constructor.name === value.constructor.name) targetProp.copy(value); // If nothing else fits, just set the single value, ignore undefined
595
- // https://github.com/react-spring/react-three-fiber/issues/274
625
+ // https://github.com/pmndrs/react-three-fiber/issues/274
596
626
  else if (value !== undefined) {
597
627
  const isColor = targetProp instanceof THREE__namespace.Color; // Allow setting array scalars
598
628
 
599
629
  if (!isColor && targetProp.setScalar) targetProp.setScalar(value); // Layers have no copy function, we must therefore copy the mask property
600
630
  else if (targetProp instanceof THREE__namespace.Layers && value instanceof THREE__namespace.Layers) targetProp.mask = value.mask; // Otherwise just set ...
601
631
  else targetProp.set(value); // Auto-convert sRGB colors, for now ...
602
- // https://github.com/react-spring/react-three-fiber/issues/344
632
+ // https://github.com/pmndrs/react-three-fiber/issues/344
603
633
 
604
634
  if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
605
635
  } // Else, just overwrite the value
606
636
 
607
637
  } else {
608
638
  currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
609
- // https://github.com/react-spring/react-three-fiber/issues/344
639
+ // https://github.com/pmndrs/react-three-fiber/issues/344
610
640
 
611
641
  if (!rootState.linear && currentInstance[key] instanceof THREE__namespace.Texture) currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
612
642
  }
@@ -810,7 +840,7 @@ function createRenderer(roots) {
810
840
  } else if (is.fun(detachFn)) {
811
841
  detachFn(child, parentInstance);
812
842
  }
813
- } else if (child.isObject3D) {
843
+ } else if (child.isObject3D && parentInstance.isObject3D) {
814
844
  var _child$__r3f;
815
845
 
816
846
  parentInstance.remove(child); // Remove interactivity
@@ -1056,11 +1086,11 @@ const createStore = (applyProps, invalidate, advance, props) => {
1056
1086
  if (shadows) {
1057
1087
  gl.shadowMap.enabled = true;
1058
1088
  if (typeof shadows === 'object') Object.assign(gl.shadowMap, shadows);else gl.shadowMap.type = THREE__namespace.PCFSoftShadowMap;
1059
- } // Set color management
1089
+ } // Set color preferences
1060
1090
 
1061
1091
 
1062
- if (!linear) gl.outputEncoding = THREE__namespace.sRGBEncoding;
1063
- if (!flat) gl.toneMapping = THREE__namespace.ACESFilmicToneMapping; // clock.elapsedTime is updated using advance(timestamp)
1092
+ if (linear) gl.outputEncoding = THREE__namespace.LinearEncoding;
1093
+ if (flat) gl.toneMapping = THREE__namespace.NoToneMapping; // clock.elapsedTime is updated using advance(timestamp)
1064
1094
 
1065
1095
  if (frameloop === 'never') {
1066
1096
  clock.stop();
@@ -1210,6 +1240,7 @@ const createStore = (applyProps, invalidate, advance, props) => {
1210
1240
  priority: 0,
1211
1241
  frames: 0,
1212
1242
  lastProps: props,
1243
+ lastEvent: /*#__PURE__*/React__namespace.createRef(null),
1213
1244
  interaction: [],
1214
1245
  hovered: new Map(),
1215
1246
  subscribers: [],
@@ -1249,38 +1280,45 @@ const createStore = (applyProps, invalidate, advance, props) => {
1249
1280
  }
1250
1281
  }
1251
1282
  };
1252
- }); // Resize camera and renderer on changes to size and pixelratio
1283
+ });
1284
+ const state = rootState.getState(); // Resize camera and renderer on changes to size and pixelratio
1253
1285
 
1286
+ let oldSize = state.size;
1287
+ let oldDpr = state.viewport.dpr;
1254
1288
  rootState.subscribe(() => {
1255
1289
  const {
1256
1290
  camera,
1257
1291
  size,
1258
1292
  viewport,
1259
1293
  internal
1260
- } = rootState.getState(); // https://github.com/pmndrs/react-three-fiber/issues/92
1261
- // Do not mess with the camera if it belongs to the user
1262
-
1263
- if (!(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1264
- if (isOrthographicCamera(camera)) {
1265
- camera.left = size.width / -2;
1266
- camera.right = size.width / 2;
1267
- camera.top = size.height / 2;
1268
- camera.bottom = size.height / -2;
1269
- } else {
1270
- camera.aspect = size.width / size.height;
1271
- }
1294
+ } = rootState.getState();
1295
+
1296
+ if (size !== oldSize || viewport.dpr !== oldDpr) {
1297
+ // https://github.com/pmndrs/react-three-fiber/issues/92
1298
+ // Do not mess with the camera if it belongs to the user
1299
+ if (!(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1300
+ if (isOrthographicCamera(camera)) {
1301
+ camera.left = size.width / -2;
1302
+ camera.right = size.width / 2;
1303
+ camera.top = size.height / 2;
1304
+ camera.bottom = size.height / -2;
1305
+ } else {
1306
+ camera.aspect = size.width / size.height;
1307
+ }
1272
1308
 
1273
- camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1274
- // Update matrix world since the renderer is a frame late
1309
+ camera.updateProjectionMatrix(); // https://github.com/pmndrs/react-three-fiber/issues/178
1310
+ // Update matrix world since the renderer is a frame late
1275
1311
 
1276
- camera.updateMatrixWorld();
1277
- } // Update renderer
1312
+ camera.updateMatrixWorld();
1313
+ } // Update renderer
1278
1314
 
1279
1315
 
1280
- gl.setPixelRatio(viewport.dpr);
1281
- gl.setSize(size.width, size.height);
1282
- }, state => [state.viewport.dpr, state.size], shallow__default['default']);
1283
- const state = rootState.getState(); // Update size
1316
+ gl.setPixelRatio(viewport.dpr);
1317
+ gl.setSize(size.width, size.height);
1318
+ oldSize = size;
1319
+ oldDpr = viewport.dpr;
1320
+ }
1321
+ }); // Update size
1284
1322
 
1285
1323
  if (size) state.setSize(size.width, size.height); // Invalidate on any change
1286
1324
 
@@ -1644,7 +1682,11 @@ const createRendererInstance = (gl, canvas) => {
1644
1682
  antialias: true,
1645
1683
  alpha: true,
1646
1684
  ...gl
1647
- });
1685
+ }); // Set color management
1686
+
1687
+ renderer.outputEncoding = THREE__namespace.sRGBEncoding;
1688
+ renderer.toneMapping = THREE__namespace.ACESFilmicToneMapping; // Set gl props
1689
+
1648
1690
  if (gl) applyProps(renderer, gl);
1649
1691
  return renderer;
1650
1692
  };