@react-three/drei 11.0.0-alpha.5 → 11.0.0-alpha.6

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/index.mjs CHANGED
@@ -2,9 +2,8 @@ import * as React from 'react';
2
2
  import { forwardRef, useImperativeHandle, useMemo, useEffect, useCallback, useRef, useLayoutEffect, useState, Fragment, createContext, useContext, Suspense } from 'react';
3
3
  import { useThree, useFrame, extend, createPortal, applyProps, useInstanceHandle, context as context$9, useLoader, addEffect, addAfterEffect } from '@react-three/fiber';
4
4
  import * as THREE from 'three';
5
- import { REVISION, WebGLRenderTarget, Frustum, Matrix4, Vector3, Vector4, Vector2, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, Object3D, WebGLCubeRenderTarget, HalfFloatType, CubeCamera as CubeCamera$1, EventDispatcher, Euler, Quaternion, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial, DynamicDrawUsage, CatmullRomCurve3, CubicBezierCurve3, QuadraticBezierCurve3, Shape as Shape$1, CanvasTexture, DoubleSide, PerspectiveCamera as PerspectiveCamera$1, OrthographicCamera as OrthographicCamera$1, AudioListener, AudioLoader, AnimationMixer, BufferAttribute, Box3, Sphere as Sphere$1, InstancedBufferAttribute, DepthTexture, DepthFormat, UnsignedShortType, CubeTextureLoader, DefaultLoadingManager, Ray, Raycaster, Camera, CubeReflectionMapping, EquirectangularReflectionMapping, Scene, RepeatWrapping, Mesh, Spherical } from 'three';
5
+ import { REVISION, WebGLRenderTarget, Frustum, Matrix4, Vector3, Vector4, Vector2, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, Object3D, WebGLCubeRenderTarget, HalfFloatType, CubeCamera as CubeCamera$1, EventDispatcher, Euler, Quaternion, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial, DynamicDrawUsage, CatmullRomCurve3, CubicBezierCurve3, QuadraticBezierCurve3, Shape as Shape$1, CanvasTexture, PerspectiveCamera as PerspectiveCamera$1, OrthographicCamera as OrthographicCamera$1, AudioListener, AudioLoader, AnimationMixer, BufferAttribute, Box3, Sphere as Sphere$1, InstancedBufferAttribute, DoubleSide, DepthTexture, DepthFormat, UnsignedShortType, CubeTextureLoader, DefaultLoadingManager, Ray, Raycaster, Camera, CubeReflectionMapping, EquirectangularReflectionMapping, Scene, RepeatWrapping, Mesh, Spherical } from 'three';
6
6
  import { ArcballControls as ArcballControls$1 } from 'three/examples/jsm/controls/ArcballControls.js';
7
- import { useGesture } from '@use-gesture/react';
8
7
  import { FirstPersonControls as FirstPersonControls$1 } from 'three/examples/jsm/controls/FirstPersonControls.js';
9
8
  import { FlyControls as FlyControls$1 } from 'three/examples/jsm/controls/FlyControls.js';
10
9
  import { create as create$1 } from 'zustand';
@@ -13,6 +12,7 @@ import { MapControls as MapControls$1 } from 'three/examples/jsm/controls/MapCon
13
12
  import { misc, easing } from 'maath';
14
13
  import { OrbitControls as OrbitControls$1 } from 'three/addons/controls/OrbitControls.js';
15
14
  import { PointerLockControls as PointerLockControls$1 } from 'three/examples/jsm/controls/PointerLockControls.js';
15
+ import { useGesture } from '@use-gesture/react';
16
16
  import * as ReactDOM from 'react-dom/client';
17
17
  import { TrackballControls as TrackballControls$1 } from 'three/examples/jsm/controls/TrackballControls.js';
18
18
  import { SimplexNoise } from 'three/examples/jsm/math/SimplexNoise.js';
@@ -31,7 +31,6 @@ import { TransformControls as TransformControls$1 } from 'three/examples/jsm/con
31
31
  import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils.js';
32
32
  import { MeshSurfaceSampler } from 'three/examples/jsm/math/MeshSurfaceSampler.js';
33
33
  import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader.js';
34
- import { Events } from 'hls.js';
35
34
  import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
36
35
  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
37
36
  import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
@@ -1444,11 +1443,11 @@ const DeviceOrientationControls = /* @__PURE__ */ React.forwardRef(
1444
1443
  );
1445
1444
 
1446
1445
  const initialModelPosition = /* @__PURE__ */ new THREE.Vector3();
1447
- const mousePosition2D = /* @__PURE__ */ new THREE.Vector2();
1448
1446
  const mousePosition3D = /* @__PURE__ */ new THREE.Vector3();
1449
1447
  const dragOffset = /* @__PURE__ */ new THREE.Vector3();
1450
1448
  const dragPlaneNormal = /* @__PURE__ */ new THREE.Vector3();
1451
1449
  const dragPlane = /* @__PURE__ */ new THREE.Plane();
1450
+ const startPointerPos = /* @__PURE__ */ new THREE.Vector3();
1452
1451
  const DragControls = React.forwardRef(
1453
1452
  ({
1454
1453
  autoTransform = true,
@@ -1464,90 +1463,132 @@ const DragControls = React.forwardRef(
1464
1463
  ...props
1465
1464
  }, fRef) => {
1466
1465
  const defaultControls = useThree((state) => state.controls);
1467
- const { camera, size, raycaster, invalidate } = useThree();
1466
+ const { camera, invalidate } = useThree();
1468
1467
  const ref = React.useRef(null);
1469
- const bind = useGesture(
1470
- {
1471
- onHover: ({ hovering }) => onHover && onHover(hovering ?? false),
1472
- onDragStart: ({ event }) => {
1473
- if (defaultControls) defaultControls.enabled = false;
1474
- const { point } = event;
1475
- ref.current.matrix.decompose(initialModelPosition, new THREE.Quaternion(), new THREE.Vector3());
1476
- mousePosition3D.copy(point);
1477
- dragOffset.copy(mousePosition3D).sub(initialModelPosition);
1478
- onDragStart && onDragStart(initialModelPosition);
1479
- invalidate();
1480
- },
1481
- onDrag: ({ xy: [dragX, dragY], intentional, event }) => {
1482
- if (!intentional) return;
1483
- if (dragConfig && dragConfig.preventOverlap) event.preventDefault();
1484
- const normalizedMouseX = (dragX - size.left) / size.width * 2 - 1;
1485
- const normalizedMouseY = -((dragY - size.top) / size.height) * 2 + 1;
1486
- mousePosition2D.set(normalizedMouseX, normalizedMouseY);
1487
- raycaster.setFromCamera(mousePosition2D, camera);
1488
- if (!axisLock) {
1489
- camera.getWorldDirection(dragPlaneNormal).negate();
1490
- } else {
1491
- switch (axisLock) {
1492
- case "x":
1493
- dragPlaneNormal.set(1, 0, 0);
1494
- break;
1495
- case "y":
1496
- dragPlaneNormal.set(0, 1, 0);
1497
- break;
1498
- case "z":
1499
- dragPlaneNormal.set(0, 0, 1);
1500
- break;
1501
- }
1502
- }
1503
- dragPlane.setFromNormalAndCoplanarPoint(dragPlaneNormal, mousePosition3D);
1504
- raycaster.ray.intersectPlane(dragPlane, mousePosition3D);
1505
- const previousLocalMatrix = ref.current.matrix.clone();
1506
- const previousWorldMatrix = ref.current.matrixWorld.clone();
1507
- const intendedNewPosition = new THREE.Vector3(
1508
- mousePosition3D.x - dragOffset.x,
1509
- mousePosition3D.y - dragOffset.y,
1510
- mousePosition3D.z - dragOffset.z
1511
- );
1512
- if (dragLimits) {
1513
- intendedNewPosition.x = dragLimits[0] ? Math.max(Math.min(intendedNewPosition.x, dragLimits[0][1]), dragLimits[0][0]) : intendedNewPosition.x;
1514
- intendedNewPosition.y = dragLimits[1] ? Math.max(Math.min(intendedNewPosition.y, dragLimits[1][1]), dragLimits[1][0]) : intendedNewPosition.y;
1515
- intendedNewPosition.z = dragLimits[2] ? Math.max(Math.min(intendedNewPosition.z, dragLimits[2][1]), dragLimits[2][0]) : intendedNewPosition.z;
1516
- }
1517
- if (autoTransform) {
1518
- ref.current.matrix.setPosition(intendedNewPosition);
1519
- const deltaLocalMatrix = ref.current.matrix.clone().multiply(previousLocalMatrix.invert());
1520
- const deltaWorldMatrix = ref.current.matrix.clone().multiply(previousWorldMatrix.invert());
1521
- onDrag && onDrag(ref.current.matrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
1522
- } else {
1523
- const tempMatrix = new THREE.Matrix4().copy(ref.current.matrix);
1524
- tempMatrix.setPosition(intendedNewPosition);
1525
- const deltaLocalMatrix = tempMatrix.clone().multiply(previousLocalMatrix.invert());
1526
- const deltaWorldMatrix = tempMatrix.clone().multiply(previousWorldMatrix.invert());
1527
- onDrag && onDrag(tempMatrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
1468
+ const dragState = React.useRef({
1469
+ active: false,
1470
+ intentional: false,
1471
+ // Has moved past threshold
1472
+ pointerId: -1
1473
+ });
1474
+ const threshold = dragConfig?.threshold ?? 0;
1475
+ const filterTaps = dragConfig?.filterTaps ?? true;
1476
+ const handlePointerDown = React.useCallback(
1477
+ (event) => {
1478
+ event.stopPropagation();
1479
+ event.target.setPointerCapture(event.pointerId);
1480
+ dragState.current.active = true;
1481
+ dragState.current.intentional = threshold === 0;
1482
+ dragState.current.pointerId = event.pointerId;
1483
+ if (defaultControls) defaultControls.enabled = false;
1484
+ ref.current.matrix.decompose(initialModelPosition, new THREE.Quaternion(), new THREE.Vector3());
1485
+ mousePosition3D.copy(event.point);
1486
+ startPointerPos.copy(event.point);
1487
+ dragOffset.copy(mousePosition3D).sub(initialModelPosition);
1488
+ if (!axisLock) {
1489
+ camera.getWorldDirection(dragPlaneNormal).negate();
1490
+ } else {
1491
+ switch (axisLock) {
1492
+ case "x":
1493
+ dragPlaneNormal.set(1, 0, 0);
1494
+ break;
1495
+ case "y":
1496
+ dragPlaneNormal.set(0, 1, 0);
1497
+ break;
1498
+ case "z":
1499
+ dragPlaneNormal.set(0, 0, 1);
1500
+ break;
1528
1501
  }
1529
- invalidate();
1530
- },
1531
- onDragEnd: () => {
1532
- if (defaultControls) defaultControls.enabled = true;
1533
- onDragEnd && onDragEnd();
1534
- invalidate();
1535
1502
  }
1503
+ dragPlane.setFromNormalAndCoplanarPoint(dragPlaneNormal, mousePosition3D);
1504
+ if (dragState.current.intentional) {
1505
+ onDragStart && onDragStart(initialModelPosition);
1506
+ }
1507
+ invalidate();
1508
+ },
1509
+ [defaultControls, camera, axisLock, threshold, onDragStart, invalidate]
1510
+ );
1511
+ const handlePointerMove = React.useCallback(
1512
+ (event) => {
1513
+ if (!dragState.current.active || event.pointerId !== dragState.current.pointerId) return;
1514
+ const intersection = event.ray.intersectPlane(dragPlane, mousePosition3D);
1515
+ if (!intersection) return;
1516
+ if (!dragState.current.intentional) {
1517
+ const distance = mousePosition3D.distanceTo(startPointerPos);
1518
+ if (distance < threshold) return;
1519
+ dragState.current.intentional = true;
1520
+ onDragStart && onDragStart(initialModelPosition);
1521
+ }
1522
+ const previousLocalMatrix = ref.current.matrix.clone();
1523
+ const previousWorldMatrix = ref.current.matrixWorld.clone();
1524
+ const intendedNewPosition = new THREE.Vector3(
1525
+ mousePosition3D.x - dragOffset.x,
1526
+ mousePosition3D.y - dragOffset.y,
1527
+ mousePosition3D.z - dragOffset.z
1528
+ );
1529
+ if (dragLimits) {
1530
+ intendedNewPosition.x = dragLimits[0] ? Math.max(Math.min(intendedNewPosition.x, dragLimits[0][1]), dragLimits[0][0]) : intendedNewPosition.x;
1531
+ intendedNewPosition.y = dragLimits[1] ? Math.max(Math.min(intendedNewPosition.y, dragLimits[1][1]), dragLimits[1][0]) : intendedNewPosition.y;
1532
+ intendedNewPosition.z = dragLimits[2] ? Math.max(Math.min(intendedNewPosition.z, dragLimits[2][1]), dragLimits[2][0]) : intendedNewPosition.z;
1533
+ }
1534
+ if (autoTransform) {
1535
+ ref.current.matrix.setPosition(intendedNewPosition);
1536
+ const deltaLocalMatrix = ref.current.matrix.clone().multiply(previousLocalMatrix.invert());
1537
+ const deltaWorldMatrix = ref.current.matrix.clone().multiply(previousWorldMatrix.invert());
1538
+ onDrag && onDrag(ref.current.matrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
1539
+ } else {
1540
+ const tempMatrix = new THREE.Matrix4().copy(ref.current.matrix);
1541
+ tempMatrix.setPosition(intendedNewPosition);
1542
+ const deltaLocalMatrix = tempMatrix.clone().multiply(previousLocalMatrix.invert());
1543
+ const deltaWorldMatrix = tempMatrix.clone().multiply(previousWorldMatrix.invert());
1544
+ onDrag && onDrag(tempMatrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
1545
+ }
1546
+ invalidate();
1536
1547
  },
1537
- {
1538
- drag: {
1539
- filterTaps: true,
1540
- threshold: 1,
1541
- ...typeof dragConfig === "object" ? dragConfig : {}
1548
+ [autoTransform, dragLimits, threshold, onDragStart, onDrag, invalidate]
1549
+ );
1550
+ const handlePointerUp = React.useCallback(
1551
+ (event) => {
1552
+ if (!dragState.current.active || event.pointerId !== dragState.current.pointerId) return;
1553
+ event.target.releasePointerCapture(event.pointerId);
1554
+ const wasIntentional = dragState.current.intentional;
1555
+ dragState.current.active = false;
1556
+ dragState.current.intentional = false;
1557
+ dragState.current.pointerId = -1;
1558
+ if (defaultControls) defaultControls.enabled = true;
1559
+ if (wasIntentional || !filterTaps) {
1560
+ onDragEnd && onDragEnd();
1542
1561
  }
1543
- }
1562
+ invalidate();
1563
+ },
1564
+ [defaultControls, filterTaps, onDragEnd, invalidate]
1544
1565
  );
1566
+ const handlePointerEnter = React.useCallback(() => {
1567
+ onHover && onHover(true);
1568
+ }, [onHover]);
1569
+ const handlePointerLeave = React.useCallback(() => {
1570
+ onHover && onHover(false);
1571
+ }, [onHover]);
1545
1572
  React.useImperativeHandle(fRef, () => ref.current, []);
1546
1573
  React.useLayoutEffect(() => {
1547
1574
  if (!matrix) return;
1548
1575
  ref.current.matrix = matrix;
1549
1576
  }, [matrix]);
1550
- return /* @__PURE__ */ React.createElement("group", { ref, ...bind(), matrix, matrixAutoUpdate: false, ...props }, children);
1577
+ return /* @__PURE__ */ React.createElement(
1578
+ "group",
1579
+ {
1580
+ ref,
1581
+ onPointerDown: handlePointerDown,
1582
+ onPointerMove: handlePointerMove,
1583
+ onPointerUp: handlePointerUp,
1584
+ onPointerEnter: handlePointerEnter,
1585
+ onPointerLeave: handlePointerLeave,
1586
+ matrix,
1587
+ matrixAutoUpdate: false,
1588
+ ...props
1589
+ },
1590
+ children
1591
+ );
1551
1592
  }
1552
1593
  );
1553
1594
 
@@ -1665,7 +1706,7 @@ function KeyboardControls({ map, children, onChange, domElement }) {
1665
1706
  source.removeEventListener("keyup", upHandler);
1666
1707
  window.removeEventListener("blur", blurHandler);
1667
1708
  };
1668
- }, [domElement, key]);
1709
+ }, [domElement, key, onChange]);
1669
1710
  return /* @__PURE__ */ React.createElement(context$8.Provider, { value: api, children });
1670
1711
  }
1671
1712
  function useKeyboardControls(sel) {
@@ -1687,20 +1728,28 @@ const MapControls = /* @__PURE__ */ React.forwardRef((props = { enableDamping: t
1687
1728
  const controls = React.useMemo(() => new MapControls$1(explCamera), [explCamera]);
1688
1729
  React.useEffect(() => {
1689
1730
  controls.connect(explDomElement);
1731
+ return () => void controls.dispose();
1732
+ }, [explDomElement, controls]);
1733
+ React.useEffect(() => {
1690
1734
  const callback = (e) => {
1691
1735
  invalidate();
1692
1736
  if (onChange) onChange(e);
1693
1737
  };
1738
+ const onStartCb = (e) => {
1739
+ if (onStart) onStart(e);
1740
+ };
1741
+ const onEndCb = (e) => {
1742
+ if (onEnd) onEnd(e);
1743
+ };
1694
1744
  controls.addEventListener("change", callback);
1695
- if (onStart) controls.addEventListener("start", onStart);
1696
- if (onEnd) controls.addEventListener("end", onEnd);
1745
+ controls.addEventListener("start", onStartCb);
1746
+ controls.addEventListener("end", onEndCb);
1697
1747
  return () => {
1698
- controls.dispose();
1748
+ controls.removeEventListener("start", onStartCb);
1749
+ controls.removeEventListener("end", onEndCb);
1699
1750
  controls.removeEventListener("change", callback);
1700
- if (onStart) controls.removeEventListener("start", onStart);
1701
- if (onEnd) controls.removeEventListener("end", onEnd);
1702
1751
  };
1703
- }, [onChange, onStart, onEnd, controls, invalidate, explDomElement]);
1752
+ }, [onChange, onStart, onEnd, controls, invalidate]);
1704
1753
  React.useEffect(() => {
1705
1754
  if (makeDefault) {
1706
1755
  const old = get().controls;
@@ -1708,7 +1757,9 @@ const MapControls = /* @__PURE__ */ React.forwardRef((props = { enableDamping: t
1708
1757
  return () => set({ controls: old });
1709
1758
  }
1710
1759
  }, [makeDefault, controls]);
1711
- useFrame(() => controls.update(), -1);
1760
+ useFrame(() => {
1761
+ if (controls.enabled) controls.update();
1762
+ }, -1);
1712
1763
  return /* @__PURE__ */ React.createElement("primitive", { ref, object: controls, enableDamping: true, ...rest });
1713
1764
  });
1714
1765
 
@@ -1834,20 +1885,16 @@ const OrbitControls = /* @__PURE__ */ React.forwardRef(
1834
1885
  onEnd,
1835
1886
  ...restProps
1836
1887
  }, ref) => {
1837
- const invalidate = useThree((state) => state.invalidate);
1838
- const defaultCamera = useThree((state) => state.camera);
1839
- const gl = useThree((state) => state.gl);
1840
- const events = useThree((state) => state.events);
1841
- const setEvents = useThree((state) => state.setEvents);
1842
- const set = useThree((state) => state.set);
1843
- const get = useThree((state) => state.get);
1844
- const performance = useThree((state) => state.performance);
1888
+ const { invalidate, camera: defaultCamera, renderer, events, setEvents, set, get, performance } = useThree();
1845
1889
  const explCamera = camera || defaultCamera;
1846
- const explDomElement = domElement || events.connected || gl.domElement;
1890
+ const explDomElement = domElement || events.connected || renderer.domElement;
1847
1891
  const controls = React.useMemo(() => new OrbitControls$1(explCamera), [explCamera]);
1848
- useFrame(() => {
1849
- if (controls.enabled) controls.update();
1850
- }, -1);
1892
+ useFrame(
1893
+ () => {
1894
+ if (controls.enabled) controls.update();
1895
+ },
1896
+ { before: "update" }
1897
+ );
1851
1898
  React.useEffect(() => {
1852
1899
  if (keyEvents) {
1853
1900
  controls.connect(keyEvents === true ? explDomElement : keyEvents);
@@ -1961,9 +2008,8 @@ function PresentationControls({
1961
2008
  azimuth = [-Infinity, Infinity],
1962
2009
  damping = 0.25
1963
2010
  }) {
1964
- const events = useThree((state) => state.events);
1965
- const gl = useThree((state) => state.gl);
1966
- const explDomElement = domElement || events.connected || gl.domElement;
2011
+ const { events, renderer, invalidate } = useThree();
2012
+ const explDomElement = domElement || events.connected || renderer.domElement;
1967
2013
  const { size } = useThree();
1968
2014
  const rPolar = React.useMemo(
1969
2015
  () => [rotation[0] + polar[0], rotation[0] + polar[1]],
@@ -1980,18 +2026,20 @@ function PresentationControls({
1980
2026
  React.useEffect(() => {
1981
2027
  if (global && cursor && enabled) {
1982
2028
  explDomElement.style.cursor = "grab";
1983
- gl.domElement.style.cursor = "";
2029
+ renderer.domElement.style.cursor = "";
1984
2030
  return () => {
1985
2031
  explDomElement.style.cursor = "default";
1986
- gl.domElement.style.cursor = "default";
2032
+ renderer.domElement.style.cursor = "default";
1987
2033
  };
1988
2034
  }
1989
2035
  }, [global, cursor, explDomElement, enabled]);
1990
2036
  const [animation] = React.useState({ scale: 1, rotation: rInitial, damping });
1991
2037
  const ref = React.useRef(null);
1992
2038
  useFrame((state, delta) => {
1993
- easing.damp3(ref.current.scale, animation.scale, animation.damping, delta);
1994
- easing.dampE(ref.current.rotation, animation.rotation, animation.damping, delta);
2039
+ let changed = false;
2040
+ changed ||= easing.damp3(ref.current.scale, animation.scale, animation.damping, delta);
2041
+ changed ||= easing.dampE(ref.current.rotation, animation.rotation, animation.damping, delta);
2042
+ if (changed) state.invalidate();
1995
2043
  });
1996
2044
  const bind = useGesture(
1997
2045
  {
@@ -1999,6 +2047,7 @@ function PresentationControls({
1999
2047
  if (cursor && !global && enabled) explDomElement.style.cursor = last ? "auto" : "grab";
2000
2048
  },
2001
2049
  onDrag: ({ down, delta: [x, y], memo: [oldY, oldX] = animation.rotation || rInitial }) => {
2050
+ invalidate();
2002
2051
  if (!enabled) return [y, x];
2003
2052
  if (cursor) explDomElement.style.cursor = down ? "grabbing" : "grab";
2004
2053
  x = MathUtils.clamp(oldX + x / size.width * Math.PI * speed, ...rAzimuth);
@@ -2007,9 +2056,12 @@ function PresentationControls({
2007
2056
  animation.rotation = snap && !down ? rInitial : [y, x, 0];
2008
2057
  animation.damping = snap && !down && typeof snap !== "boolean" ? snap : damping;
2009
2058
  return [y, x];
2059
+ },
2060
+ onDragEnd: () => {
2061
+ invalidate();
2010
2062
  }
2011
2063
  },
2012
- { target: global ? explDomElement : void 0 }
2064
+ { target: global ? explDomElement : void 0, enabled }
2013
2065
  );
2014
2066
  return /* @__PURE__ */ React.createElement("group", { ref, ...bind?.() }, children);
2015
2067
  }
@@ -2018,6 +2070,10 @@ function roundToPixelRatio(value) {
2018
2070
  const ratio = window.devicePixelRatio || 1;
2019
2071
  return Math.round(value * ratio) / ratio;
2020
2072
  }
2073
+ function getMaxAnisotropy(renderer) {
2074
+ const r = renderer;
2075
+ return r?.getMaxAnisotropy?.() ?? r?.capabilities?.getMaxAnisotropy?.() ?? 1;
2076
+ }
2021
2077
 
2022
2078
  const context$7 = /* @__PURE__ */ React.createContext(null);
2023
2079
  const rootCache = /* @__PURE__ */ new WeakMap();
@@ -2044,6 +2100,7 @@ function ScrollControls({
2044
2100
  const [fixed] = React.useState(() => document.createElement("div"));
2045
2101
  const target = gl.domElement.parentNode;
2046
2102
  const scroll = React.useRef(0);
2103
+ const disableScrollUpdate = React.useRef(false);
2047
2104
  const state = React.useMemo(() => {
2048
2105
  const state2 = {
2049
2106
  el,
@@ -2125,16 +2182,20 @@ function ScrollControls({
2125
2182
  const scrollLength = el[horizontal ? "scrollWidth" : "scrollHeight"];
2126
2183
  const scrollThreshold = scrollLength - containerLength;
2127
2184
  let current = 0;
2128
- let disableScroll = true;
2185
+ let disableScroll = false;
2129
2186
  let firstRun = true;
2130
2187
  const onScroll = () => {
2131
2188
  if (!enabled || firstRun) return;
2189
+ if (disableScrollUpdate.current) {
2190
+ disableScrollUpdate.current = false;
2191
+ return;
2192
+ }
2132
2193
  invalidate();
2133
2194
  current = el[horizontal ? "scrollLeft" : "scrollTop"];
2134
2195
  scroll.current = current / scrollThreshold;
2135
2196
  if (infinite) {
2136
2197
  if (!disableScroll) {
2137
- if (current >= scrollThreshold) {
2198
+ if (current >= scrollThreshold - 1) {
2138
2199
  const damp = 1 - state.offset;
2139
2200
  el[horizontal ? "scrollLeft" : "scrollTop"] = 1;
2140
2201
  scroll.current = state.offset = -damp;
@@ -2151,11 +2212,34 @@ function ScrollControls({
2151
2212
  };
2152
2213
  el.addEventListener("scroll", onScroll, { passive: true });
2153
2214
  requestAnimationFrame(() => firstRun = false);
2154
- const onWheel = (e) => el.scrollLeft += e.deltaY / 2;
2155
- if (horizontal) el.addEventListener("wheel", onWheel, { passive: true });
2215
+ const onResize = () => {
2216
+ if (!el) return;
2217
+ const scrollLength2 = el[horizontal ? "scrollWidth" : "scrollHeight"];
2218
+ const containerLength2 = el[horizontal ? "clientWidth" : "clientHeight"];
2219
+ disableScrollUpdate.current = true;
2220
+ el[horizontal ? "scrollLeft" : "scrollTop"] = state.offset * (scrollLength2 - containerLength2);
2221
+ };
2222
+ const onWheel = (e) => {
2223
+ if (horizontal) {
2224
+ const previous = el.scrollLeft;
2225
+ el.scrollLeft += e.deltaY / 2;
2226
+ if (infinite && previous === el.scrollLeft) {
2227
+ onScroll();
2228
+ }
2229
+ } else if (infinite) {
2230
+ if (el.scrollTop <= 1 && e.deltaY < 0) {
2231
+ onScroll();
2232
+ } else if (el.scrollTop >= el.scrollHeight - el.clientHeight - 1 && e.deltaY > 0) {
2233
+ onScroll();
2234
+ }
2235
+ }
2236
+ };
2237
+ if (horizontal || infinite) el.addEventListener("wheel", onWheel, { passive: true });
2238
+ if (horizontal) window.addEventListener("resize", onResize);
2156
2239
  return () => {
2157
2240
  el.removeEventListener("scroll", onScroll);
2158
- if (horizontal) el.removeEventListener("wheel", onWheel);
2241
+ if (horizontal || infinite) el.removeEventListener("wheel", onWheel);
2242
+ if (horizontal) window.removeEventListener("resize", onResize);
2159
2243
  };
2160
2244
  }
2161
2245
  }, [el, events, size, infinite, state, invalidate, horizontal, enabled]);
@@ -2572,10 +2656,10 @@ const CloudInstance = /* @__PURE__ */ React.forwardRef(
2572
2656
  return /* @__PURE__ */ React.createElement("group", { ref, ...props });
2573
2657
  }
2574
2658
  );
2575
- const Cloud = /* @__PURE__ */ React.forwardRef((props, fref) => {
2659
+ const Cloud = /* @__PURE__ */ React.forwardRef(({ materialFactory, ...props }, fref) => {
2576
2660
  const parent = React.useContext(context$6);
2577
2661
  if (parent) return /* @__PURE__ */ React.createElement(CloudInstance, { ref: fref, ...props });
2578
- return /* @__PURE__ */ React.createElement(Clouds, null, /* @__PURE__ */ React.createElement(CloudInstance, { ref: fref, ...props }));
2662
+ return /* @__PURE__ */ React.createElement(Clouds, { materialFactory }, /* @__PURE__ */ React.createElement(CloudInstance, { ref: fref, ...props }));
2579
2663
  });
2580
2664
 
2581
2665
  const CatmullRomLine = /* @__PURE__ */ React.forwardRef(function CatmullRomLine2({
@@ -3097,7 +3181,7 @@ const Text3D = /* @__PURE__ */ React.forwardRef(
3097
3181
  return {
3098
3182
  font,
3099
3183
  size,
3100
- height,
3184
+ depth: height,
3101
3185
  bevelThickness,
3102
3186
  bevelSize,
3103
3187
  bevelEnabled,
@@ -3280,7 +3364,7 @@ const FaceMaterial = ({
3280
3364
  "meshBasicMaterial",
3281
3365
  {
3282
3366
  map: texture,
3283
- "map-anisotropy": renderer.getMaxAnisotropy() || 1,
3367
+ "map-anisotropy": getMaxAnisotropy(renderer),
3284
3368
  attach: `material-${index}`,
3285
3369
  color: hover ? hoverColor : "white",
3286
3370
  transparent: true,
@@ -3391,7 +3475,7 @@ function AxisHead({
3391
3475
  "spriteMaterial",
3392
3476
  {
3393
3477
  map: texture,
3394
- "map-anisotropy": renderer.getMaxAnisotropy() || 1,
3478
+ "map-anisotropy": getMaxAnisotropy(renderer),
3395
3479
  alphaTest: 0.3,
3396
3480
  opacity: label ? 1 : 0.75,
3397
3481
  toneMapped: false
@@ -3536,6 +3620,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
3536
3620
  }, ref) => {
3537
3621
  const { gl, camera, scene, size, raycaster, events, viewport } = useThree();
3538
3622
  const forceEven = useThree((state) => state.internal.forceEven);
3623
+ const { frustum } = useThree();
3539
3624
  const [el] = React.useState(() => document.createElement(as));
3540
3625
  const root = React.useRef(null);
3541
3626
  const group = React.useRef(null);
@@ -3565,22 +3650,18 @@ const Html = /* @__PURE__ */ React.forwardRef(
3565
3650
  if (group.current) {
3566
3651
  if (!root.current) {
3567
3652
  root.current = ReactDOM.createRoot(el);
3568
- }
3569
- scene.updateMatrixWorld();
3570
- if (transform) {
3571
- el.style.cssText = `position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;`;
3572
- } else {
3573
- el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(0,-9999px,0);transform-origin:0 0;`;
3653
+ scene.updateMatrixWorld();
3654
+ if (transform) {
3655
+ el.style.cssText = `position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;`;
3656
+ } else {
3657
+ el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(0,-9999px,0);transform-origin:0 0;`;
3658
+ }
3574
3659
  }
3575
3660
  if (target) {
3576
3661
  if (prepend) target.prepend(el);
3577
3662
  else target.appendChild(el);
3578
3663
  }
3579
3664
  return () => {
3580
- if (root.current) {
3581
- root.current.unmount();
3582
- root.current = null;
3583
- }
3584
3665
  if (target && target.contains(el)) {
3585
3666
  target.removeChild(el);
3586
3667
  }
@@ -3714,8 +3795,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
3714
3795
  if (transformOuterRef.current) {
3715
3796
  const el2 = transformOuterRef.current.children[0];
3716
3797
  if (el2?.clientWidth && el2?.clientHeight) {
3717
- const { isOrthographicCamera } = camera;
3718
- if (isOrthographicCamera || geometry) {
3798
+ if (geometry) {
3719
3799
  if (props.scale) {
3720
3800
  if (!Array.isArray(props.scale)) {
3721
3801
  occlusionMeshRef.current.scale.setScalar(1 / props.scale);
@@ -3747,64 +3827,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
3747
3827
  }
3748
3828
  }
3749
3829
  });
3750
- const shaders = React.useMemo(
3751
- () => ({
3752
- vertexShader: !transform ? (
3753
- /* glsl */
3754
- `
3755
- /*
3756
- This shader is from the THREE's SpriteMaterial.
3757
- We need to turn the backing plane into a Sprite
3758
- (make it always face the camera) if "transfrom"
3759
- is false.
3760
- */
3761
- #include <common>
3762
-
3763
- void main() {
3764
- vec2 center = vec2(0., 1.);
3765
- float rotation = 0.0;
3766
-
3767
- // This is somewhat arbitrary, but it seems to work well
3768
- // Need to figure out how to derive this dynamically if it even matters
3769
- float size = 0.03;
3770
-
3771
- vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
3772
- vec2 scale;
3773
- scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );
3774
- scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );
3775
-
3776
- bool isPerspective = isPerspectiveMatrix( projectionMatrix );
3777
- if ( isPerspective ) scale *= - mvPosition.z;
3778
-
3779
- vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale * size;
3780
- vec2 rotatedPosition;
3781
- rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
3782
- rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
3783
- mvPosition.xy += rotatedPosition;
3784
-
3785
- gl_Position = projectionMatrix * mvPosition;
3786
- }
3787
- `
3788
- ) : void 0,
3789
- fragmentShader: (
3790
- /* glsl */
3791
- `
3792
- void main() {
3793
- gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
3794
- }
3795
- `
3796
- )
3797
- }),
3798
- [transform]
3799
- );
3800
- return /* @__PURE__ */ React.createElement("group", { ...props, ref: group }, occlude && !isRayCastOcclusion && /* @__PURE__ */ React.createElement("mesh", { castShadow, receiveShadow, ref: occlusionMeshRef }, geometry || /* @__PURE__ */ React.createElement("planeGeometry", null), material || /* @__PURE__ */ React.createElement(
3801
- "shaderMaterial",
3802
- {
3803
- side: DoubleSide,
3804
- vertexShader: shaders.vertexShader,
3805
- fragmentShader: shaders.fragmentShader
3806
- }
3807
- )));
3830
+ return /* @__PURE__ */ React.createElement("group", { ...props, ref: group }, occlude && !isRayCastOcclusion && /* @__PURE__ */ React.createElement("mesh", { castShadow, receiveShadow, ref: occlusionMeshRef }, geometry || /* @__PURE__ */ React.createElement("planeGeometry", null), material));
3808
3831
  }
3809
3832
  );
3810
3833
 
@@ -4657,6 +4680,7 @@ const mW = /* @__PURE__ */ new THREE.Matrix4();
4657
4680
  const mL = /* @__PURE__ */ new THREE.Matrix4();
4658
4681
  const mL0Inv = /* @__PURE__ */ new THREE.Matrix4();
4659
4682
  const mdL = /* @__PURE__ */ new THREE.Matrix4();
4683
+ const mdW = /* @__PURE__ */ new THREE.Matrix4();
4660
4684
  const mG = /* @__PURE__ */ new THREE.Matrix4();
4661
4685
  const bb = /* @__PURE__ */ new THREE.Box3();
4662
4686
  const bbObj = /* @__PURE__ */ new THREE.Box3();
@@ -4771,7 +4795,8 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
4771
4795
  onDragStart && onDragStart(props2);
4772
4796
  invalidate();
4773
4797
  },
4774
- onDrag: (mdW) => {
4798
+ onDrag: (mdW_) => {
4799
+ mdW.copy(mdW_);
4775
4800
  mP.copy(parentRef.current.matrixWorld);
4776
4801
  mPInv.copy(mP).invert();
4777
4802
  mW.copy(mW0).premultiply(mdW);
@@ -4783,12 +4808,12 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
4783
4808
  }
4784
4809
  const target = resolveObject(object);
4785
4810
  if (target) target.matrix.copy(mL);
4786
- onDrag && onDrag(mL, mdL, mW, mdW);
4811
+ onDrag && onDrag({ local: mL, deltaLocal: mdL, world: mW, deltaWorld: mdW });
4787
4812
  invalidate();
4788
4813
  },
4789
4814
  onDragEnd: () => {
4790
4815
  dragState.current = null;
4791
- if (onDragEnd) onDragEnd();
4816
+ if (onDragEnd) onDragEnd({ local: mL, deltaLocal: mdL, world: mW, deltaWorld: mdW });
4792
4817
  invalidate();
4793
4818
  },
4794
4819
  onHover: (props2) => {
@@ -4899,7 +4924,9 @@ const TransformControls = /* @__PURE__ */ React.forwardRef(
4899
4924
  const group = React.useRef(null);
4900
4925
  React.useLayoutEffect(() => {
4901
4926
  if (object) {
4902
- controls.attach(object instanceof THREE.Object3D ? object : object.current);
4927
+ controls.attach(
4928
+ object instanceof THREE.Object3D ? object : object.current
4929
+ );
4903
4930
  } else if (group.current instanceof THREE.Object3D) {
4904
4931
  controls.attach(group.current);
4905
4932
  }
@@ -4995,7 +5022,7 @@ const PointMaterial = /* @__PURE__ */ React.forwardRef((props, ref) => {
4995
5022
  return /* @__PURE__ */ React.createElement("primitive", { ...props, object: material, ref, attach: "material" });
4996
5023
  });
4997
5024
 
4998
- const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, loop = true, autoplay, ...props }, ref) => {
5025
+ const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, loop = false, autoplay, ...props }, ref) => {
4999
5026
  const sound = React.useRef(null);
5000
5027
  React.useImperativeHandle(ref, () => sound.current, []);
5001
5028
  const camera = useThree(({ camera: camera2 }) => camera2);
@@ -5007,7 +5034,9 @@ const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, l
5007
5034
  _sound.setBuffer(Array.isArray(buffer) ? buffer[0] : buffer);
5008
5035
  _sound.setRefDistance(distance);
5009
5036
  _sound.setLoop(loop);
5010
- if (autoplay && !_sound.isPlaying) _sound.play();
5037
+ if (autoplay && !_sound.isPlaying) {
5038
+ _sound.play();
5039
+ }
5011
5040
  }
5012
5041
  }, [buffer, camera, distance, loop]);
5013
5042
  React.useEffect(() => {
@@ -5076,7 +5105,6 @@ const tempMatrix = /* @__PURE__ */ new THREE.Matrix4();
5076
5105
  const translation = /* @__PURE__ */ new THREE.Vector3();
5077
5106
  const rotation = /* @__PURE__ */ new THREE.Quaternion();
5078
5107
  const scale = /* @__PURE__ */ new THREE.Vector3();
5079
- const isInstancedBufferAttribute = (attr) => attr.isInstancedBufferAttribute;
5080
5108
  const Instance = /* @__PURE__ */ React.forwardRef(({ context, children, ...props }, ref) => {
5081
5109
  React.useMemo(() => extend({ PositionMesh }), []);
5082
5110
  const group = React.useRef(null);
@@ -5096,24 +5124,20 @@ const Instances = /* @__PURE__ */ React.forwardRef(({ context, children, range,
5096
5124
  const parentRef = React.useRef(null);
5097
5125
  React.useImperativeHandle(ref, () => parentRef.current, []);
5098
5126
  const [instances, setInstances] = React.useState([]);
5127
+ const boundsDirty = React.useRef(true);
5099
5128
  const [[matrices, colors]] = React.useState(() => {
5100
5129
  const mArray = new Float32Array(limit * 16);
5101
5130
  for (let i = 0; i < limit; i++) tempMatrix.identity().toArray(mArray, i * 16);
5102
5131
  return [mArray, new Float32Array([...new Array(limit * 3)].map(() => 1))];
5103
5132
  });
5104
5133
  React.useEffect(() => {
5105
- parentRef.current.instanceMatrix.needsUpdate = true;
5134
+ if (parentRef.current) parentRef.current.instanceMatrix.needsUpdate = true;
5106
5135
  });
5107
5136
  let iterations = 0;
5108
5137
  let count = 0;
5109
- const attributes = React.useRef([]);
5110
- React.useLayoutEffect(() => {
5111
- attributes.current = Object.entries(parentRef.current.geometry.attributes).filter(
5112
- ([_name, value]) => isInstancedBufferAttribute(value)
5113
- );
5114
- });
5115
5138
  useFrame(() => {
5116
5139
  if (frames === Infinity || iterations < frames) {
5140
+ if (!parentRef.current) return;
5117
5141
  parentRef.current.updateMatrix();
5118
5142
  parentRef.current.updateMatrixWorld();
5119
5143
  parentMatrix.copy(parentRef.current.matrixWorld).invert();
@@ -5134,13 +5158,22 @@ const Instances = /* @__PURE__ */ React.forwardRef(({ context, children, range,
5134
5158
  }
5135
5159
  iterations++;
5136
5160
  }
5161
+ if (boundsDirty.current && (frames === Infinity || iterations === frames)) {
5162
+ boundsDirty.current = false;
5163
+ if (parentRef.current.boundingBox) parentRef.current.computeBoundingBox();
5164
+ if (parentRef.current.boundingSphere) parentRef.current.computeBoundingSphere();
5165
+ }
5137
5166
  });
5138
5167
  const api = React.useMemo(
5139
5168
  () => ({
5140
5169
  getParent: () => parentRef,
5141
5170
  subscribe: (ref2) => {
5142
5171
  setInstances((instances2) => [...instances2, ref2]);
5143
- return () => setInstances((instances2) => instances2.filter((item) => item.current !== ref2.current));
5172
+ boundsDirty.current = true;
5173
+ return () => {
5174
+ setInstances((instances2) => instances2.filter((item) => item.current !== ref2.current));
5175
+ boundsDirty.current = true;
5176
+ };
5144
5177
  }
5145
5178
  }),
5146
5179
  []
@@ -5165,10 +5198,23 @@ const Merged = /* @__PURE__ */ React.forwardRef(function Merged2({ meshes, child
5165
5198
  if (!isArray) {
5166
5199
  for (const key of Object.keys(meshes)) if (!meshes[key].isMesh) delete meshes[key];
5167
5200
  }
5168
- const render = (args) => isArray ? children(...args) : children(
5169
- Object.keys(meshes).filter((key) => meshes[key].isMesh).reduce((acc, key, i) => ({ ...acc, [key]: args[i] }), {})
5170
- );
5171
- const components = (isArray ? meshes : Object.values(meshes)).map(({ geometry, material }) => /* @__PURE__ */ React.createElement(Instances, { key: geometry.uuid, geometry, material, ...props }));
5201
+ const render = (args) => {
5202
+ if (isArray) {
5203
+ return children(
5204
+ ...args
5205
+ );
5206
+ }
5207
+ const instanceMap = {};
5208
+ const keys = Object.keys(meshes).filter((key) => meshes[key].isMesh);
5209
+ keys.forEach((key, i) => {
5210
+ instanceMap[key] = args[i];
5211
+ });
5212
+ return children(instanceMap);
5213
+ };
5214
+ const components = (isArray ? meshes : Object.values(meshes)).map((mesh) => {
5215
+ const { geometry, material } = mesh;
5216
+ return /* @__PURE__ */ React.createElement(Instances, { key: geometry.uuid, geometry, material, ...props });
5217
+ });
5172
5218
  return /* @__PURE__ */ React.createElement("group", { ref }, renderRecursive(render, components));
5173
5219
  });
5174
5220
  function renderRecursive(render, components, results = []) {
@@ -6242,12 +6288,13 @@ function Sampler({ children, weight, transform, instances, mesh, count = 16, ...
6242
6288
  return /* @__PURE__ */ React.createElement("group", { ref: group, ...props }, children);
6243
6289
  }
6244
6290
 
6291
+ const pathStyle = (path) => path.userData?.style;
6245
6292
  const Svg = /* @__PURE__ */ forwardRef(
6246
6293
  function R3FSvg({ src, skipFill, skipStrokes, fillMaterial, strokeMaterial, fillMeshProps, strokeMeshProps, ...props }, ref) {
6247
6294
  const svg = useLoader(SVGLoader, !src.startsWith("<svg") ? src : `data:image/svg+xml;utf8,${src}`);
6248
6295
  const strokeGeometries = useMemo(
6249
6296
  () => skipStrokes ? [] : svg.paths.map(
6250
- (path) => path.userData?.style.stroke === void 0 || path.userData.style.stroke === "none" ? null : path.subPaths.map((subPath) => SVGLoader.pointsToStroke(subPath.getPoints(), path.userData.style))
6297
+ (path) => pathStyle(path)?.stroke === void 0 || pathStyle(path).stroke === "none" ? null : path.subPaths.map((subPath) => SVGLoader.pointsToStroke(subPath.getPoints(), pathStyle(path)))
6251
6298
  ),
6252
6299
  [svg, skipStrokes]
6253
6300
  );
@@ -6255,21 +6302,21 @@ const Svg = /* @__PURE__ */ forwardRef(
6255
6302
  return () => strokeGeometries.forEach((group) => group && group.map((g) => g.dispose()));
6256
6303
  }, [strokeGeometries]);
6257
6304
  let renderOrder = 0;
6258
- return /* @__PURE__ */ React.createElement("object3D", { ref, ...props }, /* @__PURE__ */ React.createElement("object3D", { scale: [1, -1, 1] }, svg.paths.map((path, p) => /* @__PURE__ */ React.createElement(Fragment, { key: p }, !skipFill && path.userData?.style.fill !== void 0 && path.userData.style.fill !== "none" && SVGLoader.createShapes(path).map((shape, s) => /* @__PURE__ */ React.createElement("mesh", { key: s, ...fillMeshProps, renderOrder: renderOrder++ }, /* @__PURE__ */ React.createElement("shapeGeometry", { args: [shape] }), /* @__PURE__ */ React.createElement(
6305
+ return /* @__PURE__ */ React.createElement("object3D", { ref, ...props }, /* @__PURE__ */ React.createElement("object3D", { scale: [1, -1, 1] }, svg.paths.map((path, p) => /* @__PURE__ */ React.createElement(Fragment, { key: p }, !skipFill && pathStyle(path)?.fill !== void 0 && pathStyle(path).fill !== "none" && SVGLoader.createShapes(path).map((shape, s) => /* @__PURE__ */ React.createElement("mesh", { key: s, ...fillMeshProps, renderOrder: renderOrder++ }, /* @__PURE__ */ React.createElement("shapeGeometry", { args: [shape] }), /* @__PURE__ */ React.createElement(
6259
6306
  "meshBasicMaterial",
6260
6307
  {
6261
- color: path.userData.style.fill,
6262
- opacity: path.userData.style.fillOpacity,
6308
+ color: pathStyle(path).fill,
6309
+ opacity: pathStyle(path).fillOpacity,
6263
6310
  transparent: true,
6264
6311
  side: DoubleSide,
6265
6312
  depthWrite: false,
6266
6313
  ...fillMaterial
6267
6314
  }
6268
- ))), !skipStrokes && path.userData?.style.stroke !== void 0 && path.userData.style.stroke !== "none" && path.subPaths.map((_subPath, s) => /* @__PURE__ */ React.createElement("mesh", { key: s, geometry: strokeGeometries[p][s], ...strokeMeshProps, renderOrder: renderOrder++ }, /* @__PURE__ */ React.createElement(
6315
+ ))), !skipStrokes && pathStyle(path)?.stroke !== void 0 && pathStyle(path).stroke !== "none" && path.subPaths.map((_subPath, s) => /* @__PURE__ */ React.createElement("mesh", { key: s, geometry: strokeGeometries[p][s], ...strokeMeshProps, renderOrder: renderOrder++ }, /* @__PURE__ */ React.createElement(
6269
6316
  "meshBasicMaterial",
6270
6317
  {
6271
- color: path.userData.style.stroke,
6272
- opacity: path.userData.style.strokeOpacity,
6318
+ color: pathStyle(path).stroke,
6319
+ opacity: pathStyle(path).strokeOpacity,
6273
6320
  transparent: true,
6274
6321
  side: DoubleSide,
6275
6322
  depthWrite: false,
@@ -6492,8 +6539,8 @@ function useVideoTexture(srcOrSrcObject, {
6492
6539
  });
6493
6540
  if (src && IS_BROWSER && src.endsWith(".m3u8")) {
6494
6541
  const hls = hlsRef.current = await getHls(hlsConfig);
6495
- if (hls) {
6496
- hls.on(Events.MEDIA_ATTACHED, () => void hls.loadSource(src));
6542
+ if (hls && _HLSModule) {
6543
+ hls.on(_HLSModule.Events.MEDIA_ATTACHED, () => void hls.loadSource(src));
6497
6544
  hls.attachMedia(video2);
6498
6545
  }
6499
6546
  }
@@ -6713,9 +6760,125 @@ function Fbx({
6713
6760
  return /* @__PURE__ */ React.createElement(Clone, { ...props, object });
6714
6761
  }
6715
6762
 
6763
+ const SERVICE_KEY = "__drei_ktx2_service__";
6764
+ const DEFAULT_TRANSCODER_PATH = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
6765
+ class KTX2LoaderServiceImpl {
6766
+ loader = null;
6767
+ renderer = null;
6768
+ _isReady = false;
6769
+ transcoderPath = DEFAULT_TRANSCODER_PATH;
6770
+ pendingCallbacks = [];
6771
+ /**
6772
+ * Get or create the singleton KTX2Loader instance.
6773
+ * The loader is created lazily on first access.
6774
+ */
6775
+ getLoader() {
6776
+ if (!this.loader) {
6777
+ this.loader = new KTX2Loader();
6778
+ this.loader.setTranscoderPath(this.transcoderPath);
6779
+ }
6780
+ return this.loader;
6781
+ }
6782
+ /**
6783
+ * Register a renderer and call detectSupport.
6784
+ * Should be called from within React context (useLayoutEffect).
6785
+ * Flushes any queued callbacks.
6786
+ */
6787
+ registerRenderer(renderer) {
6788
+ if (this._isReady && this.renderer === renderer) {
6789
+ return;
6790
+ }
6791
+ this.renderer = renderer;
6792
+ const loader = this.getLoader();
6793
+ loader.detectSupport(renderer);
6794
+ this._isReady = true;
6795
+ this.flushPendingCallbacks();
6796
+ }
6797
+ /**
6798
+ * Check if the service is ready (has renderer registered).
6799
+ */
6800
+ isReady() {
6801
+ return this._isReady;
6802
+ }
6803
+ /**
6804
+ * Get the registered renderer, if any.
6805
+ */
6806
+ getRenderer() {
6807
+ return this.renderer;
6808
+ }
6809
+ /**
6810
+ * Register a callback to run when renderer becomes available.
6811
+ * If renderer is already available, runs immediately.
6812
+ */
6813
+ onReady(callback) {
6814
+ if (this._isReady) {
6815
+ callback();
6816
+ } else {
6817
+ this.pendingCallbacks.push(callback);
6818
+ }
6819
+ }
6820
+ /**
6821
+ * Process all pending callbacks.
6822
+ */
6823
+ flushPendingCallbacks() {
6824
+ const callbacks = this.pendingCallbacks;
6825
+ this.pendingCallbacks = [];
6826
+ for (const callback of callbacks) {
6827
+ try {
6828
+ callback();
6829
+ } catch (error) {
6830
+ console.error("KTX2LoaderService: Error in pending callback:", error);
6831
+ }
6832
+ }
6833
+ }
6834
+ /**
6835
+ * Set the transcoder path for basis/ktx2 decoding.
6836
+ */
6837
+ setTranscoderPath(path) {
6838
+ this.transcoderPath = path;
6839
+ if (this.loader) {
6840
+ this.loader.setTranscoderPath(path);
6841
+ }
6842
+ }
6843
+ /**
6844
+ * Get the current transcoder path.
6845
+ */
6846
+ getTranscoderPath() {
6847
+ return this.transcoderPath;
6848
+ }
6849
+ /**
6850
+ * Dispose of the loader and reset state.
6851
+ * Useful for testing or cleanup.
6852
+ */
6853
+ dispose() {
6854
+ if (this.loader) {
6855
+ this.loader.dispose();
6856
+ }
6857
+ const path = this.transcoderPath;
6858
+ this.loader = null;
6859
+ this.renderer = null;
6860
+ this._isReady = false;
6861
+ this.transcoderPath = path;
6862
+ this.pendingCallbacks = [];
6863
+ }
6864
+ }
6865
+ const KTX2LoaderService = globalThis[SERVICE_KEY] || (globalThis[SERVICE_KEY] = new KTX2LoaderServiceImpl());
6866
+
6716
6867
  let dracoLoader = null;
6717
6868
  let decoderPath = "https://www.gstatic.com/draco/versioned/decoders/1.5.5/";
6718
- function extensions(useDraco = true, useMeshopt = true, extendLoader) {
6869
+ let legacyApiWarned = false;
6870
+ function isOptionsObject(arg) {
6871
+ return typeof arg === "object" && arg !== null && !Array.isArray(arg);
6872
+ }
6873
+ function warnLegacyApi() {
6874
+ if (!legacyApiWarned) {
6875
+ legacyApiWarned = true;
6876
+ console.warn(
6877
+ "useGLTF: Boolean arguments are deprecated. Use options object instead:\n useGLTF(path, { draco: true, meshopt: true, ktx2: true })"
6878
+ );
6879
+ }
6880
+ }
6881
+ function extensions(useDraco = true, useMeshopt = true, useKTX2 = false, extendLoader, renderer) {
6719
6882
  return (loader) => {
6720
6883
  if (extendLoader) {
6721
6884
  extendLoader(loader);
@@ -6731,36 +6894,110 @@ function extensions(useDraco = true, useMeshopt = true, extendLoader) {
6731
6894
  const decoder = typeof MeshoptDecoder === "function" ? MeshoptDecoder() : MeshoptDecoder;
6732
6895
  loader.setMeshoptDecoder(decoder);
6733
6896
  }
6897
+ if (useKTX2) {
6898
+ const ktx2Loader = KTX2LoaderService.getLoader();
6899
+ if (typeof useKTX2 === "string") {
6900
+ ktx2Loader.setTranscoderPath(useKTX2);
6901
+ }
6902
+ if (renderer) {
6903
+ ktx2Loader.detectSupport(renderer);
6904
+ }
6905
+ loader.setKTX2Loader(ktx2Loader);
6906
+ }
6734
6907
  };
6735
6908
  }
6736
- const useGLTF = (path, useDraco, useMeshopt, extendLoader) => useLoader(GLTFLoader, path, extensions(useDraco, useMeshopt, extendLoader));
6737
- useGLTF.preload = (path, useDraco, useMeshopt, extendLoader) => useLoader.preload(GLTFLoader, path, extensions(useDraco, useMeshopt, extendLoader));
6909
+ function useGLTF(path, optionsOrDraco, useMeshoptArg, useKTX2Arg, extendLoaderArg) {
6910
+ let draco = true;
6911
+ let meshopt = true;
6912
+ let ktx2 = false;
6913
+ let extendLoader;
6914
+ if (isOptionsObject(optionsOrDraco)) {
6915
+ draco = optionsOrDraco.draco ?? true;
6916
+ meshopt = optionsOrDraco.meshopt ?? true;
6917
+ ktx2 = optionsOrDraco.ktx2 ?? false;
6918
+ extendLoader = optionsOrDraco.extendLoader;
6919
+ } else if (optionsOrDraco !== void 0) {
6920
+ warnLegacyApi();
6921
+ draco = optionsOrDraco;
6922
+ meshopt = useMeshoptArg ?? true;
6923
+ ktx2 = useKTX2Arg ?? false;
6924
+ extendLoader = extendLoaderArg;
6925
+ }
6926
+ const renderer = useThree((state) => state.renderer);
6927
+ useLayoutEffect(() => {
6928
+ if (ktx2) {
6929
+ KTX2LoaderService.registerRenderer(renderer);
6930
+ }
6931
+ }, [ktx2, renderer]);
6932
+ return useLoader(GLTFLoader, path, extensions(draco, meshopt, ktx2, extendLoader, ktx2 ? renderer : void 0));
6933
+ }
6934
+ useGLTF.preload = (path, optionsOrDraco, useMeshoptArg, useKTX2Arg, extendLoaderArg) => {
6935
+ let draco = true;
6936
+ let meshopt = true;
6937
+ let ktx2 = false;
6938
+ let extendLoader;
6939
+ if (isOptionsObject(optionsOrDraco)) {
6940
+ draco = optionsOrDraco.draco ?? true;
6941
+ meshopt = optionsOrDraco.meshopt ?? true;
6942
+ ktx2 = optionsOrDraco.ktx2 ?? false;
6943
+ extendLoader = optionsOrDraco.extendLoader;
6944
+ } else if (optionsOrDraco !== void 0) {
6945
+ warnLegacyApi();
6946
+ draco = optionsOrDraco;
6947
+ meshopt = useMeshoptArg ?? true;
6948
+ ktx2 = useKTX2Arg ?? false;
6949
+ extendLoader = extendLoaderArg;
6950
+ }
6951
+ if (ktx2) {
6952
+ KTX2LoaderService.onReady(() => {
6953
+ const renderer = KTX2LoaderService.getRenderer();
6954
+ useLoader.preload(GLTFLoader, path, extensions(draco, meshopt, ktx2, extendLoader, renderer));
6955
+ });
6956
+ } else {
6957
+ useLoader.preload(GLTFLoader, path, extensions(draco, meshopt, false, extendLoader));
6958
+ }
6959
+ };
6738
6960
  useGLTF.clear = (path) => useLoader.clear(GLTFLoader, path);
6739
6961
  useGLTF.setDecoderPath = (path) => {
6740
6962
  decoderPath = path;
6741
6963
  };
6964
+ useGLTF.setKTX2TranscoderPath = (path) => {
6965
+ KTX2LoaderService.setTranscoderPath(path);
6966
+ };
6742
6967
  const Gltf = /* @__PURE__ */ React.forwardRef(
6743
- ({ src, useDraco, useMeshOpt, extendLoader, ...props }, ref) => {
6744
- const { scene } = useGLTF(src, useDraco, useMeshOpt, extendLoader);
6968
+ ({ src, useDraco, useMeshOpt, extendLoader, options, ...props }, ref) => {
6969
+ const opts = options ?? {
6970
+ draco: useDraco,
6971
+ meshopt: useMeshOpt,
6972
+ extendLoader
6973
+ };
6974
+ const { scene } = useGLTF(src, opts);
6745
6975
  return /* @__PURE__ */ React.createElement(Clone, { ref, ...props, object: scene });
6746
6976
  }
6747
6977
  );
6748
6978
 
6749
- let transcoderPath = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
6750
6979
  function useKTX2(input, basisPath = true, extendLoader) {
6751
6980
  const renderer = useThree((state) => state.renderer);
6981
+ useLayoutEffect(() => {
6982
+ KTX2LoaderService.registerRenderer(renderer);
6983
+ }, [renderer]);
6752
6984
  const textures = useLoader(KTX2Loader, IsObject(input) ? Object.values(input) : input, (loader) => {
6753
6985
  if (extendLoader) {
6754
6986
  extendLoader(loader);
6755
6987
  }
6756
6988
  if (basisPath) {
6757
- loader.setTranscoderPath(typeof basisPath === "string" ? basisPath : transcoderPath);
6989
+ const path = typeof basisPath === "string" ? basisPath : KTX2LoaderService.getTranscoderPath();
6990
+ loader.setTranscoderPath(path);
6758
6991
  }
6759
6992
  loader.detectSupport(renderer);
6760
6993
  });
6761
6994
  useEffect(() => {
6762
6995
  const array = Array.isArray(textures) ? textures : [textures];
6763
- array.forEach((texture) => renderer.initTexture(texture));
6996
+ array.forEach((texture) => {
6997
+ if ("initTexture" in renderer) {
6998
+ renderer.initTexture(texture);
6999
+ }
7000
+ });
6764
7001
  }, [renderer, textures]);
6765
7002
  if (IsObject(input)) {
6766
7003
  const keys = Object.keys(input);
@@ -6771,23 +7008,81 @@ function useKTX2(input, basisPath = true, extendLoader) {
6771
7008
  return textures;
6772
7009
  }
6773
7010
  }
6774
- useKTX2.preload = (url, basisPath = true, extendLoader) => useLoader.preload(KTX2Loader, url, (loader) => {
6775
- if (extendLoader) {
6776
- extendLoader(loader);
6777
- }
6778
- if (basisPath) {
6779
- loader.setTranscoderPath(typeof basisPath === "string" ? basisPath : transcoderPath);
6780
- }
6781
- });
7011
+ useKTX2.preload = (url, basisPath = true, extendLoader) => {
7012
+ KTX2LoaderService.onReady(() => {
7013
+ const renderer = KTX2LoaderService.getRenderer();
7014
+ useLoader.preload(KTX2Loader, url, (loader) => {
7015
+ if (extendLoader) {
7016
+ extendLoader(loader);
7017
+ }
7018
+ if (basisPath) {
7019
+ const path = typeof basisPath === "string" ? basisPath : KTX2LoaderService.getTranscoderPath();
7020
+ loader.setTranscoderPath(path);
7021
+ }
7022
+ if (renderer) {
7023
+ loader.detectSupport(renderer);
7024
+ }
7025
+ });
7026
+ });
7027
+ };
6782
7028
  useKTX2.clear = (input) => useLoader.clear(KTX2Loader, input);
6783
7029
  useKTX2.setTranscoderPath = (path) => {
6784
- transcoderPath = path;
7030
+ KTX2LoaderService.setTranscoderPath(path);
6785
7031
  };
6786
7032
  const Ktx2 = ({ children, input, basisPath, extendLoader }) => {
6787
7033
  const texture = useKTX2(input, basisPath, extendLoader);
6788
7034
  return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(texture));
6789
7035
  };
6790
7036
 
7037
+ const useVariants = (model, inVariant) => {
7038
+ const [activeVariant, setActiveVariant] = useState(null);
7039
+ const [materials, setMaterials] = useState([]);
7040
+ useEffect(() => {
7041
+ model.parser.getDependencies("material").then((materials2) => {
7042
+ setMaterials(materials2);
7043
+ });
7044
+ }, [model]);
7045
+ const variants = useMemo(() => {
7046
+ return model.userData.gltfExtensions?.KHR_materials_variants?.variants;
7047
+ }, [model]);
7048
+ const applyVariant = useCallback(
7049
+ (variantIndex) => {
7050
+ model.scene.traverse(async (object) => {
7051
+ if (!("isMesh" in object) || !object.userData.gltfExtensions) return;
7052
+ const meshObject = object;
7053
+ const meshVariantDef = meshObject.userData.gltfExtensions.KHR_materials_variants;
7054
+ if (!meshVariantDef) return;
7055
+ if (!meshObject.userData.originalMaterial) meshObject.userData.originalMaterial = meshObject.material;
7056
+ const mapping = meshVariantDef.mappings.find((mapping2) => mapping2.variants.includes(variantIndex));
7057
+ if (mapping) {
7058
+ meshObject.material = await model.parser.getDependency("material", mapping.material);
7059
+ model.parser.assignFinalMaterial(meshObject);
7060
+ } else meshObject.material = meshObject.userData.originalMaterial;
7061
+ if (Array.isArray(meshObject.material)) for (const mat of meshObject.material) mat.needsUpdate = true;
7062
+ else meshObject.material.needsUpdate = true;
7063
+ });
7064
+ },
7065
+ [model]
7066
+ );
7067
+ const setVariant = useCallback(
7068
+ (variantName) => {
7069
+ if (!variants) return;
7070
+ const newVariant = variantName && variants.some((v) => v.name === variantName) ? variantName : null;
7071
+ setActiveVariant(newVariant);
7072
+ },
7073
+ [variants]
7074
+ );
7075
+ useEffect(() => {
7076
+ if (!variants) return;
7077
+ const variantIndex = variants.findIndex((v) => v.name === activeVariant);
7078
+ applyVariant(variantIndex > -1 ? variantIndex : 0);
7079
+ }, [variants, activeVariant, applyVariant]);
7080
+ useEffect(() => {
7081
+ setVariant(inVariant ?? null);
7082
+ }, [inVariant, setVariant]);
7083
+ return { variants, activeVariant, setVariant, materials };
7084
+ };
7085
+
6791
7086
  const WebcamVideoTexture = /* @__PURE__ */ forwardRef(
6792
7087
  ({
6793
7088
  constraints = {
@@ -6975,6 +7270,7 @@ function useEffectfulState(fn, deps = [], cb) {
6975
7270
  }
6976
7271
 
6977
7272
  function Stats({ showPanel = 0, className, parent }) {
7273
+ React.useEffect(() => void console.warn("drei: <Stats /> is deprecated, use <StatsGl /> instead."), []);
6978
7274
  const stats = useEffectfulState(() => new StatsImpl(), []);
6979
7275
  React.useEffect(() => {
6980
7276
  if (stats) {
@@ -7003,6 +7299,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
7003
7299
  const stats2 = new Stats$1({
7004
7300
  ...props
7005
7301
  });
7302
+ stats2.init(renderer);
7006
7303
  return stats2;
7007
7304
  }, [renderer]);
7008
7305
  React.useImperativeHandle(fref, () => stats.domElement, [stats]);
@@ -7020,7 +7317,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
7020
7317
  return () => {
7021
7318
  if (classNames.length) stats.domElement.classList.remove(...classNames);
7022
7319
  node?.removeChild(stats.domElement);
7023
- stats.end();
7320
+ stats.dispose();
7024
7321
  };
7025
7322
  }
7026
7323
  }, [parent, stats, className, id, clearStatsGlStyle]);
@@ -7028,7 +7325,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
7028
7325
  () => {
7029
7326
  stats.begin();
7030
7327
  },
7031
- { before: "render" }
7328
+ { before: "update" }
7032
7329
  );
7033
7330
  useFrame(
7034
7331
  () => {
@@ -7078,11 +7375,11 @@ const RenderCubeTexture = /* @__PURE__ */ React.forwardRef(
7078
7375
  depthBuffer,
7079
7376
  generateMipmaps
7080
7377
  };
7081
- const fboA2 = new THREE.WebGLCubeRenderTarget(fboSize, settings);
7378
+ const fboA2 = new WebGLCubeRenderTarget(fboSize, settings);
7082
7379
  fboA2.texture.isRenderTargetTexture = !flip;
7083
7380
  fboA2.texture.flipY = true;
7084
7381
  fboA2.texture.type = THREE.HalfFloatType;
7085
- const fboB2 = new THREE.WebGLCubeRenderTarget(fboSize, settings);
7382
+ const fboB2 = new WebGLCubeRenderTarget(fboSize, settings);
7086
7383
  fboB2.texture.isRenderTargetTexture = !flip;
7087
7384
  fboB2.texture.flipY = true;
7088
7385
  fboB2.texture.type = THREE.HalfFloatType;
@@ -7411,8 +7708,9 @@ const TUNNEL_KEY = "__drei_view_tunnel__";
7411
7708
  const tracked = globalThis[TUNNEL_KEY] || (globalThis[TUNNEL_KEY] = tunnel());
7412
7709
  function computeContainerPosition(canvasSize, trackRect, forceEven) {
7413
7710
  const { right, top: trackTop, left: trackLeft, bottom: trackBottom, width, height } = trackRect;
7414
- const isOffscreen = trackRect.bottom < 0 || trackTop > canvasSize.height || right < 0 || trackRect.left > canvasSize.width;
7415
7711
  const canvasBottom = canvasSize.top + canvasSize.height;
7712
+ const canvasRight = canvasSize.left + canvasSize.width;
7713
+ const isOffscreen = trackBottom < canvasSize.top || trackTop > canvasBottom || right < canvasSize.left || trackLeft > canvasRight;
7416
7714
  const rawBottom = canvasBottom - trackBottom;
7417
7715
  const rawLeft = trackLeft - canvasSize.left;
7418
7716
  const rawTop = trackTop - canvasSize.top;
@@ -7972,12 +8270,12 @@ useEnvironment.preload = (preloadOptions) => {
7972
8270
  if (extensions) extensions(loader2);
7973
8271
  });
7974
8272
  };
7975
- const clearDefaultOptins = {
8273
+ const clearDefaultOptions = {
7976
8274
  files: defaultFiles,
7977
8275
  preset: void 0
7978
8276
  };
7979
8277
  useEnvironment.clear = (clearOptions) => {
7980
- const options = { ...clearDefaultOptins, ...clearOptions };
8278
+ const options = { ...clearDefaultOptions, ...clearOptions };
7981
8279
  let { files } = options;
7982
8280
  const { preset } = options;
7983
8281
  if (preset) {
@@ -8671,9 +8969,14 @@ function Select({
8671
8969
  const oldControlsEnabled = controls?.enabled;
8672
8970
  let isDown = false;
8673
8971
  function prepareRay(event, vec) {
8674
- const { offsetX, offsetY } = event;
8972
+ const canvas = gl.domElement;
8973
+ const rect = canvas.getBoundingClientRect();
8974
+ const x = event.clientX - rect.left;
8975
+ const y = event.clientY - rect.top;
8675
8976
  const { width, height } = size;
8676
- vec.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
8977
+ const normalizedX = x / width * 2 - 1;
8978
+ const normalizedY = -(y / height) * 2 + 1;
8979
+ vec.set(normalizedX, normalizedY, -1);
8677
8980
  }
8678
8981
  function onSelectStart(event) {
8679
8982
  if (controls) controls.enabled = false;
@@ -12918,7 +13221,7 @@ const FacemeshDatas = {
12918
13221
 
12919
13222
  const FaceLandmarkerContext = /* @__PURE__ */ createContext({});
12920
13223
  const FaceLandmarkerDefaults = {
12921
- basePath: "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.17/wasm",
13224
+ basePath: `https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@${"0.10.17"}/wasm`,
12922
13225
  options: {
12923
13226
  baseOptions: {
12924
13227
  modelAssetPath: "https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task",
@@ -13666,4 +13969,4 @@ const MarchingPlane = /* @__PURE__ */ React.forwardRef(
13666
13969
  }
13667
13970
  );
13668
13971
 
13669
- export { AdaptiveDpr, AdaptiveEvents, ArcballControls, BBAnchor, Backdrop, Billboard, Bounds, Box, Bvh, CameraControls, CameraShake, Capsule, CatmullRomLine, Center, Circle, Clone, Cloud, CloudInstance, Clouds, ComputedAttribute, Cone, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, Dodecahedron, DragControls, Edges, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, FaceControls, FaceLandmarker, FaceLandmarkerDefaults, Facemesh, FacemeshDatas, FacemeshEye, FacemeshEyeDefaults, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, Helper, Html, Hud, Icosahedron, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Loader, MapControls, MarchingCube, MarchingCubes, MarchingPlane, Mask, MatcapTexture, Merged, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, Outlines, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Select, Shadow, Shape, Sky, Sphere, Splat, SpriteAnimator, Stage, Stats, StatsGl, Svg, Tetrahedron, Text3D, Texture, Torus, TorusKnot, TrackballControls, Trail, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture, calcPosFromAngles, checkIfFrameIsEmpty, createInstances, getFirstFrame, meshBounds, presetsObj, useAnimations, useAspect, useBVH, useBounds, useContextBridge, useCubeCamera, useCubeTexture, useCursor, useCustomRaycast, useDepthBuffer, useDetectGPU, useEnvironment, useFBO, useFBX, useFaceControls, useFaceLandmarker, useFont, useGLTF, useGizmoContext, useHelper, useIntersect, useKTX2, useKeyboardControls, useMask, useMatcapTexture, useMotion, useNormalTexture, usePerformanceMonitor, useProgress, useScroll, useSelect, useSpriteAnimator, useSpriteLoader, useSurfaceSampler, useTexture, useTrail, useTrailTexture, useVideoTexture };
13972
+ export { AdaptiveDpr, AdaptiveEvents, ArcballControls, BBAnchor, Backdrop, Billboard, Bounds, Box, Bvh, CameraControls, CameraShake, Capsule, CatmullRomLine, Center, Circle, Clone, Cloud, CloudInstance, Clouds, ComputedAttribute, Cone, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, Dodecahedron, DragControls, Edges, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, FaceControls, FaceLandmarker, FaceLandmarkerDefaults, Facemesh, FacemeshDatas, FacemeshEye, FacemeshEyeDefaults, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, Helper, Html, Hud, Icosahedron, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Loader, MapControls, MarchingCube, MarchingCubes, MarchingPlane, Mask, MatcapTexture, Merged, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, Outlines, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Select, Shadow, Shape, Sky, Sphere, Splat, SpriteAnimator, Stage, Stats, StatsGl, Svg, Tetrahedron, Text3D, Texture, Torus, TorusKnot, TrackballControls, Trail, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture, calcPosFromAngles, checkIfFrameIsEmpty, createInstances, getFirstFrame, meshBounds, presetsObj, useAnimations, useAspect, useBVH, useBounds, useContextBridge, useCubeCamera, useCubeTexture, useCursor, useCustomRaycast, useDepthBuffer, useDetectGPU, useEnvironment, useFBO, useFBX, useFaceControls, useFaceLandmarker, useFont, useGLTF, useGizmoContext, useHelper, useIntersect, useKTX2, useKeyboardControls, useMask, useMatcapTexture, useMotion, useNormalTexture, usePerformanceMonitor, useProgress, useScroll, useSelect, useSpriteAnimator, useSpriteLoader, useSurfaceSampler, useTexture, useTrail, useTrailTexture, useVariants, useVideoTexture };