@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/legacy/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 } from 'react';
|
|
3
3
|
import { useThree, useFrame, extend, createPortal, applyProps, useInstanceHandle, context as context$a, useLoader, addEffect, addAfterEffect } from '@react-three/fiber';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
|
-
import { REVISION, WebGLRenderTarget, HalfFloatType, LinearFilter, Vector2, Scene, Camera, BufferGeometry, BufferAttribute, Mesh, MeshStandardMaterial, Plane as Plane$1, Vector3, Matrix4, Vector4, PerspectiveCamera as PerspectiveCamera$1, DepthTexture, DepthFormat, UnsignedShortType, Frustum, MeshPhysicalMaterial, RGBAFormat, UnsignedByteType, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, Object3D, WebGLCubeRenderTarget, 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, HalfFloatType, LinearFilter, Vector2, Scene, Camera, BufferGeometry, BufferAttribute, Mesh, MeshStandardMaterial, Plane as Plane$1, Vector3, Matrix4, Vector4, PerspectiveCamera as PerspectiveCamera$1, DepthTexture, DepthFormat, UnsignedShortType, Frustum, MeshPhysicalMaterial, RGBAFormat, UnsignedByteType, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, Object3D, WebGLCubeRenderTarget, CubeCamera as CubeCamera$1, EventDispatcher, Euler, Quaternion, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial, DynamicDrawUsage, CatmullRomCurve3, CubicBezierCurve3, QuadraticBezierCurve3, Shape as Shape$1, CanvasTexture, OrthographicCamera as OrthographicCamera$1, AudioListener, AudioLoader, AnimationMixer, Box3, Sphere as Sphere$1, InstancedBufferAttribute, DoubleSide, CubeTextureLoader, DefaultLoadingManager, Ray, Raycaster, CubeReflectionMapping, EquirectangularReflectionMapping, RepeatWrapping, ShaderMaterial, CylinderGeometry, AdditiveBlending, 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';
|
|
@@ -57,7 +56,7 @@ import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
|
|
|
57
56
|
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
58
57
|
import { AsciiEffect } from 'three/examples/jsm/effects/AsciiEffect.js';
|
|
59
58
|
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
|
|
60
|
-
import { shaderStructs, shaderIntersectFunction
|
|
59
|
+
import { MeshBVHUniformStruct, MeshBVH, SAH, shaderStructs, shaderIntersectFunction } from 'three-mesh-bvh';
|
|
61
60
|
import { Text as Text$1, preloadFont } from 'troika-three-text';
|
|
62
61
|
|
|
63
62
|
const ContactShadows = /* @__PURE__ */ React.forwardRef(
|
|
@@ -799,6 +798,12 @@ const Caustics = /* @__PURE__ */ React.forwardRef(
|
|
|
799
798
|
const helper = useHelper(debug && camera, THREE.CameraHelper);
|
|
800
799
|
const normalTarget = useFBO(resolution, resolution, NORMALPROPS);
|
|
801
800
|
const normalTargetB = useFBO(resolution, resolution, NORMALPROPS);
|
|
801
|
+
if (!gl.extensions.get("OES_texture_float_linear")) {
|
|
802
|
+
console.warn(
|
|
803
|
+
"[Caustics]: `OES_texture_float_linear` extension not supported, using HalfFloatType instead of FloatType"
|
|
804
|
+
);
|
|
805
|
+
CAUSTICPROPS.type = THREE.HalfFloatType;
|
|
806
|
+
}
|
|
802
807
|
const causticsTarget = useFBO(resolution, resolution, CAUSTICPROPS);
|
|
803
808
|
const causticsTargetB = useFBO(resolution, resolution, CAUSTICPROPS);
|
|
804
809
|
const [normalMat] = React.useState(() => createNormalMaterial());
|
|
@@ -1085,7 +1090,7 @@ class MeshTransmissionMaterialImpl extends THREE.MeshPhysicalMaterial {
|
|
|
1085
1090
|
vec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {
|
|
1086
1091
|
// Direction of refracted light.
|
|
1087
1092
|
vec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );
|
|
1088
|
-
// Compute rotation-
|
|
1093
|
+
// Compute rotation-independent scaling of the model matrix.
|
|
1089
1094
|
vec3 modelScale;
|
|
1090
1095
|
modelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );
|
|
1091
1096
|
modelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );
|
|
@@ -1869,7 +1874,7 @@ const MeshReflectorMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
1869
1874
|
}
|
|
1870
1875
|
);
|
|
1871
1876
|
|
|
1872
|
-
const
|
|
1877
|
+
const MeshRefractionMaterial_ = /* @__PURE__ */ shaderMaterial(
|
|
1873
1878
|
{
|
|
1874
1879
|
envMap: null,
|
|
1875
1880
|
bounces: 3,
|
|
@@ -2030,6 +2035,56 @@ const MeshRefractionMaterial = /* @__PURE__ */ shaderMaterial(
|
|
|
2030
2035
|
#include <${version$1 >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
|
|
2031
2036
|
}`
|
|
2032
2037
|
);
|
|
2038
|
+
const isCubeTexture = (def) => def && def.isCubeTexture;
|
|
2039
|
+
const MeshRefractionMaterial = /* @__PURE__ */ React.forwardRef(
|
|
2040
|
+
({ aberrationStrength = 0, fastChroma = true, envMap, ...props }, ref) => {
|
|
2041
|
+
extend({ MeshRefractionMaterial_ });
|
|
2042
|
+
const material = React.useRef(null);
|
|
2043
|
+
const { size } = useThree();
|
|
2044
|
+
const defines = React.useMemo(() => {
|
|
2045
|
+
const temp = {};
|
|
2046
|
+
const isCubeMap = isCubeTexture(envMap);
|
|
2047
|
+
const w = (isCubeMap ? envMap.image[0]?.width : envMap.image.width) ?? 1024;
|
|
2048
|
+
const cubeSize = w / 4;
|
|
2049
|
+
const _lodMax = Math.floor(Math.log2(cubeSize));
|
|
2050
|
+
const _cubeSize = Math.pow(2, _lodMax);
|
|
2051
|
+
const width = 3 * Math.max(_cubeSize, 16 * 7);
|
|
2052
|
+
const height = 4 * _cubeSize;
|
|
2053
|
+
if (isCubeMap) temp.ENVMAP_TYPE_CUBEM = "";
|
|
2054
|
+
temp.CUBEUV_TEXEL_WIDTH = `${1 / width}`;
|
|
2055
|
+
temp.CUBEUV_TEXEL_HEIGHT = `${1 / height}`;
|
|
2056
|
+
temp.CUBEUV_MAX_MIP = `${_lodMax}.0`;
|
|
2057
|
+
if (aberrationStrength > 0) temp.CHROMATIC_ABERRATIONS = "";
|
|
2058
|
+
if (fastChroma) temp.FAST_CHROMA = "";
|
|
2059
|
+
return temp;
|
|
2060
|
+
}, [aberrationStrength, fastChroma, envMap]);
|
|
2061
|
+
React.useLayoutEffect(() => {
|
|
2062
|
+
const geometry = material.current?.__r3f?.parent?.object?.geometry;
|
|
2063
|
+
if (geometry) {
|
|
2064
|
+
const geometryNi = geometry.index ? geometry.clone().toNonIndexed() : geometry.clone();
|
|
2065
|
+
material.current.bvh = new MeshBVHUniformStruct();
|
|
2066
|
+
material.current.bvh.updateFrom(new MeshBVH(geometryNi, { strategy: SAH }));
|
|
2067
|
+
}
|
|
2068
|
+
}, []);
|
|
2069
|
+
useFrame(({ camera }) => {
|
|
2070
|
+
material.current.viewMatrixInverse = camera.matrixWorld;
|
|
2071
|
+
material.current.projectionMatrixInverse = camera.projectionMatrixInverse;
|
|
2072
|
+
});
|
|
2073
|
+
React.useImperativeHandle(ref, () => material.current, []);
|
|
2074
|
+
return /* @__PURE__ */ React.createElement(
|
|
2075
|
+
"meshRefractionMaterial_",
|
|
2076
|
+
{
|
|
2077
|
+
key: JSON.stringify(defines),
|
|
2078
|
+
defines,
|
|
2079
|
+
ref: material,
|
|
2080
|
+
resolution: [size.width, size.height],
|
|
2081
|
+
aberrationStrength,
|
|
2082
|
+
envMap,
|
|
2083
|
+
...props
|
|
2084
|
+
}
|
|
2085
|
+
);
|
|
2086
|
+
}
|
|
2087
|
+
);
|
|
2033
2088
|
|
|
2034
2089
|
function useIntersect(onChange) {
|
|
2035
2090
|
const { isLegacy } = useThree();
|
|
@@ -3053,7 +3108,7 @@ const isWebGL2Available = () => {
|
|
|
3053
3108
|
const Effects = /* @__PURE__ */ React.forwardRef(
|
|
3054
3109
|
({
|
|
3055
3110
|
children,
|
|
3056
|
-
|
|
3111
|
+
multisampling = 8,
|
|
3057
3112
|
renderIndex = 1,
|
|
3058
3113
|
disableRender,
|
|
3059
3114
|
disableGamma,
|
|
@@ -3080,7 +3135,7 @@ const Effects = /* @__PURE__ */ React.forwardRef(
|
|
|
3080
3135
|
if (type === UnsignedByteType && colorSpace != null) {
|
|
3081
3136
|
t.texture.colorSpace = colorSpace;
|
|
3082
3137
|
}
|
|
3083
|
-
t.samples =
|
|
3138
|
+
t.samples = multisampling;
|
|
3084
3139
|
return t;
|
|
3085
3140
|
});
|
|
3086
3141
|
React.useEffect(() => {
|
|
@@ -3690,11 +3745,11 @@ const DeviceOrientationControls = /* @__PURE__ */ React.forwardRef(
|
|
|
3690
3745
|
);
|
|
3691
3746
|
|
|
3692
3747
|
const initialModelPosition = /* @__PURE__ */ new THREE.Vector3();
|
|
3693
|
-
const mousePosition2D = /* @__PURE__ */ new THREE.Vector2();
|
|
3694
3748
|
const mousePosition3D = /* @__PURE__ */ new THREE.Vector3();
|
|
3695
3749
|
const dragOffset = /* @__PURE__ */ new THREE.Vector3();
|
|
3696
3750
|
const dragPlaneNormal = /* @__PURE__ */ new THREE.Vector3();
|
|
3697
3751
|
const dragPlane = /* @__PURE__ */ new THREE.Plane();
|
|
3752
|
+
const startPointerPos = /* @__PURE__ */ new THREE.Vector3();
|
|
3698
3753
|
const DragControls = React.forwardRef(
|
|
3699
3754
|
({
|
|
3700
3755
|
autoTransform = true,
|
|
@@ -3710,90 +3765,132 @@ const DragControls = React.forwardRef(
|
|
|
3710
3765
|
...props
|
|
3711
3766
|
}, fRef) => {
|
|
3712
3767
|
const defaultControls = useThree((state) => state.controls);
|
|
3713
|
-
const { camera,
|
|
3768
|
+
const { camera, invalidate } = useThree();
|
|
3714
3769
|
const ref = React.useRef(null);
|
|
3715
|
-
const
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
}
|
|
3749
|
-
dragPlane.setFromNormalAndCoplanarPoint(dragPlaneNormal, mousePosition3D);
|
|
3750
|
-
raycaster.ray.intersectPlane(dragPlane, mousePosition3D);
|
|
3751
|
-
const previousLocalMatrix = ref.current.matrix.clone();
|
|
3752
|
-
const previousWorldMatrix = ref.current.matrixWorld.clone();
|
|
3753
|
-
const intendedNewPosition = new THREE.Vector3(
|
|
3754
|
-
mousePosition3D.x - dragOffset.x,
|
|
3755
|
-
mousePosition3D.y - dragOffset.y,
|
|
3756
|
-
mousePosition3D.z - dragOffset.z
|
|
3757
|
-
);
|
|
3758
|
-
if (dragLimits) {
|
|
3759
|
-
intendedNewPosition.x = dragLimits[0] ? Math.max(Math.min(intendedNewPosition.x, dragLimits[0][1]), dragLimits[0][0]) : intendedNewPosition.x;
|
|
3760
|
-
intendedNewPosition.y = dragLimits[1] ? Math.max(Math.min(intendedNewPosition.y, dragLimits[1][1]), dragLimits[1][0]) : intendedNewPosition.y;
|
|
3761
|
-
intendedNewPosition.z = dragLimits[2] ? Math.max(Math.min(intendedNewPosition.z, dragLimits[2][1]), dragLimits[2][0]) : intendedNewPosition.z;
|
|
3762
|
-
}
|
|
3763
|
-
if (autoTransform) {
|
|
3764
|
-
ref.current.matrix.setPosition(intendedNewPosition);
|
|
3765
|
-
const deltaLocalMatrix = ref.current.matrix.clone().multiply(previousLocalMatrix.invert());
|
|
3766
|
-
const deltaWorldMatrix = ref.current.matrix.clone().multiply(previousWorldMatrix.invert());
|
|
3767
|
-
onDrag && onDrag(ref.current.matrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
|
|
3768
|
-
} else {
|
|
3769
|
-
const tempMatrix = new THREE.Matrix4().copy(ref.current.matrix);
|
|
3770
|
-
tempMatrix.setPosition(intendedNewPosition);
|
|
3771
|
-
const deltaLocalMatrix = tempMatrix.clone().multiply(previousLocalMatrix.invert());
|
|
3772
|
-
const deltaWorldMatrix = tempMatrix.clone().multiply(previousWorldMatrix.invert());
|
|
3773
|
-
onDrag && onDrag(tempMatrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
|
|
3770
|
+
const dragState = React.useRef({
|
|
3771
|
+
active: false,
|
|
3772
|
+
intentional: false,
|
|
3773
|
+
// Has moved past threshold
|
|
3774
|
+
pointerId: -1
|
|
3775
|
+
});
|
|
3776
|
+
const threshold = dragConfig?.threshold ?? 0;
|
|
3777
|
+
const filterTaps = dragConfig?.filterTaps ?? true;
|
|
3778
|
+
const handlePointerDown = React.useCallback(
|
|
3779
|
+
(event) => {
|
|
3780
|
+
event.stopPropagation();
|
|
3781
|
+
event.target.setPointerCapture(event.pointerId);
|
|
3782
|
+
dragState.current.active = true;
|
|
3783
|
+
dragState.current.intentional = threshold === 0;
|
|
3784
|
+
dragState.current.pointerId = event.pointerId;
|
|
3785
|
+
if (defaultControls) defaultControls.enabled = false;
|
|
3786
|
+
ref.current.matrix.decompose(initialModelPosition, new THREE.Quaternion(), new THREE.Vector3());
|
|
3787
|
+
mousePosition3D.copy(event.point);
|
|
3788
|
+
startPointerPos.copy(event.point);
|
|
3789
|
+
dragOffset.copy(mousePosition3D).sub(initialModelPosition);
|
|
3790
|
+
if (!axisLock) {
|
|
3791
|
+
camera.getWorldDirection(dragPlaneNormal).negate();
|
|
3792
|
+
} else {
|
|
3793
|
+
switch (axisLock) {
|
|
3794
|
+
case "x":
|
|
3795
|
+
dragPlaneNormal.set(1, 0, 0);
|
|
3796
|
+
break;
|
|
3797
|
+
case "y":
|
|
3798
|
+
dragPlaneNormal.set(0, 1, 0);
|
|
3799
|
+
break;
|
|
3800
|
+
case "z":
|
|
3801
|
+
dragPlaneNormal.set(0, 0, 1);
|
|
3802
|
+
break;
|
|
3774
3803
|
}
|
|
3775
|
-
invalidate();
|
|
3776
|
-
},
|
|
3777
|
-
onDragEnd: () => {
|
|
3778
|
-
if (defaultControls) defaultControls.enabled = true;
|
|
3779
|
-
onDragEnd && onDragEnd();
|
|
3780
|
-
invalidate();
|
|
3781
3804
|
}
|
|
3805
|
+
dragPlane.setFromNormalAndCoplanarPoint(dragPlaneNormal, mousePosition3D);
|
|
3806
|
+
if (dragState.current.intentional) {
|
|
3807
|
+
onDragStart && onDragStart(initialModelPosition);
|
|
3808
|
+
}
|
|
3809
|
+
invalidate();
|
|
3782
3810
|
},
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3811
|
+
[defaultControls, camera, axisLock, threshold, onDragStart, invalidate]
|
|
3812
|
+
);
|
|
3813
|
+
const handlePointerMove = React.useCallback(
|
|
3814
|
+
(event) => {
|
|
3815
|
+
if (!dragState.current.active || event.pointerId !== dragState.current.pointerId) return;
|
|
3816
|
+
const intersection = event.ray.intersectPlane(dragPlane, mousePosition3D);
|
|
3817
|
+
if (!intersection) return;
|
|
3818
|
+
if (!dragState.current.intentional) {
|
|
3819
|
+
const distance = mousePosition3D.distanceTo(startPointerPos);
|
|
3820
|
+
if (distance < threshold) return;
|
|
3821
|
+
dragState.current.intentional = true;
|
|
3822
|
+
onDragStart && onDragStart(initialModelPosition);
|
|
3788
3823
|
}
|
|
3789
|
-
|
|
3824
|
+
const previousLocalMatrix = ref.current.matrix.clone();
|
|
3825
|
+
const previousWorldMatrix = ref.current.matrixWorld.clone();
|
|
3826
|
+
const intendedNewPosition = new THREE.Vector3(
|
|
3827
|
+
mousePosition3D.x - dragOffset.x,
|
|
3828
|
+
mousePosition3D.y - dragOffset.y,
|
|
3829
|
+
mousePosition3D.z - dragOffset.z
|
|
3830
|
+
);
|
|
3831
|
+
if (dragLimits) {
|
|
3832
|
+
intendedNewPosition.x = dragLimits[0] ? Math.max(Math.min(intendedNewPosition.x, dragLimits[0][1]), dragLimits[0][0]) : intendedNewPosition.x;
|
|
3833
|
+
intendedNewPosition.y = dragLimits[1] ? Math.max(Math.min(intendedNewPosition.y, dragLimits[1][1]), dragLimits[1][0]) : intendedNewPosition.y;
|
|
3834
|
+
intendedNewPosition.z = dragLimits[2] ? Math.max(Math.min(intendedNewPosition.z, dragLimits[2][1]), dragLimits[2][0]) : intendedNewPosition.z;
|
|
3835
|
+
}
|
|
3836
|
+
if (autoTransform) {
|
|
3837
|
+
ref.current.matrix.setPosition(intendedNewPosition);
|
|
3838
|
+
const deltaLocalMatrix = ref.current.matrix.clone().multiply(previousLocalMatrix.invert());
|
|
3839
|
+
const deltaWorldMatrix = ref.current.matrix.clone().multiply(previousWorldMatrix.invert());
|
|
3840
|
+
onDrag && onDrag(ref.current.matrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
|
|
3841
|
+
} else {
|
|
3842
|
+
const tempMatrix = new THREE.Matrix4().copy(ref.current.matrix);
|
|
3843
|
+
tempMatrix.setPosition(intendedNewPosition);
|
|
3844
|
+
const deltaLocalMatrix = tempMatrix.clone().multiply(previousLocalMatrix.invert());
|
|
3845
|
+
const deltaWorldMatrix = tempMatrix.clone().multiply(previousWorldMatrix.invert());
|
|
3846
|
+
onDrag && onDrag(tempMatrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
|
|
3847
|
+
}
|
|
3848
|
+
invalidate();
|
|
3849
|
+
},
|
|
3850
|
+
[autoTransform, dragLimits, threshold, onDragStart, onDrag, invalidate]
|
|
3790
3851
|
);
|
|
3852
|
+
const handlePointerUp = React.useCallback(
|
|
3853
|
+
(event) => {
|
|
3854
|
+
if (!dragState.current.active || event.pointerId !== dragState.current.pointerId) return;
|
|
3855
|
+
event.target.releasePointerCapture(event.pointerId);
|
|
3856
|
+
const wasIntentional = dragState.current.intentional;
|
|
3857
|
+
dragState.current.active = false;
|
|
3858
|
+
dragState.current.intentional = false;
|
|
3859
|
+
dragState.current.pointerId = -1;
|
|
3860
|
+
if (defaultControls) defaultControls.enabled = true;
|
|
3861
|
+
if (wasIntentional || !filterTaps) {
|
|
3862
|
+
onDragEnd && onDragEnd();
|
|
3863
|
+
}
|
|
3864
|
+
invalidate();
|
|
3865
|
+
},
|
|
3866
|
+
[defaultControls, filterTaps, onDragEnd, invalidate]
|
|
3867
|
+
);
|
|
3868
|
+
const handlePointerEnter = React.useCallback(() => {
|
|
3869
|
+
onHover && onHover(true);
|
|
3870
|
+
}, [onHover]);
|
|
3871
|
+
const handlePointerLeave = React.useCallback(() => {
|
|
3872
|
+
onHover && onHover(false);
|
|
3873
|
+
}, [onHover]);
|
|
3791
3874
|
React.useImperativeHandle(fRef, () => ref.current, []);
|
|
3792
3875
|
React.useLayoutEffect(() => {
|
|
3793
3876
|
if (!matrix) return;
|
|
3794
3877
|
ref.current.matrix = matrix;
|
|
3795
3878
|
}, [matrix]);
|
|
3796
|
-
return /* @__PURE__ */ React.createElement(
|
|
3879
|
+
return /* @__PURE__ */ React.createElement(
|
|
3880
|
+
"group",
|
|
3881
|
+
{
|
|
3882
|
+
ref,
|
|
3883
|
+
onPointerDown: handlePointerDown,
|
|
3884
|
+
onPointerMove: handlePointerMove,
|
|
3885
|
+
onPointerUp: handlePointerUp,
|
|
3886
|
+
onPointerEnter: handlePointerEnter,
|
|
3887
|
+
onPointerLeave: handlePointerLeave,
|
|
3888
|
+
matrix,
|
|
3889
|
+
matrixAutoUpdate: false,
|
|
3890
|
+
...props
|
|
3891
|
+
},
|
|
3892
|
+
children
|
|
3893
|
+
);
|
|
3797
3894
|
}
|
|
3798
3895
|
);
|
|
3799
3896
|
|
|
@@ -3911,7 +4008,7 @@ function KeyboardControls({ map, children, onChange, domElement }) {
|
|
|
3911
4008
|
source.removeEventListener("keyup", upHandler);
|
|
3912
4009
|
window.removeEventListener("blur", blurHandler);
|
|
3913
4010
|
};
|
|
3914
|
-
}, [domElement, key]);
|
|
4011
|
+
}, [domElement, key, onChange]);
|
|
3915
4012
|
return /* @__PURE__ */ React.createElement(context$8.Provider, { value: api, children });
|
|
3916
4013
|
}
|
|
3917
4014
|
function useKeyboardControls(sel) {
|
|
@@ -3933,20 +4030,28 @@ const MapControls = /* @__PURE__ */ React.forwardRef((props = { enableDamping: t
|
|
|
3933
4030
|
const controls = React.useMemo(() => new MapControls$1(explCamera), [explCamera]);
|
|
3934
4031
|
React.useEffect(() => {
|
|
3935
4032
|
controls.connect(explDomElement);
|
|
4033
|
+
return () => void controls.dispose();
|
|
4034
|
+
}, [explDomElement, controls]);
|
|
4035
|
+
React.useEffect(() => {
|
|
3936
4036
|
const callback = (e) => {
|
|
3937
4037
|
invalidate();
|
|
3938
4038
|
if (onChange) onChange(e);
|
|
3939
4039
|
};
|
|
4040
|
+
const onStartCb = (e) => {
|
|
4041
|
+
if (onStart) onStart(e);
|
|
4042
|
+
};
|
|
4043
|
+
const onEndCb = (e) => {
|
|
4044
|
+
if (onEnd) onEnd(e);
|
|
4045
|
+
};
|
|
3940
4046
|
controls.addEventListener("change", callback);
|
|
3941
|
-
|
|
3942
|
-
|
|
4047
|
+
controls.addEventListener("start", onStartCb);
|
|
4048
|
+
controls.addEventListener("end", onEndCb);
|
|
3943
4049
|
return () => {
|
|
3944
|
-
controls.
|
|
4050
|
+
controls.removeEventListener("start", onStartCb);
|
|
4051
|
+
controls.removeEventListener("end", onEndCb);
|
|
3945
4052
|
controls.removeEventListener("change", callback);
|
|
3946
|
-
if (onStart) controls.removeEventListener("start", onStart);
|
|
3947
|
-
if (onEnd) controls.removeEventListener("end", onEnd);
|
|
3948
4053
|
};
|
|
3949
|
-
}, [onChange, onStart, onEnd, controls, invalidate
|
|
4054
|
+
}, [onChange, onStart, onEnd, controls, invalidate]);
|
|
3950
4055
|
React.useEffect(() => {
|
|
3951
4056
|
if (makeDefault) {
|
|
3952
4057
|
const old = get().controls;
|
|
@@ -3954,7 +4059,9 @@ const MapControls = /* @__PURE__ */ React.forwardRef((props = { enableDamping: t
|
|
|
3954
4059
|
return () => set({ controls: old });
|
|
3955
4060
|
}
|
|
3956
4061
|
}, [makeDefault, controls]);
|
|
3957
|
-
useFrame(() =>
|
|
4062
|
+
useFrame(() => {
|
|
4063
|
+
if (controls.enabled) controls.update();
|
|
4064
|
+
}, -1);
|
|
3958
4065
|
return /* @__PURE__ */ React.createElement("primitive", { ref, object: controls, enableDamping: true, ...rest });
|
|
3959
4066
|
});
|
|
3960
4067
|
|
|
@@ -4080,20 +4187,16 @@ const OrbitControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4080
4187
|
onEnd,
|
|
4081
4188
|
...restProps
|
|
4082
4189
|
}, ref) => {
|
|
4083
|
-
const invalidate = useThree(
|
|
4084
|
-
const defaultCamera = useThree((state) => state.camera);
|
|
4085
|
-
const gl = useThree((state) => state.gl);
|
|
4086
|
-
const events = useThree((state) => state.events);
|
|
4087
|
-
const setEvents = useThree((state) => state.setEvents);
|
|
4088
|
-
const set = useThree((state) => state.set);
|
|
4089
|
-
const get = useThree((state) => state.get);
|
|
4090
|
-
const performance = useThree((state) => state.performance);
|
|
4190
|
+
const { invalidate, camera: defaultCamera, renderer, events, setEvents, set, get, performance } = useThree();
|
|
4091
4191
|
const explCamera = camera || defaultCamera;
|
|
4092
|
-
const explDomElement = domElement || events.connected ||
|
|
4192
|
+
const explDomElement = domElement || events.connected || renderer.domElement;
|
|
4093
4193
|
const controls = React.useMemo(() => new OrbitControls$1(explCamera), [explCamera]);
|
|
4094
|
-
useFrame(
|
|
4095
|
-
|
|
4096
|
-
|
|
4194
|
+
useFrame(
|
|
4195
|
+
() => {
|
|
4196
|
+
if (controls.enabled) controls.update();
|
|
4197
|
+
},
|
|
4198
|
+
{ before: "update" }
|
|
4199
|
+
);
|
|
4097
4200
|
React.useEffect(() => {
|
|
4098
4201
|
if (keyEvents) {
|
|
4099
4202
|
controls.connect(keyEvents === true ? explDomElement : keyEvents);
|
|
@@ -4207,9 +4310,8 @@ function PresentationControls({
|
|
|
4207
4310
|
azimuth = [-Infinity, Infinity],
|
|
4208
4311
|
damping = 0.25
|
|
4209
4312
|
}) {
|
|
4210
|
-
const events = useThree(
|
|
4211
|
-
const
|
|
4212
|
-
const explDomElement = domElement || events.connected || gl.domElement;
|
|
4313
|
+
const { events, renderer, invalidate } = useThree();
|
|
4314
|
+
const explDomElement = domElement || events.connected || renderer.domElement;
|
|
4213
4315
|
const { size } = useThree();
|
|
4214
4316
|
const rPolar = React.useMemo(
|
|
4215
4317
|
() => [rotation[0] + polar[0], rotation[0] + polar[1]],
|
|
@@ -4226,18 +4328,20 @@ function PresentationControls({
|
|
|
4226
4328
|
React.useEffect(() => {
|
|
4227
4329
|
if (global && cursor && enabled) {
|
|
4228
4330
|
explDomElement.style.cursor = "grab";
|
|
4229
|
-
|
|
4331
|
+
renderer.domElement.style.cursor = "";
|
|
4230
4332
|
return () => {
|
|
4231
4333
|
explDomElement.style.cursor = "default";
|
|
4232
|
-
|
|
4334
|
+
renderer.domElement.style.cursor = "default";
|
|
4233
4335
|
};
|
|
4234
4336
|
}
|
|
4235
4337
|
}, [global, cursor, explDomElement, enabled]);
|
|
4236
4338
|
const [animation] = React.useState({ scale: 1, rotation: rInitial, damping });
|
|
4237
4339
|
const ref = React.useRef(null);
|
|
4238
4340
|
useFrame((state, delta) => {
|
|
4239
|
-
|
|
4240
|
-
easing.
|
|
4341
|
+
let changed = false;
|
|
4342
|
+
changed ||= easing.damp3(ref.current.scale, animation.scale, animation.damping, delta);
|
|
4343
|
+
changed ||= easing.dampE(ref.current.rotation, animation.rotation, animation.damping, delta);
|
|
4344
|
+
if (changed) state.invalidate();
|
|
4241
4345
|
});
|
|
4242
4346
|
const bind = useGesture(
|
|
4243
4347
|
{
|
|
@@ -4245,6 +4349,7 @@ function PresentationControls({
|
|
|
4245
4349
|
if (cursor && !global && enabled) explDomElement.style.cursor = last ? "auto" : "grab";
|
|
4246
4350
|
},
|
|
4247
4351
|
onDrag: ({ down, delta: [x, y], memo: [oldY, oldX] = animation.rotation || rInitial }) => {
|
|
4352
|
+
invalidate();
|
|
4248
4353
|
if (!enabled) return [y, x];
|
|
4249
4354
|
if (cursor) explDomElement.style.cursor = down ? "grabbing" : "grab";
|
|
4250
4355
|
x = MathUtils.clamp(oldX + x / size.width * Math.PI * speed, ...rAzimuth);
|
|
@@ -4253,9 +4358,12 @@ function PresentationControls({
|
|
|
4253
4358
|
animation.rotation = snap && !down ? rInitial : [y, x, 0];
|
|
4254
4359
|
animation.damping = snap && !down && typeof snap !== "boolean" ? snap : damping;
|
|
4255
4360
|
return [y, x];
|
|
4361
|
+
},
|
|
4362
|
+
onDragEnd: () => {
|
|
4363
|
+
invalidate();
|
|
4256
4364
|
}
|
|
4257
4365
|
},
|
|
4258
|
-
{ target: global ? explDomElement : void 0 }
|
|
4366
|
+
{ target: global ? explDomElement : void 0, enabled }
|
|
4259
4367
|
);
|
|
4260
4368
|
return /* @__PURE__ */ React.createElement("group", { ref, ...bind?.() }, children);
|
|
4261
4369
|
}
|
|
@@ -4264,6 +4372,10 @@ function roundToPixelRatio(value) {
|
|
|
4264
4372
|
const ratio = window.devicePixelRatio || 1;
|
|
4265
4373
|
return Math.round(value * ratio) / ratio;
|
|
4266
4374
|
}
|
|
4375
|
+
function getMaxAnisotropy(renderer) {
|
|
4376
|
+
const r = renderer;
|
|
4377
|
+
return r?.getMaxAnisotropy?.() ?? r?.capabilities?.getMaxAnisotropy?.() ?? 1;
|
|
4378
|
+
}
|
|
4267
4379
|
|
|
4268
4380
|
const context$7 = /* @__PURE__ */ React.createContext(null);
|
|
4269
4381
|
const rootCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -4290,6 +4402,7 @@ function ScrollControls({
|
|
|
4290
4402
|
const [fixed] = React.useState(() => document.createElement("div"));
|
|
4291
4403
|
const target = gl.domElement.parentNode;
|
|
4292
4404
|
const scroll = React.useRef(0);
|
|
4405
|
+
const disableScrollUpdate = React.useRef(false);
|
|
4293
4406
|
const state = React.useMemo(() => {
|
|
4294
4407
|
const state2 = {
|
|
4295
4408
|
el,
|
|
@@ -4371,16 +4484,20 @@ function ScrollControls({
|
|
|
4371
4484
|
const scrollLength = el[horizontal ? "scrollWidth" : "scrollHeight"];
|
|
4372
4485
|
const scrollThreshold = scrollLength - containerLength;
|
|
4373
4486
|
let current = 0;
|
|
4374
|
-
let disableScroll =
|
|
4487
|
+
let disableScroll = false;
|
|
4375
4488
|
let firstRun = true;
|
|
4376
4489
|
const onScroll = () => {
|
|
4377
4490
|
if (!enabled || firstRun) return;
|
|
4491
|
+
if (disableScrollUpdate.current) {
|
|
4492
|
+
disableScrollUpdate.current = false;
|
|
4493
|
+
return;
|
|
4494
|
+
}
|
|
4378
4495
|
invalidate();
|
|
4379
4496
|
current = el[horizontal ? "scrollLeft" : "scrollTop"];
|
|
4380
4497
|
scroll.current = current / scrollThreshold;
|
|
4381
4498
|
if (infinite) {
|
|
4382
4499
|
if (!disableScroll) {
|
|
4383
|
-
if (current >= scrollThreshold) {
|
|
4500
|
+
if (current >= scrollThreshold - 1) {
|
|
4384
4501
|
const damp = 1 - state.offset;
|
|
4385
4502
|
el[horizontal ? "scrollLeft" : "scrollTop"] = 1;
|
|
4386
4503
|
scroll.current = state.offset = -damp;
|
|
@@ -4397,11 +4514,34 @@ function ScrollControls({
|
|
|
4397
4514
|
};
|
|
4398
4515
|
el.addEventListener("scroll", onScroll, { passive: true });
|
|
4399
4516
|
requestAnimationFrame(() => firstRun = false);
|
|
4400
|
-
const
|
|
4401
|
-
|
|
4517
|
+
const onResize = () => {
|
|
4518
|
+
if (!el) return;
|
|
4519
|
+
const scrollLength2 = el[horizontal ? "scrollWidth" : "scrollHeight"];
|
|
4520
|
+
const containerLength2 = el[horizontal ? "clientWidth" : "clientHeight"];
|
|
4521
|
+
disableScrollUpdate.current = true;
|
|
4522
|
+
el[horizontal ? "scrollLeft" : "scrollTop"] = state.offset * (scrollLength2 - containerLength2);
|
|
4523
|
+
};
|
|
4524
|
+
const onWheel = (e) => {
|
|
4525
|
+
if (horizontal) {
|
|
4526
|
+
const previous = el.scrollLeft;
|
|
4527
|
+
el.scrollLeft += e.deltaY / 2;
|
|
4528
|
+
if (infinite && previous === el.scrollLeft) {
|
|
4529
|
+
onScroll();
|
|
4530
|
+
}
|
|
4531
|
+
} else if (infinite) {
|
|
4532
|
+
if (el.scrollTop <= 1 && e.deltaY < 0) {
|
|
4533
|
+
onScroll();
|
|
4534
|
+
} else if (el.scrollTop >= el.scrollHeight - el.clientHeight - 1 && e.deltaY > 0) {
|
|
4535
|
+
onScroll();
|
|
4536
|
+
}
|
|
4537
|
+
}
|
|
4538
|
+
};
|
|
4539
|
+
if (horizontal || infinite) el.addEventListener("wheel", onWheel, { passive: true });
|
|
4540
|
+
if (horizontal) window.addEventListener("resize", onResize);
|
|
4402
4541
|
return () => {
|
|
4403
4542
|
el.removeEventListener("scroll", onScroll);
|
|
4404
|
-
if (horizontal) el.removeEventListener("wheel", onWheel);
|
|
4543
|
+
if (horizontal || infinite) el.removeEventListener("wheel", onWheel);
|
|
4544
|
+
if (horizontal) window.removeEventListener("resize", onResize);
|
|
4405
4545
|
};
|
|
4406
4546
|
}
|
|
4407
4547
|
}, [el, events, size, infinite, state, invalidate, horizontal, enabled]);
|
|
@@ -4818,10 +4958,10 @@ const CloudInstance = /* @__PURE__ */ React.forwardRef(
|
|
|
4818
4958
|
return /* @__PURE__ */ React.createElement("group", { ref, ...props });
|
|
4819
4959
|
}
|
|
4820
4960
|
);
|
|
4821
|
-
const Cloud = /* @__PURE__ */ React.forwardRef((props, fref) => {
|
|
4961
|
+
const Cloud = /* @__PURE__ */ React.forwardRef(({ materialFactory, ...props }, fref) => {
|
|
4822
4962
|
const parent = React.useContext(context$6);
|
|
4823
4963
|
if (parent) return /* @__PURE__ */ React.createElement(CloudInstance, { ref: fref, ...props });
|
|
4824
|
-
return /* @__PURE__ */ React.createElement(Clouds,
|
|
4964
|
+
return /* @__PURE__ */ React.createElement(Clouds, { materialFactory }, /* @__PURE__ */ React.createElement(CloudInstance, { ref: fref, ...props }));
|
|
4825
4965
|
});
|
|
4826
4966
|
|
|
4827
4967
|
const CatmullRomLine = /* @__PURE__ */ React.forwardRef(function CatmullRomLine2({
|
|
@@ -5343,7 +5483,7 @@ const Text3D = /* @__PURE__ */ React.forwardRef(
|
|
|
5343
5483
|
return {
|
|
5344
5484
|
font,
|
|
5345
5485
|
size,
|
|
5346
|
-
height,
|
|
5486
|
+
depth: height,
|
|
5347
5487
|
bevelThickness,
|
|
5348
5488
|
bevelSize,
|
|
5349
5489
|
bevelEnabled,
|
|
@@ -5526,7 +5666,7 @@ const FaceMaterial = ({
|
|
|
5526
5666
|
"meshBasicMaterial",
|
|
5527
5667
|
{
|
|
5528
5668
|
map: texture,
|
|
5529
|
-
"map-anisotropy":
|
|
5669
|
+
"map-anisotropy": getMaxAnisotropy(renderer),
|
|
5530
5670
|
attach: `material-${index}`,
|
|
5531
5671
|
color: hover ? hoverColor : "white",
|
|
5532
5672
|
transparent: true,
|
|
@@ -5637,7 +5777,7 @@ function AxisHead({
|
|
|
5637
5777
|
"spriteMaterial",
|
|
5638
5778
|
{
|
|
5639
5779
|
map: texture,
|
|
5640
|
-
"map-anisotropy":
|
|
5780
|
+
"map-anisotropy": getMaxAnisotropy(renderer),
|
|
5641
5781
|
alphaTest: 0.3,
|
|
5642
5782
|
opacity: label ? 1 : 0.75,
|
|
5643
5783
|
toneMapped: false
|
|
@@ -5782,6 +5922,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
5782
5922
|
}, ref) => {
|
|
5783
5923
|
const { gl, camera, scene, size, raycaster, events, viewport } = useThree();
|
|
5784
5924
|
const forceEven = useThree((state) => state.internal.forceEven);
|
|
5925
|
+
const { frustum } = useThree();
|
|
5785
5926
|
const [el] = React.useState(() => document.createElement(as));
|
|
5786
5927
|
const root = React.useRef(null);
|
|
5787
5928
|
const group = React.useRef(null);
|
|
@@ -5811,22 +5952,18 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
5811
5952
|
if (group.current) {
|
|
5812
5953
|
if (!root.current) {
|
|
5813
5954
|
root.current = ReactDOM.createRoot(el);
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5955
|
+
scene.updateMatrixWorld();
|
|
5956
|
+
if (transform) {
|
|
5957
|
+
el.style.cssText = `position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;`;
|
|
5958
|
+
} else {
|
|
5959
|
+
el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(0,-9999px,0);transform-origin:0 0;`;
|
|
5960
|
+
}
|
|
5820
5961
|
}
|
|
5821
5962
|
if (target) {
|
|
5822
5963
|
if (prepend) target.prepend(el);
|
|
5823
5964
|
else target.appendChild(el);
|
|
5824
5965
|
}
|
|
5825
5966
|
return () => {
|
|
5826
|
-
if (root.current) {
|
|
5827
|
-
root.current.unmount();
|
|
5828
|
-
root.current = null;
|
|
5829
|
-
}
|
|
5830
5967
|
if (target && target.contains(el)) {
|
|
5831
5968
|
target.removeChild(el);
|
|
5832
5969
|
}
|
|
@@ -5960,8 +6097,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
5960
6097
|
if (transformOuterRef.current) {
|
|
5961
6098
|
const el2 = transformOuterRef.current.children[0];
|
|
5962
6099
|
if (el2?.clientWidth && el2?.clientHeight) {
|
|
5963
|
-
|
|
5964
|
-
if (isOrthographicCamera || geometry) {
|
|
6100
|
+
if (geometry) {
|
|
5965
6101
|
if (props.scale) {
|
|
5966
6102
|
if (!Array.isArray(props.scale)) {
|
|
5967
6103
|
occlusionMeshRef.current.scale.setScalar(1 / props.scale);
|
|
@@ -5993,64 +6129,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
5993
6129
|
}
|
|
5994
6130
|
}
|
|
5995
6131
|
});
|
|
5996
|
-
|
|
5997
|
-
() => ({
|
|
5998
|
-
vertexShader: !transform ? (
|
|
5999
|
-
/* glsl */
|
|
6000
|
-
`
|
|
6001
|
-
/*
|
|
6002
|
-
This shader is from the THREE's SpriteMaterial.
|
|
6003
|
-
We need to turn the backing plane into a Sprite
|
|
6004
|
-
(make it always face the camera) if "transfrom"
|
|
6005
|
-
is false.
|
|
6006
|
-
*/
|
|
6007
|
-
#include <common>
|
|
6008
|
-
|
|
6009
|
-
void main() {
|
|
6010
|
-
vec2 center = vec2(0., 1.);
|
|
6011
|
-
float rotation = 0.0;
|
|
6012
|
-
|
|
6013
|
-
// This is somewhat arbitrary, but it seems to work well
|
|
6014
|
-
// Need to figure out how to derive this dynamically if it even matters
|
|
6015
|
-
float size = 0.03;
|
|
6016
|
-
|
|
6017
|
-
vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
|
|
6018
|
-
vec2 scale;
|
|
6019
|
-
scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );
|
|
6020
|
-
scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );
|
|
6021
|
-
|
|
6022
|
-
bool isPerspective = isPerspectiveMatrix( projectionMatrix );
|
|
6023
|
-
if ( isPerspective ) scale *= - mvPosition.z;
|
|
6024
|
-
|
|
6025
|
-
vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale * size;
|
|
6026
|
-
vec2 rotatedPosition;
|
|
6027
|
-
rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
|
|
6028
|
-
rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
|
|
6029
|
-
mvPosition.xy += rotatedPosition;
|
|
6030
|
-
|
|
6031
|
-
gl_Position = projectionMatrix * mvPosition;
|
|
6032
|
-
}
|
|
6033
|
-
`
|
|
6034
|
-
) : void 0,
|
|
6035
|
-
fragmentShader: (
|
|
6036
|
-
/* glsl */
|
|
6037
|
-
`
|
|
6038
|
-
void main() {
|
|
6039
|
-
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
|
6040
|
-
}
|
|
6041
|
-
`
|
|
6042
|
-
)
|
|
6043
|
-
}),
|
|
6044
|
-
[transform]
|
|
6045
|
-
);
|
|
6046
|
-
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(
|
|
6047
|
-
"shaderMaterial",
|
|
6048
|
-
{
|
|
6049
|
-
side: DoubleSide,
|
|
6050
|
-
vertexShader: shaders.vertexShader,
|
|
6051
|
-
fragmentShader: shaders.fragmentShader
|
|
6052
|
-
}
|
|
6053
|
-
)));
|
|
6132
|
+
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));
|
|
6054
6133
|
}
|
|
6055
6134
|
);
|
|
6056
6135
|
|
|
@@ -6903,6 +6982,7 @@ const mW = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
6903
6982
|
const mL = /* @__PURE__ */ new THREE.Matrix4();
|
|
6904
6983
|
const mL0Inv = /* @__PURE__ */ new THREE.Matrix4();
|
|
6905
6984
|
const mdL = /* @__PURE__ */ new THREE.Matrix4();
|
|
6985
|
+
const mdW = /* @__PURE__ */ new THREE.Matrix4();
|
|
6906
6986
|
const mG = /* @__PURE__ */ new THREE.Matrix4();
|
|
6907
6987
|
const bb = /* @__PURE__ */ new THREE.Box3();
|
|
6908
6988
|
const bbObj = /* @__PURE__ */ new THREE.Box3();
|
|
@@ -7017,7 +7097,8 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7017
7097
|
onDragStart && onDragStart(props2);
|
|
7018
7098
|
invalidate();
|
|
7019
7099
|
},
|
|
7020
|
-
onDrag: (
|
|
7100
|
+
onDrag: (mdW_) => {
|
|
7101
|
+
mdW.copy(mdW_);
|
|
7021
7102
|
mP.copy(parentRef.current.matrixWorld);
|
|
7022
7103
|
mPInv.copy(mP).invert();
|
|
7023
7104
|
mW.copy(mW0).premultiply(mdW);
|
|
@@ -7029,12 +7110,12 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7029
7110
|
}
|
|
7030
7111
|
const target = resolveObject(object);
|
|
7031
7112
|
if (target) target.matrix.copy(mL);
|
|
7032
|
-
onDrag && onDrag(mL, mdL, mW, mdW);
|
|
7113
|
+
onDrag && onDrag({ local: mL, deltaLocal: mdL, world: mW, deltaWorld: mdW });
|
|
7033
7114
|
invalidate();
|
|
7034
7115
|
},
|
|
7035
7116
|
onDragEnd: () => {
|
|
7036
7117
|
dragState.current = null;
|
|
7037
|
-
if (onDragEnd) onDragEnd();
|
|
7118
|
+
if (onDragEnd) onDragEnd({ local: mL, deltaLocal: mdL, world: mW, deltaWorld: mdW });
|
|
7038
7119
|
invalidate();
|
|
7039
7120
|
},
|
|
7040
7121
|
onHover: (props2) => {
|
|
@@ -7145,7 +7226,9 @@ const TransformControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7145
7226
|
const group = React.useRef(null);
|
|
7146
7227
|
React.useLayoutEffect(() => {
|
|
7147
7228
|
if (object) {
|
|
7148
|
-
controls.attach(
|
|
7229
|
+
controls.attach(
|
|
7230
|
+
object instanceof THREE.Object3D ? object : object.current
|
|
7231
|
+
);
|
|
7149
7232
|
} else if (group.current instanceof THREE.Object3D) {
|
|
7150
7233
|
controls.attach(group.current);
|
|
7151
7234
|
}
|
|
@@ -7241,7 +7324,7 @@ const PointMaterial = /* @__PURE__ */ React.forwardRef((props, ref) => {
|
|
|
7241
7324
|
return /* @__PURE__ */ React.createElement("primitive", { ...props, object: material, ref, attach: "material" });
|
|
7242
7325
|
});
|
|
7243
7326
|
|
|
7244
|
-
const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, loop =
|
|
7327
|
+
const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, loop = false, autoplay, ...props }, ref) => {
|
|
7245
7328
|
const sound = React.useRef(null);
|
|
7246
7329
|
React.useImperativeHandle(ref, () => sound.current, []);
|
|
7247
7330
|
const camera = useThree(({ camera: camera2 }) => camera2);
|
|
@@ -7253,7 +7336,9 @@ const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, l
|
|
|
7253
7336
|
_sound.setBuffer(Array.isArray(buffer) ? buffer[0] : buffer);
|
|
7254
7337
|
_sound.setRefDistance(distance);
|
|
7255
7338
|
_sound.setLoop(loop);
|
|
7256
|
-
if (autoplay && !_sound.isPlaying)
|
|
7339
|
+
if (autoplay && !_sound.isPlaying) {
|
|
7340
|
+
_sound.play();
|
|
7341
|
+
}
|
|
7257
7342
|
}
|
|
7258
7343
|
}, [buffer, camera, distance, loop]);
|
|
7259
7344
|
React.useEffect(() => {
|
|
@@ -7322,7 +7407,6 @@ const tempMatrix = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
7322
7407
|
const translation = /* @__PURE__ */ new THREE.Vector3();
|
|
7323
7408
|
const rotation = /* @__PURE__ */ new THREE.Quaternion();
|
|
7324
7409
|
const scale = /* @__PURE__ */ new THREE.Vector3();
|
|
7325
|
-
const isInstancedBufferAttribute = (attr) => attr.isInstancedBufferAttribute;
|
|
7326
7410
|
const Instance = /* @__PURE__ */ React.forwardRef(({ context, children, ...props }, ref) => {
|
|
7327
7411
|
React.useMemo(() => extend({ PositionMesh }), []);
|
|
7328
7412
|
const group = React.useRef(null);
|
|
@@ -7342,24 +7426,20 @@ const Instances = /* @__PURE__ */ React.forwardRef(({ context, children, range,
|
|
|
7342
7426
|
const parentRef = React.useRef(null);
|
|
7343
7427
|
React.useImperativeHandle(ref, () => parentRef.current, []);
|
|
7344
7428
|
const [instances, setInstances] = React.useState([]);
|
|
7429
|
+
const boundsDirty = React.useRef(true);
|
|
7345
7430
|
const [[matrices, colors]] = React.useState(() => {
|
|
7346
7431
|
const mArray = new Float32Array(limit * 16);
|
|
7347
7432
|
for (let i = 0; i < limit; i++) tempMatrix.identity().toArray(mArray, i * 16);
|
|
7348
7433
|
return [mArray, new Float32Array([...new Array(limit * 3)].map(() => 1))];
|
|
7349
7434
|
});
|
|
7350
7435
|
React.useEffect(() => {
|
|
7351
|
-
parentRef.current.instanceMatrix.needsUpdate = true;
|
|
7436
|
+
if (parentRef.current) parentRef.current.instanceMatrix.needsUpdate = true;
|
|
7352
7437
|
});
|
|
7353
7438
|
let iterations = 0;
|
|
7354
7439
|
let count = 0;
|
|
7355
|
-
const attributes = React.useRef([]);
|
|
7356
|
-
React.useLayoutEffect(() => {
|
|
7357
|
-
attributes.current = Object.entries(parentRef.current.geometry.attributes).filter(
|
|
7358
|
-
([_name, value]) => isInstancedBufferAttribute(value)
|
|
7359
|
-
);
|
|
7360
|
-
});
|
|
7361
7440
|
useFrame(() => {
|
|
7362
7441
|
if (frames === Infinity || iterations < frames) {
|
|
7442
|
+
if (!parentRef.current) return;
|
|
7363
7443
|
parentRef.current.updateMatrix();
|
|
7364
7444
|
parentRef.current.updateMatrixWorld();
|
|
7365
7445
|
parentMatrix.copy(parentRef.current.matrixWorld).invert();
|
|
@@ -7380,13 +7460,22 @@ const Instances = /* @__PURE__ */ React.forwardRef(({ context, children, range,
|
|
|
7380
7460
|
}
|
|
7381
7461
|
iterations++;
|
|
7382
7462
|
}
|
|
7463
|
+
if (boundsDirty.current && (frames === Infinity || iterations === frames)) {
|
|
7464
|
+
boundsDirty.current = false;
|
|
7465
|
+
if (parentRef.current.boundingBox) parentRef.current.computeBoundingBox();
|
|
7466
|
+
if (parentRef.current.boundingSphere) parentRef.current.computeBoundingSphere();
|
|
7467
|
+
}
|
|
7383
7468
|
});
|
|
7384
7469
|
const api = React.useMemo(
|
|
7385
7470
|
() => ({
|
|
7386
7471
|
getParent: () => parentRef,
|
|
7387
7472
|
subscribe: (ref2) => {
|
|
7388
7473
|
setInstances((instances2) => [...instances2, ref2]);
|
|
7389
|
-
|
|
7474
|
+
boundsDirty.current = true;
|
|
7475
|
+
return () => {
|
|
7476
|
+
setInstances((instances2) => instances2.filter((item) => item.current !== ref2.current));
|
|
7477
|
+
boundsDirty.current = true;
|
|
7478
|
+
};
|
|
7390
7479
|
}
|
|
7391
7480
|
}),
|
|
7392
7481
|
[]
|
|
@@ -7411,10 +7500,23 @@ const Merged = /* @__PURE__ */ React.forwardRef(function Merged2({ meshes, child
|
|
|
7411
7500
|
if (!isArray) {
|
|
7412
7501
|
for (const key of Object.keys(meshes)) if (!meshes[key].isMesh) delete meshes[key];
|
|
7413
7502
|
}
|
|
7414
|
-
const render = (args) =>
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7503
|
+
const render = (args) => {
|
|
7504
|
+
if (isArray) {
|
|
7505
|
+
return children(
|
|
7506
|
+
...args
|
|
7507
|
+
);
|
|
7508
|
+
}
|
|
7509
|
+
const instanceMap = {};
|
|
7510
|
+
const keys = Object.keys(meshes).filter((key) => meshes[key].isMesh);
|
|
7511
|
+
keys.forEach((key, i) => {
|
|
7512
|
+
instanceMap[key] = args[i];
|
|
7513
|
+
});
|
|
7514
|
+
return children(instanceMap);
|
|
7515
|
+
};
|
|
7516
|
+
const components = (isArray ? meshes : Object.values(meshes)).map((mesh) => {
|
|
7517
|
+
const { geometry, material } = mesh;
|
|
7518
|
+
return /* @__PURE__ */ React.createElement(Instances, { key: geometry.uuid, geometry, material, ...props });
|
|
7519
|
+
});
|
|
7418
7520
|
return /* @__PURE__ */ React.createElement("group", { ref }, renderRecursive(render, components));
|
|
7419
7521
|
});
|
|
7420
7522
|
function renderRecursive(render, components, results = []) {
|
|
@@ -8488,12 +8590,13 @@ function Sampler({ children, weight, transform, instances, mesh, count = 16, ...
|
|
|
8488
8590
|
return /* @__PURE__ */ React.createElement("group", { ref: group, ...props }, children);
|
|
8489
8591
|
}
|
|
8490
8592
|
|
|
8593
|
+
const pathStyle = (path) => path.userData?.style;
|
|
8491
8594
|
const Svg = /* @__PURE__ */ forwardRef(
|
|
8492
8595
|
function R3FSvg({ src, skipFill, skipStrokes, fillMaterial, strokeMaterial, fillMeshProps, strokeMeshProps, ...props }, ref) {
|
|
8493
8596
|
const svg = useLoader(SVGLoader, !src.startsWith("<svg") ? src : `data:image/svg+xml;utf8,${src}`);
|
|
8494
8597
|
const strokeGeometries = useMemo(
|
|
8495
8598
|
() => skipStrokes ? [] : svg.paths.map(
|
|
8496
|
-
(path) => path
|
|
8599
|
+
(path) => pathStyle(path)?.stroke === void 0 || pathStyle(path).stroke === "none" ? null : path.subPaths.map((subPath) => SVGLoader.pointsToStroke(subPath.getPoints(), pathStyle(path)))
|
|
8497
8600
|
),
|
|
8498
8601
|
[svg, skipStrokes]
|
|
8499
8602
|
);
|
|
@@ -8501,21 +8604,21 @@ const Svg = /* @__PURE__ */ forwardRef(
|
|
|
8501
8604
|
return () => strokeGeometries.forEach((group) => group && group.map((g) => g.dispose()));
|
|
8502
8605
|
}, [strokeGeometries]);
|
|
8503
8606
|
let renderOrder = 0;
|
|
8504
|
-
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
|
|
8607
|
+
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(
|
|
8505
8608
|
"meshBasicMaterial",
|
|
8506
8609
|
{
|
|
8507
|
-
color: path.
|
|
8508
|
-
opacity: path.
|
|
8610
|
+
color: pathStyle(path).fill,
|
|
8611
|
+
opacity: pathStyle(path).fillOpacity,
|
|
8509
8612
|
transparent: true,
|
|
8510
8613
|
side: DoubleSide,
|
|
8511
8614
|
depthWrite: false,
|
|
8512
8615
|
...fillMaterial
|
|
8513
8616
|
}
|
|
8514
|
-
))), !skipStrokes && path
|
|
8617
|
+
))), !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(
|
|
8515
8618
|
"meshBasicMaterial",
|
|
8516
8619
|
{
|
|
8517
|
-
color: path.
|
|
8518
|
-
opacity: path.
|
|
8620
|
+
color: pathStyle(path).stroke,
|
|
8621
|
+
opacity: pathStyle(path).strokeOpacity,
|
|
8519
8622
|
transparent: true,
|
|
8520
8623
|
side: DoubleSide,
|
|
8521
8624
|
depthWrite: false,
|
|
@@ -8738,8 +8841,8 @@ function useVideoTexture(srcOrSrcObject, {
|
|
|
8738
8841
|
});
|
|
8739
8842
|
if (src && IS_BROWSER && src.endsWith(".m3u8")) {
|
|
8740
8843
|
const hls = hlsRef.current = await getHls(hlsConfig);
|
|
8741
|
-
if (hls) {
|
|
8742
|
-
hls.on(Events.MEDIA_ATTACHED, () => void hls.loadSource(src));
|
|
8844
|
+
if (hls && _HLSModule) {
|
|
8845
|
+
hls.on(_HLSModule.Events.MEDIA_ATTACHED, () => void hls.loadSource(src));
|
|
8743
8846
|
hls.attachMedia(video2);
|
|
8744
8847
|
}
|
|
8745
8848
|
}
|
|
@@ -8959,9 +9062,125 @@ function Fbx({
|
|
|
8959
9062
|
return /* @__PURE__ */ React.createElement(Clone, { ...props, object });
|
|
8960
9063
|
}
|
|
8961
9064
|
|
|
9065
|
+
const SERVICE_KEY = "__drei_ktx2_service__";
|
|
9066
|
+
const DEFAULT_TRANSCODER_PATH = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
|
|
9067
|
+
class KTX2LoaderServiceImpl {
|
|
9068
|
+
loader = null;
|
|
9069
|
+
renderer = null;
|
|
9070
|
+
_isReady = false;
|
|
9071
|
+
transcoderPath = DEFAULT_TRANSCODER_PATH;
|
|
9072
|
+
pendingCallbacks = [];
|
|
9073
|
+
/**
|
|
9074
|
+
* Get or create the singleton KTX2Loader instance.
|
|
9075
|
+
* The loader is created lazily on first access.
|
|
9076
|
+
*/
|
|
9077
|
+
getLoader() {
|
|
9078
|
+
if (!this.loader) {
|
|
9079
|
+
this.loader = new KTX2Loader();
|
|
9080
|
+
this.loader.setTranscoderPath(this.transcoderPath);
|
|
9081
|
+
}
|
|
9082
|
+
return this.loader;
|
|
9083
|
+
}
|
|
9084
|
+
/**
|
|
9085
|
+
* Register a renderer and call detectSupport.
|
|
9086
|
+
* Should be called from within React context (useLayoutEffect).
|
|
9087
|
+
* Flushes any queued callbacks.
|
|
9088
|
+
*/
|
|
9089
|
+
registerRenderer(renderer) {
|
|
9090
|
+
if (this._isReady && this.renderer === renderer) {
|
|
9091
|
+
return;
|
|
9092
|
+
}
|
|
9093
|
+
this.renderer = renderer;
|
|
9094
|
+
const loader = this.getLoader();
|
|
9095
|
+
loader.detectSupport(renderer);
|
|
9096
|
+
this._isReady = true;
|
|
9097
|
+
this.flushPendingCallbacks();
|
|
9098
|
+
}
|
|
9099
|
+
/**
|
|
9100
|
+
* Check if the service is ready (has renderer registered).
|
|
9101
|
+
*/
|
|
9102
|
+
isReady() {
|
|
9103
|
+
return this._isReady;
|
|
9104
|
+
}
|
|
9105
|
+
/**
|
|
9106
|
+
* Get the registered renderer, if any.
|
|
9107
|
+
*/
|
|
9108
|
+
getRenderer() {
|
|
9109
|
+
return this.renderer;
|
|
9110
|
+
}
|
|
9111
|
+
/**
|
|
9112
|
+
* Register a callback to run when renderer becomes available.
|
|
9113
|
+
* If renderer is already available, runs immediately.
|
|
9114
|
+
*/
|
|
9115
|
+
onReady(callback) {
|
|
9116
|
+
if (this._isReady) {
|
|
9117
|
+
callback();
|
|
9118
|
+
} else {
|
|
9119
|
+
this.pendingCallbacks.push(callback);
|
|
9120
|
+
}
|
|
9121
|
+
}
|
|
9122
|
+
/**
|
|
9123
|
+
* Process all pending callbacks.
|
|
9124
|
+
*/
|
|
9125
|
+
flushPendingCallbacks() {
|
|
9126
|
+
const callbacks = this.pendingCallbacks;
|
|
9127
|
+
this.pendingCallbacks = [];
|
|
9128
|
+
for (const callback of callbacks) {
|
|
9129
|
+
try {
|
|
9130
|
+
callback();
|
|
9131
|
+
} catch (error) {
|
|
9132
|
+
console.error("KTX2LoaderService: Error in pending callback:", error);
|
|
9133
|
+
}
|
|
9134
|
+
}
|
|
9135
|
+
}
|
|
9136
|
+
/**
|
|
9137
|
+
* Set the transcoder path for basis/ktx2 decoding.
|
|
9138
|
+
*/
|
|
9139
|
+
setTranscoderPath(path) {
|
|
9140
|
+
this.transcoderPath = path;
|
|
9141
|
+
if (this.loader) {
|
|
9142
|
+
this.loader.setTranscoderPath(path);
|
|
9143
|
+
}
|
|
9144
|
+
}
|
|
9145
|
+
/**
|
|
9146
|
+
* Get the current transcoder path.
|
|
9147
|
+
*/
|
|
9148
|
+
getTranscoderPath() {
|
|
9149
|
+
return this.transcoderPath;
|
|
9150
|
+
}
|
|
9151
|
+
/**
|
|
9152
|
+
* Dispose of the loader and reset state.
|
|
9153
|
+
* Useful for testing or cleanup.
|
|
9154
|
+
*/
|
|
9155
|
+
dispose() {
|
|
9156
|
+
if (this.loader) {
|
|
9157
|
+
this.loader.dispose();
|
|
9158
|
+
}
|
|
9159
|
+
const path = this.transcoderPath;
|
|
9160
|
+
this.loader = null;
|
|
9161
|
+
this.renderer = null;
|
|
9162
|
+
this._isReady = false;
|
|
9163
|
+
this.transcoderPath = path;
|
|
9164
|
+
this.pendingCallbacks = [];
|
|
9165
|
+
}
|
|
9166
|
+
}
|
|
9167
|
+
const KTX2LoaderService = globalThis[SERVICE_KEY] || (globalThis[SERVICE_KEY] = new KTX2LoaderServiceImpl());
|
|
9168
|
+
|
|
8962
9169
|
let dracoLoader = null;
|
|
8963
9170
|
let decoderPath = "https://www.gstatic.com/draco/versioned/decoders/1.5.5/";
|
|
8964
|
-
|
|
9171
|
+
let legacyApiWarned = false;
|
|
9172
|
+
function isOptionsObject(arg) {
|
|
9173
|
+
return typeof arg === "object" && arg !== null && !Array.isArray(arg);
|
|
9174
|
+
}
|
|
9175
|
+
function warnLegacyApi() {
|
|
9176
|
+
if (!legacyApiWarned) {
|
|
9177
|
+
legacyApiWarned = true;
|
|
9178
|
+
console.warn(
|
|
9179
|
+
"useGLTF: Boolean arguments are deprecated. Use options object instead:\n useGLTF(path, { draco: true, meshopt: true, ktx2: true })"
|
|
9180
|
+
);
|
|
9181
|
+
}
|
|
9182
|
+
}
|
|
9183
|
+
function extensions(useDraco = true, useMeshopt = true, useKTX2 = false, extendLoader, renderer) {
|
|
8965
9184
|
return (loader) => {
|
|
8966
9185
|
if (extendLoader) {
|
|
8967
9186
|
extendLoader(loader);
|
|
@@ -8977,36 +9196,110 @@ function extensions(useDraco = true, useMeshopt = true, extendLoader) {
|
|
|
8977
9196
|
const decoder = typeof MeshoptDecoder === "function" ? MeshoptDecoder() : MeshoptDecoder;
|
|
8978
9197
|
loader.setMeshoptDecoder(decoder);
|
|
8979
9198
|
}
|
|
9199
|
+
if (useKTX2) {
|
|
9200
|
+
const ktx2Loader = KTX2LoaderService.getLoader();
|
|
9201
|
+
if (typeof useKTX2 === "string") {
|
|
9202
|
+
ktx2Loader.setTranscoderPath(useKTX2);
|
|
9203
|
+
}
|
|
9204
|
+
if (renderer) {
|
|
9205
|
+
ktx2Loader.detectSupport(renderer);
|
|
9206
|
+
}
|
|
9207
|
+
loader.setKTX2Loader(ktx2Loader);
|
|
9208
|
+
}
|
|
8980
9209
|
};
|
|
8981
9210
|
}
|
|
8982
|
-
|
|
8983
|
-
|
|
9211
|
+
function useGLTF(path, optionsOrDraco, useMeshoptArg, useKTX2Arg, extendLoaderArg) {
|
|
9212
|
+
let draco = true;
|
|
9213
|
+
let meshopt = true;
|
|
9214
|
+
let ktx2 = false;
|
|
9215
|
+
let extendLoader;
|
|
9216
|
+
if (isOptionsObject(optionsOrDraco)) {
|
|
9217
|
+
draco = optionsOrDraco.draco ?? true;
|
|
9218
|
+
meshopt = optionsOrDraco.meshopt ?? true;
|
|
9219
|
+
ktx2 = optionsOrDraco.ktx2 ?? false;
|
|
9220
|
+
extendLoader = optionsOrDraco.extendLoader;
|
|
9221
|
+
} else if (optionsOrDraco !== void 0) {
|
|
9222
|
+
warnLegacyApi();
|
|
9223
|
+
draco = optionsOrDraco;
|
|
9224
|
+
meshopt = useMeshoptArg ?? true;
|
|
9225
|
+
ktx2 = useKTX2Arg ?? false;
|
|
9226
|
+
extendLoader = extendLoaderArg;
|
|
9227
|
+
}
|
|
9228
|
+
const renderer = useThree((state) => state.renderer);
|
|
9229
|
+
useLayoutEffect(() => {
|
|
9230
|
+
if (ktx2) {
|
|
9231
|
+
KTX2LoaderService.registerRenderer(renderer);
|
|
9232
|
+
}
|
|
9233
|
+
}, [ktx2, renderer]);
|
|
9234
|
+
return useLoader(GLTFLoader, path, extensions(draco, meshopt, ktx2, extendLoader, ktx2 ? renderer : void 0));
|
|
9235
|
+
}
|
|
9236
|
+
useGLTF.preload = (path, optionsOrDraco, useMeshoptArg, useKTX2Arg, extendLoaderArg) => {
|
|
9237
|
+
let draco = true;
|
|
9238
|
+
let meshopt = true;
|
|
9239
|
+
let ktx2 = false;
|
|
9240
|
+
let extendLoader;
|
|
9241
|
+
if (isOptionsObject(optionsOrDraco)) {
|
|
9242
|
+
draco = optionsOrDraco.draco ?? true;
|
|
9243
|
+
meshopt = optionsOrDraco.meshopt ?? true;
|
|
9244
|
+
ktx2 = optionsOrDraco.ktx2 ?? false;
|
|
9245
|
+
extendLoader = optionsOrDraco.extendLoader;
|
|
9246
|
+
} else if (optionsOrDraco !== void 0) {
|
|
9247
|
+
warnLegacyApi();
|
|
9248
|
+
draco = optionsOrDraco;
|
|
9249
|
+
meshopt = useMeshoptArg ?? true;
|
|
9250
|
+
ktx2 = useKTX2Arg ?? false;
|
|
9251
|
+
extendLoader = extendLoaderArg;
|
|
9252
|
+
}
|
|
9253
|
+
if (ktx2) {
|
|
9254
|
+
KTX2LoaderService.onReady(() => {
|
|
9255
|
+
const renderer = KTX2LoaderService.getRenderer();
|
|
9256
|
+
useLoader.preload(GLTFLoader, path, extensions(draco, meshopt, ktx2, extendLoader, renderer));
|
|
9257
|
+
});
|
|
9258
|
+
} else {
|
|
9259
|
+
useLoader.preload(GLTFLoader, path, extensions(draco, meshopt, false, extendLoader));
|
|
9260
|
+
}
|
|
9261
|
+
};
|
|
8984
9262
|
useGLTF.clear = (path) => useLoader.clear(GLTFLoader, path);
|
|
8985
9263
|
useGLTF.setDecoderPath = (path) => {
|
|
8986
9264
|
decoderPath = path;
|
|
8987
9265
|
};
|
|
9266
|
+
useGLTF.setKTX2TranscoderPath = (path) => {
|
|
9267
|
+
KTX2LoaderService.setTranscoderPath(path);
|
|
9268
|
+
};
|
|
8988
9269
|
const Gltf = /* @__PURE__ */ React.forwardRef(
|
|
8989
|
-
({ src, useDraco, useMeshOpt, extendLoader, ...props }, ref) => {
|
|
8990
|
-
const
|
|
9270
|
+
({ src, useDraco, useMeshOpt, extendLoader, options, ...props }, ref) => {
|
|
9271
|
+
const opts = options ?? {
|
|
9272
|
+
draco: useDraco,
|
|
9273
|
+
meshopt: useMeshOpt,
|
|
9274
|
+
extendLoader
|
|
9275
|
+
};
|
|
9276
|
+
const { scene } = useGLTF(src, opts);
|
|
8991
9277
|
return /* @__PURE__ */ React.createElement(Clone, { ref, ...props, object: scene });
|
|
8992
9278
|
}
|
|
8993
9279
|
);
|
|
8994
9280
|
|
|
8995
|
-
let transcoderPath = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
|
|
8996
9281
|
function useKTX2(input, basisPath = true, extendLoader) {
|
|
8997
9282
|
const renderer = useThree((state) => state.renderer);
|
|
9283
|
+
useLayoutEffect(() => {
|
|
9284
|
+
KTX2LoaderService.registerRenderer(renderer);
|
|
9285
|
+
}, [renderer]);
|
|
8998
9286
|
const textures = useLoader(KTX2Loader, IsObject(input) ? Object.values(input) : input, (loader) => {
|
|
8999
9287
|
if (extendLoader) {
|
|
9000
9288
|
extendLoader(loader);
|
|
9001
9289
|
}
|
|
9002
9290
|
if (basisPath) {
|
|
9003
|
-
|
|
9291
|
+
const path = typeof basisPath === "string" ? basisPath : KTX2LoaderService.getTranscoderPath();
|
|
9292
|
+
loader.setTranscoderPath(path);
|
|
9004
9293
|
}
|
|
9005
9294
|
loader.detectSupport(renderer);
|
|
9006
9295
|
});
|
|
9007
9296
|
useEffect(() => {
|
|
9008
9297
|
const array = Array.isArray(textures) ? textures : [textures];
|
|
9009
|
-
array.forEach((texture) =>
|
|
9298
|
+
array.forEach((texture) => {
|
|
9299
|
+
if ("initTexture" in renderer) {
|
|
9300
|
+
renderer.initTexture(texture);
|
|
9301
|
+
}
|
|
9302
|
+
});
|
|
9010
9303
|
}, [renderer, textures]);
|
|
9011
9304
|
if (IsObject(input)) {
|
|
9012
9305
|
const keys = Object.keys(input);
|
|
@@ -9017,23 +9310,81 @@ function useKTX2(input, basisPath = true, extendLoader) {
|
|
|
9017
9310
|
return textures;
|
|
9018
9311
|
}
|
|
9019
9312
|
}
|
|
9020
|
-
useKTX2.preload = (url, basisPath = true, extendLoader) =>
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
|
|
9313
|
+
useKTX2.preload = (url, basisPath = true, extendLoader) => {
|
|
9314
|
+
KTX2LoaderService.onReady(() => {
|
|
9315
|
+
const renderer = KTX2LoaderService.getRenderer();
|
|
9316
|
+
useLoader.preload(KTX2Loader, url, (loader) => {
|
|
9317
|
+
if (extendLoader) {
|
|
9318
|
+
extendLoader(loader);
|
|
9319
|
+
}
|
|
9320
|
+
if (basisPath) {
|
|
9321
|
+
const path = typeof basisPath === "string" ? basisPath : KTX2LoaderService.getTranscoderPath();
|
|
9322
|
+
loader.setTranscoderPath(path);
|
|
9323
|
+
}
|
|
9324
|
+
if (renderer) {
|
|
9325
|
+
loader.detectSupport(renderer);
|
|
9326
|
+
}
|
|
9327
|
+
});
|
|
9328
|
+
});
|
|
9329
|
+
};
|
|
9028
9330
|
useKTX2.clear = (input) => useLoader.clear(KTX2Loader, input);
|
|
9029
9331
|
useKTX2.setTranscoderPath = (path) => {
|
|
9030
|
-
|
|
9332
|
+
KTX2LoaderService.setTranscoderPath(path);
|
|
9031
9333
|
};
|
|
9032
9334
|
const Ktx2 = ({ children, input, basisPath, extendLoader }) => {
|
|
9033
9335
|
const texture = useKTX2(input, basisPath, extendLoader);
|
|
9034
9336
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(texture));
|
|
9035
9337
|
};
|
|
9036
9338
|
|
|
9339
|
+
const useVariants = (model, inVariant) => {
|
|
9340
|
+
const [activeVariant, setActiveVariant] = useState(null);
|
|
9341
|
+
const [materials, setMaterials] = useState([]);
|
|
9342
|
+
useEffect(() => {
|
|
9343
|
+
model.parser.getDependencies("material").then((materials2) => {
|
|
9344
|
+
setMaterials(materials2);
|
|
9345
|
+
});
|
|
9346
|
+
}, [model]);
|
|
9347
|
+
const variants = useMemo(() => {
|
|
9348
|
+
return model.userData.gltfExtensions?.KHR_materials_variants?.variants;
|
|
9349
|
+
}, [model]);
|
|
9350
|
+
const applyVariant = useCallback(
|
|
9351
|
+
(variantIndex) => {
|
|
9352
|
+
model.scene.traverse(async (object) => {
|
|
9353
|
+
if (!("isMesh" in object) || !object.userData.gltfExtensions) return;
|
|
9354
|
+
const meshObject = object;
|
|
9355
|
+
const meshVariantDef = meshObject.userData.gltfExtensions.KHR_materials_variants;
|
|
9356
|
+
if (!meshVariantDef) return;
|
|
9357
|
+
if (!meshObject.userData.originalMaterial) meshObject.userData.originalMaterial = meshObject.material;
|
|
9358
|
+
const mapping = meshVariantDef.mappings.find((mapping2) => mapping2.variants.includes(variantIndex));
|
|
9359
|
+
if (mapping) {
|
|
9360
|
+
meshObject.material = await model.parser.getDependency("material", mapping.material);
|
|
9361
|
+
model.parser.assignFinalMaterial(meshObject);
|
|
9362
|
+
} else meshObject.material = meshObject.userData.originalMaterial;
|
|
9363
|
+
if (Array.isArray(meshObject.material)) for (const mat of meshObject.material) mat.needsUpdate = true;
|
|
9364
|
+
else meshObject.material.needsUpdate = true;
|
|
9365
|
+
});
|
|
9366
|
+
},
|
|
9367
|
+
[model]
|
|
9368
|
+
);
|
|
9369
|
+
const setVariant = useCallback(
|
|
9370
|
+
(variantName) => {
|
|
9371
|
+
if (!variants) return;
|
|
9372
|
+
const newVariant = variantName && variants.some((v) => v.name === variantName) ? variantName : null;
|
|
9373
|
+
setActiveVariant(newVariant);
|
|
9374
|
+
},
|
|
9375
|
+
[variants]
|
|
9376
|
+
);
|
|
9377
|
+
useEffect(() => {
|
|
9378
|
+
if (!variants) return;
|
|
9379
|
+
const variantIndex = variants.findIndex((v) => v.name === activeVariant);
|
|
9380
|
+
applyVariant(variantIndex > -1 ? variantIndex : 0);
|
|
9381
|
+
}, [variants, activeVariant, applyVariant]);
|
|
9382
|
+
useEffect(() => {
|
|
9383
|
+
setVariant(inVariant ?? null);
|
|
9384
|
+
}, [inVariant, setVariant]);
|
|
9385
|
+
return { variants, activeVariant, setVariant, materials };
|
|
9386
|
+
};
|
|
9387
|
+
|
|
9037
9388
|
const WebcamVideoTexture = /* @__PURE__ */ forwardRef(
|
|
9038
9389
|
({
|
|
9039
9390
|
constraints = {
|
|
@@ -9221,6 +9572,7 @@ function useEffectfulState(fn, deps = [], cb) {
|
|
|
9221
9572
|
}
|
|
9222
9573
|
|
|
9223
9574
|
function Stats({ showPanel = 0, className, parent }) {
|
|
9575
|
+
React.useEffect(() => void console.warn("drei: <Stats /> is deprecated, use <StatsGl /> instead."), []);
|
|
9224
9576
|
const stats = useEffectfulState(() => new StatsImpl(), []);
|
|
9225
9577
|
React.useEffect(() => {
|
|
9226
9578
|
if (stats) {
|
|
@@ -9249,6 +9601,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
|
|
|
9249
9601
|
const stats2 = new Stats$1({
|
|
9250
9602
|
...props
|
|
9251
9603
|
});
|
|
9604
|
+
stats2.init(renderer);
|
|
9252
9605
|
return stats2;
|
|
9253
9606
|
}, [renderer]);
|
|
9254
9607
|
React.useImperativeHandle(fref, () => stats.domElement, [stats]);
|
|
@@ -9266,7 +9619,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
|
|
|
9266
9619
|
return () => {
|
|
9267
9620
|
if (classNames.length) stats.domElement.classList.remove(...classNames);
|
|
9268
9621
|
node?.removeChild(stats.domElement);
|
|
9269
|
-
stats.
|
|
9622
|
+
stats.dispose();
|
|
9270
9623
|
};
|
|
9271
9624
|
}
|
|
9272
9625
|
}, [parent, stats, className, id, clearStatsGlStyle]);
|
|
@@ -9274,7 +9627,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
|
|
|
9274
9627
|
() => {
|
|
9275
9628
|
stats.begin();
|
|
9276
9629
|
},
|
|
9277
|
-
{ before: "
|
|
9630
|
+
{ before: "update" }
|
|
9278
9631
|
);
|
|
9279
9632
|
useFrame(
|
|
9280
9633
|
() => {
|
|
@@ -9324,11 +9677,11 @@ const RenderCubeTexture = /* @__PURE__ */ React.forwardRef(
|
|
|
9324
9677
|
depthBuffer,
|
|
9325
9678
|
generateMipmaps
|
|
9326
9679
|
};
|
|
9327
|
-
const fboA2 = new
|
|
9680
|
+
const fboA2 = new WebGLCubeRenderTarget(fboSize, settings);
|
|
9328
9681
|
fboA2.texture.isRenderTargetTexture = !flip;
|
|
9329
9682
|
fboA2.texture.flipY = true;
|
|
9330
9683
|
fboA2.texture.type = THREE.HalfFloatType;
|
|
9331
|
-
const fboB2 = new
|
|
9684
|
+
const fboB2 = new WebGLCubeRenderTarget(fboSize, settings);
|
|
9332
9685
|
fboB2.texture.isRenderTargetTexture = !flip;
|
|
9333
9686
|
fboB2.texture.flipY = true;
|
|
9334
9687
|
fboB2.texture.type = THREE.HalfFloatType;
|
|
@@ -9657,8 +10010,9 @@ const TUNNEL_KEY = "__drei_view_tunnel__";
|
|
|
9657
10010
|
const tracked = globalThis[TUNNEL_KEY] || (globalThis[TUNNEL_KEY] = tunnel());
|
|
9658
10011
|
function computeContainerPosition(canvasSize, trackRect, forceEven) {
|
|
9659
10012
|
const { right, top: trackTop, left: trackLeft, bottom: trackBottom, width, height } = trackRect;
|
|
9660
|
-
const isOffscreen = trackRect.bottom < 0 || trackTop > canvasSize.height || right < 0 || trackRect.left > canvasSize.width;
|
|
9661
10013
|
const canvasBottom = canvasSize.top + canvasSize.height;
|
|
10014
|
+
const canvasRight = canvasSize.left + canvasSize.width;
|
|
10015
|
+
const isOffscreen = trackBottom < canvasSize.top || trackTop > canvasBottom || right < canvasSize.left || trackLeft > canvasRight;
|
|
9662
10016
|
const rawBottom = canvasBottom - trackBottom;
|
|
9663
10017
|
const rawLeft = trackLeft - canvasSize.left;
|
|
9664
10018
|
const rawTop = trackTop - canvasSize.top;
|
|
@@ -10218,12 +10572,12 @@ useEnvironment.preload = (preloadOptions) => {
|
|
|
10218
10572
|
if (extensions) extensions(loader2);
|
|
10219
10573
|
});
|
|
10220
10574
|
};
|
|
10221
|
-
const
|
|
10575
|
+
const clearDefaultOptions = {
|
|
10222
10576
|
files: defaultFiles,
|
|
10223
10577
|
preset: void 0
|
|
10224
10578
|
};
|
|
10225
10579
|
useEnvironment.clear = (clearOptions) => {
|
|
10226
|
-
const options = { ...
|
|
10580
|
+
const options = { ...clearDefaultOptions, ...clearOptions };
|
|
10227
10581
|
let { files } = options;
|
|
10228
10582
|
const { preset } = options;
|
|
10229
10583
|
if (preset) {
|
|
@@ -10917,9 +11271,14 @@ function Select({
|
|
|
10917
11271
|
const oldControlsEnabled = controls?.enabled;
|
|
10918
11272
|
let isDown = false;
|
|
10919
11273
|
function prepareRay(event, vec) {
|
|
10920
|
-
const
|
|
11274
|
+
const canvas = gl.domElement;
|
|
11275
|
+
const rect = canvas.getBoundingClientRect();
|
|
11276
|
+
const x = event.clientX - rect.left;
|
|
11277
|
+
const y = event.clientY - rect.top;
|
|
10921
11278
|
const { width, height } = size;
|
|
10922
|
-
|
|
11279
|
+
const normalizedX = x / width * 2 - 1;
|
|
11280
|
+
const normalizedY = -(y / height) * 2 + 1;
|
|
11281
|
+
vec.set(normalizedX, normalizedY, -1);
|
|
10923
11282
|
}
|
|
10924
11283
|
function onSelectStart(event) {
|
|
10925
11284
|
if (controls) controls.enabled = false;
|
|
@@ -11653,8 +12012,8 @@ vec3 highPassRandRGB(vec2 uv) {
|
|
|
11653
12012
|
|
|
11654
12013
|
|
|
11655
12014
|
vec2 vogelDiskSample(int sampleIndex, int sampleCount, float angle) {
|
|
11656
|
-
|
|
11657
|
-
float r = sqrt(float(sampleIndex) + 0.
|
|
12015
|
+
float goldenAngle = 2.399963;
|
|
12016
|
+
float r = sqrt(float(sampleIndex) + 0.5) / sqrt(float(sampleCount));
|
|
11658
12017
|
float theta = float(sampleIndex) * goldenAngle + angle;
|
|
11659
12018
|
float sine = sin(theta);
|
|
11660
12019
|
float cosine = cos(theta);
|
|
@@ -11675,7 +12034,7 @@ float findBlocker(sampler2D shadowMap, vec2 uv, float compare, float angle) {
|
|
|
11675
12034
|
#pragma unroll_loop_start
|
|
11676
12035
|
for(int i = 0; i < ${samples}; i ++) {
|
|
11677
12036
|
offset = (vogelDiskSample(j, ${samples}, angle) * texelSize) * 2.0 * PENUMBRA_FILTER_SIZE;
|
|
11678
|
-
depth =
|
|
12037
|
+
depth = texture2D( shadowMap, uv + offset ).r;
|
|
11679
12038
|
if (depth < compare) {
|
|
11680
12039
|
blockerDepthSum += depth;
|
|
11681
12040
|
blockers++;
|
|
@@ -11693,7 +12052,7 @@ float findBlocker(sampler2D shadowMap, vec2 uv, float compare, float angle) {
|
|
|
11693
12052
|
|
|
11694
12053
|
float vogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRadius, float angle) {
|
|
11695
12054
|
float texelSize = 1.0 / float(textureSize(shadowMap, 0).x);
|
|
11696
|
-
float shadow = 0.
|
|
12055
|
+
float shadow = 0.0;
|
|
11697
12056
|
int j = 0;
|
|
11698
12057
|
vec2 vogelSample = vec2(0.0);
|
|
11699
12058
|
vec2 offset = vec2(0.0);
|
|
@@ -11701,7 +12060,7 @@ float vogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRad
|
|
|
11701
12060
|
for (int i = 0; i < ${samples}; i++) {
|
|
11702
12061
|
vogelSample = vogelDiskSample(j, ${samples}, angle) * texelSize;
|
|
11703
12062
|
offset = vogelSample * (1.0 + filterRadius * float(${size}));
|
|
11704
|
-
shadow += step( zReceiver,
|
|
12063
|
+
shadow += step( zReceiver, texture2D( shadowMap, uv + offset ).r );
|
|
11705
12064
|
j++;
|
|
11706
12065
|
}
|
|
11707
12066
|
#pragma unroll_loop_end
|
|
@@ -11710,7 +12069,7 @@ float vogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRad
|
|
|
11710
12069
|
|
|
11711
12070
|
float PCSS (sampler2D shadowMap, vec4 coords) {
|
|
11712
12071
|
vec2 uv = coords.xy;
|
|
11713
|
-
float zReceiver = coords.z;
|
|
12072
|
+
float zReceiver = coords.z;
|
|
11714
12073
|
float angle = highPassRandRGB(gl_FragCoord.xy).r * PI2;
|
|
11715
12074
|
float avgBlockerDepth = findBlocker(shadowMap, uv, zReceiver, angle);
|
|
11716
12075
|
if (avgBlockerDepth == -1.0) {
|
|
@@ -11734,14 +12093,27 @@ function SoftShadows({ focus = 0, samples = 10, size = 25 }) {
|
|
|
11734
12093
|
const scene = useThree((state) => state.scene);
|
|
11735
12094
|
const camera = useThree((state) => state.camera);
|
|
11736
12095
|
React.useEffect(() => {
|
|
11737
|
-
const
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
);
|
|
12096
|
+
const originalShader = THREE.ShaderChunk.shadowmap_pars_fragment;
|
|
12097
|
+
const originalShadowMapType = gl.shadowMap.type;
|
|
12098
|
+
gl.shadowMap.type = THREE.BasicShadowMap;
|
|
12099
|
+
let shader = THREE.ShaderChunk.shadowmap_pars_fragment;
|
|
12100
|
+
shader = shader.replace("#ifdef USE_SHADOWMAP", "#ifdef USE_SHADOWMAP\n" + pcss({ size, samples, focus }));
|
|
12101
|
+
const basicIfBlockRegex = /if\s*\(\s*frustumTest\s*\)\s*\{\s*float\s+depth\s*=\s*texture2D\s*\(\s*shadowMap\s*,\s*shadowCoord\.xy\s*\)\.r;\s*#ifdef\s+USE_REVERSED_DEPTH_BUFFER\s*shadow\s*=\s*step\s*\(\s*depth\s*,\s*shadowCoord\.z\s*\)\s*;\s*#else\s*shadow\s*=\s*step\s*\(\s*shadowCoord\.z\s*,\s*depth\s*\)\s*;\s*#endif\s*\}/;
|
|
12102
|
+
if (basicIfBlockRegex.test(shader)) {
|
|
12103
|
+
shader = shader.replace(
|
|
12104
|
+
basicIfBlockRegex,
|
|
12105
|
+
`if ( frustumTest ) {
|
|
12106
|
+
shadow = PCSS( shadowMap, shadowCoord );
|
|
12107
|
+
}`
|
|
12108
|
+
);
|
|
12109
|
+
} else {
|
|
12110
|
+
console.warn("[SoftShadows] Could not find injection point in shader!");
|
|
12111
|
+
}
|
|
12112
|
+
THREE.ShaderChunk.shadowmap_pars_fragment = shader;
|
|
11742
12113
|
reset(gl, scene, camera);
|
|
11743
12114
|
return () => {
|
|
11744
|
-
THREE.ShaderChunk.shadowmap_pars_fragment =
|
|
12115
|
+
THREE.ShaderChunk.shadowmap_pars_fragment = originalShader;
|
|
12116
|
+
gl.shadowMap.type = originalShadowMapType;
|
|
11745
12117
|
reset(gl, scene, camera);
|
|
11746
12118
|
};
|
|
11747
12119
|
}, [focus, size, samples]);
|
|
@@ -11847,6 +12219,60 @@ class SpotLightMaterial extends THREE.ShaderMaterial {
|
|
|
11847
12219
|
}
|
|
11848
12220
|
}
|
|
11849
12221
|
|
|
12222
|
+
const HtmlMaterial = ({ transform }) => {
|
|
12223
|
+
const shaders = useMemo(
|
|
12224
|
+
() => ({
|
|
12225
|
+
vertexShader: !transform ? (
|
|
12226
|
+
/* glsl */
|
|
12227
|
+
`
|
|
12228
|
+
/*
|
|
12229
|
+
This shader is from the THREE's SpriteMaterial.
|
|
12230
|
+
We need to turn the backing plane into a Sprite
|
|
12231
|
+
(make it always face the camera) if "transform"
|
|
12232
|
+
is false.
|
|
12233
|
+
*/
|
|
12234
|
+
#include <common>
|
|
12235
|
+
|
|
12236
|
+
void main() {
|
|
12237
|
+
vec2 center = vec2(0., 1.);
|
|
12238
|
+
float rotation = 0.0;
|
|
12239
|
+
|
|
12240
|
+
// This is somewhat arbitrary, but it seems to work well
|
|
12241
|
+
// Need to figure out how to derive this dynamically if it even matters
|
|
12242
|
+
float size = 0.03;
|
|
12243
|
+
|
|
12244
|
+
vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
|
|
12245
|
+
vec2 scale;
|
|
12246
|
+
scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );
|
|
12247
|
+
scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );
|
|
12248
|
+
|
|
12249
|
+
bool isPerspective = isPerspectiveMatrix( projectionMatrix );
|
|
12250
|
+
if ( isPerspective ) scale *= - mvPosition.z;
|
|
12251
|
+
|
|
12252
|
+
vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale * size;
|
|
12253
|
+
vec2 rotatedPosition;
|
|
12254
|
+
rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
|
|
12255
|
+
rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
|
|
12256
|
+
mvPosition.xy += rotatedPosition;
|
|
12257
|
+
|
|
12258
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
12259
|
+
}
|
|
12260
|
+
`
|
|
12261
|
+
) : void 0,
|
|
12262
|
+
fragmentShader: (
|
|
12263
|
+
/* glsl */
|
|
12264
|
+
`
|
|
12265
|
+
void main() {
|
|
12266
|
+
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
|
12267
|
+
}
|
|
12268
|
+
`
|
|
12269
|
+
)
|
|
12270
|
+
}),
|
|
12271
|
+
[transform]
|
|
12272
|
+
);
|
|
12273
|
+
return /* @__PURE__ */ React.createElement("shaderMaterial", { side: DoubleSide, vertexShader: shaders.vertexShader, fragmentShader: shaders.fragmentShader });
|
|
12274
|
+
};
|
|
12275
|
+
|
|
11850
12276
|
class StarfieldMaterial extends ShaderMaterial {
|
|
11851
12277
|
constructor() {
|
|
11852
12278
|
super({
|
|
@@ -11921,8 +12347,8 @@ class SparklesMaterial extends ShaderMaterial {
|
|
|
11921
12347
|
modelPosition.z += cos(time * speed + modelPosition.x * noise.y * 100.0) * 0.2;
|
|
11922
12348
|
modelPosition.x += cos(time * speed + modelPosition.x * noise.z * 100.0) * 0.2;
|
|
11923
12349
|
vec4 viewPosition = viewMatrix * modelPosition;
|
|
11924
|
-
vec4
|
|
11925
|
-
gl_Position =
|
|
12350
|
+
vec4 projectionPosition = projectionMatrix * viewPosition;
|
|
12351
|
+
gl_Position = projectionPosition;
|
|
11926
12352
|
gl_PointSize = size * 25. * pixelRatio;
|
|
11927
12353
|
gl_PointSize *= (1.0 / - viewPosition.z);
|
|
11928
12354
|
vColor = color;
|
|
@@ -11937,8 +12363,9 @@ class SparklesMaterial extends ShaderMaterial {
|
|
|
11937
12363
|
varying float vOpacity;
|
|
11938
12364
|
void main() {
|
|
11939
12365
|
float distanceToCenter = distance(gl_PointCoord, vec2(0.5));
|
|
11940
|
-
float strength = 0.05 / distanceToCenter - 0.1;
|
|
12366
|
+
float strength = clamp(0.05 / distanceToCenter - 0.1, 0.0, 1.0);
|
|
11941
12367
|
gl_FragColor = vec4(vColor, strength * vOpacity);
|
|
12368
|
+
// Note: tonemapping may shift hue (e.g. orange \u2192 yellow) compared to the WebGPU version
|
|
11942
12369
|
#include <tonemapping_fragment>
|
|
11943
12370
|
#include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
|
|
11944
12371
|
}
|
|
@@ -12628,4 +13055,4 @@ const Text = /* @__PURE__ */ React.forwardRef(
|
|
|
12628
13055
|
}
|
|
12629
13056
|
);
|
|
12630
13057
|
|
|
12631
|
-
export { AccumulativeShadows, AdaptiveDpr, AdaptiveEvents, ArcballControls, AsciiRenderer, BBAnchor, Backdrop, BakeShadows, Billboard, BlurPass, Bounds, Box, CameraShake, Capsule, CatmullRomLine, Caustics, Center, Circle, Clone, Cloud, CloudInstance, CloudMaterial, Clouds, ComputedAttribute, Cone, ContactShadows, ConvolutionMaterial, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, DiscardMaterial, Dodecahedron, DragControls, Edges, Effects, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, GradientTexture, GradientType, Grid, Helper, Html, Hud, Icosahedron, Image, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Line, Loader, MapControls, Mask, MatcapTexture, Merged, MeshDiscardMaterial, MeshDistortMaterial, MeshPortalMaterial, MeshReflectorMaterial, MeshRefractionMaterial, MeshTransmissionMaterial, MeshWobbleMaterial, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, Outlines, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RandomizedLight, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Segment, SegmentObject, Segments, Select, Shadow, Shape, Sky, SoftShadows, Sparkles, SparklesMaterial, Sphere, SpotLight, SpotLightMaterial, SpotLightShadow, SpriteAnimator, Stage, StarfieldMaterial, Stars, Stats, StatsGl, Svg, Tetrahedron, Text, Text3D, Texture, Torus, TorusKnot, TrackballControls, Trail, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture, Wireframe, WireframeMaterial, WireframeMaterialShaders, accumulativeContext, calcPosFromAngles, checkIfFrameIsEmpty, createInstances, getFirstFrame, isWebGL2Available, meshBounds, presetsObj, setWireframeOverride, shaderMaterial, useAnimations, useAspect, useBounds, useBoxProjectedEnv, useContextBridge, useCubeCamera, useCubeTexture, useCursor, useCustomRaycast, useDepthBuffer, useDetectGPU, useEnvironment, useFBO, useFBX, useFont, useGLTF, useGizmoContext, useHelper, useIntersect, useKTX2, useKeyboardControls, useMask, useMatcapTexture, useMotion, useNormalTexture, usePerformanceMonitor, useProgress, useScroll, useSelect, useSpriteAnimator, useSpriteLoader, useSurfaceSampler, useTexture, useTrail, useTrailTexture, useVideoTexture, useWireframeUniforms };
|
|
13058
|
+
export { AccumulativeShadows, AdaptiveDpr, AdaptiveEvents, ArcballControls, AsciiRenderer, BBAnchor, Backdrop, BakeShadows, Billboard, BlurPass, Bounds, Box, CameraShake, Capsule, CatmullRomLine, Caustics, Center, Circle, Clone, Cloud, CloudInstance, CloudMaterial, Clouds, ComputedAttribute, Cone, ContactShadows, ConvolutionMaterial, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, DiscardMaterial, Dodecahedron, DragControls, Edges, Effects, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, GradientTexture, GradientType, Grid, Helper, Html, HtmlMaterial, Hud, Icosahedron, Image, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Line, Loader, MapControls, Mask, MatcapTexture, Merged, MeshDiscardMaterial, MeshDistortMaterial, MeshPortalMaterial, MeshReflectorMaterial, MeshRefractionMaterial, MeshTransmissionMaterial, MeshWobbleMaterial, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, Outlines, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RandomizedLight, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Segment, SegmentObject, Segments, Select, Shadow, Shape, Sky, SoftShadows, Sparkles, SparklesMaterial, Sphere, SpotLight, SpotLightMaterial, SpotLightShadow, SpriteAnimator, Stage, StarfieldMaterial, Stars, Stats, StatsGl, Svg, Tetrahedron, Text, Text3D, Texture, Torus, TorusKnot, TrackballControls, Trail, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture, Wireframe, WireframeMaterial, WireframeMaterialShaders, accumulativeContext, calcPosFromAngles, checkIfFrameIsEmpty, createInstances, getFirstFrame, isWebGL2Available, meshBounds, presetsObj, setWireframeOverride, shaderMaterial, useAnimations, useAspect, useBounds, useBoxProjectedEnv, useContextBridge, useCubeCamera, useCubeTexture, useCursor, useCustomRaycast, useDepthBuffer, useDetectGPU, useEnvironment, useFBO, useFBX, useFont, useGLTF, useGizmoContext, useHelper, useIntersect, useKTX2, useKeyboardControls, useMask, useMatcapTexture, useMotion, useNormalTexture, usePerformanceMonitor, useProgress, useScroll, useSelect, useSpriteAnimator, useSpriteLoader, useSurfaceSampler, useTexture, useTrail, useTrailTexture, useVariants, useVideoTexture, useWireframeUniforms };
|