@react-three/fiber 10.0.0-alpha.4 → 10.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/legacy.mjs CHANGED
@@ -11,6 +11,7 @@ export { Scheduler, getScheduler } from '@pmndrs/scheduler';
11
11
  import Tb, { unstable_getCurrentPriorityLevel, unstable_IdlePriority, unstable_LowPriority, unstable_NormalPriority, unstable_UserBlockingPriority, unstable_ImmediatePriority, unstable_scheduleCallback } from 'scheduler';
12
12
  import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
13
13
  import { HDRLoader } from 'three/examples/jsm/loaders/HDRLoader.js';
14
+ import { HDRCubeTextureLoader } from 'three/examples/jsm/loaders/HDRCubeTextureLoader.js';
14
15
  import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
15
16
  import { UltraHDRLoader } from 'three/examples/jsm/loaders/UltraHDRLoader.js';
16
17
  import { GainMapLoader } from '@monogrid/gainmap-js';
@@ -33,11 +34,11 @@ const R3F_BUILD_WEBGPU = false;
33
34
  async function loadInspector() {
34
35
  throw new Error("Inspector is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
35
36
  }
36
- const WebGPURenderer = class WebGPURenderer2 {
37
+ class WebGPURenderer {
37
38
  constructor() {
38
39
  throw new Error("WebGPURenderer is not available in legacy builds. Use @react-three/fiber/webgpu instead.");
39
40
  }
40
- };
41
+ }
41
42
  const RenderTarget = null;
42
43
  const CubeRenderTarget = null;
43
44
 
@@ -513,8 +514,10 @@ function hasVisibilityHandlers(handlers) {
513
514
  }
514
515
 
515
516
  const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
516
- function fromRef(ref) {
517
- return { [FROM_REF]: ref };
517
+ function fromRef(ref, transform) {
518
+ const marker = { [FROM_REF]: ref };
519
+ if (transform) marker.transform = transform;
520
+ return marker;
518
521
  }
519
522
  function isFromRef(value) {
520
523
  return value !== null && typeof value === "object" && FROM_REF in value;
@@ -615,11 +618,9 @@ function diffProps(instance, newProps) {
615
618
  for (const prop in instance.props) {
616
619
  if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
617
620
  const { root, key } = resolve(instance.object, prop);
618
- if (root.constructor && root.constructor.length === 0) {
621
+ if (typeof root?.constructor === "function") {
619
622
  const ctor = getMemoizedPrototype(root);
620
623
  if (!is.und(ctor)) changedProps[prop] = ctor[key];
621
- } else {
622
- changedProps[prop] = 0;
623
624
  }
624
625
  }
625
626
  return changedProps;
@@ -1052,7 +1053,8 @@ const createStore = (invalidate, advance) => {
1052
1053
  const resizeTarget = canvasTarget ?? actualRenderer;
1053
1054
  if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
1054
1055
  resizeTarget.setSize(size.width, size.height, false);
1055
- internal.canvasTargetSizeDirty = true;
1056
+ const activeTarget = actualRenderer.getCanvasTarget?.();
1057
+ if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
1056
1058
  }
1057
1059
  if (camera !== oldCamera) {
1058
1060
  oldCamera = camera;
@@ -1341,12 +1343,24 @@ function useTexture(input, optionsOrOnLoad) {
1341
1343
  TextureLoader,
1342
1344
  IsObject(stableInput) ? Object.values(stableInput) : stableInput
1343
1345
  );
1346
+ const mappedTextures = useMemo(() => {
1347
+ if (cachedResult) return cachedResult;
1348
+ if (IsObject(stableInput)) {
1349
+ const keyed = {};
1350
+ const textureArray = loadedTextures;
1351
+ let i = 0;
1352
+ for (const key in stableInput) keyed[key] = textureArray[i++];
1353
+ return keyed;
1354
+ } else {
1355
+ return loadedTextures;
1356
+ }
1357
+ }, [stableInput, loadedTextures, cachedResult]);
1344
1358
  useLayoutEffect(() => {
1345
1359
  if (cachedResult) return;
1346
1360
  if (onLoadCalledForRef.current === inputKey) return;
1347
1361
  onLoadCalledForRef.current = inputKey;
1348
- onLoadRef.current?.(loadedTextures);
1349
- }, [cachedResult, loadedTextures, inputKey]);
1362
+ onLoadRef.current?.(mappedTextures);
1363
+ }, [cachedResult, mappedTextures, inputKey]);
1350
1364
  useEffect(() => {
1351
1365
  if (cachedResult) return;
1352
1366
  if ("initTexture" in renderer) {
@@ -1365,18 +1379,6 @@ function useTexture(input, optionsOrOnLoad) {
1365
1379
  });
1366
1380
  }
1367
1381
  }, [renderer, loadedTextures, cachedResult]);
1368
- const mappedTextures = useMemo(() => {
1369
- if (cachedResult) return cachedResult;
1370
- if (IsObject(stableInput)) {
1371
- const keyed = {};
1372
- const textureArray = loadedTextures;
1373
- let i = 0;
1374
- for (const key in stableInput) keyed[key] = textureArray[i++];
1375
- return keyed;
1376
- } else {
1377
- return loadedTextures;
1378
- }
1379
- }, [stableInput, loadedTextures, cachedResult]);
1380
1382
  useEffect(() => {
1381
1383
  if (!cache) return;
1382
1384
  const urlTextureMap = [];
@@ -1578,7 +1580,7 @@ function useEnvironment({
1578
1580
  texture = texture.renderTarget?.texture;
1579
1581
  }
1580
1582
  texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
1581
- texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
1583
+ texture.colorSpace = colorSpace ?? (isCubemap && extension !== "hdr-cube" ? "srgb" : "srgb-linear");
1582
1584
  return texture;
1583
1585
  }
1584
1586
  const preloadDefaultOptions = {
@@ -1631,11 +1633,12 @@ function getExtension(files) {
1631
1633
  const isCubemap = isArray(files) && files.length === 6;
1632
1634
  const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
1633
1635
  const firstEntry = isArray(files) ? files[0] : files;
1634
- const extension = isCubemap ? "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
1636
+ const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
1637
+ const extension = isCubemap ? firstExtension === "hdr" ? "hdr-cube" : "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstExtension;
1635
1638
  return { extension, isCubemap, isGainmap };
1636
1639
  }
1637
1640
  function getLoader(extension) {
1638
- const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
1641
+ const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr-cube" ? HDRCubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
1639
1642
  return loader;
1640
1643
  }
1641
1644
 
@@ -1698,7 +1701,7 @@ function advance(timestamp, runGlobalEffects, state) {
1698
1701
  else scheduler.step(timestamp);
1699
1702
  }
1700
1703
 
1701
- const version = "10.0.0-alpha.4";
1704
+ const version = "10.0.0-alpha.5";
1702
1705
  const packageData = {
1703
1706
  version: version};
1704
1707
 
@@ -13557,7 +13560,10 @@ function extend(objects) {
13557
13560
  catalogue[Component] = objects;
13558
13561
  return Component;
13559
13562
  } else {
13560
- Object.assign(catalogue, objects);
13563
+ for (const name in objects) {
13564
+ const object = objects[name];
13565
+ if (isConstructor(object)) catalogue[name] = object;
13566
+ }
13561
13567
  }
13562
13568
  }
13563
13569
  function validateInstance(type, props) {
@@ -13905,7 +13911,7 @@ const reconciler = /* @__PURE__ */ createReconciler({
13905
13911
  getRootHostContext: () => NO_CONTEXT,
13906
13912
  getChildHostContext: () => NO_CONTEXT,
13907
13913
  commitUpdate(instance, type, oldProps, newProps, fiber) {
13908
- validateInstance(type, newProps);
13914
+ validateInstance(instance.type, newProps);
13909
13915
  let reconstruct = false;
13910
13916
  if (instance.type === "primitive" && oldProps.object !== newProps.object) reconstruct = true;
13911
13917
  else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
@@ -13932,8 +13938,8 @@ const reconciler = /* @__PURE__ */ createReconciler({
13932
13938
  for (const prop in instance.props) {
13933
13939
  const value = instance.props[prop];
13934
13940
  if (isFromRef(value)) {
13935
- const ref = value[FROM_REF];
13936
- if (ref.current != null) resolved[prop] = ref.current;
13941
+ const { [FROM_REF]: ref, transform } = value;
13942
+ if (ref.current != null) resolved[prop] = transform ? transform(ref.current) : ref.current;
13937
13943
  }
13938
13944
  }
13939
13945
  if (Object.keys(resolved).length) applyProps(instance.object, resolved);
@@ -14409,9 +14415,10 @@ function createRoot(canvas) {
14409
14415
  const unregisterCanvasTarget = scheduler.register(
14410
14416
  () => {
14411
14417
  const state2 = store.getState();
14412
- if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
14418
+ const canvasTarget = state2.internal.canvasTarget;
14419
+ if (canvasTarget) {
14413
14420
  const renderer2 = state2.internal.actualRenderer;
14414
- renderer2.setCanvasTarget(state2.internal.canvasTarget);
14421
+ if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
14415
14422
  if (state2.internal.canvasTargetSizeDirty) {
14416
14423
  state2.internal.canvasTargetSizeDirty = false;
14417
14424
  renderer2.backend?.updateSize?.();
@@ -14575,7 +14582,7 @@ function unmountComponentAtNode(canvas, callback) {
14575
14582
  const unregisterPrimary = state.internal.unregisterPrimary;
14576
14583
  if (unregisterPrimary) unregisterPrimary();
14577
14584
  const canvasTarget = state.internal.canvasTarget;
14578
- if (canvasTarget?.dispose) canvasTarget.dispose();
14585
+ if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
14579
14586
  state.events.disconnect?.();
14580
14587
  cleanupHelperGroup(root.store);
14581
14588
  if (state.isLegacy && renderer) {
@@ -14716,16 +14723,11 @@ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {})
14716
14723
  const oldbg = target.background;
14717
14724
  const oldenv = target.environment;
14718
14725
  const oldSceneProps = {
14719
- // @ts-ignore
14720
14726
  backgroundBlurriness: target.backgroundBlurriness,
14721
- // @ts-ignore
14722
14727
  backgroundIntensity: target.backgroundIntensity,
14723
- // @ts-ignore
14724
- backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
14725
- // @ts-ignore
14728
+ backgroundRotation: target.backgroundRotation.clone(),
14726
14729
  environmentIntensity: target.environmentIntensity,
14727
- // @ts-ignore
14728
- environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
14730
+ environmentRotation: target.environmentRotation.clone()
14729
14731
  };
14730
14732
  if (background !== "only") target.environment = texture;
14731
14733
  if (background) target.background = texture;
@@ -15019,9 +15021,9 @@ function CanvasImpl({
15019
15021
  React.useMemo(() => extend(THREE), []);
15020
15022
  const Bridge = useBridge();
15021
15023
  const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
15022
- const hasInitialSizeRef = React.useRef(false);
15024
+ const [hasInitialSize, setHasInitialSize] = React.useState(false);
15023
15025
  const measureConfig = React.useMemo(() => {
15024
- if (!hasInitialSizeRef.current) {
15026
+ if (!hasInitialSize) {
15025
15027
  return {
15026
15028
  ...resize,
15027
15029
  scroll: resize?.scroll ?? true,
@@ -15033,7 +15035,7 @@ function CanvasImpl({
15033
15035
  debounce: { scroll: 50, resize: 0 },
15034
15036
  ...resize
15035
15037
  };
15036
- }, [resize, hasInitialSizeRef.current]);
15038
+ }, [hasInitialSize, resize]);
15037
15039
  const [containerRef, containerRect] = useMeasure(measureConfig);
15038
15040
  const effectiveSize = React.useMemo(() => {
15039
15041
  let w = width ?? containerRect.width;
@@ -15049,9 +15051,7 @@ function CanvasImpl({
15049
15051
  left: containerRect.left
15050
15052
  };
15051
15053
  }, [width, height, containerRect, forceEven]);
15052
- if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
15053
- hasInitialSizeRef.current = true;
15054
- }
15054
+ if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
15055
15055
  const canvasRef = React.useRef(null);
15056
15056
  const divRef = React.useRef(null);
15057
15057
  React.useImperativeHandle(ref, () => canvasRef.current);