@react-three/fiber 8.0.21 → 8.0.24

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,23 @@
1
1
  # @react-three/fiber
2
2
 
3
+ ## 8.0.24
4
+
5
+ ### Patch Changes
6
+
7
+ - ee8e785: fix: attach timings
8
+
9
+ ## 8.0.23
10
+
11
+ ### Patch Changes
12
+
13
+ - 29d03c64: revert multi attach
14
+
15
+ ## 8.0.22
16
+
17
+ ### Patch Changes
18
+
19
+ - 419e854: fix: always prepare primitives
20
+
3
21
  ## 8.0.21
4
22
 
5
23
  ### Patch Changes
@@ -1,5 +1,6 @@
1
1
  import * as THREE from 'three';
2
2
  import { StateSelector, EqualityChecker } from 'zustand';
3
+ import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
3
4
  import { RootState, RenderCallback } from './store';
4
5
  import { ObjectMap } from './utils';
5
6
  export interface Loader<T> extends THREE.Loader {
@@ -13,12 +14,8 @@ export declare function useStore(): import("zustand").UseBoundStore<RootState, i
13
14
  export declare function useThree<T = RootState>(selector?: StateSelector<RootState, T>, equalityFn?: EqualityChecker<T>): T;
14
15
  export declare function useFrame(callback: RenderCallback, renderPriority?: number): null;
15
16
  export declare function useGraph(object: THREE.Object3D): ObjectMap;
16
- interface GLTFLike {
17
- scene: THREE.Object3D;
18
- }
19
- export declare function useLoader<T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U, extensions?: Extensions, onProgress?: (event: ProgressEvent<EventTarget>) => void): U extends any[] ? BranchingReturn<T, GLTFLike, GLTFLike & ObjectMap>[] : BranchingReturn<T, GLTFLike, GLTFLike & ObjectMap>;
17
+ export declare function useLoader<T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U, extensions?: Extensions, onProgress?: (event: ProgressEvent<EventTarget>) => void): U extends any[] ? BranchingReturn<T, GLTF, GLTF & ObjectMap>[] : BranchingReturn<T, GLTF, GLTF & ObjectMap>;
20
18
  export declare namespace useLoader {
21
19
  var preload: <T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U, extensions?: Extensions | undefined) => undefined;
22
20
  var clear: <T, U extends string | string[]>(Proto: new () => LoaderResult<T>, input: U) => void;
23
21
  }
24
- export {};
@@ -12,7 +12,7 @@ export declare type LocalState = {
12
12
  type: string;
13
13
  root: UseBoundStore<RootState>;
14
14
  objects: Instance[];
15
- parents: Instance[];
15
+ parent: Instance | null;
16
16
  primitive?: boolean;
17
17
  eventCount: number;
18
18
  handlers: Partial<EventHandlers>;
@@ -164,7 +164,7 @@ function dispose(obj) {
164
164
  function prepare(object, state) {
165
165
  const instance = object;
166
166
 
167
- if (!instance.__r3f) {
167
+ if (state != null && state.primitive || !instance.__r3f) {
168
168
  instance.__r3f = {
169
169
  type: '',
170
170
  root: null,
@@ -173,7 +173,7 @@ function prepare(object, state) {
173
173
  eventCount: 0,
174
174
  handlers: {},
175
175
  objects: [],
176
- parents: [],
176
+ parent: null,
177
177
  ...state
178
178
  };
179
179
  }
@@ -287,7 +287,7 @@ function diffProps(instance, {
287
287
  } // This function applies a set of changes to the instance
288
288
 
289
289
  function applyProps$1(instance, data) {
290
- var _instance$__r3f3, _root$getState, _localState$parents;
290
+ var _instance$__r3f3, _root$getState;
291
291
 
292
292
  // Filter equals, events and reserved props
293
293
  const localState = (_instance$__r3f3 = instance.__r3f) != null ? _instance$__r3f3 : {};
@@ -378,7 +378,7 @@ function applyProps$1(instance, data) {
378
378
  invalidateInstance(instance);
379
379
  });
380
380
 
381
- if ((_localState$parents = localState.parents) != null && _localState$parents.length && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
381
+ if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
382
382
  // Pre-emptively remove the instance from the interaction manager
383
383
  const index = rootState.internal.interaction.indexOf(instance);
384
384
  if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
@@ -913,9 +913,10 @@ function createRenderer(roots, getEventPriority) {
913
913
  if (child) {
914
914
  var _child$__r3f, _parentInstance$__r3f;
915
915
 
916
- // The attach attribute implies that the object attaches itself on the parent.
917
- // That is handled at commit to avoid duplication during Suspense
918
- if (!((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) && child.isObject3D && parentInstance.isObject3D) {
916
+ // The attach attribute implies that the object attaches itself on the parent
917
+ if ((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) {
918
+ attach(parentInstance, child, child.__r3f.attach);
919
+ } else if (child.isObject3D && parentInstance.isObject3D) {
919
920
  // add in the usual parent-child way
920
921
  parentInstance.add(child);
921
922
  added = true;
@@ -925,9 +926,7 @@ function createRenderer(roots, getEventPriority) {
925
926
 
926
927
  if (!added) (_parentInstance$__r3f = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f.objects.push(child);
927
928
  if (!child.__r3f) prepare(child, {});
928
-
929
- child.__r3f.parents.push(parentInstance);
930
-
929
+ child.__r3f.parent = parentInstance;
931
930
  updateInstance(child);
932
931
  invalidateInstance(child);
933
932
  }
@@ -939,7 +938,9 @@ function createRenderer(roots, getEventPriority) {
939
938
  if (child) {
940
939
  var _child$__r3f2, _parentInstance$__r3f2;
941
940
 
942
- if (!((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) && child.isObject3D && parentInstance.isObject3D) {
941
+ if ((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) {
942
+ attach(parentInstance, child, child.__r3f.attach);
943
+ } else if (child.isObject3D && parentInstance.isObject3D) {
943
944
  child.parent = parentInstance;
944
945
  child.dispatchEvent({
945
946
  type: 'added'
@@ -952,9 +953,7 @@ function createRenderer(roots, getEventPriority) {
952
953
 
953
954
  if (!added) (_parentInstance$__r3f2 = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f2.objects.push(child);
954
955
  if (!child.__r3f) prepare(child, {});
955
-
956
- child.__r3f.parents.push(parentInstance);
957
-
956
+ child.__r3f.parent = parentInstance;
958
957
  updateInstance(child);
959
958
  invalidateInstance(child);
960
959
  }
@@ -969,7 +968,7 @@ function createRenderer(roots, getEventPriority) {
969
968
  var _parentInstance$__r3f3, _child$__r3f3, _child$__r3f5;
970
969
 
971
970
  // Clear the parent reference
972
- if (child.__r3f) child.__r3f.parents = child.__r3f.parents.filter(parent => parent !== parentInstance); // Remove child from the parents objects
971
+ if (child.__r3f) child.__r3f.parent = null; // Remove child from the parents objects
973
972
 
974
973
  if ((_parentInstance$__r3f3 = parentInstance.__r3f) != null && _parentInstance$__r3f3.objects) parentInstance.__r3f.objects = parentInstance.__r3f.objects.filter(x => x !== child); // Remove attachment
975
974
 
@@ -1030,10 +1029,10 @@ function createRenderer(roots, getEventPriority) {
1030
1029
  }
1031
1030
 
1032
1031
  function switchInstance(instance, type, newProps, fiber) {
1033
- var _instance$__r3f, _newInstance$__r3f;
1032
+ var _instance$__r3f;
1034
1033
 
1035
- const parents = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parents;
1036
- if (!(parents != null && parents.length)) return;
1034
+ const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
1035
+ if (!parent) return;
1037
1036
  const newInstance = createInstance(type, newProps, instance.__r3f.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
1038
1037
  // When args change the instance has to be re-constructed, which then
1039
1038
  // forces r3f to re-parent the children and non-scene objects
@@ -1042,34 +1041,18 @@ function createRenderer(roots, getEventPriority) {
1042
1041
  if (type !== 'primitive' && instance.children) {
1043
1042
  instance.children.forEach(child => appendChild(newInstance, child));
1044
1043
  instance.children = [];
1045
- } // Copy over child attachments
1046
-
1047
-
1048
- for (const child of instance.__r3f.objects) {
1049
- appendChild(newInstance, child);
1050
- detach(instance, child, child.__r3f.attach);
1051
- attach(newInstance, child, child.__r3f.attach);
1052
1044
  }
1053
1045
 
1054
- instance.__r3f.objects = [];
1055
-
1056
- for (const parent of parents) {
1057
- removeChild(parent, instance);
1058
- appendChild(parent, newInstance);
1059
- } // Re-bind event handlers
1046
+ instance.__r3f.objects.forEach(child => appendChild(newInstance, child));
1060
1047
 
1048
+ instance.__r3f.objects = [];
1049
+ removeChild(parent, instance);
1050
+ appendChild(parent, newInstance); // Re-bind event handlers
1061
1051
 
1062
1052
  if (newInstance.raycast && newInstance.__r3f.eventCount) {
1063
1053
  const rootState = newInstance.__r3f.root.getState();
1064
1054
 
1065
1055
  rootState.internal.interaction.push(newInstance);
1066
- } // Attach instance to parent
1067
-
1068
-
1069
- if ((_newInstance$__r3f = newInstance.__r3f) != null && _newInstance$__r3f.attach) {
1070
- for (const parent of parents) {
1071
- attach(parent, newInstance, newInstance.__r3f.attach);
1072
- }
1073
1056
  } // This evil hack switches the react-internal fiber node
1074
1057
  [fiber, fiber.alternate].forEach(fiber => {
1075
1058
  if (fiber !== null) {
@@ -1110,7 +1093,7 @@ function createRenderer(roots, getEventPriority) {
1110
1093
  const localState = (_instance$__r3f2 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f2 : {}; // https://github.com/facebook/react/issues/20271
1111
1094
  // Returning true will trigger commitMount
1112
1095
 
1113
- return !!localState.handlers || !!localState.attach;
1096
+ return !!localState.handlers;
1114
1097
  },
1115
1098
 
1116
1099
  prepareUpdate(instance, type, oldProps, newProps) {
@@ -1156,13 +1139,6 @@ function createRenderer(roots, getEventPriority) {
1156
1139
 
1157
1140
  if (instance.raycast && localState.handlers && localState.eventCount) {
1158
1141
  instance.__r3f.root.getState().internal.interaction.push(instance);
1159
- } // The attach attribute implies that the object attaches itself on the parent
1160
-
1161
-
1162
- if (localState.attach) {
1163
- for (const parent of localState.parents) {
1164
- attach(parent, instance, localState.attach);
1165
- }
1166
1142
  }
1167
1143
  },
1168
1144
 
@@ -1176,11 +1152,27 @@ function createRenderer(roots, getEventPriority) {
1176
1152
  detachDeletedInstance: () => {},
1177
1153
 
1178
1154
  hideInstance(instance) {
1155
+ var _instance$__r3f4;
1156
+
1157
+ // Deatch while the instance is hidden
1158
+ const {
1159
+ attach: type,
1160
+ parent
1161
+ } = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
1162
+ if (type && parent) detach(parent, instance, type);
1179
1163
  if (instance.isObject3D) instance.visible = false;
1180
1164
  invalidateInstance(instance);
1181
1165
  },
1182
1166
 
1183
1167
  unhideInstance(instance, props) {
1168
+ var _instance$__r3f5;
1169
+
1170
+ // Re-attach when the instance is unhidden
1171
+ const {
1172
+ attach: type,
1173
+ parent
1174
+ } = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
1175
+ if (type && parent) attach(parent, instance, type);
1184
1176
  if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
1185
1177
  invalidateInstance(instance);
1186
1178
  },
@@ -1605,13 +1597,14 @@ function loadingFn(extensions, onProgress) {
1605
1597
  }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1606
1598
  };
1607
1599
  }
1608
-
1609
1600
  /**
1610
1601
  * Synchronously loads and caches assets with a three loader.
1611
1602
  *
1612
1603
  * Note: this hook's caller must be wrapped with `React.Suspense`
1613
1604
  * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1614
1605
  */
1606
+
1607
+
1615
1608
  function useLoader(Proto, input, extensions, onProgress) {
1616
1609
  // Use suspense to load async assets
1617
1610
  const keys = Array.isArray(input) ? input : [input];
@@ -137,7 +137,7 @@ function dispose(obj) {
137
137
  function prepare(object, state) {
138
138
  const instance = object;
139
139
 
140
- if (!instance.__r3f) {
140
+ if (state != null && state.primitive || !instance.__r3f) {
141
141
  instance.__r3f = {
142
142
  type: '',
143
143
  root: null,
@@ -146,7 +146,7 @@ function prepare(object, state) {
146
146
  eventCount: 0,
147
147
  handlers: {},
148
148
  objects: [],
149
- parents: [],
149
+ parent: null,
150
150
  ...state
151
151
  };
152
152
  }
@@ -260,7 +260,7 @@ function diffProps(instance, {
260
260
  } // This function applies a set of changes to the instance
261
261
 
262
262
  function applyProps$1(instance, data) {
263
- var _instance$__r3f3, _root$getState, _localState$parents;
263
+ var _instance$__r3f3, _root$getState;
264
264
 
265
265
  // Filter equals, events and reserved props
266
266
  const localState = (_instance$__r3f3 = instance.__r3f) != null ? _instance$__r3f3 : {};
@@ -351,7 +351,7 @@ function applyProps$1(instance, data) {
351
351
  invalidateInstance(instance);
352
352
  });
353
353
 
354
- if ((_localState$parents = localState.parents) != null && _localState$parents.length && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
354
+ if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
355
355
  // Pre-emptively remove the instance from the interaction manager
356
356
  const index = rootState.internal.interaction.indexOf(instance);
357
357
  if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
@@ -886,9 +886,10 @@ function createRenderer(roots, getEventPriority) {
886
886
  if (child) {
887
887
  var _child$__r3f, _parentInstance$__r3f;
888
888
 
889
- // The attach attribute implies that the object attaches itself on the parent.
890
- // That is handled at commit to avoid duplication during Suspense
891
- if (!((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) && child.isObject3D && parentInstance.isObject3D) {
889
+ // The attach attribute implies that the object attaches itself on the parent
890
+ if ((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) {
891
+ attach(parentInstance, child, child.__r3f.attach);
892
+ } else if (child.isObject3D && parentInstance.isObject3D) {
892
893
  // add in the usual parent-child way
893
894
  parentInstance.add(child);
894
895
  added = true;
@@ -898,9 +899,7 @@ function createRenderer(roots, getEventPriority) {
898
899
 
899
900
  if (!added) (_parentInstance$__r3f = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f.objects.push(child);
900
901
  if (!child.__r3f) prepare(child, {});
901
-
902
- child.__r3f.parents.push(parentInstance);
903
-
902
+ child.__r3f.parent = parentInstance;
904
903
  updateInstance(child);
905
904
  invalidateInstance(child);
906
905
  }
@@ -912,7 +911,9 @@ function createRenderer(roots, getEventPriority) {
912
911
  if (child) {
913
912
  var _child$__r3f2, _parentInstance$__r3f2;
914
913
 
915
- if (!((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) && child.isObject3D && parentInstance.isObject3D) {
914
+ if ((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) {
915
+ attach(parentInstance, child, child.__r3f.attach);
916
+ } else if (child.isObject3D && parentInstance.isObject3D) {
916
917
  child.parent = parentInstance;
917
918
  child.dispatchEvent({
918
919
  type: 'added'
@@ -925,9 +926,7 @@ function createRenderer(roots, getEventPriority) {
925
926
 
926
927
  if (!added) (_parentInstance$__r3f2 = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f2.objects.push(child);
927
928
  if (!child.__r3f) prepare(child, {});
928
-
929
- child.__r3f.parents.push(parentInstance);
930
-
929
+ child.__r3f.parent = parentInstance;
931
930
  updateInstance(child);
932
931
  invalidateInstance(child);
933
932
  }
@@ -942,7 +941,7 @@ function createRenderer(roots, getEventPriority) {
942
941
  var _parentInstance$__r3f3, _child$__r3f3, _child$__r3f5;
943
942
 
944
943
  // Clear the parent reference
945
- if (child.__r3f) child.__r3f.parents = child.__r3f.parents.filter(parent => parent !== parentInstance); // Remove child from the parents objects
944
+ if (child.__r3f) child.__r3f.parent = null; // Remove child from the parents objects
946
945
 
947
946
  if ((_parentInstance$__r3f3 = parentInstance.__r3f) != null && _parentInstance$__r3f3.objects) parentInstance.__r3f.objects = parentInstance.__r3f.objects.filter(x => x !== child); // Remove attachment
948
947
 
@@ -1003,10 +1002,10 @@ function createRenderer(roots, getEventPriority) {
1003
1002
  }
1004
1003
 
1005
1004
  function switchInstance(instance, type, newProps, fiber) {
1006
- var _instance$__r3f, _newInstance$__r3f;
1005
+ var _instance$__r3f;
1007
1006
 
1008
- const parents = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parents;
1009
- if (!(parents != null && parents.length)) return;
1007
+ const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
1008
+ if (!parent) return;
1010
1009
  const newInstance = createInstance(type, newProps, instance.__r3f.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
1011
1010
  // When args change the instance has to be re-constructed, which then
1012
1011
  // forces r3f to re-parent the children and non-scene objects
@@ -1015,34 +1014,18 @@ function createRenderer(roots, getEventPriority) {
1015
1014
  if (type !== 'primitive' && instance.children) {
1016
1015
  instance.children.forEach(child => appendChild(newInstance, child));
1017
1016
  instance.children = [];
1018
- } // Copy over child attachments
1019
-
1020
-
1021
- for (const child of instance.__r3f.objects) {
1022
- appendChild(newInstance, child);
1023
- detach(instance, child, child.__r3f.attach);
1024
- attach(newInstance, child, child.__r3f.attach);
1025
1017
  }
1026
1018
 
1027
- instance.__r3f.objects = [];
1028
-
1029
- for (const parent of parents) {
1030
- removeChild(parent, instance);
1031
- appendChild(parent, newInstance);
1032
- } // Re-bind event handlers
1019
+ instance.__r3f.objects.forEach(child => appendChild(newInstance, child));
1033
1020
 
1021
+ instance.__r3f.objects = [];
1022
+ removeChild(parent, instance);
1023
+ appendChild(parent, newInstance); // Re-bind event handlers
1034
1024
 
1035
1025
  if (newInstance.raycast && newInstance.__r3f.eventCount) {
1036
1026
  const rootState = newInstance.__r3f.root.getState();
1037
1027
 
1038
1028
  rootState.internal.interaction.push(newInstance);
1039
- } // Attach instance to parent
1040
-
1041
-
1042
- if ((_newInstance$__r3f = newInstance.__r3f) != null && _newInstance$__r3f.attach) {
1043
- for (const parent of parents) {
1044
- attach(parent, newInstance, newInstance.__r3f.attach);
1045
- }
1046
1029
  } // This evil hack switches the react-internal fiber node
1047
1030
  [fiber, fiber.alternate].forEach(fiber => {
1048
1031
  if (fiber !== null) {
@@ -1083,7 +1066,7 @@ function createRenderer(roots, getEventPriority) {
1083
1066
  const localState = (_instance$__r3f2 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f2 : {}; // https://github.com/facebook/react/issues/20271
1084
1067
  // Returning true will trigger commitMount
1085
1068
 
1086
- return !!localState.handlers || !!localState.attach;
1069
+ return !!localState.handlers;
1087
1070
  },
1088
1071
 
1089
1072
  prepareUpdate(instance, type, oldProps, newProps) {
@@ -1129,13 +1112,6 @@ function createRenderer(roots, getEventPriority) {
1129
1112
 
1130
1113
  if (instance.raycast && localState.handlers && localState.eventCount) {
1131
1114
  instance.__r3f.root.getState().internal.interaction.push(instance);
1132
- } // The attach attribute implies that the object attaches itself on the parent
1133
-
1134
-
1135
- if (localState.attach) {
1136
- for (const parent of localState.parents) {
1137
- attach(parent, instance, localState.attach);
1138
- }
1139
1115
  }
1140
1116
  },
1141
1117
 
@@ -1149,11 +1125,27 @@ function createRenderer(roots, getEventPriority) {
1149
1125
  detachDeletedInstance: () => {},
1150
1126
 
1151
1127
  hideInstance(instance) {
1128
+ var _instance$__r3f4;
1129
+
1130
+ // Deatch while the instance is hidden
1131
+ const {
1132
+ attach: type,
1133
+ parent
1134
+ } = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
1135
+ if (type && parent) detach(parent, instance, type);
1152
1136
  if (instance.isObject3D) instance.visible = false;
1153
1137
  invalidateInstance(instance);
1154
1138
  },
1155
1139
 
1156
1140
  unhideInstance(instance, props) {
1141
+ var _instance$__r3f5;
1142
+
1143
+ // Re-attach when the instance is unhidden
1144
+ const {
1145
+ attach: type,
1146
+ parent
1147
+ } = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
1148
+ if (type && parent) attach(parent, instance, type);
1157
1149
  if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
1158
1150
  invalidateInstance(instance);
1159
1151
  },
@@ -1578,13 +1570,14 @@ function loadingFn(extensions, onProgress) {
1578
1570
  }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1579
1571
  };
1580
1572
  }
1581
-
1582
1573
  /**
1583
1574
  * Synchronously loads and caches assets with a three loader.
1584
1575
  *
1585
1576
  * Note: this hook's caller must be wrapped with `React.Suspense`
1586
1577
  * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1587
1578
  */
1579
+
1580
+
1588
1581
  function useLoader(Proto, input, extensions, onProgress) {
1589
1582
  // Use suspense to load async assets
1590
1583
  const keys = Array.isArray(input) ? input : [input];
@@ -164,7 +164,7 @@ function dispose(obj) {
164
164
  function prepare(object, state) {
165
165
  const instance = object;
166
166
 
167
- if (!instance.__r3f) {
167
+ if (state != null && state.primitive || !instance.__r3f) {
168
168
  instance.__r3f = {
169
169
  type: '',
170
170
  root: null,
@@ -173,7 +173,7 @@ function prepare(object, state) {
173
173
  eventCount: 0,
174
174
  handlers: {},
175
175
  objects: [],
176
- parents: [],
176
+ parent: null,
177
177
  ...state
178
178
  };
179
179
  }
@@ -287,7 +287,7 @@ function diffProps(instance, {
287
287
  } // This function applies a set of changes to the instance
288
288
 
289
289
  function applyProps$1(instance, data) {
290
- var _instance$__r3f3, _root$getState, _localState$parents;
290
+ var _instance$__r3f3, _root$getState;
291
291
 
292
292
  // Filter equals, events and reserved props
293
293
  const localState = (_instance$__r3f3 = instance.__r3f) != null ? _instance$__r3f3 : {};
@@ -378,7 +378,7 @@ function applyProps$1(instance, data) {
378
378
  invalidateInstance(instance);
379
379
  });
380
380
 
381
- if ((_localState$parents = localState.parents) != null && _localState$parents.length && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
381
+ if (localState.parent && rootState.internal && instance.raycast && prevHandlers !== localState.eventCount) {
382
382
  // Pre-emptively remove the instance from the interaction manager
383
383
  const index = rootState.internal.interaction.indexOf(instance);
384
384
  if (index > -1) rootState.internal.interaction.splice(index, 1); // Add the instance to the interaction manager only when it has handlers
@@ -913,9 +913,10 @@ function createRenderer(roots, getEventPriority) {
913
913
  if (child) {
914
914
  var _child$__r3f, _parentInstance$__r3f;
915
915
 
916
- // The attach attribute implies that the object attaches itself on the parent.
917
- // That is handled at commit to avoid duplication during Suspense
918
- if (!((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) && child.isObject3D && parentInstance.isObject3D) {
916
+ // The attach attribute implies that the object attaches itself on the parent
917
+ if ((_child$__r3f = child.__r3f) != null && _child$__r3f.attach) {
918
+ attach(parentInstance, child, child.__r3f.attach);
919
+ } else if (child.isObject3D && parentInstance.isObject3D) {
919
920
  // add in the usual parent-child way
920
921
  parentInstance.add(child);
921
922
  added = true;
@@ -925,9 +926,7 @@ function createRenderer(roots, getEventPriority) {
925
926
 
926
927
  if (!added) (_parentInstance$__r3f = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f.objects.push(child);
927
928
  if (!child.__r3f) prepare(child, {});
928
-
929
- child.__r3f.parents.push(parentInstance);
930
-
929
+ child.__r3f.parent = parentInstance;
931
930
  updateInstance(child);
932
931
  invalidateInstance(child);
933
932
  }
@@ -939,7 +938,9 @@ function createRenderer(roots, getEventPriority) {
939
938
  if (child) {
940
939
  var _child$__r3f2, _parentInstance$__r3f2;
941
940
 
942
- if (!((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) && child.isObject3D && parentInstance.isObject3D) {
941
+ if ((_child$__r3f2 = child.__r3f) != null && _child$__r3f2.attach) {
942
+ attach(parentInstance, child, child.__r3f.attach);
943
+ } else if (child.isObject3D && parentInstance.isObject3D) {
943
944
  child.parent = parentInstance;
944
945
  child.dispatchEvent({
945
946
  type: 'added'
@@ -952,9 +953,7 @@ function createRenderer(roots, getEventPriority) {
952
953
 
953
954
  if (!added) (_parentInstance$__r3f2 = parentInstance.__r3f) == null ? void 0 : _parentInstance$__r3f2.objects.push(child);
954
955
  if (!child.__r3f) prepare(child, {});
955
-
956
- child.__r3f.parents.push(parentInstance);
957
-
956
+ child.__r3f.parent = parentInstance;
958
957
  updateInstance(child);
959
958
  invalidateInstance(child);
960
959
  }
@@ -969,7 +968,7 @@ function createRenderer(roots, getEventPriority) {
969
968
  var _parentInstance$__r3f3, _child$__r3f3, _child$__r3f5;
970
969
 
971
970
  // Clear the parent reference
972
- if (child.__r3f) child.__r3f.parents = child.__r3f.parents.filter(parent => parent !== parentInstance); // Remove child from the parents objects
971
+ if (child.__r3f) child.__r3f.parent = null; // Remove child from the parents objects
973
972
 
974
973
  if ((_parentInstance$__r3f3 = parentInstance.__r3f) != null && _parentInstance$__r3f3.objects) parentInstance.__r3f.objects = parentInstance.__r3f.objects.filter(x => x !== child); // Remove attachment
975
974
 
@@ -1030,10 +1029,10 @@ function createRenderer(roots, getEventPriority) {
1030
1029
  }
1031
1030
 
1032
1031
  function switchInstance(instance, type, newProps, fiber) {
1033
- var _instance$__r3f, _newInstance$__r3f;
1032
+ var _instance$__r3f;
1034
1033
 
1035
- const parents = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parents;
1036
- if (!(parents != null && parents.length)) return;
1034
+ const parent = (_instance$__r3f = instance.__r3f) == null ? void 0 : _instance$__r3f.parent;
1035
+ if (!parent) return;
1037
1036
  const newInstance = createInstance(type, newProps, instance.__r3f.root); // https://github.com/pmndrs/react-three-fiber/issues/1348
1038
1037
  // When args change the instance has to be re-constructed, which then
1039
1038
  // forces r3f to re-parent the children and non-scene objects
@@ -1042,34 +1041,18 @@ function createRenderer(roots, getEventPriority) {
1042
1041
  if (type !== 'primitive' && instance.children) {
1043
1042
  instance.children.forEach(child => appendChild(newInstance, child));
1044
1043
  instance.children = [];
1045
- } // Copy over child attachments
1046
-
1047
-
1048
- for (const child of instance.__r3f.objects) {
1049
- appendChild(newInstance, child);
1050
- detach(instance, child, child.__r3f.attach);
1051
- attach(newInstance, child, child.__r3f.attach);
1052
1044
  }
1053
1045
 
1054
- instance.__r3f.objects = [];
1055
-
1056
- for (const parent of parents) {
1057
- removeChild(parent, instance);
1058
- appendChild(parent, newInstance);
1059
- } // Re-bind event handlers
1046
+ instance.__r3f.objects.forEach(child => appendChild(newInstance, child));
1060
1047
 
1048
+ instance.__r3f.objects = [];
1049
+ removeChild(parent, instance);
1050
+ appendChild(parent, newInstance); // Re-bind event handlers
1061
1051
 
1062
1052
  if (newInstance.raycast && newInstance.__r3f.eventCount) {
1063
1053
  const rootState = newInstance.__r3f.root.getState();
1064
1054
 
1065
1055
  rootState.internal.interaction.push(newInstance);
1066
- } // Attach instance to parent
1067
-
1068
-
1069
- if ((_newInstance$__r3f = newInstance.__r3f) != null && _newInstance$__r3f.attach) {
1070
- for (const parent of parents) {
1071
- attach(parent, newInstance, newInstance.__r3f.attach);
1072
- }
1073
1056
  } // This evil hack switches the react-internal fiber node
1074
1057
  [fiber, fiber.alternate].forEach(fiber => {
1075
1058
  if (fiber !== null) {
@@ -1110,7 +1093,7 @@ function createRenderer(roots, getEventPriority) {
1110
1093
  const localState = (_instance$__r3f2 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f2 : {}; // https://github.com/facebook/react/issues/20271
1111
1094
  // Returning true will trigger commitMount
1112
1095
 
1113
- return !!localState.handlers || !!localState.attach;
1096
+ return !!localState.handlers;
1114
1097
  },
1115
1098
 
1116
1099
  prepareUpdate(instance, type, oldProps, newProps) {
@@ -1156,13 +1139,6 @@ function createRenderer(roots, getEventPriority) {
1156
1139
 
1157
1140
  if (instance.raycast && localState.handlers && localState.eventCount) {
1158
1141
  instance.__r3f.root.getState().internal.interaction.push(instance);
1159
- } // The attach attribute implies that the object attaches itself on the parent
1160
-
1161
-
1162
- if (localState.attach) {
1163
- for (const parent of localState.parents) {
1164
- attach(parent, instance, localState.attach);
1165
- }
1166
1142
  }
1167
1143
  },
1168
1144
 
@@ -1176,11 +1152,27 @@ function createRenderer(roots, getEventPriority) {
1176
1152
  detachDeletedInstance: () => {},
1177
1153
 
1178
1154
  hideInstance(instance) {
1155
+ var _instance$__r3f4;
1156
+
1157
+ // Deatch while the instance is hidden
1158
+ const {
1159
+ attach: type,
1160
+ parent
1161
+ } = (_instance$__r3f4 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f4 : {};
1162
+ if (type && parent) detach(parent, instance, type);
1179
1163
  if (instance.isObject3D) instance.visible = false;
1180
1164
  invalidateInstance(instance);
1181
1165
  },
1182
1166
 
1183
1167
  unhideInstance(instance, props) {
1168
+ var _instance$__r3f5;
1169
+
1170
+ // Re-attach when the instance is unhidden
1171
+ const {
1172
+ attach: type,
1173
+ parent
1174
+ } = (_instance$__r3f5 = instance == null ? void 0 : instance.__r3f) != null ? _instance$__r3f5 : {};
1175
+ if (type && parent) attach(parent, instance, type);
1184
1176
  if (instance.isObject3D && props.visible == null || props.visible) instance.visible = true;
1185
1177
  invalidateInstance(instance);
1186
1178
  },
@@ -1605,13 +1597,14 @@ function loadingFn(extensions, onProgress) {
1605
1597
  }, onProgress, error => reject(`Could not load ${input}: ${error.message}`)))));
1606
1598
  };
1607
1599
  }
1608
-
1609
1600
  /**
1610
1601
  * Synchronously loads and caches assets with a three loader.
1611
1602
  *
1612
1603
  * Note: this hook's caller must be wrapped with `React.Suspense`
1613
1604
  * @see https://docs.pmnd.rs/react-three-fiber/api/hooks#useloader
1614
1605
  */
1606
+
1607
+
1615
1608
  function useLoader(Proto, input, extensions, onProgress) {
1616
1609
  // Use suspense to load async assets
1617
1610
  const keys = Array.isArray(input) ? input : [input];
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-8e20caed.cjs.dev.js');
5
+ var index = require('./index-cc1b2b8b.cjs.dev.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-786a40b6.cjs.prod.js');
5
+ var index = require('./index-fbc2ae01.cjs.prod.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -1,5 +1,5 @@
1
- import { c as createEvents, e as extend, u as useMutableCallback, a as createRoot, E as ErrorBoundary, B as Block, b as useIsomorphicLayoutEffect, d as unmountComponentAtNode } from './index-30926efc.esm.js';
2
- export { t as ReactThreeFiber, s as _roots, q as act, n as addAfterEffect, m as addEffect, o as addTail, l as advance, i as applyProps, f as context, g as createPortal, a as createRoot, j as dispose, e as extend, p as getRootState, k as invalidate, h as reconciler, r as render, d as unmountComponentAtNode, x as useFrame, y as useGraph, z as useLoader, v as useStore, w as useThree } from './index-30926efc.esm.js';
1
+ import { c as createEvents, e as extend, u as useMutableCallback, a as createRoot, E as ErrorBoundary, B as Block, b as useIsomorphicLayoutEffect, d as unmountComponentAtNode } from './index-d1db558e.esm.js';
2
+ export { t as ReactThreeFiber, s as _roots, q as act, n as addAfterEffect, m as addEffect, o as addTail, l as advance, i as applyProps, f as context, g as createPortal, a as createRoot, j as dispose, e as extend, p as getRootState, k as invalidate, h as reconciler, r as render, d as unmountComponentAtNode, x as useFrame, y as useGraph, z as useLoader, v as useStore, w as useThree } from './index-d1db558e.esm.js';
3
3
  import _extends from '@babel/runtime/helpers/esm/extends';
4
4
  import * as React from 'react';
5
5
  import * as THREE from 'three';
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('../../dist/index-8e20caed.cjs.dev.js');
5
+ var index = require('../../dist/index-cc1b2b8b.cjs.dev.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('../../dist/index-786a40b6.cjs.prod.js');
5
+ var index = require('../../dist/index-fbc2ae01.cjs.prod.js');
6
6
  var _extends = require('@babel/runtime/helpers/extends');
7
7
  var React = require('react');
8
8
  var THREE = require('three');
@@ -1,5 +1,5 @@
1
- import { c as createEvents, e as extend, u as useMutableCallback, a as createRoot, E as ErrorBoundary, B as Block, d as unmountComponentAtNode } from '../../dist/index-30926efc.esm.js';
2
- export { t as ReactThreeFiber, s as _roots, q as act, n as addAfterEffect, m as addEffect, o as addTail, l as advance, i as applyProps, f as context, g as createPortal, a as createRoot, j as dispose, e as extend, p as getRootState, k as invalidate, h as reconciler, r as render, d as unmountComponentAtNode, x as useFrame, y as useGraph, z as useLoader, v as useStore, w as useThree } from '../../dist/index-30926efc.esm.js';
1
+ import { c as createEvents, e as extend, u as useMutableCallback, a as createRoot, E as ErrorBoundary, B as Block, d as unmountComponentAtNode } from '../../dist/index-d1db558e.esm.js';
2
+ export { t as ReactThreeFiber, s as _roots, q as act, n as addAfterEffect, m as addEffect, o as addTail, l as advance, i as applyProps, f as context, g as createPortal, a as createRoot, j as dispose, e as extend, p as getRootState, k as invalidate, h as reconciler, r as render, d as unmountComponentAtNode, x as useFrame, y as useGraph, z as useLoader, v as useStore, w as useThree } from '../../dist/index-d1db558e.esm.js';
3
3
  import _extends from '@babel/runtime/helpers/esm/extends';
4
4
  import * as React from 'react';
5
5
  import * as THREE from 'three';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/fiber",
3
- "version": "8.0.21",
3
+ "version": "8.0.24",
4
4
  "description": "A React renderer for Threejs",
5
5
  "keywords": [
6
6
  "react",