@react-three/fiber 7.0.22 → 7.0.26

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.26
4
+
5
+ ### Patch Changes
6
+
7
+ - ccda644: passthrough size via raycaster#computeOffsets
8
+
9
+ ## 7.0.25
10
+
11
+ ### Patch Changes
12
+
13
+ - 8698734: Release latest patches
14
+
15
+ ## 7.0.24
16
+
17
+ ### Patch Changes
18
+
19
+ - 7f46ddf: cleanup captured pointers when released (#1914)
20
+
21
+ ## 7.0.23
22
+
23
+ ### Patch Changes
24
+
25
+ - 30d38b1: remove logs
26
+
3
27
  ## 7.0.22
4
28
 
5
29
  ### Patch Changes
@@ -90,6 +90,8 @@ export declare type FilterFunction = (items: THREE.Intersection[], state: RootSt
90
90
  export declare type ComputeOffsetsFunction = (event: any, state: RootState) => {
91
91
  offsetX: number;
92
92
  offsetY: number;
93
+ width?: number;
94
+ height?: number;
93
95
  };
94
96
  export declare type StoreProps = {
95
97
  gl: THREE.WebGLRenderer;
@@ -27,7 +27,10 @@ export interface NodeProps<T, P> {
27
27
  key?: React.Key;
28
28
  onUpdate?: (self: T) => void;
29
29
  }
30
- export declare type Node<T, P> = Overwrite<Partial<T>, NodeProps<T, P>>;
30
+ export declare type ExtendedColors<T> = {
31
+ [K in keyof T]: T[K] extends THREE.Color | undefined ? Color : T[K];
32
+ };
33
+ export declare type Node<T, P> = ExtendedColors<Overwrite<Partial<T>, NodeProps<T, P>>>;
31
34
  export declare type Object3DNode<T, P> = Overwrite<Node<T, P>, {
32
35
  position?: Vector3;
33
36
  up?: Vector3;
@@ -38,13 +41,9 @@ export declare type Object3DNode<T, P> = Overwrite<Node<T, P>, {
38
41
  layers?: Layers;
39
42
  dispose?: (() => void) | null;
40
43
  }> & EventHandlers;
41
- export declare type BufferGeometryNode<T extends THREE.BufferGeometry, P> = Overwrite<Node<T, P>, {}>;
42
- export declare type MaterialNode<T extends THREE.Material, P> = Overwrite<Node<T, P>, {
43
- color?: Color;
44
- }>;
45
- export declare type LightNode<T extends THREE.Light, P> = Overwrite<Object3DNode<T, P>, {
46
- color?: Color;
47
- }>;
44
+ export declare type BufferGeometryNode<T extends THREE.BufferGeometry, P> = Node<T, P>;
45
+ export declare type MaterialNode<T extends THREE.Material, P> = Node<T, P>;
46
+ export declare type LightNode<T extends THREE.Light, P> = Object3DNode<T, P>;
48
47
  export declare type AudioListenerProps = Object3DNode<THREE.AudioListener, typeof THREE.AudioListener>;
49
48
  export declare type PositionalAudioProps = Object3DNode<THREE.PositionalAudio, typeof THREE.PositionalAudio>;
50
49
  export declare type MeshProps = Object3DNode<THREE.Mesh, typeof THREE.Mesh>;
@@ -75,19 +74,16 @@ export declare type ExtrudeBufferGeometryProps = BufferGeometryNode<THREE.Extrud
75
74
  export declare type IcosahedronBufferGeometryProps = BufferGeometryNode<THREE.IcosahedronBufferGeometry, typeof THREE.IcosahedronBufferGeometry>;
76
75
  export declare type LatheBufferGeometryProps = BufferGeometryNode<THREE.LatheBufferGeometry, typeof THREE.LatheBufferGeometry>;
77
76
  export declare type OctahedronBufferGeometryProps = BufferGeometryNode<THREE.OctahedronBufferGeometry, typeof THREE.OctahedronBufferGeometry>;
78
- export declare type ParametricBufferGeometryProps = BufferGeometryNode<THREE.ParametricBufferGeometry, typeof THREE.ParametricBufferGeometry>;
79
77
  export declare type PlaneBufferGeometryProps = BufferGeometryNode<THREE.PlaneBufferGeometry, typeof THREE.PlaneBufferGeometry>;
80
78
  export declare type PolyhedronBufferGeometryProps = BufferGeometryNode<THREE.PolyhedronBufferGeometry, typeof THREE.PolyhedronBufferGeometry>;
81
79
  export declare type RingBufferGeometryProps = BufferGeometryNode<THREE.RingBufferGeometry, typeof THREE.RingBufferGeometry>;
82
80
  export declare type ShapeBufferGeometryProps = BufferGeometryNode<THREE.ShapeBufferGeometry, typeof THREE.ShapeBufferGeometry>;
83
81
  export declare type SphereBufferGeometryProps = BufferGeometryNode<THREE.SphereBufferGeometry, typeof THREE.SphereBufferGeometry>;
84
82
  export declare type TetrahedronBufferGeometryProps = BufferGeometryNode<THREE.TetrahedronBufferGeometry, typeof THREE.TetrahedronBufferGeometry>;
85
- export declare type TextBufferGeometryProps = BufferGeometryNode<THREE.TextBufferGeometry, typeof THREE.TextBufferGeometry>;
86
83
  export declare type TorusBufferGeometryProps = BufferGeometryNode<THREE.TorusBufferGeometry, typeof THREE.TorusBufferGeometry>;
87
84
  export declare type TorusKnotBufferGeometryProps = BufferGeometryNode<THREE.TorusKnotBufferGeometry, typeof THREE.TorusKnotBufferGeometry>;
88
85
  export declare type TubeBufferGeometryProps = BufferGeometryNode<THREE.TubeBufferGeometry, typeof THREE.TubeBufferGeometry>;
89
86
  export declare type WireframeGeometryProps = BufferGeometryNode<THREE.WireframeGeometry, typeof THREE.WireframeGeometry>;
90
- export declare type ParametricGeometryProps = BufferGeometryNode<THREE.ParametricGeometry, typeof THREE.ParametricGeometry>;
91
87
  export declare type TetrahedronGeometryProps = BufferGeometryNode<THREE.TetrahedronGeometry, typeof THREE.TetrahedronGeometry>;
92
88
  export declare type OctahedronGeometryProps = BufferGeometryNode<THREE.OctahedronGeometry, typeof THREE.OctahedronGeometry>;
93
89
  export declare type IcosahedronGeometryProps = BufferGeometryNode<THREE.IcosahedronGeometry, typeof THREE.IcosahedronGeometry>;
@@ -96,7 +92,6 @@ export declare type PolyhedronGeometryProps = BufferGeometryNode<THREE.Polyhedro
96
92
  export declare type TubeGeometryProps = BufferGeometryNode<THREE.TubeGeometry, typeof THREE.TubeGeometry>;
97
93
  export declare type TorusKnotGeometryProps = BufferGeometryNode<THREE.TorusKnotGeometry, typeof THREE.TorusKnotGeometry>;
98
94
  export declare type TorusGeometryProps = BufferGeometryNode<THREE.TorusGeometry, typeof THREE.TorusGeometry>;
99
- export declare type TextGeometryProps = BufferGeometryNode<THREE.TextGeometry, typeof THREE.TextGeometry>;
100
95
  export declare type SphereGeometryProps = BufferGeometryNode<THREE.SphereGeometry, typeof THREE.SphereGeometry>;
101
96
  export declare type RingGeometryProps = BufferGeometryNode<THREE.RingGeometry, typeof THREE.RingGeometry>;
102
97
  export declare type PlaneGeometryProps = BufferGeometryNode<THREE.PlaneGeometry, typeof THREE.PlaneGeometry>;
@@ -213,19 +208,16 @@ declare global {
213
208
  icosahedronBufferGeometry: IcosahedronBufferGeometryProps;
214
209
  latheBufferGeometry: LatheBufferGeometryProps;
215
210
  octahedronBufferGeometry: OctahedronBufferGeometryProps;
216
- parametricBufferGeometry: ParametricBufferGeometryProps;
217
211
  planeBufferGeometry: PlaneBufferGeometryProps;
218
212
  polyhedronBufferGeometry: PolyhedronBufferGeometryProps;
219
213
  ringBufferGeometry: RingBufferGeometryProps;
220
214
  shapeBufferGeometry: ShapeBufferGeometryProps;
221
215
  sphereBufferGeometry: SphereBufferGeometryProps;
222
216
  tetrahedronBufferGeometry: TetrahedronBufferGeometryProps;
223
- textBufferGeometry: TextBufferGeometryProps;
224
217
  torusBufferGeometry: TorusBufferGeometryProps;
225
218
  torusKnotBufferGeometry: TorusKnotBufferGeometryProps;
226
219
  tubeBufferGeometry: TubeBufferGeometryProps;
227
220
  wireframeGeometry: WireframeGeometryProps;
228
- parametricGeometry: ParametricGeometryProps;
229
221
  tetrahedronGeometry: TetrahedronGeometryProps;
230
222
  octahedronGeometry: OctahedronGeometryProps;
231
223
  icosahedronGeometry: IcosahedronGeometryProps;
@@ -234,7 +226,6 @@ declare global {
234
226
  tubeGeometry: TubeGeometryProps;
235
227
  torusKnotGeometry: TorusKnotGeometryProps;
236
228
  torusGeometry: TorusGeometryProps;
237
- textGeometry: TextGeometryProps;
238
229
  sphereGeometry: SphereGeometryProps;
239
230
  ringGeometry: RingGeometryProps;
240
231
  planeGeometry: PlaneGeometryProps;
@@ -74,7 +74,8 @@ const is = {
74
74
  function makeId(event) {
75
75
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
76
76
  }
77
- /** Release pointer captures.
77
+ /**
78
+ * Release pointer captures.
78
79
  * This is called by releasePointerCapture in the API, and when an object is removed.
79
80
  */
80
81
 
@@ -113,7 +114,7 @@ function createEvents(store) {
113
114
  /** Sets up defaultRaycaster */
114
115
 
115
116
  function prepareRay(event) {
116
- var _raycaster$computeOff;
117
+ var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
117
118
 
118
119
  const state = store.getState();
119
120
  const {
@@ -124,14 +125,11 @@ function createEvents(store) {
124
125
  } = state; // https://github.com/pmndrs/react-three-fiber/pull/782
125
126
  // Events trigger outside of canvas when moved
126
127
 
127
- const {
128
- offsetX,
129
- offsetY
130
- } = (_raycaster$computeOff = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state)) != null ? _raycaster$computeOff : event;
131
- const {
132
- width,
133
- height
134
- } = size;
128
+ const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
129
+ const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
130
+ const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
131
+ const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
132
+ const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
135
133
  mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
136
134
  raycaster.setFromCamera(mouse, camera);
137
135
  }
@@ -361,13 +359,16 @@ function createEvents(store) {
361
359
 
362
360
  case 'onLostPointerCapture':
363
361
  return event => {
364
- if ('pointerId' in event) {
362
+ const {
363
+ internal
364
+ } = store.getState();
365
+
366
+ if ('pointerId' in event && !internal.capturedMap.has(event.pointerId)) {
365
367
  // If the object event interface had onLostPointerCapture, we'd call it here on every
366
368
  // object that's getting removed.
367
- store.getState().internal.capturedMap.delete(event.pointerId);
369
+ internal.capturedMap.delete(event.pointerId);
370
+ cancelPointer([]);
368
371
  }
369
-
370
- cancelPointer([]);
371
372
  };
372
373
  } // Any other pointer goes here ...
373
374
 
@@ -584,6 +585,8 @@ function createRenderer(roots) {
584
585
 
585
586
  if (instance.__r3f) instance.__r3f.memoizedProps = memoized;
586
587
  changes.forEach(([key, value, isEvent, keys]) => {
588
+ var _rootState$gl;
589
+
587
590
  let currentInstance = instance;
588
591
  let targetProp = currentInstance[key]; // Revolve dashed props
589
592
 
@@ -614,8 +617,9 @@ function createRenderer(roots) {
614
617
 
615
618
  if (defaultClassCall.dispose) defaultClassCall.dispose(); // instance does not have constructor, just set it to 0
616
619
  } else value = 0;
617
- } // Deal with pointer events ...
620
+ }
618
621
 
622
+ const isLinear = (rootState == null ? void 0 : (_rootState$gl = rootState.gl) == null ? void 0 : _rootState$gl.outputEncoding) === THREE__namespace.LinearEncoding; // Deal with pointer events ...
619
623
 
620
624
  if (isEvent) {
621
625
  if (value) localState.handlers[key] = value;else delete localState.handlers[key];
@@ -636,14 +640,14 @@ function createRenderer(roots) {
636
640
  else targetProp.set(value); // Auto-convert sRGB colors, for now ...
637
641
  // https://github.com/pmndrs/react-three-fiber/issues/344
638
642
 
639
- if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
643
+ if (!isLinear && isColor) targetProp.convertSRGBToLinear();
640
644
  } // Else, just overwrite the value
641
645
 
642
646
  } else {
643
647
  currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
644
648
  // https://github.com/pmndrs/react-three-fiber/issues/344
645
649
 
646
- if (!rootState.linear && currentInstance[key] instanceof THREE__namespace.Texture) currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
650
+ if (!isLinear && currentInstance[key] instanceof THREE__namespace.Texture) currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
647
651
  }
648
652
 
649
653
  invalidateInstance(instance);
@@ -837,7 +841,7 @@ function createRenderer(roots) {
837
841
  parentInstance[child.attachArray] = parentInstance[child.attachArray].filter(x => x !== child);
838
842
  } else if (child.attachObject) {
839
843
  delete parentInstance[child.attachObject[0]][child.attachObject[1]];
840
- } else if (child.attach && !is.fun(child.attach)) {
844
+ } else if (child.attach && !is.fun(child.attach) && parentInstance[child.attach] === child) {
841
845
  parentInstance[child.attach] = null;
842
846
  } else if (is.arr(child.attachFns)) {
843
847
  const [, detachFn] = child.attachFns;
@@ -920,10 +924,13 @@ function createRenderer(roots) {
920
924
 
921
925
  instance.__r3f.objects = [];
922
926
  removeChild(parent, instance);
923
- appendChild(parent, newInstance) // This evil hack switches the react-internal fiber node
924
- // https://github.com/facebook/react/issues/14983
925
- // https://github.com/facebook/react/pull/15021
926
- ;
927
+ appendChild(parent, newInstance); // Re-bind event handlers
928
+
929
+ if (newInstance.raycast && newInstance.__r3f.eventCount) {
930
+ const rootState = newInstance.__r3f.root.getState();
931
+
932
+ rootState.internal.interaction.push(newInstance);
933
+ } // This evil hack switches the react-internal fiber node
927
934
  [fiber, fiber.alternate].forEach(fiber => {
928
935
  if (fiber !== null) {
929
936
  fiber.stateNode = newInstance;
@@ -985,7 +992,17 @@ function createRenderer(roots) {
985
992
  if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
986
993
 
987
994
  const diff = diffProps(instance, restNew, restOld, true);
988
- if (diff.changes.length) return [false, diff]; // Otherwise do not touch the instance
995
+ if (diff.changes.length) return [false, diff]; // If instance was never attached, attach it
996
+
997
+ if (instance.attach && typeof instance.attach !== 'function') {
998
+ const localState = instance.__r3f;
999
+ const parent = localState.parent;
1000
+
1001
+ if (parent && parent[instance.attach] !== instance) {
1002
+ appendChild(parent, instance);
1003
+ }
1004
+ } // Otherwise do not touch the instance
1005
+
989
1006
 
990
1007
  return null;
991
1008
  }
@@ -1322,8 +1339,6 @@ const createStore = (applyProps, invalidate, advance, props) => {
1322
1339
  // https://github.com/pmndrs/react-three-fiber/issues/92
1323
1340
  // Do not mess with the camera if it belongs to the user
1324
1341
  if (!camera.manual && !(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1325
- console.log('update camera');
1326
-
1327
1342
  if (isOrthographicCamera(camera)) {
1328
1343
  camera.left = size.width / -2;
1329
1344
  camera.right = size.width / 2;
@@ -74,7 +74,8 @@ const is = {
74
74
  function makeId(event) {
75
75
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
76
76
  }
77
- /** Release pointer captures.
77
+ /**
78
+ * Release pointer captures.
78
79
  * This is called by releasePointerCapture in the API, and when an object is removed.
79
80
  */
80
81
 
@@ -113,7 +114,7 @@ function createEvents(store) {
113
114
  /** Sets up defaultRaycaster */
114
115
 
115
116
  function prepareRay(event) {
116
- var _raycaster$computeOff;
117
+ var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
117
118
 
118
119
  const state = store.getState();
119
120
  const {
@@ -124,14 +125,11 @@ function createEvents(store) {
124
125
  } = state; // https://github.com/pmndrs/react-three-fiber/pull/782
125
126
  // Events trigger outside of canvas when moved
126
127
 
127
- const {
128
- offsetX,
129
- offsetY
130
- } = (_raycaster$computeOff = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state)) != null ? _raycaster$computeOff : event;
131
- const {
132
- width,
133
- height
134
- } = size;
128
+ const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
129
+ const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
130
+ const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
131
+ const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
132
+ const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
135
133
  mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
136
134
  raycaster.setFromCamera(mouse, camera);
137
135
  }
@@ -361,13 +359,16 @@ function createEvents(store) {
361
359
 
362
360
  case 'onLostPointerCapture':
363
361
  return event => {
364
- if ('pointerId' in event) {
362
+ const {
363
+ internal
364
+ } = store.getState();
365
+
366
+ if ('pointerId' in event && !internal.capturedMap.has(event.pointerId)) {
365
367
  // If the object event interface had onLostPointerCapture, we'd call it here on every
366
368
  // object that's getting removed.
367
- store.getState().internal.capturedMap.delete(event.pointerId);
369
+ internal.capturedMap.delete(event.pointerId);
370
+ cancelPointer([]);
368
371
  }
369
-
370
- cancelPointer([]);
371
372
  };
372
373
  } // Any other pointer goes here ...
373
374
 
@@ -584,6 +585,8 @@ function createRenderer(roots) {
584
585
 
585
586
  if (instance.__r3f) instance.__r3f.memoizedProps = memoized;
586
587
  changes.forEach(([key, value, isEvent, keys]) => {
588
+ var _rootState$gl;
589
+
587
590
  let currentInstance = instance;
588
591
  let targetProp = currentInstance[key]; // Revolve dashed props
589
592
 
@@ -614,8 +617,9 @@ function createRenderer(roots) {
614
617
 
615
618
  if (defaultClassCall.dispose) defaultClassCall.dispose(); // instance does not have constructor, just set it to 0
616
619
  } else value = 0;
617
- } // Deal with pointer events ...
620
+ }
618
621
 
622
+ const isLinear = (rootState == null ? void 0 : (_rootState$gl = rootState.gl) == null ? void 0 : _rootState$gl.outputEncoding) === THREE__namespace.LinearEncoding; // Deal with pointer events ...
619
623
 
620
624
  if (isEvent) {
621
625
  if (value) localState.handlers[key] = value;else delete localState.handlers[key];
@@ -636,14 +640,14 @@ function createRenderer(roots) {
636
640
  else targetProp.set(value); // Auto-convert sRGB colors, for now ...
637
641
  // https://github.com/pmndrs/react-three-fiber/issues/344
638
642
 
639
- if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
643
+ if (!isLinear && isColor) targetProp.convertSRGBToLinear();
640
644
  } // Else, just overwrite the value
641
645
 
642
646
  } else {
643
647
  currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
644
648
  // https://github.com/pmndrs/react-three-fiber/issues/344
645
649
 
646
- if (!rootState.linear && currentInstance[key] instanceof THREE__namespace.Texture) currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
650
+ if (!isLinear && currentInstance[key] instanceof THREE__namespace.Texture) currentInstance[key].encoding = THREE__namespace.sRGBEncoding;
647
651
  }
648
652
 
649
653
  invalidateInstance(instance);
@@ -837,7 +841,7 @@ function createRenderer(roots) {
837
841
  parentInstance[child.attachArray] = parentInstance[child.attachArray].filter(x => x !== child);
838
842
  } else if (child.attachObject) {
839
843
  delete parentInstance[child.attachObject[0]][child.attachObject[1]];
840
- } else if (child.attach && !is.fun(child.attach)) {
844
+ } else if (child.attach && !is.fun(child.attach) && parentInstance[child.attach] === child) {
841
845
  parentInstance[child.attach] = null;
842
846
  } else if (is.arr(child.attachFns)) {
843
847
  const [, detachFn] = child.attachFns;
@@ -920,10 +924,13 @@ function createRenderer(roots) {
920
924
 
921
925
  instance.__r3f.objects = [];
922
926
  removeChild(parent, instance);
923
- appendChild(parent, newInstance) // This evil hack switches the react-internal fiber node
924
- // https://github.com/facebook/react/issues/14983
925
- // https://github.com/facebook/react/pull/15021
926
- ;
927
+ appendChild(parent, newInstance); // Re-bind event handlers
928
+
929
+ if (newInstance.raycast && newInstance.__r3f.eventCount) {
930
+ const rootState = newInstance.__r3f.root.getState();
931
+
932
+ rootState.internal.interaction.push(newInstance);
933
+ } // This evil hack switches the react-internal fiber node
927
934
  [fiber, fiber.alternate].forEach(fiber => {
928
935
  if (fiber !== null) {
929
936
  fiber.stateNode = newInstance;
@@ -985,7 +992,17 @@ function createRenderer(roots) {
985
992
  if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
986
993
 
987
994
  const diff = diffProps(instance, restNew, restOld, true);
988
- if (diff.changes.length) return [false, diff]; // Otherwise do not touch the instance
995
+ if (diff.changes.length) return [false, diff]; // If instance was never attached, attach it
996
+
997
+ if (instance.attach && typeof instance.attach !== 'function') {
998
+ const localState = instance.__r3f;
999
+ const parent = localState.parent;
1000
+
1001
+ if (parent && parent[instance.attach] !== instance) {
1002
+ appendChild(parent, instance);
1003
+ }
1004
+ } // Otherwise do not touch the instance
1005
+
989
1006
 
990
1007
  return null;
991
1008
  }
@@ -1322,8 +1339,6 @@ const createStore = (applyProps, invalidate, advance, props) => {
1322
1339
  // https://github.com/pmndrs/react-three-fiber/issues/92
1323
1340
  // Do not mess with the camera if it belongs to the user
1324
1341
  if (!camera.manual && !(internal.lastProps.camera instanceof THREE__namespace.Camera)) {
1325
- console.log('update camera');
1326
-
1327
1342
  if (isOrthographicCamera(camera)) {
1328
1343
  camera.left = size.width / -2;
1329
1344
  camera.right = size.width / 2;
@@ -41,7 +41,8 @@ const is = {
41
41
  function makeId(event) {
42
42
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
43
43
  }
44
- /** Release pointer captures.
44
+ /**
45
+ * Release pointer captures.
45
46
  * This is called by releasePointerCapture in the API, and when an object is removed.
46
47
  */
47
48
 
@@ -80,7 +81,7 @@ function createEvents(store) {
80
81
  /** Sets up defaultRaycaster */
81
82
 
82
83
  function prepareRay(event) {
83
- var _raycaster$computeOff;
84
+ var _customOffsets$offset, _customOffsets$offset2, _customOffsets$width, _customOffsets$height;
84
85
 
85
86
  const state = store.getState();
86
87
  const {
@@ -91,14 +92,11 @@ function createEvents(store) {
91
92
  } = state; // https://github.com/pmndrs/react-three-fiber/pull/782
92
93
  // Events trigger outside of canvas when moved
93
94
 
94
- const {
95
- offsetX,
96
- offsetY
97
- } = (_raycaster$computeOff = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state)) != null ? _raycaster$computeOff : event;
98
- const {
99
- width,
100
- height
101
- } = size;
95
+ const customOffsets = raycaster.computeOffsets == null ? void 0 : raycaster.computeOffsets(event, state);
96
+ const offsetX = (_customOffsets$offset = customOffsets == null ? void 0 : customOffsets.offsetX) != null ? _customOffsets$offset : event.offsetX;
97
+ const offsetY = (_customOffsets$offset2 = customOffsets == null ? void 0 : customOffsets.offsetY) != null ? _customOffsets$offset2 : event.offsetY;
98
+ const width = (_customOffsets$width = customOffsets == null ? void 0 : customOffsets.width) != null ? _customOffsets$width : size.width;
99
+ const height = (_customOffsets$height = customOffsets == null ? void 0 : customOffsets.height) != null ? _customOffsets$height : size.height;
102
100
  mouse.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
103
101
  raycaster.setFromCamera(mouse, camera);
104
102
  }
@@ -328,13 +326,16 @@ function createEvents(store) {
328
326
 
329
327
  case 'onLostPointerCapture':
330
328
  return event => {
331
- if ('pointerId' in event) {
329
+ const {
330
+ internal
331
+ } = store.getState();
332
+
333
+ if ('pointerId' in event && !internal.capturedMap.has(event.pointerId)) {
332
334
  // If the object event interface had onLostPointerCapture, we'd call it here on every
333
335
  // object that's getting removed.
334
- store.getState().internal.capturedMap.delete(event.pointerId);
336
+ internal.capturedMap.delete(event.pointerId);
337
+ cancelPointer([]);
335
338
  }
336
-
337
- cancelPointer([]);
338
339
  };
339
340
  } // Any other pointer goes here ...
340
341
 
@@ -551,6 +552,8 @@ function createRenderer(roots) {
551
552
 
552
553
  if (instance.__r3f) instance.__r3f.memoizedProps = memoized;
553
554
  changes.forEach(([key, value, isEvent, keys]) => {
555
+ var _rootState$gl;
556
+
554
557
  let currentInstance = instance;
555
558
  let targetProp = currentInstance[key]; // Revolve dashed props
556
559
 
@@ -581,8 +584,9 @@ function createRenderer(roots) {
581
584
 
582
585
  if (defaultClassCall.dispose) defaultClassCall.dispose(); // instance does not have constructor, just set it to 0
583
586
  } else value = 0;
584
- } // Deal with pointer events ...
587
+ }
585
588
 
589
+ const isLinear = (rootState == null ? void 0 : (_rootState$gl = rootState.gl) == null ? void 0 : _rootState$gl.outputEncoding) === THREE.LinearEncoding; // Deal with pointer events ...
586
590
 
587
591
  if (isEvent) {
588
592
  if (value) localState.handlers[key] = value;else delete localState.handlers[key];
@@ -603,14 +607,14 @@ function createRenderer(roots) {
603
607
  else targetProp.set(value); // Auto-convert sRGB colors, for now ...
604
608
  // https://github.com/pmndrs/react-three-fiber/issues/344
605
609
 
606
- if (!rootState.linear && isColor) targetProp.convertSRGBToLinear();
610
+ if (!isLinear && isColor) targetProp.convertSRGBToLinear();
607
611
  } // Else, just overwrite the value
608
612
 
609
613
  } else {
610
614
  currentInstance[key] = value; // Auto-convert sRGB textures, for now ...
611
615
  // https://github.com/pmndrs/react-three-fiber/issues/344
612
616
 
613
- if (!rootState.linear && currentInstance[key] instanceof THREE.Texture) currentInstance[key].encoding = THREE.sRGBEncoding;
617
+ if (!isLinear && currentInstance[key] instanceof THREE.Texture) currentInstance[key].encoding = THREE.sRGBEncoding;
614
618
  }
615
619
 
616
620
  invalidateInstance(instance);
@@ -804,7 +808,7 @@ function createRenderer(roots) {
804
808
  parentInstance[child.attachArray] = parentInstance[child.attachArray].filter(x => x !== child);
805
809
  } else if (child.attachObject) {
806
810
  delete parentInstance[child.attachObject[0]][child.attachObject[1]];
807
- } else if (child.attach && !is.fun(child.attach)) {
811
+ } else if (child.attach && !is.fun(child.attach) && parentInstance[child.attach] === child) {
808
812
  parentInstance[child.attach] = null;
809
813
  } else if (is.arr(child.attachFns)) {
810
814
  const [, detachFn] = child.attachFns;
@@ -887,10 +891,13 @@ function createRenderer(roots) {
887
891
 
888
892
  instance.__r3f.objects = [];
889
893
  removeChild(parent, instance);
890
- appendChild(parent, newInstance) // This evil hack switches the react-internal fiber node
891
- // https://github.com/facebook/react/issues/14983
892
- // https://github.com/facebook/react/pull/15021
893
- ;
894
+ appendChild(parent, newInstance); // Re-bind event handlers
895
+
896
+ if (newInstance.raycast && newInstance.__r3f.eventCount) {
897
+ const rootState = newInstance.__r3f.root.getState();
898
+
899
+ rootState.internal.interaction.push(newInstance);
900
+ } // This evil hack switches the react-internal fiber node
894
901
  [fiber, fiber.alternate].forEach(fiber => {
895
902
  if (fiber !== null) {
896
903
  fiber.stateNode = newInstance;
@@ -952,7 +959,17 @@ function createRenderer(roots) {
952
959
  if (argsNew.some((value, index) => value !== argsOld[index])) return [true]; // Create a diff-set, flag if there are any changes
953
960
 
954
961
  const diff = diffProps(instance, restNew, restOld, true);
955
- if (diff.changes.length) return [false, diff]; // Otherwise do not touch the instance
962
+ if (diff.changes.length) return [false, diff]; // If instance was never attached, attach it
963
+
964
+ if (instance.attach && typeof instance.attach !== 'function') {
965
+ const localState = instance.__r3f;
966
+ const parent = localState.parent;
967
+
968
+ if (parent && parent[instance.attach] !== instance) {
969
+ appendChild(parent, instance);
970
+ }
971
+ } // Otherwise do not touch the instance
972
+
956
973
 
957
974
  return null;
958
975
  }
@@ -1289,8 +1306,6 @@ const createStore = (applyProps, invalidate, advance, props) => {
1289
1306
  // https://github.com/pmndrs/react-three-fiber/issues/92
1290
1307
  // Do not mess with the camera if it belongs to the user
1291
1308
  if (!camera.manual && !(internal.lastProps.camera instanceof THREE.Camera)) {
1292
- console.log('update camera');
1293
-
1294
1309
  if (isOrthographicCamera(camera)) {
1295
1310
  camera.left = size.width / -2;
1296
1311
  camera.right = size.width / 2;