@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/README.md +17 -1
- package/core/index.d.mts +194 -51
- package/core/index.d.ts +194 -51
- package/core/index.mjs +543 -240
- package/experimental/index.d.mts +20 -0
- package/experimental/index.d.ts +20 -0
- package/external/index.d.mts +38 -2
- package/external/index.d.ts +38 -2
- package/external/index.mjs +3 -4
- package/index.d.mts +211 -53
- package/index.d.ts +211 -53
- package/index.mjs +544 -241
- package/legacy/index.d.mts +211 -56
- package/legacy/index.d.ts +211 -56
- package/legacy/index.mjs +687 -260
- package/native/index.d.mts +219 -130
- package/native/index.d.ts +219 -130
- package/native/index.mjs +1225 -416
- package/package.json +7 -7
- package/webgpu/index.d.mts +249 -129
- package/webgpu/index.d.ts +249 -129
- package/webgpu/index.mjs +1468 -516
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,
|
|
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,
|
|
1466
|
+
const { camera, invalidate } = useThree();
|
|
1468
1467
|
const ref = React.useRef(null);
|
|
1469
|
-
const
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
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
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
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(
|
|
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
|
-
|
|
1696
|
-
|
|
1745
|
+
controls.addEventListener("start", onStartCb);
|
|
1746
|
+
controls.addEventListener("end", onEndCb);
|
|
1697
1747
|
return () => {
|
|
1698
|
-
controls.
|
|
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
|
|
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(() =>
|
|
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(
|
|
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 ||
|
|
1890
|
+
const explDomElement = domElement || events.connected || renderer.domElement;
|
|
1847
1891
|
const controls = React.useMemo(() => new OrbitControls$1(explCamera), [explCamera]);
|
|
1848
|
-
useFrame(
|
|
1849
|
-
|
|
1850
|
-
|
|
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(
|
|
1965
|
-
const
|
|
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
|
-
|
|
2029
|
+
renderer.domElement.style.cursor = "";
|
|
1984
2030
|
return () => {
|
|
1985
2031
|
explDomElement.style.cursor = "default";
|
|
1986
|
-
|
|
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
|
-
|
|
1994
|
-
easing.
|
|
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 =
|
|
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
|
|
2155
|
-
|
|
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,
|
|
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":
|
|
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":
|
|
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
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: (
|
|
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(
|
|
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 =
|
|
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)
|
|
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
|
-
|
|
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) =>
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
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
|
|
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
|
|
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.
|
|
6262
|
-
opacity: path.
|
|
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
|
|
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.
|
|
6272
|
-
opacity: path.
|
|
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
|
-
|
|
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
|
-
|
|
6737
|
-
|
|
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
|
|
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
|
-
|
|
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) =>
|
|
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) =>
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
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
|
-
|
|
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.
|
|
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: "
|
|
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
|
|
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
|
|
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
|
|
8273
|
+
const clearDefaultOptions = {
|
|
7976
8274
|
files: defaultFiles,
|
|
7977
8275
|
preset: void 0
|
|
7978
8276
|
};
|
|
7979
8277
|
useEnvironment.clear = (clearOptions) => {
|
|
7980
|
-
const options = { ...
|
|
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
|
|
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
|
-
|
|
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:
|
|
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 };
|