@react-three/drei 11.0.0-alpha.4 → 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 +249 -108
- package/core/index.d.ts +249 -108
- package/core/index.mjs +919 -692
- package/experimental/index.d.mts +24 -4
- package/experimental/index.d.ts +24 -4
- package/experimental/index.mjs +1 -0
- package/external/index.d.mts +42 -6
- package/external/index.d.ts +42 -6
- package/external/index.mjs +4 -4
- package/index.d.mts +266 -110
- package/index.d.ts +266 -110
- package/index.mjs +920 -693
- package/legacy/index.d.mts +344 -142
- package/legacy/index.d.ts +344 -142
- package/legacy/index.mjs +1536 -803
- package/native/index.d.mts +385 -489
- package/native/index.d.ts +385 -489
- package/native/index.mjs +2047 -2434
- package/package.json +8 -9
- package/webgpu/index.d.mts +416 -332
- package/webgpu/index.d.ts +416 -332
- package/webgpu/index.mjs +2273 -1880
package/legacy/index.mjs
CHANGED
|
@@ -2,10 +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, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial,
|
|
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 { DeviceOrientationControls as DeviceOrientationControls$1 } from 'three-stdlib';
|
|
8
|
-
import { useGesture } from '@use-gesture/react';
|
|
9
7
|
import { FirstPersonControls as FirstPersonControls$1 } from 'three/examples/jsm/controls/FirstPersonControls.js';
|
|
10
8
|
import { FlyControls as FlyControls$1 } from 'three/examples/jsm/controls/FlyControls.js';
|
|
11
9
|
import { create as create$1 } from 'zustand';
|
|
@@ -14,6 +12,7 @@ import { MapControls as MapControls$1 } from 'three/examples/jsm/controls/MapCon
|
|
|
14
12
|
import { misc, easing } from 'maath';
|
|
15
13
|
import { OrbitControls as OrbitControls$1 } from 'three/addons/controls/OrbitControls.js';
|
|
16
14
|
import { PointerLockControls as PointerLockControls$1 } from 'three/examples/jsm/controls/PointerLockControls.js';
|
|
15
|
+
import { useGesture } from '@use-gesture/react';
|
|
17
16
|
import * as ReactDOM from 'react-dom/client';
|
|
18
17
|
import { TrackballControls as TrackballControls$1 } from 'three/examples/jsm/controls/TrackballControls.js';
|
|
19
18
|
import { SimplexNoise } from 'three/examples/jsm/math/SimplexNoise.js';
|
|
@@ -32,7 +31,6 @@ import { TransformControls as TransformControls$1 } from 'three/examples/jsm/con
|
|
|
32
31
|
import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils.js';
|
|
33
32
|
import { MeshSurfaceSampler } from 'three/examples/jsm/math/MeshSurfaceSampler.js';
|
|
34
33
|
import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader.js';
|
|
35
|
-
import { Events } from 'hls.js';
|
|
36
34
|
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
|
|
37
35
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
38
36
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
@@ -58,7 +56,7 @@ import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
|
|
|
58
56
|
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
59
57
|
import { AsciiEffect } from 'three/examples/jsm/effects/AsciiEffect.js';
|
|
60
58
|
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
|
|
61
|
-
import { shaderStructs, shaderIntersectFunction
|
|
59
|
+
import { MeshBVHUniformStruct, MeshBVH, SAH, shaderStructs, shaderIntersectFunction } from 'three-mesh-bvh';
|
|
62
60
|
import { Text as Text$1, preloadFont } from 'troika-three-text';
|
|
63
61
|
|
|
64
62
|
const ContactShadows = /* @__PURE__ */ React.forwardRef(
|
|
@@ -188,6 +186,7 @@ function shaderMaterial(uniforms, vertexShader, fragmentShader, onInit) {
|
|
|
188
186
|
});
|
|
189
187
|
}
|
|
190
188
|
this.uniforms = THREE.UniformsUtils.clone(this.uniforms);
|
|
189
|
+
Object.assign(this, parameters);
|
|
191
190
|
onInit?.(this);
|
|
192
191
|
}
|
|
193
192
|
};
|
|
@@ -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 ) );
|
|
@@ -1517,6 +1522,7 @@ let MeshReflectorMaterial$1 = class MeshReflectorMaterial extends MeshStandardMa
|
|
|
1517
1522
|
uniform float depthScale;
|
|
1518
1523
|
uniform float depthToBlurRatioBias;
|
|
1519
1524
|
varying vec4 my_vUv;
|
|
1525
|
+
#include <tonemapping_pars_fragment>
|
|
1520
1526
|
${shader.fragmentShader}`;
|
|
1521
1527
|
shader.fragmentShader = shader.fragmentShader.replace(
|
|
1522
1528
|
"#include <emissivemap_fragment>",
|
|
@@ -1577,6 +1583,9 @@ let MeshReflectorMaterial$1 = class MeshReflectorMaterial extends MeshStandardMa
|
|
|
1577
1583
|
merge = mix(merge, blur, blurFactor);
|
|
1578
1584
|
#endif
|
|
1579
1585
|
|
|
1586
|
+
// Apply tone mapping to HDR reflection values before contrast adjustment
|
|
1587
|
+
merge.rgb = toneMapping(merge.rgb);
|
|
1588
|
+
|
|
1580
1589
|
vec4 newMerge = vec4(0.0, 0.0, 0.0, 1.0);
|
|
1581
1590
|
newMerge.r = (merge.r - 0.5) * mixContrast + 0.5;
|
|
1582
1591
|
newMerge.g = (merge.g - 0.5) * mixContrast + 0.5;
|
|
@@ -1835,6 +1844,7 @@ const MeshReflectorMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
1835
1844
|
useFrame(() => {
|
|
1836
1845
|
const parent = materialRef.current.parent || materialRef.current?.__r3f.parent?.object;
|
|
1837
1846
|
if (!parent) return;
|
|
1847
|
+
if (gl.xr.isPresenting) return;
|
|
1838
1848
|
parent.visible = false;
|
|
1839
1849
|
const currentXrEnabled = gl.xr.enabled;
|
|
1840
1850
|
const currentShadowAutoUpdate = gl.shadowMap.autoUpdate;
|
|
@@ -1864,7 +1874,7 @@ const MeshReflectorMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
1864
1874
|
}
|
|
1865
1875
|
);
|
|
1866
1876
|
|
|
1867
|
-
const
|
|
1877
|
+
const MeshRefractionMaterial_ = /* @__PURE__ */ shaderMaterial(
|
|
1868
1878
|
{
|
|
1869
1879
|
envMap: null,
|
|
1870
1880
|
bounces: 3,
|
|
@@ -2025,6 +2035,56 @@ const MeshRefractionMaterial = /* @__PURE__ */ shaderMaterial(
|
|
|
2025
2035
|
#include <${version$1 >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
|
|
2026
2036
|
}`
|
|
2027
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
|
+
);
|
|
2028
2088
|
|
|
2029
2089
|
function useIntersect(onChange) {
|
|
2030
2090
|
const { isLegacy } = useThree();
|
|
@@ -2248,6 +2308,8 @@ const MeshPortalMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
2248
2308
|
children,
|
|
2249
2309
|
events = void 0,
|
|
2250
2310
|
blur = 0,
|
|
2311
|
+
blend = 0,
|
|
2312
|
+
samples = 8,
|
|
2251
2313
|
eventPriority = 0,
|
|
2252
2314
|
renderPriority = 0,
|
|
2253
2315
|
worldUnits = false,
|
|
@@ -2260,7 +2322,7 @@ const MeshPortalMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
2260
2322
|
const maskRenderTarget = useFBO(resolution, resolution);
|
|
2261
2323
|
const [priority, setPriority] = React.useState(0);
|
|
2262
2324
|
useFrame(() => {
|
|
2263
|
-
const p = ref.current.blend > 0 ? Math.max(1, renderPriority) : 0;
|
|
2325
|
+
const p = (ref.current.blend ?? 0) > 0 ? Math.max(1, renderPriority) : 0;
|
|
2264
2326
|
if (priority !== p) setPriority(p);
|
|
2265
2327
|
});
|
|
2266
2328
|
React.useEffect(() => {
|
|
@@ -2334,7 +2396,8 @@ const MeshPortalMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
2334
2396
|
frames: visible ? Infinity : 0,
|
|
2335
2397
|
eventPriority,
|
|
2336
2398
|
renderPriority,
|
|
2337
|
-
compute
|
|
2399
|
+
compute,
|
|
2400
|
+
samples
|
|
2338
2401
|
},
|
|
2339
2402
|
children,
|
|
2340
2403
|
/* @__PURE__ */ React.createElement(
|
|
@@ -2414,7 +2477,7 @@ function ManagePortalScene({
|
|
|
2414
2477
|
scene.matrixWorld.copy(parent.matrixWorld);
|
|
2415
2478
|
} else scene.matrixWorld.identity();
|
|
2416
2479
|
if (priority) {
|
|
2417
|
-
if (material.current?.blend > 0 && material.current?.blend < 1) {
|
|
2480
|
+
if (material.current?.blend && material.current?.blend > 0 && material.current?.blend < 1) {
|
|
2418
2481
|
blend.value = material.current.blend;
|
|
2419
2482
|
state.gl.setRenderTarget(buffer1);
|
|
2420
2483
|
state.gl.render(scene, state.camera);
|
|
@@ -3045,7 +3108,7 @@ const isWebGL2Available = () => {
|
|
|
3045
3108
|
const Effects = /* @__PURE__ */ React.forwardRef(
|
|
3046
3109
|
({
|
|
3047
3110
|
children,
|
|
3048
|
-
|
|
3111
|
+
multisampling = 8,
|
|
3049
3112
|
renderIndex = 1,
|
|
3050
3113
|
disableRender,
|
|
3051
3114
|
disableGamma,
|
|
@@ -3072,7 +3135,7 @@ const Effects = /* @__PURE__ */ React.forwardRef(
|
|
|
3072
3135
|
if (type === UnsignedByteType && colorSpace != null) {
|
|
3073
3136
|
t.texture.colorSpace = colorSpace;
|
|
3074
3137
|
}
|
|
3075
|
-
t.samples =
|
|
3138
|
+
t.samples = multisampling;
|
|
3076
3139
|
return t;
|
|
3077
3140
|
});
|
|
3078
3141
|
React.useEffect(() => {
|
|
@@ -3207,12 +3270,12 @@ const Segments = /* @__PURE__ */ React.forwardRef((props, forwardedRef) => {
|
|
|
3207
3270
|
for (let i = 0; i < limit; i++) {
|
|
3208
3271
|
const segment = segments[i]?.current;
|
|
3209
3272
|
if (segment) {
|
|
3210
|
-
positions[i * 6 + 0] = segment.start
|
|
3211
|
-
positions[i * 6 + 1] = segment.start
|
|
3212
|
-
positions[i * 6 + 2] = segment.start
|
|
3213
|
-
positions[i * 6 + 3] = segment.end
|
|
3214
|
-
positions[i * 6 + 4] = segment.end
|
|
3215
|
-
positions[i * 6 + 5] = segment.end
|
|
3273
|
+
positions[i * 6 + 0] = segment.start?.x || 0;
|
|
3274
|
+
positions[i * 6 + 1] = segment.start?.y || 0;
|
|
3275
|
+
positions[i * 6 + 2] = segment.start?.z || 0;
|
|
3276
|
+
positions[i * 6 + 3] = segment.end?.x || 0;
|
|
3277
|
+
positions[i * 6 + 4] = segment.end?.y || 0;
|
|
3278
|
+
positions[i * 6 + 5] = segment.end?.z || 0;
|
|
3216
3279
|
colors[i * 6 + 0] = segment.color.r;
|
|
3217
3280
|
colors[i * 6 + 1] = segment.color.g;
|
|
3218
3281
|
colors[i * 6 + 2] = segment.color.b;
|
|
@@ -3247,7 +3310,10 @@ class SegmentObject {
|
|
|
3247
3310
|
this.end = new THREE.Vector3(0, 0, 0);
|
|
3248
3311
|
}
|
|
3249
3312
|
}
|
|
3250
|
-
const normPos = (pos) =>
|
|
3313
|
+
const normPos = (pos) => {
|
|
3314
|
+
if (!pos) return new THREE.Vector3(0, 0, 0);
|
|
3315
|
+
return pos instanceof THREE.Vector3 ? pos : new THREE.Vector3(...typeof pos === "number" ? [pos, pos, pos] : pos);
|
|
3316
|
+
};
|
|
3251
3317
|
const Segment = /* @__PURE__ */ React.forwardRef(({ color, start, end }, forwardedRef) => {
|
|
3252
3318
|
const api = React.useContext(context$9);
|
|
3253
3319
|
if (!api) throw "Segment must used inside Segments component.";
|
|
@@ -3569,6 +3635,81 @@ const ArcballControls = /* @__PURE__ */ forwardRef(
|
|
|
3569
3635
|
}
|
|
3570
3636
|
);
|
|
3571
3637
|
|
|
3638
|
+
let DeviceOrientationControls$1 = class DeviceOrientationControls extends EventDispatcher {
|
|
3639
|
+
object;
|
|
3640
|
+
changeEvent = { type: "change" };
|
|
3641
|
+
EPS = 1e-6;
|
|
3642
|
+
enabled = true;
|
|
3643
|
+
deviceOrientation = { alpha: 0, beta: 0, gamma: 0 };
|
|
3644
|
+
screenOrientation = 0;
|
|
3645
|
+
alphaOffset = 0;
|
|
3646
|
+
// radians
|
|
3647
|
+
constructor(object) {
|
|
3648
|
+
super();
|
|
3649
|
+
this.object = object;
|
|
3650
|
+
this.object.rotation.reorder("YXZ");
|
|
3651
|
+
this.connect();
|
|
3652
|
+
}
|
|
3653
|
+
onDeviceOrientationChangeEvent = (event) => {
|
|
3654
|
+
this.deviceOrientation = event;
|
|
3655
|
+
};
|
|
3656
|
+
onScreenOrientationChangeEvent = () => {
|
|
3657
|
+
this.screenOrientation = window.orientation || 0;
|
|
3658
|
+
};
|
|
3659
|
+
// The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''
|
|
3660
|
+
zee = new Vector3(0, 0, 1);
|
|
3661
|
+
euler = new Euler();
|
|
3662
|
+
q0 = new Quaternion();
|
|
3663
|
+
q1 = new Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));
|
|
3664
|
+
// - PI/2 around the x-axis
|
|
3665
|
+
setObjectQuaternion = (quaternion, alpha, beta, gamma, orient) => {
|
|
3666
|
+
this.euler.set(beta, alpha, -gamma, "YXZ");
|
|
3667
|
+
quaternion.setFromEuler(this.euler);
|
|
3668
|
+
quaternion.multiply(this.q1);
|
|
3669
|
+
quaternion.multiply(this.q0.setFromAxisAngle(this.zee, -orient));
|
|
3670
|
+
};
|
|
3671
|
+
connect = () => {
|
|
3672
|
+
this.onScreenOrientationChangeEvent();
|
|
3673
|
+
if (window.DeviceOrientationEvent !== void 0 && // @ts-ignore
|
|
3674
|
+
typeof window.DeviceOrientationEvent.requestPermission === "function") {
|
|
3675
|
+
window.DeviceOrientationEvent.requestPermission().then((response) => {
|
|
3676
|
+
if (response == "granted") {
|
|
3677
|
+
window.addEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
3678
|
+
window.addEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
3679
|
+
}
|
|
3680
|
+
}).catch((error) => {
|
|
3681
|
+
console.error("THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:", error);
|
|
3682
|
+
});
|
|
3683
|
+
} else {
|
|
3684
|
+
window.addEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
3685
|
+
window.addEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
3686
|
+
}
|
|
3687
|
+
this.enabled = true;
|
|
3688
|
+
};
|
|
3689
|
+
disconnect = () => {
|
|
3690
|
+
window.removeEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
3691
|
+
window.removeEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
3692
|
+
this.enabled = false;
|
|
3693
|
+
};
|
|
3694
|
+
lastQuaternion = new Quaternion();
|
|
3695
|
+
update = () => {
|
|
3696
|
+
if (this.enabled === false) return;
|
|
3697
|
+
const device = this.deviceOrientation;
|
|
3698
|
+
if (device) {
|
|
3699
|
+
const alpha = device.alpha ? MathUtils.degToRad(device.alpha) + this.alphaOffset : 0;
|
|
3700
|
+
const beta = device.beta ? MathUtils.degToRad(device.beta) : 0;
|
|
3701
|
+
const gamma = device.gamma ? MathUtils.degToRad(device.gamma) : 0;
|
|
3702
|
+
const orient = this.screenOrientation ? MathUtils.degToRad(this.screenOrientation) : 0;
|
|
3703
|
+
this.setObjectQuaternion(this.object.quaternion, alpha, beta, gamma, orient);
|
|
3704
|
+
if (8 * (1 - this.lastQuaternion.dot(this.object.quaternion)) > this.EPS) {
|
|
3705
|
+
this.lastQuaternion.copy(this.object.quaternion);
|
|
3706
|
+
this.dispatchEvent(this.changeEvent);
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
};
|
|
3710
|
+
dispose = () => this.disconnect();
|
|
3711
|
+
};
|
|
3712
|
+
|
|
3572
3713
|
const DeviceOrientationControls = /* @__PURE__ */ React.forwardRef(
|
|
3573
3714
|
(props, ref) => {
|
|
3574
3715
|
const { camera, onChange, makeDefault, ...rest } = props;
|
|
@@ -3604,11 +3745,11 @@ const DeviceOrientationControls = /* @__PURE__ */ React.forwardRef(
|
|
|
3604
3745
|
);
|
|
3605
3746
|
|
|
3606
3747
|
const initialModelPosition = /* @__PURE__ */ new THREE.Vector3();
|
|
3607
|
-
const mousePosition2D = /* @__PURE__ */ new THREE.Vector2();
|
|
3608
3748
|
const mousePosition3D = /* @__PURE__ */ new THREE.Vector3();
|
|
3609
3749
|
const dragOffset = /* @__PURE__ */ new THREE.Vector3();
|
|
3610
3750
|
const dragPlaneNormal = /* @__PURE__ */ new THREE.Vector3();
|
|
3611
3751
|
const dragPlane = /* @__PURE__ */ new THREE.Plane();
|
|
3752
|
+
const startPointerPos = /* @__PURE__ */ new THREE.Vector3();
|
|
3612
3753
|
const DragControls = React.forwardRef(
|
|
3613
3754
|
({
|
|
3614
3755
|
autoTransform = true,
|
|
@@ -3624,89 +3765,132 @@ const DragControls = React.forwardRef(
|
|
|
3624
3765
|
...props
|
|
3625
3766
|
}, fRef) => {
|
|
3626
3767
|
const defaultControls = useThree((state) => state.controls);
|
|
3627
|
-
const { camera,
|
|
3768
|
+
const { camera, invalidate } = useThree();
|
|
3628
3769
|
const ref = React.useRef(null);
|
|
3629
|
-
const
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
dragPlane.setFromNormalAndCoplanarPoint(dragPlaneNormal, mousePosition3D);
|
|
3663
|
-
raycaster.ray.intersectPlane(dragPlane, mousePosition3D);
|
|
3664
|
-
const previousLocalMatrix = ref.current.matrix.clone();
|
|
3665
|
-
const previousWorldMatrix = ref.current.matrixWorld.clone();
|
|
3666
|
-
const intendedNewPosition = new THREE.Vector3(
|
|
3667
|
-
mousePosition3D.x - dragOffset.x,
|
|
3668
|
-
mousePosition3D.y - dragOffset.y,
|
|
3669
|
-
mousePosition3D.z - dragOffset.z
|
|
3670
|
-
);
|
|
3671
|
-
if (dragLimits) {
|
|
3672
|
-
intendedNewPosition.x = dragLimits[0] ? Math.max(Math.min(intendedNewPosition.x, dragLimits[0][1]), dragLimits[0][0]) : intendedNewPosition.x;
|
|
3673
|
-
intendedNewPosition.y = dragLimits[1] ? Math.max(Math.min(intendedNewPosition.y, dragLimits[1][1]), dragLimits[1][0]) : intendedNewPosition.y;
|
|
3674
|
-
intendedNewPosition.z = dragLimits[2] ? Math.max(Math.min(intendedNewPosition.z, dragLimits[2][1]), dragLimits[2][0]) : intendedNewPosition.z;
|
|
3675
|
-
}
|
|
3676
|
-
if (autoTransform) {
|
|
3677
|
-
ref.current.matrix.setPosition(intendedNewPosition);
|
|
3678
|
-
const deltaLocalMatrix = ref.current.matrix.clone().multiply(previousLocalMatrix.invert());
|
|
3679
|
-
const deltaWorldMatrix = ref.current.matrix.clone().multiply(previousWorldMatrix.invert());
|
|
3680
|
-
onDrag && onDrag(ref.current.matrix, deltaLocalMatrix, ref.current.matrixWorld, deltaWorldMatrix);
|
|
3681
|
-
} else {
|
|
3682
|
-
const tempMatrix = new THREE.Matrix4().copy(ref.current.matrix);
|
|
3683
|
-
tempMatrix.setPosition(intendedNewPosition);
|
|
3684
|
-
const deltaLocalMatrix = tempMatrix.clone().multiply(previousLocalMatrix.invert());
|
|
3685
|
-
const deltaWorldMatrix = tempMatrix.clone().multiply(previousWorldMatrix.invert());
|
|
3686
|
-
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;
|
|
3687
3803
|
}
|
|
3688
|
-
invalidate();
|
|
3689
|
-
},
|
|
3690
|
-
onDragEnd: () => {
|
|
3691
|
-
if (defaultControls) defaultControls.enabled = true;
|
|
3692
|
-
onDragEnd && onDragEnd();
|
|
3693
|
-
invalidate();
|
|
3694
3804
|
}
|
|
3805
|
+
dragPlane.setFromNormalAndCoplanarPoint(dragPlaneNormal, mousePosition3D);
|
|
3806
|
+
if (dragState.current.intentional) {
|
|
3807
|
+
onDragStart && onDragStart(initialModelPosition);
|
|
3808
|
+
}
|
|
3809
|
+
invalidate();
|
|
3695
3810
|
},
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
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);
|
|
3701
3823
|
}
|
|
3702
|
-
|
|
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]
|
|
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]
|
|
3703
3867
|
);
|
|
3868
|
+
const handlePointerEnter = React.useCallback(() => {
|
|
3869
|
+
onHover && onHover(true);
|
|
3870
|
+
}, [onHover]);
|
|
3871
|
+
const handlePointerLeave = React.useCallback(() => {
|
|
3872
|
+
onHover && onHover(false);
|
|
3873
|
+
}, [onHover]);
|
|
3704
3874
|
React.useImperativeHandle(fRef, () => ref.current, []);
|
|
3705
3875
|
React.useLayoutEffect(() => {
|
|
3706
3876
|
if (!matrix) return;
|
|
3707
3877
|
ref.current.matrix = matrix;
|
|
3708
3878
|
}, [matrix]);
|
|
3709
|
-
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
|
+
);
|
|
3710
3894
|
}
|
|
3711
3895
|
);
|
|
3712
3896
|
|
|
@@ -3808,14 +3992,23 @@ function KeyboardControls({ map, children, onChange, domElement }) {
|
|
|
3808
3992
|
obj.pressed = false;
|
|
3809
3993
|
if (up) fn(false);
|
|
3810
3994
|
};
|
|
3995
|
+
const blurHandler = () => {
|
|
3996
|
+
const resetState = map.reduce((prev, cur) => ({ ...prev, [cur.name]: false }), {});
|
|
3997
|
+
set(resetState);
|
|
3998
|
+
Object.values(keyMap).forEach((obj) => {
|
|
3999
|
+
obj.pressed = false;
|
|
4000
|
+
});
|
|
4001
|
+
};
|
|
3811
4002
|
const source = domElement || window;
|
|
3812
4003
|
source.addEventListener("keydown", downHandler, { passive: true });
|
|
3813
4004
|
source.addEventListener("keyup", upHandler, { passive: true });
|
|
4005
|
+
window.addEventListener("blur", blurHandler);
|
|
3814
4006
|
return () => {
|
|
3815
4007
|
source.removeEventListener("keydown", downHandler);
|
|
3816
4008
|
source.removeEventListener("keyup", upHandler);
|
|
4009
|
+
window.removeEventListener("blur", blurHandler);
|
|
3817
4010
|
};
|
|
3818
|
-
}, [domElement, key]);
|
|
4011
|
+
}, [domElement, key, onChange]);
|
|
3819
4012
|
return /* @__PURE__ */ React.createElement(context$8.Provider, { value: api, children });
|
|
3820
4013
|
}
|
|
3821
4014
|
function useKeyboardControls(sel) {
|
|
@@ -3837,20 +4030,28 @@ const MapControls = /* @__PURE__ */ React.forwardRef((props = { enableDamping: t
|
|
|
3837
4030
|
const controls = React.useMemo(() => new MapControls$1(explCamera), [explCamera]);
|
|
3838
4031
|
React.useEffect(() => {
|
|
3839
4032
|
controls.connect(explDomElement);
|
|
4033
|
+
return () => void controls.dispose();
|
|
4034
|
+
}, [explDomElement, controls]);
|
|
4035
|
+
React.useEffect(() => {
|
|
3840
4036
|
const callback = (e) => {
|
|
3841
4037
|
invalidate();
|
|
3842
4038
|
if (onChange) onChange(e);
|
|
3843
4039
|
};
|
|
4040
|
+
const onStartCb = (e) => {
|
|
4041
|
+
if (onStart) onStart(e);
|
|
4042
|
+
};
|
|
4043
|
+
const onEndCb = (e) => {
|
|
4044
|
+
if (onEnd) onEnd(e);
|
|
4045
|
+
};
|
|
3844
4046
|
controls.addEventListener("change", callback);
|
|
3845
|
-
|
|
3846
|
-
|
|
4047
|
+
controls.addEventListener("start", onStartCb);
|
|
4048
|
+
controls.addEventListener("end", onEndCb);
|
|
3847
4049
|
return () => {
|
|
3848
|
-
controls.
|
|
4050
|
+
controls.removeEventListener("start", onStartCb);
|
|
4051
|
+
controls.removeEventListener("end", onEndCb);
|
|
3849
4052
|
controls.removeEventListener("change", callback);
|
|
3850
|
-
if (onStart) controls.removeEventListener("start", onStart);
|
|
3851
|
-
if (onEnd) controls.removeEventListener("end", onEnd);
|
|
3852
4053
|
};
|
|
3853
|
-
}, [onChange, onStart, onEnd, controls, invalidate
|
|
4054
|
+
}, [onChange, onStart, onEnd, controls, invalidate]);
|
|
3854
4055
|
React.useEffect(() => {
|
|
3855
4056
|
if (makeDefault) {
|
|
3856
4057
|
const old = get().controls;
|
|
@@ -3858,7 +4059,9 @@ const MapControls = /* @__PURE__ */ React.forwardRef((props = { enableDamping: t
|
|
|
3858
4059
|
return () => set({ controls: old });
|
|
3859
4060
|
}
|
|
3860
4061
|
}, [makeDefault, controls]);
|
|
3861
|
-
useFrame(() =>
|
|
4062
|
+
useFrame(() => {
|
|
4063
|
+
if (controls.enabled) controls.update();
|
|
4064
|
+
}, -1);
|
|
3862
4065
|
return /* @__PURE__ */ React.createElement("primitive", { ref, object: controls, enableDamping: true, ...rest });
|
|
3863
4066
|
});
|
|
3864
4067
|
|
|
@@ -3984,20 +4187,16 @@ const OrbitControls = /* @__PURE__ */ React.forwardRef(
|
|
|
3984
4187
|
onEnd,
|
|
3985
4188
|
...restProps
|
|
3986
4189
|
}, ref) => {
|
|
3987
|
-
const invalidate = useThree(
|
|
3988
|
-
const defaultCamera = useThree((state) => state.camera);
|
|
3989
|
-
const gl = useThree((state) => state.gl);
|
|
3990
|
-
const events = useThree((state) => state.events);
|
|
3991
|
-
const setEvents = useThree((state) => state.setEvents);
|
|
3992
|
-
const set = useThree((state) => state.set);
|
|
3993
|
-
const get = useThree((state) => state.get);
|
|
3994
|
-
const performance = useThree((state) => state.performance);
|
|
4190
|
+
const { invalidate, camera: defaultCamera, renderer, events, setEvents, set, get, performance } = useThree();
|
|
3995
4191
|
const explCamera = camera || defaultCamera;
|
|
3996
|
-
const explDomElement = domElement || events.connected ||
|
|
4192
|
+
const explDomElement = domElement || events.connected || renderer.domElement;
|
|
3997
4193
|
const controls = React.useMemo(() => new OrbitControls$1(explCamera), [explCamera]);
|
|
3998
|
-
useFrame(
|
|
3999
|
-
|
|
4000
|
-
|
|
4194
|
+
useFrame(
|
|
4195
|
+
() => {
|
|
4196
|
+
if (controls.enabled) controls.update();
|
|
4197
|
+
},
|
|
4198
|
+
{ before: "update" }
|
|
4199
|
+
);
|
|
4001
4200
|
React.useEffect(() => {
|
|
4002
4201
|
if (keyEvents) {
|
|
4003
4202
|
controls.connect(keyEvents === true ? explDomElement : keyEvents);
|
|
@@ -4111,9 +4310,8 @@ function PresentationControls({
|
|
|
4111
4310
|
azimuth = [-Infinity, Infinity],
|
|
4112
4311
|
damping = 0.25
|
|
4113
4312
|
}) {
|
|
4114
|
-
const events = useThree(
|
|
4115
|
-
const
|
|
4116
|
-
const explDomElement = domElement || events.connected || gl.domElement;
|
|
4313
|
+
const { events, renderer, invalidate } = useThree();
|
|
4314
|
+
const explDomElement = domElement || events.connected || renderer.domElement;
|
|
4117
4315
|
const { size } = useThree();
|
|
4118
4316
|
const rPolar = React.useMemo(
|
|
4119
4317
|
() => [rotation[0] + polar[0], rotation[0] + polar[1]],
|
|
@@ -4130,18 +4328,20 @@ function PresentationControls({
|
|
|
4130
4328
|
React.useEffect(() => {
|
|
4131
4329
|
if (global && cursor && enabled) {
|
|
4132
4330
|
explDomElement.style.cursor = "grab";
|
|
4133
|
-
|
|
4331
|
+
renderer.domElement.style.cursor = "";
|
|
4134
4332
|
return () => {
|
|
4135
4333
|
explDomElement.style.cursor = "default";
|
|
4136
|
-
|
|
4334
|
+
renderer.domElement.style.cursor = "default";
|
|
4137
4335
|
};
|
|
4138
4336
|
}
|
|
4139
4337
|
}, [global, cursor, explDomElement, enabled]);
|
|
4140
4338
|
const [animation] = React.useState({ scale: 1, rotation: rInitial, damping });
|
|
4141
4339
|
const ref = React.useRef(null);
|
|
4142
4340
|
useFrame((state, delta) => {
|
|
4143
|
-
|
|
4144
|
-
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();
|
|
4145
4345
|
});
|
|
4146
4346
|
const bind = useGesture(
|
|
4147
4347
|
{
|
|
@@ -4149,6 +4349,7 @@ function PresentationControls({
|
|
|
4149
4349
|
if (cursor && !global && enabled) explDomElement.style.cursor = last ? "auto" : "grab";
|
|
4150
4350
|
},
|
|
4151
4351
|
onDrag: ({ down, delta: [x, y], memo: [oldY, oldX] = animation.rotation || rInitial }) => {
|
|
4352
|
+
invalidate();
|
|
4152
4353
|
if (!enabled) return [y, x];
|
|
4153
4354
|
if (cursor) explDomElement.style.cursor = down ? "grabbing" : "grab";
|
|
4154
4355
|
x = MathUtils.clamp(oldX + x / size.width * Math.PI * speed, ...rAzimuth);
|
|
@@ -4157,14 +4358,27 @@ function PresentationControls({
|
|
|
4157
4358
|
animation.rotation = snap && !down ? rInitial : [y, x, 0];
|
|
4158
4359
|
animation.damping = snap && !down && typeof snap !== "boolean" ? snap : damping;
|
|
4159
4360
|
return [y, x];
|
|
4361
|
+
},
|
|
4362
|
+
onDragEnd: () => {
|
|
4363
|
+
invalidate();
|
|
4160
4364
|
}
|
|
4161
4365
|
},
|
|
4162
|
-
{ target: global ? explDomElement : void 0 }
|
|
4366
|
+
{ target: global ? explDomElement : void 0, enabled }
|
|
4163
4367
|
);
|
|
4164
4368
|
return /* @__PURE__ */ React.createElement("group", { ref, ...bind?.() }, children);
|
|
4165
4369
|
}
|
|
4166
4370
|
|
|
4371
|
+
function roundToPixelRatio(value) {
|
|
4372
|
+
const ratio = window.devicePixelRatio || 1;
|
|
4373
|
+
return Math.round(value * ratio) / ratio;
|
|
4374
|
+
}
|
|
4375
|
+
function getMaxAnisotropy(renderer) {
|
|
4376
|
+
const r = renderer;
|
|
4377
|
+
return r?.getMaxAnisotropy?.() ?? r?.capabilities?.getMaxAnisotropy?.() ?? 1;
|
|
4378
|
+
}
|
|
4379
|
+
|
|
4167
4380
|
const context$7 = /* @__PURE__ */ React.createContext(null);
|
|
4381
|
+
const rootCache = /* @__PURE__ */ new WeakMap();
|
|
4168
4382
|
function useScroll() {
|
|
4169
4383
|
return React.useContext(context$7);
|
|
4170
4384
|
}
|
|
@@ -4178,6 +4392,7 @@ function ScrollControls({
|
|
|
4178
4392
|
damping = 0.25,
|
|
4179
4393
|
maxSpeed = Infinity,
|
|
4180
4394
|
prepend = false,
|
|
4395
|
+
pixelPerfect = true,
|
|
4181
4396
|
style = {},
|
|
4182
4397
|
children
|
|
4183
4398
|
}) {
|
|
@@ -4187,6 +4402,7 @@ function ScrollControls({
|
|
|
4187
4402
|
const [fixed] = React.useState(() => document.createElement("div"));
|
|
4188
4403
|
const target = gl.domElement.parentNode;
|
|
4189
4404
|
const scroll = React.useRef(0);
|
|
4405
|
+
const disableScrollUpdate = React.useRef(false);
|
|
4190
4406
|
const state = React.useMemo(() => {
|
|
4191
4407
|
const state2 = {
|
|
4192
4408
|
el,
|
|
@@ -4199,6 +4415,7 @@ function ScrollControls({
|
|
|
4199
4415
|
delta: 0,
|
|
4200
4416
|
scroll,
|
|
4201
4417
|
pages,
|
|
4418
|
+
pixelPerfect,
|
|
4202
4419
|
// 0-1 for a range between from -> from + distance
|
|
4203
4420
|
range(from, distance2, margin = 0) {
|
|
4204
4421
|
const start = from - margin;
|
|
@@ -4217,7 +4434,7 @@ function ScrollControls({
|
|
|
4217
4434
|
}
|
|
4218
4435
|
};
|
|
4219
4436
|
return state2;
|
|
4220
|
-
}, [eps, damping, horizontal, pages]);
|
|
4437
|
+
}, [eps, damping, horizontal, pages, pixelPerfect]);
|
|
4221
4438
|
React.useEffect(() => {
|
|
4222
4439
|
el.style.position = "absolute";
|
|
4223
4440
|
el.style.width = "100%";
|
|
@@ -4267,16 +4484,20 @@ function ScrollControls({
|
|
|
4267
4484
|
const scrollLength = el[horizontal ? "scrollWidth" : "scrollHeight"];
|
|
4268
4485
|
const scrollThreshold = scrollLength - containerLength;
|
|
4269
4486
|
let current = 0;
|
|
4270
|
-
let disableScroll =
|
|
4487
|
+
let disableScroll = false;
|
|
4271
4488
|
let firstRun = true;
|
|
4272
4489
|
const onScroll = () => {
|
|
4273
4490
|
if (!enabled || firstRun) return;
|
|
4491
|
+
if (disableScrollUpdate.current) {
|
|
4492
|
+
disableScrollUpdate.current = false;
|
|
4493
|
+
return;
|
|
4494
|
+
}
|
|
4274
4495
|
invalidate();
|
|
4275
4496
|
current = el[horizontal ? "scrollLeft" : "scrollTop"];
|
|
4276
4497
|
scroll.current = current / scrollThreshold;
|
|
4277
4498
|
if (infinite) {
|
|
4278
4499
|
if (!disableScroll) {
|
|
4279
|
-
if (current >= scrollThreshold) {
|
|
4500
|
+
if (current >= scrollThreshold - 1) {
|
|
4280
4501
|
const damp = 1 - state.offset;
|
|
4281
4502
|
el[horizontal ? "scrollLeft" : "scrollTop"] = 1;
|
|
4282
4503
|
scroll.current = state.offset = -damp;
|
|
@@ -4293,11 +4514,34 @@ function ScrollControls({
|
|
|
4293
4514
|
};
|
|
4294
4515
|
el.addEventListener("scroll", onScroll, { passive: true });
|
|
4295
4516
|
requestAnimationFrame(() => firstRun = false);
|
|
4296
|
-
const
|
|
4297
|
-
|
|
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);
|
|
4298
4541
|
return () => {
|
|
4299
4542
|
el.removeEventListener("scroll", onScroll);
|
|
4300
|
-
if (horizontal) el.removeEventListener("wheel", onWheel);
|
|
4543
|
+
if (horizontal || infinite) el.removeEventListener("wheel", onWheel);
|
|
4544
|
+
if (horizontal) window.removeEventListener("resize", onResize);
|
|
4301
4545
|
};
|
|
4302
4546
|
}
|
|
4303
4547
|
}, [el, events, size, infinite, state, invalidate, horizontal, enabled]);
|
|
@@ -4330,10 +4574,23 @@ const ScrollHtml = React.forwardRef(
|
|
|
4330
4574
|
React.useImperativeHandle(ref, () => group.current, []);
|
|
4331
4575
|
const { width, height } = useThree((state2) => state2.size);
|
|
4332
4576
|
const fiberState = React.useContext(context$a);
|
|
4333
|
-
const root = React.useMemo(() =>
|
|
4577
|
+
const root = React.useMemo(() => {
|
|
4578
|
+
let root2 = rootCache.get(state.fixed);
|
|
4579
|
+
if (!root2) {
|
|
4580
|
+
root2 = ReactDOM.createRoot(state.fixed);
|
|
4581
|
+
rootCache.set(state.fixed, root2);
|
|
4582
|
+
}
|
|
4583
|
+
return root2;
|
|
4584
|
+
}, [state.fixed]);
|
|
4334
4585
|
useFrame(() => {
|
|
4335
4586
|
if (state.delta > state.eps) {
|
|
4336
|
-
|
|
4587
|
+
let x = state.horizontal ? -width * (state.pages - 1) * state.offset : 0;
|
|
4588
|
+
let y = state.horizontal ? 0 : height * (state.pages - 1) * -state.offset;
|
|
4589
|
+
if (state.pixelPerfect) {
|
|
4590
|
+
x = roundToPixelRatio(x);
|
|
4591
|
+
y = roundToPixelRatio(y);
|
|
4592
|
+
}
|
|
4593
|
+
group.current.style.transform = `translate3d(${x}px,${y}px,0)`;
|
|
4337
4594
|
}
|
|
4338
4595
|
});
|
|
4339
4596
|
root.render(
|
|
@@ -4701,10 +4958,10 @@ const CloudInstance = /* @__PURE__ */ React.forwardRef(
|
|
|
4701
4958
|
return /* @__PURE__ */ React.createElement("group", { ref, ...props });
|
|
4702
4959
|
}
|
|
4703
4960
|
);
|
|
4704
|
-
const Cloud = /* @__PURE__ */ React.forwardRef((props, fref) => {
|
|
4961
|
+
const Cloud = /* @__PURE__ */ React.forwardRef(({ materialFactory, ...props }, fref) => {
|
|
4705
4962
|
const parent = React.useContext(context$6);
|
|
4706
4963
|
if (parent) return /* @__PURE__ */ React.createElement(CloudInstance, { ref: fref, ...props });
|
|
4707
|
-
return /* @__PURE__ */ React.createElement(Clouds,
|
|
4964
|
+
return /* @__PURE__ */ React.createElement(Clouds, { materialFactory }, /* @__PURE__ */ React.createElement(CloudInstance, { ref: fref, ...props }));
|
|
4708
4965
|
});
|
|
4709
4966
|
|
|
4710
4967
|
const CatmullRomLine = /* @__PURE__ */ React.forwardRef(function CatmullRomLine2({
|
|
@@ -5226,7 +5483,7 @@ const Text3D = /* @__PURE__ */ React.forwardRef(
|
|
|
5226
5483
|
return {
|
|
5227
5484
|
font,
|
|
5228
5485
|
size,
|
|
5229
|
-
height,
|
|
5486
|
+
depth: height,
|
|
5230
5487
|
bevelThickness,
|
|
5231
5488
|
bevelSize,
|
|
5232
5489
|
bevelEnabled,
|
|
@@ -5262,380 +5519,9 @@ const Text3D = /* @__PURE__ */ React.forwardRef(
|
|
|
5262
5519
|
}
|
|
5263
5520
|
);
|
|
5264
5521
|
|
|
5265
|
-
const
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
fillOpacity: 0.25,
|
|
5269
|
-
fillMix: 0,
|
|
5270
|
-
thickness: 0.05,
|
|
5271
|
-
colorBackfaces: false,
|
|
5272
|
-
dashInvert: true,
|
|
5273
|
-
dash: false,
|
|
5274
|
-
dashRepeats: 4,
|
|
5275
|
-
dashLength: 0.5,
|
|
5276
|
-
squeeze: false,
|
|
5277
|
-
squeezeMin: 0.2,
|
|
5278
|
-
squeezeMax: 1,
|
|
5279
|
-
stroke: /* @__PURE__ */ new THREE.Color("#ff0000"),
|
|
5280
|
-
backfaceStroke: /* @__PURE__ */ new THREE.Color("#0000ff"),
|
|
5281
|
-
fill: /* @__PURE__ */ new THREE.Color("#00ff00")
|
|
5282
|
-
},
|
|
5283
|
-
vertex: (
|
|
5284
|
-
/* glsl */
|
|
5285
|
-
`
|
|
5286
|
-
attribute vec3 barycentric;
|
|
5287
|
-
|
|
5288
|
-
varying vec3 v_edges_Barycentric;
|
|
5289
|
-
varying vec3 v_edges_Position;
|
|
5290
|
-
|
|
5291
|
-
void initWireframe() {
|
|
5292
|
-
v_edges_Barycentric = barycentric;
|
|
5293
|
-
v_edges_Position = position.xyz;
|
|
5294
|
-
}
|
|
5295
|
-
`
|
|
5296
|
-
),
|
|
5297
|
-
fragment: (
|
|
5298
|
-
/* glsl */
|
|
5299
|
-
`
|
|
5300
|
-
#ifndef PI
|
|
5301
|
-
#define PI 3.1415926535897932384626433832795
|
|
5302
|
-
#endif
|
|
5303
|
-
|
|
5304
|
-
varying vec3 v_edges_Barycentric;
|
|
5305
|
-
varying vec3 v_edges_Position;
|
|
5306
|
-
|
|
5307
|
-
uniform float strokeOpacity;
|
|
5308
|
-
uniform float fillOpacity;
|
|
5309
|
-
uniform float fillMix;
|
|
5310
|
-
uniform float thickness;
|
|
5311
|
-
uniform bool colorBackfaces;
|
|
5312
|
-
|
|
5313
|
-
// Dash
|
|
5314
|
-
uniform bool dashInvert;
|
|
5315
|
-
uniform bool dash;
|
|
5316
|
-
uniform bool dashOnly;
|
|
5317
|
-
uniform float dashRepeats;
|
|
5318
|
-
uniform float dashLength;
|
|
5319
|
-
|
|
5320
|
-
// Squeeze
|
|
5321
|
-
uniform bool squeeze;
|
|
5322
|
-
uniform float squeezeMin;
|
|
5323
|
-
uniform float squeezeMax;
|
|
5324
|
-
|
|
5325
|
-
// Colors
|
|
5326
|
-
uniform vec3 stroke;
|
|
5327
|
-
uniform vec3 backfaceStroke;
|
|
5328
|
-
uniform vec3 fill;
|
|
5329
|
-
|
|
5330
|
-
// This is like
|
|
5331
|
-
float wireframe_aastep(float threshold, float dist) {
|
|
5332
|
-
float afwidth = fwidth(dist) * 0.5;
|
|
5333
|
-
return smoothstep(threshold - afwidth, threshold + afwidth, dist);
|
|
5334
|
-
}
|
|
5335
|
-
|
|
5336
|
-
float wireframe_map(float value, float min1, float max1, float min2, float max2) {
|
|
5337
|
-
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
|
|
5338
|
-
}
|
|
5339
|
-
|
|
5340
|
-
float getWireframe() {
|
|
5341
|
-
vec3 barycentric = v_edges_Barycentric;
|
|
5342
|
-
|
|
5343
|
-
// Distance from center of each triangle to its edges.
|
|
5344
|
-
float d = min(min(barycentric.x, barycentric.y), barycentric.z);
|
|
5345
|
-
|
|
5346
|
-
// for dashed rendering, we can use this to get the 0 .. 1 value of the line length
|
|
5347
|
-
float positionAlong = max(barycentric.x, barycentric.y);
|
|
5348
|
-
if (barycentric.y < barycentric.x && barycentric.y < barycentric.z) {
|
|
5349
|
-
positionAlong = 1.0 - positionAlong;
|
|
5350
|
-
}
|
|
5351
|
-
|
|
5352
|
-
// the thickness of the stroke
|
|
5353
|
-
float computedThickness = wireframe_map(thickness, 0.0, 1.0, 0.0, 0.34);
|
|
5354
|
-
|
|
5355
|
-
// if we want to shrink the thickness toward the center of the line segment
|
|
5356
|
-
if (squeeze) {
|
|
5357
|
-
computedThickness *= mix(squeezeMin, squeezeMax, (1.0 - sin(positionAlong * PI)));
|
|
5358
|
-
}
|
|
5359
|
-
|
|
5360
|
-
// Create dash pattern
|
|
5361
|
-
if (dash) {
|
|
5362
|
-
// here we offset the stroke position depending on whether it
|
|
5363
|
-
// should overlap or not
|
|
5364
|
-
float offset = 1.0 / dashRepeats * dashLength / 2.0;
|
|
5365
|
-
if (!dashInvert) {
|
|
5366
|
-
offset += 1.0 / dashRepeats / 2.0;
|
|
5367
|
-
}
|
|
5368
|
-
|
|
5369
|
-
// if we should animate the dash or not
|
|
5370
|
-
// if (dashAnimate) {
|
|
5371
|
-
// offset += time * 0.22;
|
|
5372
|
-
// }
|
|
5373
|
-
|
|
5374
|
-
// create the repeating dash pattern
|
|
5375
|
-
float pattern = fract((positionAlong + offset) * dashRepeats);
|
|
5376
|
-
computedThickness *= 1.0 - wireframe_aastep(dashLength, pattern);
|
|
5377
|
-
}
|
|
5378
|
-
|
|
5379
|
-
// compute the anti-aliased stroke edge
|
|
5380
|
-
float edge = 1.0 - wireframe_aastep(computedThickness, d);
|
|
5381
|
-
|
|
5382
|
-
return edge;
|
|
5383
|
-
}
|
|
5384
|
-
`
|
|
5385
|
-
)
|
|
5386
|
-
};
|
|
5387
|
-
const WireframeMaterial = /* @__PURE__ */ shaderMaterial(
|
|
5388
|
-
WireframeMaterialShaders.uniforms,
|
|
5389
|
-
WireframeMaterialShaders.vertex + /* glsl */
|
|
5390
|
-
`
|
|
5391
|
-
void main() {
|
|
5392
|
-
initWireframe();
|
|
5393
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
5394
|
-
}
|
|
5395
|
-
`,
|
|
5396
|
-
WireframeMaterialShaders.fragment + /* glsl */
|
|
5397
|
-
`
|
|
5398
|
-
void main () {
|
|
5399
|
-
// Compute color
|
|
5400
|
-
|
|
5401
|
-
float edge = getWireframe();
|
|
5402
|
-
vec4 colorStroke = vec4(stroke, edge);
|
|
5403
|
-
|
|
5404
|
-
#ifdef FLIP_SIDED
|
|
5405
|
-
colorStroke.rgb = backfaceStroke;
|
|
5406
|
-
#endif
|
|
5407
|
-
|
|
5408
|
-
vec4 colorFill = vec4(fill, fillOpacity);
|
|
5409
|
-
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
5410
|
-
|
|
5411
|
-
gl_FragColor = outColor;
|
|
5412
|
-
}
|
|
5413
|
-
`
|
|
5414
|
-
);
|
|
5415
|
-
function setWireframeOverride(material, uniforms) {
|
|
5416
|
-
material.onBeforeCompile = (shader) => {
|
|
5417
|
-
shader.uniforms = {
|
|
5418
|
-
...shader.uniforms,
|
|
5419
|
-
...uniforms
|
|
5420
|
-
};
|
|
5421
|
-
shader.vertexShader = shader.vertexShader.replace(
|
|
5422
|
-
"void main() {",
|
|
5423
|
-
`
|
|
5424
|
-
${WireframeMaterialShaders.vertex}
|
|
5425
|
-
void main() {
|
|
5426
|
-
initWireframe();
|
|
5427
|
-
`
|
|
5428
|
-
);
|
|
5429
|
-
shader.fragmentShader = shader.fragmentShader.replace(
|
|
5430
|
-
"void main() {",
|
|
5431
|
-
`
|
|
5432
|
-
${WireframeMaterialShaders.fragment}
|
|
5433
|
-
void main() {
|
|
5434
|
-
`
|
|
5435
|
-
);
|
|
5436
|
-
shader.fragmentShader = shader.fragmentShader.replace(
|
|
5437
|
-
"#include <color_fragment>",
|
|
5438
|
-
/* glsl */
|
|
5439
|
-
`
|
|
5440
|
-
#include <color_fragment>
|
|
5441
|
-
float edge = getWireframe();
|
|
5442
|
-
vec4 colorStroke = vec4(stroke, edge);
|
|
5443
|
-
#ifdef FLIP_SIDED
|
|
5444
|
-
colorStroke.rgb = backfaceStroke;
|
|
5445
|
-
#endif
|
|
5446
|
-
vec4 colorFill = vec4(mix(diffuseColor.rgb, fill, fillMix), mix(diffuseColor.a, fillOpacity, fillMix));
|
|
5447
|
-
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
5448
|
-
|
|
5449
|
-
diffuseColor.rgb = outColor.rgb;
|
|
5450
|
-
diffuseColor.a *= outColor.a;
|
|
5451
|
-
`
|
|
5452
|
-
);
|
|
5453
|
-
};
|
|
5454
|
-
material.side = THREE.DoubleSide;
|
|
5455
|
-
material.transparent = true;
|
|
5456
|
-
}
|
|
5457
|
-
function useWireframeUniforms(uniforms, props) {
|
|
5458
|
-
React.useEffect(
|
|
5459
|
-
() => void (uniforms.fillOpacity.value = props.fillOpacity ?? uniforms.fillOpacity.value),
|
|
5460
|
-
[props.fillOpacity]
|
|
5461
|
-
);
|
|
5462
|
-
React.useEffect(() => void (uniforms.fillMix.value = props.fillMix ?? uniforms.fillMix.value), [props.fillMix]);
|
|
5463
|
-
React.useEffect(
|
|
5464
|
-
() => void (uniforms.strokeOpacity.value = props.strokeOpacity ?? uniforms.strokeOpacity.value),
|
|
5465
|
-
[props.strokeOpacity]
|
|
5466
|
-
);
|
|
5467
|
-
React.useEffect(
|
|
5468
|
-
() => void (uniforms.thickness.value = props.thickness ?? uniforms.thickness.value),
|
|
5469
|
-
[props.thickness]
|
|
5470
|
-
);
|
|
5471
|
-
React.useEffect(() => void (uniforms.colorBackfaces.value = !!props.colorBackfaces), [props.colorBackfaces]);
|
|
5472
|
-
React.useEffect(() => void (uniforms.dash.value = !!props.dash), [props.dash]);
|
|
5473
|
-
React.useEffect(() => void (uniforms.dashInvert.value = !!props.dashInvert), [props.dashInvert]);
|
|
5474
|
-
React.useEffect(
|
|
5475
|
-
() => void (uniforms.dashRepeats.value = props.dashRepeats ?? uniforms.dashRepeats.value),
|
|
5476
|
-
[props.dashRepeats]
|
|
5477
|
-
);
|
|
5478
|
-
React.useEffect(
|
|
5479
|
-
() => void (uniforms.dashLength.value = props.dashLength ?? uniforms.dashLength.value),
|
|
5480
|
-
[props.dashLength]
|
|
5481
|
-
);
|
|
5482
|
-
React.useEffect(() => void (uniforms.squeeze.value = !!props.squeeze), [props.squeeze]);
|
|
5483
|
-
React.useEffect(
|
|
5484
|
-
() => void (uniforms.squeezeMin.value = props.squeezeMin ?? uniforms.squeezeMin.value),
|
|
5485
|
-
[props.squeezeMin]
|
|
5486
|
-
);
|
|
5487
|
-
React.useEffect(
|
|
5488
|
-
() => void (uniforms.squeezeMax.value = props.squeezeMax ?? uniforms.squeezeMax.value),
|
|
5489
|
-
[props.squeezeMax]
|
|
5490
|
-
);
|
|
5491
|
-
React.useEffect(
|
|
5492
|
-
() => void (uniforms.stroke.value = props.stroke ? new THREE.Color(props.stroke) : uniforms.stroke.value),
|
|
5493
|
-
[props.stroke]
|
|
5494
|
-
);
|
|
5495
|
-
React.useEffect(
|
|
5496
|
-
() => void (uniforms.fill.value = props.fill ? new THREE.Color(props.fill) : uniforms.fill.value),
|
|
5497
|
-
[props.fill]
|
|
5498
|
-
);
|
|
5499
|
-
React.useEffect(
|
|
5500
|
-
() => void (uniforms.backfaceStroke.value = props.backfaceStroke ? new THREE.Color(props.backfaceStroke) : uniforms.backfaceStroke.value),
|
|
5501
|
-
[props.backfaceStroke]
|
|
5502
|
-
);
|
|
5503
|
-
}
|
|
5504
|
-
|
|
5505
|
-
function isWithGeometry(object) {
|
|
5506
|
-
return !!object?.geometry;
|
|
5507
|
-
}
|
|
5508
|
-
function isGeometry(object) {
|
|
5509
|
-
return !!object?.isBufferGeometry;
|
|
5510
|
-
}
|
|
5511
|
-
function isRefObject$1(object) {
|
|
5512
|
-
return !!object?.current;
|
|
5513
|
-
}
|
|
5514
|
-
function isRef$1(object) {
|
|
5515
|
-
return object?.current !== void 0;
|
|
5516
|
-
}
|
|
5517
|
-
function isWireframeGeometry(geometry) {
|
|
5518
|
-
return geometry.type === "WireframeGeometry";
|
|
5519
|
-
}
|
|
5520
|
-
function getUniforms() {
|
|
5521
|
-
const u = {};
|
|
5522
|
-
for (const key in WireframeMaterialShaders.uniforms) {
|
|
5523
|
-
u[key] = { value: WireframeMaterialShaders.uniforms[key] };
|
|
5524
|
-
}
|
|
5525
|
-
return u;
|
|
5526
|
-
}
|
|
5527
|
-
function getBarycentricCoordinates(geometry, removeEdge) {
|
|
5528
|
-
const position = geometry.getAttribute("position");
|
|
5529
|
-
const count = position.count;
|
|
5530
|
-
const barycentric = [];
|
|
5531
|
-
for (let i = 0; i < count; i++) {
|
|
5532
|
-
const even = i % 2 === 0;
|
|
5533
|
-
const Q = removeEdge ? 1 : 0;
|
|
5534
|
-
if (even) {
|
|
5535
|
-
barycentric.push(0, 0, 1, 0, 1, 0, 1, 0, Q);
|
|
5536
|
-
} else {
|
|
5537
|
-
barycentric.push(0, 1, 0, 0, 0, 1, 1, 0, Q);
|
|
5538
|
-
}
|
|
5539
|
-
}
|
|
5540
|
-
return new THREE.BufferAttribute(Float32Array.from(barycentric), 3);
|
|
5541
|
-
}
|
|
5542
|
-
function getInputGeometry(inputGeometry) {
|
|
5543
|
-
const geo = isRefObject$1(inputGeometry) ? inputGeometry.current : inputGeometry;
|
|
5544
|
-
if (!isGeometry(geo)) {
|
|
5545
|
-
if (isWireframeGeometry(geo)) {
|
|
5546
|
-
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
5547
|
-
}
|
|
5548
|
-
const parent = geo.parent;
|
|
5549
|
-
if (isWithGeometry(parent)) {
|
|
5550
|
-
if (isWireframeGeometry(parent.geometry)) {
|
|
5551
|
-
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
5552
|
-
}
|
|
5553
|
-
return parent.geometry;
|
|
5554
|
-
}
|
|
5555
|
-
} else {
|
|
5556
|
-
return geo;
|
|
5557
|
-
}
|
|
5558
|
-
}
|
|
5559
|
-
function setBarycentricCoordinates(geometry, simplify) {
|
|
5560
|
-
if (geometry.index) {
|
|
5561
|
-
console.warn("Wireframe: Requires non-indexed geometry, converting to non-indexed geometry.");
|
|
5562
|
-
const nonIndexedGeo = geometry.toNonIndexed();
|
|
5563
|
-
geometry.copy(nonIndexedGeo);
|
|
5564
|
-
geometry.setIndex(null);
|
|
5565
|
-
}
|
|
5566
|
-
const newBarycentric = getBarycentricCoordinates(geometry, simplify);
|
|
5567
|
-
geometry.setAttribute("barycentric", newBarycentric);
|
|
5568
|
-
}
|
|
5569
|
-
function WireframeWithCustomGeo({
|
|
5570
|
-
geometry: customGeometry,
|
|
5571
|
-
simplify = false,
|
|
5572
|
-
...props
|
|
5573
|
-
}) {
|
|
5574
|
-
extend({ MeshWireframeMaterial: WireframeMaterial });
|
|
5575
|
-
const [geometry, setGeometry] = React.useState(null);
|
|
5576
|
-
React.useLayoutEffect(() => {
|
|
5577
|
-
const geom = getInputGeometry(customGeometry);
|
|
5578
|
-
if (!geom) {
|
|
5579
|
-
throw new Error("Wireframe: geometry prop must be a BufferGeometry or a ref to a BufferGeometry.");
|
|
5580
|
-
}
|
|
5581
|
-
setBarycentricCoordinates(geom, simplify);
|
|
5582
|
-
if (isRef$1(customGeometry)) {
|
|
5583
|
-
setGeometry(geom);
|
|
5584
|
-
}
|
|
5585
|
-
}, [simplify, customGeometry]);
|
|
5586
|
-
const drawnGeo = isRef$1(customGeometry) ? geometry : customGeometry;
|
|
5587
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, drawnGeo && /* @__PURE__ */ React.createElement("mesh", { geometry: drawnGeo }, /* @__PURE__ */ React.createElement(
|
|
5588
|
-
"meshWireframeMaterial",
|
|
5589
|
-
{
|
|
5590
|
-
attach: "material",
|
|
5591
|
-
transparent: true,
|
|
5592
|
-
side: THREE.DoubleSide,
|
|
5593
|
-
polygonOffset: true,
|
|
5594
|
-
polygonOffsetFactor: -4,
|
|
5595
|
-
...props
|
|
5596
|
-
}
|
|
5597
|
-
)));
|
|
5598
|
-
}
|
|
5599
|
-
function WireframeWithoutCustomGeo({
|
|
5600
|
-
simplify = false,
|
|
5601
|
-
...props
|
|
5602
|
-
}) {
|
|
5603
|
-
const objectRef = React.useRef(null);
|
|
5604
|
-
const uniforms = React.useMemo(() => getUniforms(), [WireframeMaterialShaders.uniforms]);
|
|
5605
|
-
useWireframeUniforms(uniforms, props);
|
|
5606
|
-
React.useLayoutEffect(() => {
|
|
5607
|
-
const geom = getInputGeometry(objectRef);
|
|
5608
|
-
if (!geom) {
|
|
5609
|
-
throw new Error("Wireframe: Must be a child of a Mesh, Line or Points object or specify a geometry prop.");
|
|
5610
|
-
}
|
|
5611
|
-
const og = geom.clone();
|
|
5612
|
-
setBarycentricCoordinates(geom, simplify);
|
|
5613
|
-
return () => {
|
|
5614
|
-
geom.copy(og);
|
|
5615
|
-
og.dispose();
|
|
5616
|
-
};
|
|
5617
|
-
}, [simplify]);
|
|
5618
|
-
React.useLayoutEffect(() => {
|
|
5619
|
-
const parentMesh = objectRef.current.parent;
|
|
5620
|
-
const og = parentMesh.material.clone();
|
|
5621
|
-
setWireframeOverride(parentMesh.material, uniforms);
|
|
5622
|
-
return () => {
|
|
5623
|
-
parentMesh.material.dispose();
|
|
5624
|
-
parentMesh.material = og;
|
|
5625
|
-
};
|
|
5626
|
-
}, []);
|
|
5627
|
-
return /* @__PURE__ */ React.createElement("object3D", { ref: objectRef });
|
|
5628
|
-
}
|
|
5629
|
-
function Wireframe({ geometry: customGeometry, ...props }) {
|
|
5630
|
-
if (customGeometry) {
|
|
5631
|
-
return /* @__PURE__ */ React.createElement(WireframeWithCustomGeo, { geometry: customGeometry, ...props });
|
|
5632
|
-
}
|
|
5633
|
-
return /* @__PURE__ */ React.createElement(WireframeWithoutCustomGeo, { ...props });
|
|
5634
|
-
}
|
|
5635
|
-
|
|
5636
|
-
const Context = /* @__PURE__ */ React.createContext({});
|
|
5637
|
-
const useGizmoContext = () => {
|
|
5638
|
-
return React.useContext(Context);
|
|
5522
|
+
const Context = /* @__PURE__ */ React.createContext({});
|
|
5523
|
+
const useGizmoContext = () => {
|
|
5524
|
+
return React.useContext(Context);
|
|
5639
5525
|
};
|
|
5640
5526
|
const turnRate = 2 * Math.PI;
|
|
5641
5527
|
const dummy = /* @__PURE__ */ new Object3D();
|
|
@@ -5780,7 +5666,7 @@ const FaceMaterial = ({
|
|
|
5780
5666
|
"meshBasicMaterial",
|
|
5781
5667
|
{
|
|
5782
5668
|
map: texture,
|
|
5783
|
-
"map-anisotropy":
|
|
5669
|
+
"map-anisotropy": getMaxAnisotropy(renderer),
|
|
5784
5670
|
attach: `material-${index}`,
|
|
5785
5671
|
color: hover ? hoverColor : "white",
|
|
5786
5672
|
transparent: true,
|
|
@@ -5891,7 +5777,7 @@ function AxisHead({
|
|
|
5891
5777
|
"spriteMaterial",
|
|
5892
5778
|
{
|
|
5893
5779
|
map: texture,
|
|
5894
|
-
"map-anisotropy":
|
|
5780
|
+
"map-anisotropy": getMaxAnisotropy(renderer),
|
|
5895
5781
|
alphaTest: 0.3,
|
|
5896
5782
|
opacity: label ? 1 : 0.75,
|
|
5897
5783
|
toneMapped: false
|
|
@@ -5928,6 +5814,11 @@ const GizmoViewport = ({
|
|
|
5928
5814
|
return /* @__PURE__ */ React.createElement("group", { scale: 40, ...props }, /* @__PURE__ */ React.createElement(Axis, { color: colorX, rotation: [0, 0, 0], scale: axisScale }), /* @__PURE__ */ React.createElement(Axis, { color: colorY, rotation: [0, 0, Math.PI / 2], scale: axisScale }), /* @__PURE__ */ React.createElement(Axis, { color: colorZ, rotation: [0, -Math.PI / 2, 0], scale: axisScale }), !hideAxisHeads && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(AxisHead, { arcStyle: colorX, position: [1, 0, 0], label: labels[0], ...axisHeadProps }), /* @__PURE__ */ React.createElement(AxisHead, { arcStyle: colorY, position: [0, 1, 0], label: labels[1], ...axisHeadProps }), /* @__PURE__ */ React.createElement(AxisHead, { arcStyle: colorZ, position: [0, 0, 1], label: labels[2], ...axisHeadProps }), !hideNegativeAxes && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(AxisHead, { arcStyle: colorX, position: [-1, 0, 0], ...axisHeadProps }), /* @__PURE__ */ React.createElement(AxisHead, { arcStyle: colorY, position: [0, -1, 0], ...axisHeadProps }), /* @__PURE__ */ React.createElement(AxisHead, { arcStyle: colorZ, position: [0, 0, -1], ...axisHeadProps }))));
|
|
5929
5815
|
};
|
|
5930
5816
|
|
|
5817
|
+
const roundEven = (n) => {
|
|
5818
|
+
const rounded = Math.ceil(n);
|
|
5819
|
+
return rounded % 2 === 0 ? rounded : rounded + 1;
|
|
5820
|
+
};
|
|
5821
|
+
|
|
5931
5822
|
const v1 = /* @__PURE__ */ new Vector3();
|
|
5932
5823
|
const v2 = /* @__PURE__ */ new Vector3();
|
|
5933
5824
|
const v3 = /* @__PURE__ */ new Vector3();
|
|
@@ -5999,7 +5890,7 @@ const getCameraCSSMatrix = /* @__PURE__ */ ((multipliers) => {
|
|
|
5999
5890
|
const getObjectCSSMatrix = /* @__PURE__ */ ((scaleMultipliers) => {
|
|
6000
5891
|
return (matrix, factor) => getCSSMatrix(matrix, scaleMultipliers(factor), "translate(-50%,-50%)");
|
|
6001
5892
|
})((f) => [1 / f, 1 / f, 1 / f, 1, -1 / f, -1 / f, -1 / f, -1, 1 / f, 1 / f, 1 / f, 1, 1, 1, 1, 1]);
|
|
6002
|
-
function isRefObject(ref) {
|
|
5893
|
+
function isRefObject$1(ref) {
|
|
6003
5894
|
return ref && typeof ref === "object" && "current" in ref;
|
|
6004
5895
|
}
|
|
6005
5896
|
const Html = /* @__PURE__ */ React.forwardRef(
|
|
@@ -6026,9 +5917,12 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6026
5917
|
as = "div",
|
|
6027
5918
|
wrapperClass,
|
|
6028
5919
|
pointerEvents = "auto",
|
|
5920
|
+
pixelPerfect = true,
|
|
6029
5921
|
...props
|
|
6030
5922
|
}, ref) => {
|
|
6031
5923
|
const { gl, camera, scene, size, raycaster, events, viewport } = useThree();
|
|
5924
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
5925
|
+
const { frustum } = useThree();
|
|
6032
5926
|
const [el] = React.useState(() => document.createElement(as));
|
|
6033
5927
|
const root = React.useRef(null);
|
|
6034
5928
|
const group = React.useRef(null);
|
|
@@ -6040,7 +5934,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6040
5934
|
const occlusionMeshRef = React.useRef(null);
|
|
6041
5935
|
const isMeshSizeSet = React.useRef(false);
|
|
6042
5936
|
const isRayCastOcclusion = React.useMemo(() => {
|
|
6043
|
-
return occlude && occlude !== "blending" || Array.isArray(occlude) && occlude.length && isRefObject(occlude[0]);
|
|
5937
|
+
return occlude && occlude !== "blending" || Array.isArray(occlude) && occlude.length && isRefObject$1(occlude[0]);
|
|
6044
5938
|
}, [occlude]);
|
|
6045
5939
|
React.useLayoutEffect(() => {
|
|
6046
5940
|
const el2 = gl.domElement;
|
|
@@ -6053,38 +5947,50 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6053
5947
|
el2.style.position = null;
|
|
6054
5948
|
el2.style.pointerEvents = null;
|
|
6055
5949
|
}
|
|
6056
|
-
}, [occlude]);
|
|
5950
|
+
}, [occlude, zIndexRange, gl.domElement]);
|
|
6057
5951
|
React.useLayoutEffect(() => {
|
|
6058
5952
|
if (group.current) {
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
5953
|
+
if (!root.current) {
|
|
5954
|
+
root.current = ReactDOM.createRoot(el);
|
|
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
|
+
}
|
|
6066
5961
|
}
|
|
6067
5962
|
if (target) {
|
|
6068
5963
|
if (prepend) target.prepend(el);
|
|
6069
5964
|
else target.appendChild(el);
|
|
6070
5965
|
}
|
|
6071
5966
|
return () => {
|
|
6072
|
-
if (target
|
|
6073
|
-
|
|
5967
|
+
if (target && target.contains(el)) {
|
|
5968
|
+
target.removeChild(el);
|
|
5969
|
+
}
|
|
6074
5970
|
};
|
|
6075
5971
|
}
|
|
6076
|
-
}, [target, transform]);
|
|
5972
|
+
}, [target, transform, el, prepend, scene]);
|
|
6077
5973
|
React.useLayoutEffect(() => {
|
|
6078
5974
|
if (wrapperClass) el.className = wrapperClass;
|
|
6079
|
-
}, [wrapperClass]);
|
|
5975
|
+
}, [wrapperClass, el]);
|
|
5976
|
+
React.useLayoutEffect(() => {
|
|
5977
|
+
return () => {
|
|
5978
|
+
if (root.current) {
|
|
5979
|
+
root.current.unmount();
|
|
5980
|
+
root.current = null;
|
|
5981
|
+
}
|
|
5982
|
+
};
|
|
5983
|
+
}, []);
|
|
6080
5984
|
const styles = React.useMemo(() => {
|
|
5985
|
+
const width = forceEven ? roundEven(size.width) : size.width;
|
|
5986
|
+
const height = forceEven ? roundEven(size.height) : size.height;
|
|
6081
5987
|
if (transform) {
|
|
6082
5988
|
return {
|
|
6083
5989
|
position: "absolute",
|
|
6084
5990
|
top: 0,
|
|
6085
5991
|
left: 0,
|
|
6086
|
-
width
|
|
6087
|
-
height
|
|
5992
|
+
width,
|
|
5993
|
+
height,
|
|
6088
5994
|
transformStyle: "preserve-3d",
|
|
6089
5995
|
pointerEvents: "none"
|
|
6090
5996
|
};
|
|
@@ -6093,15 +5999,15 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6093
5999
|
position: "absolute",
|
|
6094
6000
|
transform: center ? "translate3d(-50%,-50%,0)" : "none",
|
|
6095
6001
|
...fullscreen && {
|
|
6096
|
-
top: -size.height / 2,
|
|
6097
|
-
left: -size.width / 2,
|
|
6098
|
-
width
|
|
6099
|
-
height
|
|
6002
|
+
top: forceEven ? roundEven(-size.height / 2) : -size.height / 2,
|
|
6003
|
+
left: forceEven ? roundEven(-size.width / 2) : -size.width / 2,
|
|
6004
|
+
width,
|
|
6005
|
+
height
|
|
6100
6006
|
},
|
|
6101
6007
|
...style
|
|
6102
6008
|
};
|
|
6103
6009
|
}
|
|
6104
|
-
}, [style, center, fullscreen, size, transform]);
|
|
6010
|
+
}, [style, center, fullscreen, size, transform, forceEven]);
|
|
6105
6011
|
const transformInnerStyles = React.useMemo(
|
|
6106
6012
|
() => ({ position: "absolute", pointerEvents }),
|
|
6107
6013
|
[pointerEvents]
|
|
@@ -6115,7 +6021,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6115
6021
|
} else {
|
|
6116
6022
|
root.current?.render(/* @__PURE__ */ React.createElement("div", { ref, style: styles, className, children }));
|
|
6117
6023
|
}
|
|
6118
|
-
});
|
|
6024
|
+
}, [transform, styles, transformInnerStyles, ref, className, style, children]);
|
|
6119
6025
|
const visible = React.useRef(true);
|
|
6120
6026
|
useFrame((gl2) => {
|
|
6121
6027
|
if (group.current) {
|
|
@@ -6147,7 +6053,12 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6147
6053
|
const zRange = occlude ? isRayCastOcclusion ? [zIndexRange[0], halfRange] : [halfRange - 1, 0] : zIndexRange;
|
|
6148
6054
|
el.style.zIndex = `${objectZIndex(group.current, camera, zRange)}`;
|
|
6149
6055
|
if (transform) {
|
|
6150
|
-
|
|
6056
|
+
let widthHalf = forceEven ? roundEven(size.width / 2) : size.width / 2;
|
|
6057
|
+
let heightHalf = forceEven ? roundEven(size.height / 2) : size.height / 2;
|
|
6058
|
+
if (pixelPerfect) {
|
|
6059
|
+
widthHalf = roundToPixelRatio(widthHalf);
|
|
6060
|
+
heightHalf = roundToPixelRatio(heightHalf);
|
|
6061
|
+
}
|
|
6151
6062
|
const fov = camera.projectionMatrix.elements[5] * heightHalf;
|
|
6152
6063
|
const { isOrthographicCamera, top, left, bottom, right } = camera;
|
|
6153
6064
|
const cameraMatrix = getCameraCSSMatrix(camera.matrixWorldInverse);
|
|
@@ -6158,8 +6069,10 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6158
6069
|
matrix.elements[3] = matrix.elements[7] = matrix.elements[11] = 0;
|
|
6159
6070
|
matrix.elements[15] = 1;
|
|
6160
6071
|
}
|
|
6161
|
-
|
|
6162
|
-
|
|
6072
|
+
const elWidth = forceEven ? roundEven(size.width) : size.width;
|
|
6073
|
+
const elHeight = forceEven ? roundEven(size.height) : size.height;
|
|
6074
|
+
el.style.width = elWidth + "px";
|
|
6075
|
+
el.style.height = elHeight + "px";
|
|
6163
6076
|
el.style.perspective = isOrthographicCamera ? "" : `${fov}px`;
|
|
6164
6077
|
if (transformOuterRef.current && transformInnerRef.current) {
|
|
6165
6078
|
transformOuterRef.current.style.transform = `${cameraTransform}${cameraMatrix}translate(${widthHalf}px,${heightHalf}px)`;
|
|
@@ -6167,7 +6080,13 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6167
6080
|
}
|
|
6168
6081
|
} else {
|
|
6169
6082
|
const scale = distanceFactor === void 0 ? 1 : objectScale(group.current, camera) * distanceFactor;
|
|
6170
|
-
|
|
6083
|
+
let x = forceEven ? roundEven(vec[0]) : vec[0];
|
|
6084
|
+
let y = forceEven ? roundEven(vec[1]) : vec[1];
|
|
6085
|
+
if (pixelPerfect) {
|
|
6086
|
+
x = roundToPixelRatio(x);
|
|
6087
|
+
y = roundToPixelRatio(y);
|
|
6088
|
+
}
|
|
6089
|
+
el.style.transform = `translate3d(${x}px,${y}px,0) scale(${scale})`;
|
|
6171
6090
|
}
|
|
6172
6091
|
oldPosition.current = vec;
|
|
6173
6092
|
oldZoom.current = camera.zoom;
|
|
@@ -6178,8 +6097,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6178
6097
|
if (transformOuterRef.current) {
|
|
6179
6098
|
const el2 = transformOuterRef.current.children[0];
|
|
6180
6099
|
if (el2?.clientWidth && el2?.clientHeight) {
|
|
6181
|
-
|
|
6182
|
-
if (isOrthographicCamera || geometry) {
|
|
6100
|
+
if (geometry) {
|
|
6183
6101
|
if (props.scale) {
|
|
6184
6102
|
if (!Array.isArray(props.scale)) {
|
|
6185
6103
|
occlusionMeshRef.current.scale.setScalar(1 / props.scale);
|
|
@@ -6211,68 +6129,16 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6211
6129
|
}
|
|
6212
6130
|
}
|
|
6213
6131
|
});
|
|
6214
|
-
|
|
6215
|
-
() => ({
|
|
6216
|
-
vertexShader: !transform ? (
|
|
6217
|
-
/* glsl */
|
|
6218
|
-
`
|
|
6219
|
-
/*
|
|
6220
|
-
This shader is from the THREE's SpriteMaterial.
|
|
6221
|
-
We need to turn the backing plane into a Sprite
|
|
6222
|
-
(make it always face the camera) if "transfrom"
|
|
6223
|
-
is false.
|
|
6224
|
-
*/
|
|
6225
|
-
#include <common>
|
|
6226
|
-
|
|
6227
|
-
void main() {
|
|
6228
|
-
vec2 center = vec2(0., 1.);
|
|
6229
|
-
float rotation = 0.0;
|
|
6230
|
-
|
|
6231
|
-
// This is somewhat arbitrary, but it seems to work well
|
|
6232
|
-
// Need to figure out how to derive this dynamically if it even matters
|
|
6233
|
-
float size = 0.03;
|
|
6234
|
-
|
|
6235
|
-
vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
|
|
6236
|
-
vec2 scale;
|
|
6237
|
-
scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );
|
|
6238
|
-
scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );
|
|
6239
|
-
|
|
6240
|
-
bool isPerspective = isPerspectiveMatrix( projectionMatrix );
|
|
6241
|
-
if ( isPerspective ) scale *= - mvPosition.z;
|
|
6242
|
-
|
|
6243
|
-
vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale * size;
|
|
6244
|
-
vec2 rotatedPosition;
|
|
6245
|
-
rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
|
|
6246
|
-
rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
|
|
6247
|
-
mvPosition.xy += rotatedPosition;
|
|
6248
|
-
|
|
6249
|
-
gl_Position = projectionMatrix * mvPosition;
|
|
6250
|
-
}
|
|
6251
|
-
`
|
|
6252
|
-
) : void 0,
|
|
6253
|
-
fragmentShader: (
|
|
6254
|
-
/* glsl */
|
|
6255
|
-
`
|
|
6256
|
-
void main() {
|
|
6257
|
-
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
|
6258
|
-
}
|
|
6259
|
-
`
|
|
6260
|
-
)
|
|
6261
|
-
}),
|
|
6262
|
-
[transform]
|
|
6263
|
-
);
|
|
6264
|
-
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(
|
|
6265
|
-
"shaderMaterial",
|
|
6266
|
-
{
|
|
6267
|
-
side: DoubleSide,
|
|
6268
|
-
vertexShader: shaders.vertexShader,
|
|
6269
|
-
fragmentShader: shaders.fragmentShader
|
|
6270
|
-
}
|
|
6271
|
-
)));
|
|
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));
|
|
6272
6133
|
}
|
|
6273
6134
|
);
|
|
6274
6135
|
|
|
6275
6136
|
const context$4 = /* @__PURE__ */ React.createContext(null);
|
|
6137
|
+
const resolveObject = (object, fallback) => {
|
|
6138
|
+
if (!object) return fallback;
|
|
6139
|
+
if ("current" in object) return object.current;
|
|
6140
|
+
return object;
|
|
6141
|
+
};
|
|
6276
6142
|
|
|
6277
6143
|
const vec1$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
6278
6144
|
const vec2$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
@@ -6307,6 +6173,8 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
6307
6173
|
onDragStart,
|
|
6308
6174
|
onDrag,
|
|
6309
6175
|
onDragEnd,
|
|
6176
|
+
onHover,
|
|
6177
|
+
dragState,
|
|
6310
6178
|
userData,
|
|
6311
6179
|
LineComponent: Line
|
|
6312
6180
|
} = React.useContext(context$4);
|
|
@@ -6338,7 +6206,13 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
6338
6206
|
const onPointerMove = React.useCallback(
|
|
6339
6207
|
(e) => {
|
|
6340
6208
|
e.stopPropagation();
|
|
6341
|
-
if (!isHovered)
|
|
6209
|
+
if (!isHovered) {
|
|
6210
|
+
const drag = dragState.current;
|
|
6211
|
+
if (drag === null || drag.component === "Arrow" && drag.axis === axis) {
|
|
6212
|
+
setIsHovered(true);
|
|
6213
|
+
onHover({ component: "Arrow", axis, hovering: true });
|
|
6214
|
+
}
|
|
6215
|
+
}
|
|
6342
6216
|
if (clickInfo.current) {
|
|
6343
6217
|
const { clickPoint, dir } = clickInfo.current;
|
|
6344
6218
|
const [min, max] = translationLimits?.[axis] || [void 0, void 0];
|
|
@@ -6357,7 +6231,7 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
6357
6231
|
onDrag(offsetMatrix$1);
|
|
6358
6232
|
}
|
|
6359
6233
|
},
|
|
6360
|
-
[annotations, onDrag, isHovered, translation, translationLimits, axis]
|
|
6234
|
+
[annotations, onDrag, onHover, dragState, isHovered, translation, translationLimits, axis]
|
|
6361
6235
|
);
|
|
6362
6236
|
const onPointerUp = React.useCallback(
|
|
6363
6237
|
(e) => {
|
|
@@ -6372,10 +6246,16 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
6372
6246
|
},
|
|
6373
6247
|
[annotations, camControls, onDragEnd]
|
|
6374
6248
|
);
|
|
6375
|
-
const onPointerOut = React.useCallback(
|
|
6376
|
-
e
|
|
6377
|
-
|
|
6378
|
-
|
|
6249
|
+
const onPointerOut = React.useCallback(
|
|
6250
|
+
(e) => {
|
|
6251
|
+
e.stopPropagation();
|
|
6252
|
+
if (isHovered) {
|
|
6253
|
+
setIsHovered(false);
|
|
6254
|
+
onHover({ component: "Arrow", axis, hovering: false });
|
|
6255
|
+
}
|
|
6256
|
+
},
|
|
6257
|
+
[onHover, axis, isHovered]
|
|
6258
|
+
);
|
|
6379
6259
|
const { cylinderLength, coneWidth, coneLength, matrixL } = React.useMemo(() => {
|
|
6380
6260
|
const coneWidth2 = fixed ? lineWidth / scale * 1.6 : scale / 20;
|
|
6381
6261
|
const coneLength2 = fixed ? 0.2 : scale / 5;
|
|
@@ -6479,6 +6359,8 @@ const rotMatrix = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
6479
6359
|
const posNew = /* @__PURE__ */ new THREE.Vector3();
|
|
6480
6360
|
const ray$1 = /* @__PURE__ */ new THREE.Ray();
|
|
6481
6361
|
const intersection$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
6362
|
+
const viewPlane = /* @__PURE__ */ new THREE.Plane();
|
|
6363
|
+
const viewIntersection = /* @__PURE__ */ new THREE.Vector3();
|
|
6482
6364
|
const AxisRotator = ({
|
|
6483
6365
|
dir1,
|
|
6484
6366
|
dir2,
|
|
@@ -6499,6 +6381,8 @@ const AxisRotator = ({
|
|
|
6499
6381
|
onDragStart,
|
|
6500
6382
|
onDrag,
|
|
6501
6383
|
onDragEnd,
|
|
6384
|
+
onHover,
|
|
6385
|
+
dragState,
|
|
6502
6386
|
userData,
|
|
6503
6387
|
LineComponent: Line
|
|
6504
6388
|
} = React.useContext(context$4);
|
|
@@ -6532,14 +6416,29 @@ const AxisRotator = ({
|
|
|
6532
6416
|
const onPointerMove = React.useCallback(
|
|
6533
6417
|
(e) => {
|
|
6534
6418
|
e.stopPropagation();
|
|
6535
|
-
if (!isHovered)
|
|
6419
|
+
if (!isHovered) {
|
|
6420
|
+
const drag = dragState.current;
|
|
6421
|
+
if (drag === null || drag.component === "Rotator" && drag.axis === axis) {
|
|
6422
|
+
setIsHovered(true);
|
|
6423
|
+
onHover({ component: "Rotator", axis, hovering: true });
|
|
6424
|
+
}
|
|
6425
|
+
}
|
|
6536
6426
|
if (clickInfo.current) {
|
|
6537
6427
|
const { clickPoint, origin, e1, e2, normal, plane } = clickInfo.current;
|
|
6538
6428
|
const [min, max] = rotationLimits?.[axis] || [void 0, void 0];
|
|
6539
6429
|
ray$1.copy(e.ray);
|
|
6540
|
-
ray$1.
|
|
6541
|
-
|
|
6542
|
-
|
|
6430
|
+
const dotProduct = Math.abs(ray$1.direction.dot(normal));
|
|
6431
|
+
if (dotProduct < 0.1) {
|
|
6432
|
+
viewPlane.setFromNormalAndCoplanarPoint(ray$1.direction.clone().negate(), origin);
|
|
6433
|
+
ray$1.intersectPlane(viewPlane, viewIntersection);
|
|
6434
|
+
const toIntersection = viewIntersection.clone().sub(origin);
|
|
6435
|
+
const projectedDist = toIntersection.dot(normal);
|
|
6436
|
+
intersection$1.copy(viewIntersection).sub(normal.clone().multiplyScalar(projectedDist));
|
|
6437
|
+
} else {
|
|
6438
|
+
ray$1.intersectPlane(plane, intersection$1);
|
|
6439
|
+
ray$1.direction.negate();
|
|
6440
|
+
ray$1.intersectPlane(plane, intersection$1);
|
|
6441
|
+
}
|
|
6543
6442
|
let deltaAngle = calculateAngle(clickPoint, intersection$1, origin, e1, e2);
|
|
6544
6443
|
let degrees = toDegrees(deltaAngle);
|
|
6545
6444
|
if (e.shiftKey) {
|
|
@@ -6565,7 +6464,7 @@ const AxisRotator = ({
|
|
|
6565
6464
|
onDrag(rotMatrix);
|
|
6566
6465
|
}
|
|
6567
6466
|
},
|
|
6568
|
-
[annotations, onDrag, isHovered, rotationLimits, axis]
|
|
6467
|
+
[annotations, onDrag, onHover, dragState, isHovered, rotationLimits, axis]
|
|
6569
6468
|
);
|
|
6570
6469
|
const onPointerUp = React.useCallback(
|
|
6571
6470
|
(e) => {
|
|
@@ -6581,10 +6480,16 @@ const AxisRotator = ({
|
|
|
6581
6480
|
},
|
|
6582
6481
|
[annotations, camControls, onDragEnd]
|
|
6583
6482
|
);
|
|
6584
|
-
const onPointerOut = React.useCallback(
|
|
6585
|
-
e
|
|
6586
|
-
|
|
6587
|
-
|
|
6483
|
+
const onPointerOut = React.useCallback(
|
|
6484
|
+
(e) => {
|
|
6485
|
+
e.stopPropagation();
|
|
6486
|
+
if (isHovered) {
|
|
6487
|
+
setIsHovered(false);
|
|
6488
|
+
onHover({ component: "Rotator", axis, hovering: false });
|
|
6489
|
+
}
|
|
6490
|
+
},
|
|
6491
|
+
[onHover, axis, isHovered]
|
|
6492
|
+
);
|
|
6588
6493
|
const matrixL = React.useMemo(() => {
|
|
6589
6494
|
const dir1N = dir1.clone().normalize();
|
|
6590
6495
|
const dir2N = dir2.clone().normalize();
|
|
@@ -6685,6 +6590,8 @@ const PlaneSlider = ({
|
|
|
6685
6590
|
onDragStart,
|
|
6686
6591
|
onDrag,
|
|
6687
6592
|
onDragEnd,
|
|
6593
|
+
onHover,
|
|
6594
|
+
dragState,
|
|
6688
6595
|
userData,
|
|
6689
6596
|
LineComponent: Line
|
|
6690
6597
|
} = React.useContext(context$4);
|
|
@@ -6720,7 +6627,13 @@ const PlaneSlider = ({
|
|
|
6720
6627
|
const onPointerMove = React.useCallback(
|
|
6721
6628
|
(e) => {
|
|
6722
6629
|
e.stopPropagation();
|
|
6723
|
-
if (!isHovered)
|
|
6630
|
+
if (!isHovered) {
|
|
6631
|
+
const drag = dragState.current;
|
|
6632
|
+
if (drag === null || drag.component === "Slider" && drag.axis === axis) {
|
|
6633
|
+
setIsHovered(true);
|
|
6634
|
+
onHover({ component: "Slider", axis, hovering: true });
|
|
6635
|
+
}
|
|
6636
|
+
}
|
|
6724
6637
|
if (clickInfo.current) {
|
|
6725
6638
|
const { clickPoint, e1, e2, plane } = clickInfo.current;
|
|
6726
6639
|
const [minX, maxX] = translationLimits?.[(axis + 1) % 3] || [void 0, void 0];
|
|
@@ -6756,7 +6669,7 @@ const PlaneSlider = ({
|
|
|
6756
6669
|
onDrag(offsetMatrix);
|
|
6757
6670
|
}
|
|
6758
6671
|
},
|
|
6759
|
-
[annotations, onDrag, isHovered, translation, translationLimits, axis]
|
|
6672
|
+
[annotations, onDrag, onHover, dragState, isHovered, translation, translationLimits, axis]
|
|
6760
6673
|
);
|
|
6761
6674
|
const onPointerUp = React.useCallback(
|
|
6762
6675
|
(e) => {
|
|
@@ -6771,10 +6684,16 @@ const PlaneSlider = ({
|
|
|
6771
6684
|
},
|
|
6772
6685
|
[annotations, camControls, onDragEnd]
|
|
6773
6686
|
);
|
|
6774
|
-
const onPointerOut = React.useCallback(
|
|
6775
|
-
e
|
|
6776
|
-
|
|
6777
|
-
|
|
6687
|
+
const onPointerOut = React.useCallback(
|
|
6688
|
+
(e) => {
|
|
6689
|
+
e.stopPropagation();
|
|
6690
|
+
if (isHovered) {
|
|
6691
|
+
setIsHovered(false);
|
|
6692
|
+
onHover({ component: "Slider", axis, hovering: false });
|
|
6693
|
+
}
|
|
6694
|
+
},
|
|
6695
|
+
[onHover, axis, isHovered]
|
|
6696
|
+
);
|
|
6778
6697
|
const matrixL = React.useMemo(() => {
|
|
6779
6698
|
const dir1N = dir1.clone().normalize();
|
|
6780
6699
|
const dir2N = dir2.clone().normalize();
|
|
@@ -6912,6 +6831,8 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
6912
6831
|
onDragStart,
|
|
6913
6832
|
onDrag,
|
|
6914
6833
|
onDragEnd,
|
|
6834
|
+
onHover,
|
|
6835
|
+
dragState,
|
|
6915
6836
|
userData
|
|
6916
6837
|
} = React.useContext(context$4);
|
|
6917
6838
|
const size = useThree((state) => state.size);
|
|
@@ -6948,7 +6869,13 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
6948
6869
|
const onPointerMove = React.useCallback(
|
|
6949
6870
|
(e) => {
|
|
6950
6871
|
e.stopPropagation();
|
|
6951
|
-
if (!isHovered)
|
|
6872
|
+
if (!isHovered) {
|
|
6873
|
+
const drag = dragState.current;
|
|
6874
|
+
if (drag === null || drag.component === "Sphere" && drag.axis === axis) {
|
|
6875
|
+
setIsHovered(true);
|
|
6876
|
+
onHover({ component: "Sphere", axis, hovering: true });
|
|
6877
|
+
}
|
|
6878
|
+
}
|
|
6952
6879
|
if (clickInfo.current) {
|
|
6953
6880
|
const { clickPoint, dir, mPLG, mPLGInv, offsetMultiplier } = clickInfo.current;
|
|
6954
6881
|
const [min, max] = scaleLimits?.[axis] || [1e-5, void 0];
|
|
@@ -6974,7 +6901,7 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
6974
6901
|
onDrag(scaleMatrix);
|
|
6975
6902
|
}
|
|
6976
6903
|
},
|
|
6977
|
-
[annotations, position, onDrag, isHovered, scaleLimits, axis]
|
|
6904
|
+
[annotations, position, onDrag, onHover, dragState, isHovered, scaleLimits, axis]
|
|
6978
6905
|
);
|
|
6979
6906
|
const onPointerUp = React.useCallback(
|
|
6980
6907
|
(e) => {
|
|
@@ -6991,10 +6918,16 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
6991
6918
|
},
|
|
6992
6919
|
[annotations, camControls, onDragEnd, position]
|
|
6993
6920
|
);
|
|
6994
|
-
const onPointerOut = React.useCallback(
|
|
6995
|
-
e
|
|
6996
|
-
|
|
6997
|
-
|
|
6921
|
+
const onPointerOut = React.useCallback(
|
|
6922
|
+
(e) => {
|
|
6923
|
+
e.stopPropagation();
|
|
6924
|
+
if (isHovered) {
|
|
6925
|
+
setIsHovered(false);
|
|
6926
|
+
onHover({ component: "Sphere", axis, hovering: false });
|
|
6927
|
+
}
|
|
6928
|
+
},
|
|
6929
|
+
[onHover, axis, isHovered]
|
|
6930
|
+
);
|
|
6998
6931
|
const { radius, matrixL } = React.useMemo(() => {
|
|
6999
6932
|
const radius2 = fixed ? lineWidth / scale * 1.8 : scale / 22.5;
|
|
7000
6933
|
const quaternion = new THREE.Quaternion().setFromUnitVectors(upV, direction.clone().normalize());
|
|
@@ -7049,6 +6982,7 @@ const mW = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
7049
6982
|
const mL = /* @__PURE__ */ new THREE.Matrix4();
|
|
7050
6983
|
const mL0Inv = /* @__PURE__ */ new THREE.Matrix4();
|
|
7051
6984
|
const mdL = /* @__PURE__ */ new THREE.Matrix4();
|
|
6985
|
+
const mdW = /* @__PURE__ */ new THREE.Matrix4();
|
|
7052
6986
|
const mG = /* @__PURE__ */ new THREE.Matrix4();
|
|
7053
6987
|
const bb = /* @__PURE__ */ new THREE.Box3();
|
|
7054
6988
|
const bbObj = /* @__PURE__ */ new THREE.Box3();
|
|
@@ -7064,9 +6998,11 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7064
6998
|
({
|
|
7065
6999
|
enabled = true,
|
|
7066
7000
|
matrix,
|
|
7001
|
+
object,
|
|
7067
7002
|
onDragStart,
|
|
7068
7003
|
onDrag,
|
|
7069
7004
|
onDragEnd,
|
|
7005
|
+
onHover,
|
|
7070
7006
|
autoTransform = true,
|
|
7071
7007
|
anchor,
|
|
7072
7008
|
disableAxes = false,
|
|
@@ -7102,14 +7038,35 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7102
7038
|
const gizmoRef = React.useRef(null);
|
|
7103
7039
|
const childrenRef = React.useRef(null);
|
|
7104
7040
|
const translation = React.useRef([0, 0, 0]);
|
|
7041
|
+
const dragState = React.useRef(null);
|
|
7105
7042
|
const cameraScale = React.useRef(new THREE.Vector3(1, 1, 1));
|
|
7106
7043
|
const gizmoScale = React.useRef(new THREE.Vector3(1, 1, 1));
|
|
7044
|
+
React.useEffect(() => {
|
|
7045
|
+
if (object) {
|
|
7046
|
+
const target = resolveObject(object);
|
|
7047
|
+
if (target) {
|
|
7048
|
+
const pivot = ref.current;
|
|
7049
|
+
const didAutoUpdate = target.matrixAutoUpdate;
|
|
7050
|
+
target.updateWorldMatrix(true, true);
|
|
7051
|
+
target.matrixAutoUpdate = false;
|
|
7052
|
+
pivot.matrix.copy(target.matrix);
|
|
7053
|
+
return () => {
|
|
7054
|
+
if (didAutoUpdate) {
|
|
7055
|
+
target.matrixAutoUpdate = true;
|
|
7056
|
+
target.matrix.decompose(target.position, target.quaternion, target.scale);
|
|
7057
|
+
}
|
|
7058
|
+
};
|
|
7059
|
+
}
|
|
7060
|
+
}
|
|
7061
|
+
}, [object]);
|
|
7107
7062
|
React.useLayoutEffect(() => {
|
|
7108
7063
|
if (!anchor) return;
|
|
7109
|
-
childrenRef.current
|
|
7110
|
-
|
|
7064
|
+
const anchorTarget = resolveObject(object, childrenRef.current);
|
|
7065
|
+
if (!anchorTarget) return;
|
|
7066
|
+
anchorTarget.updateWorldMatrix(true, true);
|
|
7067
|
+
mPInv.copy(anchorTarget.matrixWorld).invert();
|
|
7111
7068
|
bb.makeEmpty();
|
|
7112
|
-
|
|
7069
|
+
anchorTarget.traverse((obj) => {
|
|
7113
7070
|
if (!obj.geometry) return;
|
|
7114
7071
|
if (!obj.geometry.boundingBox) obj.geometry.computeBoundingBox();
|
|
7115
7072
|
mL.copy(obj.matrixWorld).premultiply(mPInv);
|
|
@@ -7124,15 +7081,24 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7124
7081
|
gizmoRef.current.position.copy(vPosition);
|
|
7125
7082
|
invalidate();
|
|
7126
7083
|
});
|
|
7084
|
+
const mergedUserData = React.useMemo(
|
|
7085
|
+
() => ({
|
|
7086
|
+
...userData,
|
|
7087
|
+
...depthTest === false && { interactivePriority: 1 }
|
|
7088
|
+
}),
|
|
7089
|
+
[userData, depthTest]
|
|
7090
|
+
);
|
|
7127
7091
|
const config = React.useMemo(
|
|
7128
7092
|
() => ({
|
|
7129
7093
|
onDragStart: (props2) => {
|
|
7094
|
+
dragState.current = props2;
|
|
7130
7095
|
mL0.copy(ref.current.matrix);
|
|
7131
7096
|
mW0.copy(ref.current.matrixWorld);
|
|
7132
7097
|
onDragStart && onDragStart(props2);
|
|
7133
7098
|
invalidate();
|
|
7134
7099
|
},
|
|
7135
|
-
onDrag: (
|
|
7100
|
+
onDrag: (mdW_) => {
|
|
7101
|
+
mdW.copy(mdW_);
|
|
7136
7102
|
mP.copy(parentRef.current.matrixWorld);
|
|
7137
7103
|
mPInv.copy(mP).invert();
|
|
7138
7104
|
mW.copy(mW0).premultiply(mdW);
|
|
@@ -7142,13 +7108,20 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7142
7108
|
if (autoTransform) {
|
|
7143
7109
|
ref.current.matrix.copy(mL);
|
|
7144
7110
|
}
|
|
7145
|
-
|
|
7111
|
+
const target = resolveObject(object);
|
|
7112
|
+
if (target) target.matrix.copy(mL);
|
|
7113
|
+
onDrag && onDrag({ local: mL, deltaLocal: mdL, world: mW, deltaWorld: mdW });
|
|
7146
7114
|
invalidate();
|
|
7147
7115
|
},
|
|
7148
7116
|
onDragEnd: () => {
|
|
7149
|
-
|
|
7117
|
+
dragState.current = null;
|
|
7118
|
+
if (onDragEnd) onDragEnd({ local: mL, deltaLocal: mdL, world: mW, deltaWorld: mdW });
|
|
7150
7119
|
invalidate();
|
|
7151
7120
|
},
|
|
7121
|
+
onHover: (props2) => {
|
|
7122
|
+
if (onHover) onHover(props2);
|
|
7123
|
+
},
|
|
7124
|
+
dragState,
|
|
7152
7125
|
translation,
|
|
7153
7126
|
translationLimits,
|
|
7154
7127
|
rotationLimits,
|
|
@@ -7160,7 +7133,7 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7160
7133
|
fixed,
|
|
7161
7134
|
depthTest,
|
|
7162
7135
|
renderOrder,
|
|
7163
|
-
userData,
|
|
7136
|
+
userData: mergedUserData,
|
|
7164
7137
|
annotations,
|
|
7165
7138
|
annotationsClass,
|
|
7166
7139
|
LineComponent: LineComp
|
|
@@ -7169,6 +7142,7 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7169
7142
|
onDragStart,
|
|
7170
7143
|
onDrag,
|
|
7171
7144
|
onDragEnd,
|
|
7145
|
+
onHover,
|
|
7172
7146
|
translation,
|
|
7173
7147
|
translationLimits,
|
|
7174
7148
|
rotationLimits,
|
|
@@ -7180,11 +7154,12 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7180
7154
|
...axisColors,
|
|
7181
7155
|
hoveredColor,
|
|
7182
7156
|
opacity,
|
|
7183
|
-
|
|
7157
|
+
mergedUserData,
|
|
7184
7158
|
autoTransform,
|
|
7185
7159
|
annotations,
|
|
7186
7160
|
annotationsClass,
|
|
7187
|
-
LineComp
|
|
7161
|
+
LineComp,
|
|
7162
|
+
object
|
|
7188
7163
|
]
|
|
7189
7164
|
);
|
|
7190
7165
|
const vec = new THREE.Vector3();
|
|
@@ -7251,7 +7226,9 @@ const TransformControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7251
7226
|
const group = React.useRef(null);
|
|
7252
7227
|
React.useLayoutEffect(() => {
|
|
7253
7228
|
if (object) {
|
|
7254
|
-
controls.attach(
|
|
7229
|
+
controls.attach(
|
|
7230
|
+
object instanceof THREE.Object3D ? object : object.current
|
|
7231
|
+
);
|
|
7255
7232
|
} else if (group.current instanceof THREE.Object3D) {
|
|
7256
7233
|
controls.attach(group.current);
|
|
7257
7234
|
}
|
|
@@ -7347,7 +7324,7 @@ const PointMaterial = /* @__PURE__ */ React.forwardRef((props, ref) => {
|
|
|
7347
7324
|
return /* @__PURE__ */ React.createElement("primitive", { ...props, object: material, ref, attach: "material" });
|
|
7348
7325
|
});
|
|
7349
7326
|
|
|
7350
|
-
const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, loop =
|
|
7327
|
+
const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, loop = false, autoplay, ...props }, ref) => {
|
|
7351
7328
|
const sound = React.useRef(null);
|
|
7352
7329
|
React.useImperativeHandle(ref, () => sound.current, []);
|
|
7353
7330
|
const camera = useThree(({ camera: camera2 }) => camera2);
|
|
@@ -7359,7 +7336,9 @@ const PositionalAudio = /* @__PURE__ */ React.forwardRef(({ url, distance = 1, l
|
|
|
7359
7336
|
_sound.setBuffer(Array.isArray(buffer) ? buffer[0] : buffer);
|
|
7360
7337
|
_sound.setRefDistance(distance);
|
|
7361
7338
|
_sound.setLoop(loop);
|
|
7362
|
-
if (autoplay && !_sound.isPlaying)
|
|
7339
|
+
if (autoplay && !_sound.isPlaying) {
|
|
7340
|
+
_sound.play();
|
|
7341
|
+
}
|
|
7363
7342
|
}
|
|
7364
7343
|
}, [buffer, camera, distance, loop]);
|
|
7365
7344
|
React.useEffect(() => {
|
|
@@ -7428,7 +7407,6 @@ const tempMatrix = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
7428
7407
|
const translation = /* @__PURE__ */ new THREE.Vector3();
|
|
7429
7408
|
const rotation = /* @__PURE__ */ new THREE.Quaternion();
|
|
7430
7409
|
const scale = /* @__PURE__ */ new THREE.Vector3();
|
|
7431
|
-
const isInstancedBufferAttribute = (attr) => attr.isInstancedBufferAttribute;
|
|
7432
7410
|
const Instance = /* @__PURE__ */ React.forwardRef(({ context, children, ...props }, ref) => {
|
|
7433
7411
|
React.useMemo(() => extend({ PositionMesh }), []);
|
|
7434
7412
|
const group = React.useRef(null);
|
|
@@ -7448,24 +7426,20 @@ const Instances = /* @__PURE__ */ React.forwardRef(({ context, children, range,
|
|
|
7448
7426
|
const parentRef = React.useRef(null);
|
|
7449
7427
|
React.useImperativeHandle(ref, () => parentRef.current, []);
|
|
7450
7428
|
const [instances, setInstances] = React.useState([]);
|
|
7429
|
+
const boundsDirty = React.useRef(true);
|
|
7451
7430
|
const [[matrices, colors]] = React.useState(() => {
|
|
7452
7431
|
const mArray = new Float32Array(limit * 16);
|
|
7453
7432
|
for (let i = 0; i < limit; i++) tempMatrix.identity().toArray(mArray, i * 16);
|
|
7454
7433
|
return [mArray, new Float32Array([...new Array(limit * 3)].map(() => 1))];
|
|
7455
7434
|
});
|
|
7456
7435
|
React.useEffect(() => {
|
|
7457
|
-
parentRef.current.instanceMatrix.needsUpdate = true;
|
|
7436
|
+
if (parentRef.current) parentRef.current.instanceMatrix.needsUpdate = true;
|
|
7458
7437
|
});
|
|
7459
7438
|
let iterations = 0;
|
|
7460
7439
|
let count = 0;
|
|
7461
|
-
const attributes = React.useRef([]);
|
|
7462
|
-
React.useLayoutEffect(() => {
|
|
7463
|
-
attributes.current = Object.entries(parentRef.current.geometry.attributes).filter(
|
|
7464
|
-
([_name, value]) => isInstancedBufferAttribute(value)
|
|
7465
|
-
);
|
|
7466
|
-
});
|
|
7467
7440
|
useFrame(() => {
|
|
7468
7441
|
if (frames === Infinity || iterations < frames) {
|
|
7442
|
+
if (!parentRef.current) return;
|
|
7469
7443
|
parentRef.current.updateMatrix();
|
|
7470
7444
|
parentRef.current.updateMatrixWorld();
|
|
7471
7445
|
parentMatrix.copy(parentRef.current.matrixWorld).invert();
|
|
@@ -7486,13 +7460,22 @@ const Instances = /* @__PURE__ */ React.forwardRef(({ context, children, range,
|
|
|
7486
7460
|
}
|
|
7487
7461
|
iterations++;
|
|
7488
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
|
+
}
|
|
7489
7468
|
});
|
|
7490
7469
|
const api = React.useMemo(
|
|
7491
7470
|
() => ({
|
|
7492
7471
|
getParent: () => parentRef,
|
|
7493
7472
|
subscribe: (ref2) => {
|
|
7494
7473
|
setInstances((instances2) => [...instances2, ref2]);
|
|
7495
|
-
|
|
7474
|
+
boundsDirty.current = true;
|
|
7475
|
+
return () => {
|
|
7476
|
+
setInstances((instances2) => instances2.filter((item) => item.current !== ref2.current));
|
|
7477
|
+
boundsDirty.current = true;
|
|
7478
|
+
};
|
|
7496
7479
|
}
|
|
7497
7480
|
}),
|
|
7498
7481
|
[]
|
|
@@ -7517,10 +7500,23 @@ const Merged = /* @__PURE__ */ React.forwardRef(function Merged2({ meshes, child
|
|
|
7517
7500
|
if (!isArray) {
|
|
7518
7501
|
for (const key of Object.keys(meshes)) if (!meshes[key].isMesh) delete meshes[key];
|
|
7519
7502
|
}
|
|
7520
|
-
const render = (args) =>
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
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
|
+
});
|
|
7524
7520
|
return /* @__PURE__ */ React.createElement("group", { ref }, renderRecursive(render, components));
|
|
7525
7521
|
});
|
|
7526
7522
|
function renderRecursive(render, components, results = []) {
|
|
@@ -7546,7 +7542,7 @@ function createInstances() {
|
|
|
7546
7542
|
];
|
|
7547
7543
|
}
|
|
7548
7544
|
const InstancedAttribute = React.forwardRef(
|
|
7549
|
-
({ name, defaultValue, normalized, usage = THREE.DynamicDrawUsage }, fref) => {
|
|
7545
|
+
({ name, defaultValue, normalized, usage = THREE.DynamicDrawUsage, type = "float" }, fref) => {
|
|
7550
7546
|
const ref = React.useRef(null);
|
|
7551
7547
|
React.useImperativeHandle(fref, () => ref.current, []);
|
|
7552
7548
|
React.useLayoutEffect(() => {
|
|
@@ -7554,7 +7550,26 @@ const InstancedAttribute = React.forwardRef(
|
|
|
7554
7550
|
parent.geometry.attributes[name] = ref.current;
|
|
7555
7551
|
const value = Array.isArray(defaultValue) ? defaultValue : [defaultValue];
|
|
7556
7552
|
const array = Array.from({ length: parent.userData.limit }, () => value).flat();
|
|
7557
|
-
|
|
7553
|
+
switch (type) {
|
|
7554
|
+
case "float":
|
|
7555
|
+
ref.current.array = new Float32Array(array);
|
|
7556
|
+
break;
|
|
7557
|
+
case "int":
|
|
7558
|
+
ref.current.array = new Int32Array(array);
|
|
7559
|
+
break;
|
|
7560
|
+
case "uint":
|
|
7561
|
+
ref.current.array = new Uint32Array(array);
|
|
7562
|
+
break;
|
|
7563
|
+
case "short":
|
|
7564
|
+
ref.current.array = new Int16Array(array);
|
|
7565
|
+
break;
|
|
7566
|
+
case "ushort":
|
|
7567
|
+
ref.current.array = new Uint16Array(array);
|
|
7568
|
+
break;
|
|
7569
|
+
case "byte":
|
|
7570
|
+
ref.current.array = new Uint8Array(array);
|
|
7571
|
+
break;
|
|
7572
|
+
}
|
|
7558
7573
|
ref.current.itemSize = value.length;
|
|
7559
7574
|
ref.current.count = array.length / ref.current.itemSize;
|
|
7560
7575
|
return () => {
|
|
@@ -8575,12 +8590,13 @@ function Sampler({ children, weight, transform, instances, mesh, count = 16, ...
|
|
|
8575
8590
|
return /* @__PURE__ */ React.createElement("group", { ref: group, ...props }, children);
|
|
8576
8591
|
}
|
|
8577
8592
|
|
|
8593
|
+
const pathStyle = (path) => path.userData?.style;
|
|
8578
8594
|
const Svg = /* @__PURE__ */ forwardRef(
|
|
8579
8595
|
function R3FSvg({ src, skipFill, skipStrokes, fillMaterial, strokeMaterial, fillMeshProps, strokeMeshProps, ...props }, ref) {
|
|
8580
8596
|
const svg = useLoader(SVGLoader, !src.startsWith("<svg") ? src : `data:image/svg+xml;utf8,${src}`);
|
|
8581
8597
|
const strokeGeometries = useMemo(
|
|
8582
8598
|
() => skipStrokes ? [] : svg.paths.map(
|
|
8583
|
-
(path) => path
|
|
8599
|
+
(path) => pathStyle(path)?.stroke === void 0 || pathStyle(path).stroke === "none" ? null : path.subPaths.map((subPath) => SVGLoader.pointsToStroke(subPath.getPoints(), pathStyle(path)))
|
|
8584
8600
|
),
|
|
8585
8601
|
[svg, skipStrokes]
|
|
8586
8602
|
);
|
|
@@ -8588,21 +8604,21 @@ const Svg = /* @__PURE__ */ forwardRef(
|
|
|
8588
8604
|
return () => strokeGeometries.forEach((group) => group && group.map((g) => g.dispose()));
|
|
8589
8605
|
}, [strokeGeometries]);
|
|
8590
8606
|
let renderOrder = 0;
|
|
8591
|
-
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(
|
|
8592
8608
|
"meshBasicMaterial",
|
|
8593
8609
|
{
|
|
8594
|
-
color: path.
|
|
8595
|
-
opacity: path.
|
|
8610
|
+
color: pathStyle(path).fill,
|
|
8611
|
+
opacity: pathStyle(path).fillOpacity,
|
|
8596
8612
|
transparent: true,
|
|
8597
8613
|
side: DoubleSide,
|
|
8598
8614
|
depthWrite: false,
|
|
8599
8615
|
...fillMaterial
|
|
8600
8616
|
}
|
|
8601
|
-
))), !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(
|
|
8602
8618
|
"meshBasicMaterial",
|
|
8603
8619
|
{
|
|
8604
|
-
color: path.
|
|
8605
|
-
opacity: path.
|
|
8620
|
+
color: pathStyle(path).stroke,
|
|
8621
|
+
opacity: pathStyle(path).strokeOpacity,
|
|
8606
8622
|
transparent: true,
|
|
8607
8623
|
side: DoubleSide,
|
|
8608
8624
|
depthWrite: false,
|
|
@@ -8825,8 +8841,8 @@ function useVideoTexture(srcOrSrcObject, {
|
|
|
8825
8841
|
});
|
|
8826
8842
|
if (src && IS_BROWSER && src.endsWith(".m3u8")) {
|
|
8827
8843
|
const hls = hlsRef.current = await getHls(hlsConfig);
|
|
8828
|
-
if (hls) {
|
|
8829
|
-
hls.on(Events.MEDIA_ATTACHED, () => void hls.loadSource(src));
|
|
8844
|
+
if (hls && _HLSModule) {
|
|
8845
|
+
hls.on(_HLSModule.Events.MEDIA_ATTACHED, () => void hls.loadSource(src));
|
|
8830
8846
|
hls.attachMedia(video2);
|
|
8831
8847
|
}
|
|
8832
8848
|
}
|
|
@@ -9046,9 +9062,125 @@ function Fbx({
|
|
|
9046
9062
|
return /* @__PURE__ */ React.createElement(Clone, { ...props, object });
|
|
9047
9063
|
}
|
|
9048
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
|
+
|
|
9049
9169
|
let dracoLoader = null;
|
|
9050
9170
|
let decoderPath = "https://www.gstatic.com/draco/versioned/decoders/1.5.5/";
|
|
9051
|
-
|
|
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) {
|
|
9052
9184
|
return (loader) => {
|
|
9053
9185
|
if (extendLoader) {
|
|
9054
9186
|
extendLoader(loader);
|
|
@@ -9064,31 +9196,110 @@ function extensions(useDraco = true, useMeshopt = true, extendLoader) {
|
|
|
9064
9196
|
const decoder = typeof MeshoptDecoder === "function" ? MeshoptDecoder() : MeshoptDecoder;
|
|
9065
9197
|
loader.setMeshoptDecoder(decoder);
|
|
9066
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
|
+
}
|
|
9067
9209
|
};
|
|
9068
9210
|
}
|
|
9069
|
-
|
|
9070
|
-
|
|
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
|
+
};
|
|
9071
9262
|
useGLTF.clear = (path) => useLoader.clear(GLTFLoader, path);
|
|
9072
9263
|
useGLTF.setDecoderPath = (path) => {
|
|
9073
9264
|
decoderPath = path;
|
|
9074
9265
|
};
|
|
9266
|
+
useGLTF.setKTX2TranscoderPath = (path) => {
|
|
9267
|
+
KTX2LoaderService.setTranscoderPath(path);
|
|
9268
|
+
};
|
|
9075
9269
|
const Gltf = /* @__PURE__ */ React.forwardRef(
|
|
9076
|
-
({ src, useDraco, useMeshOpt, extendLoader, ...props }, ref) => {
|
|
9077
|
-
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);
|
|
9078
9277
|
return /* @__PURE__ */ React.createElement(Clone, { ref, ...props, object: scene });
|
|
9079
9278
|
}
|
|
9080
9279
|
);
|
|
9081
9280
|
|
|
9082
|
-
|
|
9083
|
-
function useKTX2(input, basisPath = `${cdn}/basis/`) {
|
|
9281
|
+
function useKTX2(input, basisPath = true, extendLoader) {
|
|
9084
9282
|
const renderer = useThree((state) => state.renderer);
|
|
9283
|
+
useLayoutEffect(() => {
|
|
9284
|
+
KTX2LoaderService.registerRenderer(renderer);
|
|
9285
|
+
}, [renderer]);
|
|
9085
9286
|
const textures = useLoader(KTX2Loader, IsObject(input) ? Object.values(input) : input, (loader) => {
|
|
9287
|
+
if (extendLoader) {
|
|
9288
|
+
extendLoader(loader);
|
|
9289
|
+
}
|
|
9290
|
+
if (basisPath) {
|
|
9291
|
+
const path = typeof basisPath === "string" ? basisPath : KTX2LoaderService.getTranscoderPath();
|
|
9292
|
+
loader.setTranscoderPath(path);
|
|
9293
|
+
}
|
|
9086
9294
|
loader.detectSupport(renderer);
|
|
9087
|
-
loader.setTranscoderPath(basisPath);
|
|
9088
9295
|
});
|
|
9089
9296
|
useEffect(() => {
|
|
9090
9297
|
const array = Array.isArray(textures) ? textures : [textures];
|
|
9091
|
-
array.forEach((texture) =>
|
|
9298
|
+
array.forEach((texture) => {
|
|
9299
|
+
if ("initTexture" in renderer) {
|
|
9300
|
+
renderer.initTexture(texture);
|
|
9301
|
+
}
|
|
9302
|
+
});
|
|
9092
9303
|
}, [renderer, textures]);
|
|
9093
9304
|
if (IsObject(input)) {
|
|
9094
9305
|
const keys = Object.keys(input);
|
|
@@ -9099,19 +9310,81 @@ function useKTX2(input, basisPath = `${cdn}/basis/`) {
|
|
|
9099
9310
|
return textures;
|
|
9100
9311
|
}
|
|
9101
9312
|
}
|
|
9102
|
-
useKTX2.preload = (url, basisPath =
|
|
9103
|
-
|
|
9104
|
-
|
|
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
|
+
};
|
|
9105
9330
|
useKTX2.clear = (input) => useLoader.clear(KTX2Loader, input);
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
const texture = useKTX2(input, basisPath);
|
|
9331
|
+
useKTX2.setTranscoderPath = (path) => {
|
|
9332
|
+
KTX2LoaderService.setTranscoderPath(path);
|
|
9333
|
+
};
|
|
9334
|
+
const Ktx2 = ({ children, input, basisPath, extendLoader }) => {
|
|
9335
|
+
const texture = useKTX2(input, basisPath, extendLoader);
|
|
9112
9336
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(texture));
|
|
9113
9337
|
};
|
|
9114
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
|
+
|
|
9115
9388
|
const WebcamVideoTexture = /* @__PURE__ */ forwardRef(
|
|
9116
9389
|
({
|
|
9117
9390
|
constraints = {
|
|
@@ -9299,6 +9572,7 @@ function useEffectfulState(fn, deps = [], cb) {
|
|
|
9299
9572
|
}
|
|
9300
9573
|
|
|
9301
9574
|
function Stats({ showPanel = 0, className, parent }) {
|
|
9575
|
+
React.useEffect(() => void console.warn("drei: <Stats /> is deprecated, use <StatsGl /> instead."), []);
|
|
9302
9576
|
const stats = useEffectfulState(() => new StatsImpl(), []);
|
|
9303
9577
|
React.useEffect(() => {
|
|
9304
9578
|
if (stats) {
|
|
@@ -9327,6 +9601,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
|
|
|
9327
9601
|
const stats2 = new Stats$1({
|
|
9328
9602
|
...props
|
|
9329
9603
|
});
|
|
9604
|
+
stats2.init(renderer);
|
|
9330
9605
|
return stats2;
|
|
9331
9606
|
}, [renderer]);
|
|
9332
9607
|
React.useImperativeHandle(fref, () => stats.domElement, [stats]);
|
|
@@ -9344,7 +9619,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
|
|
|
9344
9619
|
return () => {
|
|
9345
9620
|
if (classNames.length) stats.domElement.classList.remove(...classNames);
|
|
9346
9621
|
node?.removeChild(stats.domElement);
|
|
9347
|
-
stats.
|
|
9622
|
+
stats.dispose();
|
|
9348
9623
|
};
|
|
9349
9624
|
}
|
|
9350
9625
|
}, [parent, stats, className, id, clearStatsGlStyle]);
|
|
@@ -9352,7 +9627,7 @@ const StatsGl = /* @__PURE__ */ React.forwardRef(
|
|
|
9352
9627
|
() => {
|
|
9353
9628
|
stats.begin();
|
|
9354
9629
|
},
|
|
9355
|
-
{ before: "
|
|
9630
|
+
{ before: "update" }
|
|
9356
9631
|
);
|
|
9357
9632
|
useFrame(
|
|
9358
9633
|
() => {
|
|
@@ -9402,11 +9677,11 @@ const RenderCubeTexture = /* @__PURE__ */ React.forwardRef(
|
|
|
9402
9677
|
depthBuffer,
|
|
9403
9678
|
generateMipmaps
|
|
9404
9679
|
};
|
|
9405
|
-
const fboA2 = new
|
|
9680
|
+
const fboA2 = new WebGLCubeRenderTarget(fboSize, settings);
|
|
9406
9681
|
fboA2.texture.isRenderTargetTexture = !flip;
|
|
9407
9682
|
fboA2.texture.flipY = true;
|
|
9408
9683
|
fboA2.texture.type = THREE.HalfFloatType;
|
|
9409
|
-
const fboB2 = new
|
|
9684
|
+
const fboB2 = new WebGLCubeRenderTarget(fboSize, settings);
|
|
9410
9685
|
fboB2.texture.isRenderTargetTexture = !flip;
|
|
9411
9686
|
fboB2.texture.flipY = true;
|
|
9412
9687
|
fboB2.texture.type = THREE.HalfFloatType;
|
|
@@ -9584,18 +9859,21 @@ function Fisheye({
|
|
|
9584
9859
|
const normal = new THREE.Vector3();
|
|
9585
9860
|
const sph = new THREE.Sphere(new THREE.Vector3(), radius);
|
|
9586
9861
|
const normalMatrix = new THREE.Matrix3();
|
|
9587
|
-
const compute = React.useCallback(
|
|
9588
|
-
|
|
9589
|
-
|
|
9590
|
-
|
|
9591
|
-
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9862
|
+
const compute = React.useCallback(
|
|
9863
|
+
(event, state, prev) => {
|
|
9864
|
+
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
9865
|
+
state.raycaster.setFromCamera(state.pointer, orthoC);
|
|
9866
|
+
if (!state.raycaster.ray.intersectSphere(sph, normal)) return;
|
|
9867
|
+
else normal.normalize();
|
|
9868
|
+
normalMatrix.getNormalMatrix(cubeApi.current.camera.matrixWorld);
|
|
9869
|
+
cubeApi.current.camera.getWorldPosition(state.raycaster.ray.origin);
|
|
9870
|
+
state.raycaster.ray.direction.set(0, 0, 1).reflect(normal);
|
|
9871
|
+
state.raycaster.ray.direction.x *= -1;
|
|
9872
|
+
state.raycaster.ray.direction.applyNormalMatrix(normalMatrix).multiplyScalar(-1);
|
|
9873
|
+
return void 0;
|
|
9874
|
+
},
|
|
9875
|
+
[width, height]
|
|
9876
|
+
);
|
|
9599
9877
|
useFrame(
|
|
9600
9878
|
({ gl }) => {
|
|
9601
9879
|
if (renderPriority) gl.render(sphere.current, orthoC);
|
|
@@ -9730,14 +10008,23 @@ const isWebGPURenderer = (def) => !!def.isWebGPURenderer;
|
|
|
9730
10008
|
const col = /* @__PURE__ */ new THREE.Color();
|
|
9731
10009
|
const TUNNEL_KEY = "__drei_view_tunnel__";
|
|
9732
10010
|
const tracked = globalThis[TUNNEL_KEY] || (globalThis[TUNNEL_KEY] = tunnel());
|
|
9733
|
-
function computeContainerPosition(canvasSize, trackRect) {
|
|
10011
|
+
function computeContainerPosition(canvasSize, trackRect, forceEven) {
|
|
9734
10012
|
const { right, top: trackTop, left: trackLeft, bottom: trackBottom, width, height } = trackRect;
|
|
9735
|
-
const isOffscreen = trackRect.bottom < 0 || trackTop > canvasSize.height || right < 0 || trackRect.left > canvasSize.width;
|
|
9736
10013
|
const canvasBottom = canvasSize.top + canvasSize.height;
|
|
9737
|
-
const
|
|
9738
|
-
const
|
|
9739
|
-
const
|
|
9740
|
-
|
|
10014
|
+
const canvasRight = canvasSize.left + canvasSize.width;
|
|
10015
|
+
const isOffscreen = trackBottom < canvasSize.top || trackTop > canvasBottom || right < canvasSize.left || trackLeft > canvasRight;
|
|
10016
|
+
const rawBottom = canvasBottom - trackBottom;
|
|
10017
|
+
const rawLeft = trackLeft - canvasSize.left;
|
|
10018
|
+
const rawTop = trackTop - canvasSize.top;
|
|
10019
|
+
const position = forceEven ? {
|
|
10020
|
+
width: roundEven(width),
|
|
10021
|
+
height: roundEven(height),
|
|
10022
|
+
left: roundEven(rawLeft),
|
|
10023
|
+
top: roundEven(rawTop),
|
|
10024
|
+
bottom: roundEven(rawBottom),
|
|
10025
|
+
right: roundEven(right)
|
|
10026
|
+
} : { width, height, left: rawLeft, top: rawTop, bottom: rawBottom, right };
|
|
10027
|
+
return { position, isOffscreen };
|
|
9741
10028
|
}
|
|
9742
10029
|
function prepareSkissor(renderer, camera, {
|
|
9743
10030
|
left,
|
|
@@ -9777,6 +10064,7 @@ function clear(renderer) {
|
|
|
9777
10064
|
}
|
|
9778
10065
|
function Container({ visible = true, canvasSize, scene, index, children, frames, rect, track }) {
|
|
9779
10066
|
const { scene: portalScene, camera: portalCamera, renderer, get, setEvents } = useThree();
|
|
10067
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
9780
10068
|
const [isOffscreen, setOffscreen] = React.useState(false);
|
|
9781
10069
|
const mountedRef = React.useRef(true);
|
|
9782
10070
|
React.useEffect(() => {
|
|
@@ -9794,7 +10082,7 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
9794
10082
|
frameCount++;
|
|
9795
10083
|
}
|
|
9796
10084
|
if (rect.current) {
|
|
9797
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, rect.current);
|
|
10085
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, rect.current, forceEven);
|
|
9798
10086
|
if (isOffscreen !== _isOffscreen) setOffscreen(_isOffscreen);
|
|
9799
10087
|
if (visible && !_isOffscreen && rect.current) {
|
|
9800
10088
|
const targetScene = children ? portalScene : scene;
|
|
@@ -9816,14 +10104,14 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
9816
10104
|
React.useLayoutEffect(() => {
|
|
9817
10105
|
const curRect = rect.current;
|
|
9818
10106
|
if (curRect && (!visible || !isOffscreen)) {
|
|
9819
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect);
|
|
10107
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect, forceEven);
|
|
9820
10108
|
if (!_isOffscreen) {
|
|
9821
10109
|
const autoClear = prepareSkissor(renderer, portalCamera, position);
|
|
9822
10110
|
clear(renderer);
|
|
9823
10111
|
finishSkissor(renderer, autoClear);
|
|
9824
10112
|
}
|
|
9825
10113
|
}
|
|
9826
|
-
}, [visible, isOffscreen, renderer, portalCamera, canvasSize]);
|
|
10114
|
+
}, [visible, isOffscreen, renderer, portalCamera, canvasSize, forceEven]);
|
|
9827
10115
|
React.useEffect(() => {
|
|
9828
10116
|
if (!track) return;
|
|
9829
10117
|
const curRect = rect.current;
|
|
@@ -9831,7 +10119,7 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
9831
10119
|
setEvents({ connected: track.current });
|
|
9832
10120
|
return () => {
|
|
9833
10121
|
if (curRect) {
|
|
9834
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect);
|
|
10122
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect, forceEven);
|
|
9835
10123
|
if (!_isOffscreen) {
|
|
9836
10124
|
const autoClear = prepareSkissor(renderer, portalCamera, position);
|
|
9837
10125
|
clear(renderer);
|
|
@@ -9840,13 +10128,14 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
9840
10128
|
}
|
|
9841
10129
|
setEvents({ connected: old });
|
|
9842
10130
|
};
|
|
9843
|
-
}, [track, renderer, portalCamera, canvasSize, get, setEvents]);
|
|
10131
|
+
}, [track, renderer, portalCamera, canvasSize, get, setEvents, forceEven]);
|
|
9844
10132
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children, /* @__PURE__ */ React.createElement("group", { onPointerOver: () => null }));
|
|
9845
10133
|
}
|
|
9846
10134
|
const CanvasView = /* @__PURE__ */ React.forwardRef(
|
|
9847
10135
|
({ track, visible = true, index = 1, id, style, className, frames = Infinity, children, ...props }, fref) => {
|
|
9848
10136
|
const rect = React.useRef(null);
|
|
9849
10137
|
const { size, scene } = useThree();
|
|
10138
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
9850
10139
|
const [virtualScene] = React.useState(() => new THREE.Scene());
|
|
9851
10140
|
const [ready, toggle] = React.useReducer(() => true, false);
|
|
9852
10141
|
const compute = React.useCallback(
|
|
@@ -9883,12 +10172,12 @@ const CanvasView = /* @__PURE__ */ React.forwardRef(
|
|
|
9883
10172
|
{
|
|
9884
10173
|
events: { compute, priority: index },
|
|
9885
10174
|
size: {
|
|
9886
|
-
width: rect.current?.width,
|
|
9887
|
-
height: rect.current?.height,
|
|
10175
|
+
width: forceEven && rect.current?.width ? roundEven(rect.current.width) : rect.current?.width,
|
|
10176
|
+
height: forceEven && rect.current?.height ? roundEven(rect.current.height) : rect.current?.height,
|
|
9888
10177
|
// @ts-ignore
|
|
9889
|
-
top: rect.current?.top,
|
|
10178
|
+
top: forceEven && rect.current?.top ? roundEven(rect.current.top) : rect.current?.top,
|
|
9890
10179
|
// @ts-ignore
|
|
9891
|
-
left: rect.current?.left
|
|
10180
|
+
left: forceEven && rect.current?.left ? roundEven(rect.current.left) : rect.current?.left
|
|
9892
10181
|
}
|
|
9893
10182
|
}
|
|
9894
10183
|
));
|
|
@@ -10283,12 +10572,12 @@ useEnvironment.preload = (preloadOptions) => {
|
|
|
10283
10572
|
if (extensions) extensions(loader2);
|
|
10284
10573
|
});
|
|
10285
10574
|
};
|
|
10286
|
-
const
|
|
10575
|
+
const clearDefaultOptions = {
|
|
10287
10576
|
files: defaultFiles,
|
|
10288
10577
|
preset: void 0
|
|
10289
10578
|
};
|
|
10290
10579
|
useEnvironment.clear = (clearOptions) => {
|
|
10291
|
-
const options = { ...
|
|
10580
|
+
const options = { ...clearDefaultOptions, ...clearOptions };
|
|
10292
10581
|
let { files } = options;
|
|
10293
10582
|
const { preset } = options;
|
|
10294
10583
|
if (preset) {
|
|
@@ -10315,8 +10604,8 @@ function getLoader(extension) {
|
|
|
10315
10604
|
return loader;
|
|
10316
10605
|
}
|
|
10317
10606
|
|
|
10318
|
-
const isRef = (obj) => obj.current && obj.current.isScene;
|
|
10319
|
-
const resolveScene = (scene) => isRef(scene) ? scene.current : scene;
|
|
10607
|
+
const isRef$1 = (obj) => obj.current && obj.current.isScene;
|
|
10608
|
+
const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
|
|
10320
10609
|
function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
|
|
10321
10610
|
sceneProps = {
|
|
10322
10611
|
backgroundBlurriness: 0,
|
|
@@ -10982,9 +11271,14 @@ function Select({
|
|
|
10982
11271
|
const oldControlsEnabled = controls?.enabled;
|
|
10983
11272
|
let isDown = false;
|
|
10984
11273
|
function prepareRay(event, vec) {
|
|
10985
|
-
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;
|
|
10986
11278
|
const { width, height } = size;
|
|
10987
|
-
|
|
11279
|
+
const normalizedX = x / width * 2 - 1;
|
|
11280
|
+
const normalizedY = -(y / height) * 2 + 1;
|
|
11281
|
+
vec.set(normalizedX, normalizedY, -1);
|
|
10988
11282
|
}
|
|
10989
11283
|
function onSelectStart(event) {
|
|
10990
11284
|
if (controls) controls.enabled = false;
|
|
@@ -11102,83 +11396,454 @@ function AsciiRenderer({
|
|
|
11102
11396
|
return /* @__PURE__ */ React.createElement(React.Fragment, null);
|
|
11103
11397
|
}
|
|
11104
11398
|
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
|
|
11122
|
-
function GradientTexture({
|
|
11123
|
-
stops,
|
|
11124
|
-
colors,
|
|
11125
|
-
size = 1024,
|
|
11126
|
-
width = 16,
|
|
11127
|
-
type = "linear" /* Linear */,
|
|
11128
|
-
innerCircleRadius = 0,
|
|
11129
|
-
outerCircleRadius = "auto",
|
|
11130
|
-
...props
|
|
11131
|
-
}) {
|
|
11132
|
-
const gl = useThree((state) => state.gl);
|
|
11133
|
-
const canvas = React.useMemo(() => {
|
|
11134
|
-
const canvas2 = document.createElement("canvas");
|
|
11135
|
-
const context = canvas2.getContext("2d");
|
|
11136
|
-
canvas2.width = width;
|
|
11137
|
-
canvas2.height = size;
|
|
11138
|
-
let gradient;
|
|
11139
|
-
if (type === "linear" /* Linear */) {
|
|
11140
|
-
gradient = context.createLinearGradient(0, 0, 0, size);
|
|
11141
|
-
} else {
|
|
11142
|
-
const canvasCenterX = canvas2.width / 2;
|
|
11143
|
-
const canvasCenterY = canvas2.height / 2;
|
|
11144
|
-
const radius = outerCircleRadius !== "auto" ? Math.abs(Number(outerCircleRadius)) : Math.sqrt(canvasCenterX ** 2 + canvasCenterY ** 2);
|
|
11145
|
-
gradient = context.createRadialGradient(
|
|
11146
|
-
canvasCenterX,
|
|
11147
|
-
canvasCenterY,
|
|
11148
|
-
Math.abs(innerCircleRadius),
|
|
11149
|
-
canvasCenterX,
|
|
11150
|
-
canvasCenterY,
|
|
11151
|
-
radius
|
|
11152
|
-
);
|
|
11153
|
-
}
|
|
11154
|
-
const tempColor = new THREE.Color();
|
|
11155
|
-
let i = stops.length;
|
|
11156
|
-
while (i--) {
|
|
11157
|
-
gradient.addColorStop(stops[i], tempColor.set(colors[i]).getStyle());
|
|
11158
|
-
}
|
|
11159
|
-
context.save();
|
|
11160
|
-
context.fillStyle = gradient;
|
|
11161
|
-
context.fillRect(0, 0, width, size);
|
|
11162
|
-
context.restore();
|
|
11163
|
-
return canvas2;
|
|
11164
|
-
}, [stops]);
|
|
11165
|
-
return /* @__PURE__ */ React.createElement("canvasTexture", { colorSpace: gl.outputColorSpace, args: [canvas], attach: "map", ...props });
|
|
11166
|
-
}
|
|
11167
|
-
|
|
11168
|
-
const ImageMaterialImpl = /* @__PURE__ */ shaderMaterial(
|
|
11169
|
-
{
|
|
11170
|
-
color: /* @__PURE__ */ new THREE.Color("white"),
|
|
11171
|
-
scale: /* @__PURE__ */ new THREE.Vector2(1, 1),
|
|
11172
|
-
imageBounds: /* @__PURE__ */ new THREE.Vector2(1, 1),
|
|
11173
|
-
resolution: 1024,
|
|
11174
|
-
map: null,
|
|
11175
|
-
zoom: 1,
|
|
11176
|
-
radius: 0,
|
|
11177
|
-
grayscale: 0,
|
|
11178
|
-
opacity: 1
|
|
11399
|
+
const WireframeMaterialShaders = {
|
|
11400
|
+
uniforms: {
|
|
11401
|
+
strokeOpacity: 1,
|
|
11402
|
+
fillOpacity: 0.25,
|
|
11403
|
+
fillMix: 0,
|
|
11404
|
+
thickness: 0.05,
|
|
11405
|
+
colorBackfaces: false,
|
|
11406
|
+
dashInvert: true,
|
|
11407
|
+
dash: false,
|
|
11408
|
+
dashRepeats: 4,
|
|
11409
|
+
dashLength: 0.5,
|
|
11410
|
+
squeeze: false,
|
|
11411
|
+
squeezeMin: 0.2,
|
|
11412
|
+
squeezeMax: 1,
|
|
11413
|
+
stroke: /* @__PURE__ */ new THREE.Color("#ff0000"),
|
|
11414
|
+
backfaceStroke: /* @__PURE__ */ new THREE.Color("#0000ff"),
|
|
11415
|
+
fill: /* @__PURE__ */ new THREE.Color("#00ff00")
|
|
11179
11416
|
},
|
|
11180
|
-
|
|
11181
|
-
|
|
11417
|
+
vertex: (
|
|
11418
|
+
/* glsl */
|
|
11419
|
+
`
|
|
11420
|
+
attribute vec3 barycentric;
|
|
11421
|
+
|
|
11422
|
+
varying vec3 v_edges_Barycentric;
|
|
11423
|
+
varying vec3 v_edges_Position;
|
|
11424
|
+
|
|
11425
|
+
void initWireframe() {
|
|
11426
|
+
v_edges_Barycentric = barycentric;
|
|
11427
|
+
v_edges_Position = position.xyz;
|
|
11428
|
+
}
|
|
11429
|
+
`
|
|
11430
|
+
),
|
|
11431
|
+
fragment: (
|
|
11432
|
+
/* glsl */
|
|
11433
|
+
`
|
|
11434
|
+
#ifndef PI
|
|
11435
|
+
#define PI 3.1415926535897932384626433832795
|
|
11436
|
+
#endif
|
|
11437
|
+
|
|
11438
|
+
varying vec3 v_edges_Barycentric;
|
|
11439
|
+
varying vec3 v_edges_Position;
|
|
11440
|
+
|
|
11441
|
+
uniform float strokeOpacity;
|
|
11442
|
+
uniform float fillOpacity;
|
|
11443
|
+
uniform float fillMix;
|
|
11444
|
+
uniform float thickness;
|
|
11445
|
+
uniform bool colorBackfaces;
|
|
11446
|
+
|
|
11447
|
+
// Dash
|
|
11448
|
+
uniform bool dashInvert;
|
|
11449
|
+
uniform bool dash;
|
|
11450
|
+
uniform bool dashOnly;
|
|
11451
|
+
uniform float dashRepeats;
|
|
11452
|
+
uniform float dashLength;
|
|
11453
|
+
|
|
11454
|
+
// Squeeze
|
|
11455
|
+
uniform bool squeeze;
|
|
11456
|
+
uniform float squeezeMin;
|
|
11457
|
+
uniform float squeezeMax;
|
|
11458
|
+
|
|
11459
|
+
// Colors
|
|
11460
|
+
uniform vec3 stroke;
|
|
11461
|
+
uniform vec3 backfaceStroke;
|
|
11462
|
+
uniform vec3 fill;
|
|
11463
|
+
|
|
11464
|
+
// This is like
|
|
11465
|
+
float wireframe_aastep(float threshold, float dist) {
|
|
11466
|
+
float afwidth = fwidth(dist) * 0.5;
|
|
11467
|
+
return smoothstep(threshold - afwidth, threshold + afwidth, dist);
|
|
11468
|
+
}
|
|
11469
|
+
|
|
11470
|
+
float wireframe_map(float value, float min1, float max1, float min2, float max2) {
|
|
11471
|
+
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
|
|
11472
|
+
}
|
|
11473
|
+
|
|
11474
|
+
float getWireframe() {
|
|
11475
|
+
vec3 barycentric = v_edges_Barycentric;
|
|
11476
|
+
|
|
11477
|
+
// Distance from center of each triangle to its edges.
|
|
11478
|
+
float d = min(min(barycentric.x, barycentric.y), barycentric.z);
|
|
11479
|
+
|
|
11480
|
+
// for dashed rendering, we can use this to get the 0 .. 1 value of the line length
|
|
11481
|
+
float positionAlong = max(barycentric.x, barycentric.y);
|
|
11482
|
+
if (barycentric.y < barycentric.x && barycentric.y < barycentric.z) {
|
|
11483
|
+
positionAlong = 1.0 - positionAlong;
|
|
11484
|
+
}
|
|
11485
|
+
|
|
11486
|
+
// the thickness of the stroke
|
|
11487
|
+
float computedThickness = wireframe_map(thickness, 0.0, 1.0, 0.0, 0.34);
|
|
11488
|
+
|
|
11489
|
+
// if we want to shrink the thickness toward the center of the line segment
|
|
11490
|
+
if (squeeze) {
|
|
11491
|
+
computedThickness *= mix(squeezeMin, squeezeMax, (1.0 - sin(positionAlong * PI)));
|
|
11492
|
+
}
|
|
11493
|
+
|
|
11494
|
+
// Create dash pattern
|
|
11495
|
+
if (dash) {
|
|
11496
|
+
// here we offset the stroke position depending on whether it
|
|
11497
|
+
// should overlap or not
|
|
11498
|
+
float offset = 1.0 / dashRepeats * dashLength / 2.0;
|
|
11499
|
+
if (!dashInvert) {
|
|
11500
|
+
offset += 1.0 / dashRepeats / 2.0;
|
|
11501
|
+
}
|
|
11502
|
+
|
|
11503
|
+
// if we should animate the dash or not
|
|
11504
|
+
// if (dashAnimate) {
|
|
11505
|
+
// offset += time * 0.22;
|
|
11506
|
+
// }
|
|
11507
|
+
|
|
11508
|
+
// create the repeating dash pattern
|
|
11509
|
+
float pattern = fract((positionAlong + offset) * dashRepeats);
|
|
11510
|
+
computedThickness *= 1.0 - wireframe_aastep(dashLength, pattern);
|
|
11511
|
+
}
|
|
11512
|
+
|
|
11513
|
+
// compute the anti-aliased stroke edge
|
|
11514
|
+
float edge = 1.0 - wireframe_aastep(computedThickness, d);
|
|
11515
|
+
|
|
11516
|
+
return edge;
|
|
11517
|
+
}
|
|
11518
|
+
`
|
|
11519
|
+
)
|
|
11520
|
+
};
|
|
11521
|
+
const WireframeMaterial = /* @__PURE__ */ shaderMaterial(
|
|
11522
|
+
WireframeMaterialShaders.uniforms,
|
|
11523
|
+
WireframeMaterialShaders.vertex + /* glsl */
|
|
11524
|
+
`
|
|
11525
|
+
void main() {
|
|
11526
|
+
initWireframe();
|
|
11527
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
11528
|
+
}
|
|
11529
|
+
`,
|
|
11530
|
+
WireframeMaterialShaders.fragment + /* glsl */
|
|
11531
|
+
`
|
|
11532
|
+
void main () {
|
|
11533
|
+
// Compute color
|
|
11534
|
+
|
|
11535
|
+
float edge = getWireframe();
|
|
11536
|
+
vec4 colorStroke = vec4(stroke, edge);
|
|
11537
|
+
|
|
11538
|
+
#ifdef FLIP_SIDED
|
|
11539
|
+
colorStroke.rgb = backfaceStroke;
|
|
11540
|
+
#endif
|
|
11541
|
+
|
|
11542
|
+
vec4 colorFill = vec4(fill, fillOpacity);
|
|
11543
|
+
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
11544
|
+
|
|
11545
|
+
gl_FragColor = outColor;
|
|
11546
|
+
}
|
|
11547
|
+
`
|
|
11548
|
+
);
|
|
11549
|
+
function setWireframeOverride(material, uniforms) {
|
|
11550
|
+
material.onBeforeCompile = (shader) => {
|
|
11551
|
+
shader.uniforms = {
|
|
11552
|
+
...shader.uniforms,
|
|
11553
|
+
...uniforms
|
|
11554
|
+
};
|
|
11555
|
+
shader.vertexShader = shader.vertexShader.replace(
|
|
11556
|
+
"void main() {",
|
|
11557
|
+
`
|
|
11558
|
+
${WireframeMaterialShaders.vertex}
|
|
11559
|
+
void main() {
|
|
11560
|
+
initWireframe();
|
|
11561
|
+
`
|
|
11562
|
+
);
|
|
11563
|
+
shader.fragmentShader = shader.fragmentShader.replace(
|
|
11564
|
+
"void main() {",
|
|
11565
|
+
`
|
|
11566
|
+
${WireframeMaterialShaders.fragment}
|
|
11567
|
+
void main() {
|
|
11568
|
+
`
|
|
11569
|
+
);
|
|
11570
|
+
shader.fragmentShader = shader.fragmentShader.replace(
|
|
11571
|
+
"#include <color_fragment>",
|
|
11572
|
+
/* glsl */
|
|
11573
|
+
`
|
|
11574
|
+
#include <color_fragment>
|
|
11575
|
+
float edge = getWireframe();
|
|
11576
|
+
vec4 colorStroke = vec4(stroke, edge);
|
|
11577
|
+
#ifdef FLIP_SIDED
|
|
11578
|
+
colorStroke.rgb = backfaceStroke;
|
|
11579
|
+
#endif
|
|
11580
|
+
vec4 colorFill = vec4(mix(diffuseColor.rgb, fill, fillMix), mix(diffuseColor.a, fillOpacity, fillMix));
|
|
11581
|
+
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
11582
|
+
|
|
11583
|
+
diffuseColor.rgb = outColor.rgb;
|
|
11584
|
+
diffuseColor.a *= outColor.a;
|
|
11585
|
+
`
|
|
11586
|
+
);
|
|
11587
|
+
};
|
|
11588
|
+
material.side = THREE.DoubleSide;
|
|
11589
|
+
material.transparent = true;
|
|
11590
|
+
}
|
|
11591
|
+
function useWireframeUniforms(uniforms, props) {
|
|
11592
|
+
React.useEffect(
|
|
11593
|
+
() => void (uniforms.fillOpacity.value = props.fillOpacity ?? uniforms.fillOpacity.value),
|
|
11594
|
+
[props.fillOpacity]
|
|
11595
|
+
);
|
|
11596
|
+
React.useEffect(() => void (uniforms.fillMix.value = props.fillMix ?? uniforms.fillMix.value), [props.fillMix]);
|
|
11597
|
+
React.useEffect(
|
|
11598
|
+
() => void (uniforms.strokeOpacity.value = props.strokeOpacity ?? uniforms.strokeOpacity.value),
|
|
11599
|
+
[props.strokeOpacity]
|
|
11600
|
+
);
|
|
11601
|
+
React.useEffect(
|
|
11602
|
+
() => void (uniforms.thickness.value = props.thickness ?? uniforms.thickness.value),
|
|
11603
|
+
[props.thickness]
|
|
11604
|
+
);
|
|
11605
|
+
React.useEffect(() => void (uniforms.colorBackfaces.value = !!props.colorBackfaces), [props.colorBackfaces]);
|
|
11606
|
+
React.useEffect(() => void (uniforms.dash.value = !!props.dash), [props.dash]);
|
|
11607
|
+
React.useEffect(() => void (uniforms.dashInvert.value = !!props.dashInvert), [props.dashInvert]);
|
|
11608
|
+
React.useEffect(
|
|
11609
|
+
() => void (uniforms.dashRepeats.value = props.dashRepeats ?? uniforms.dashRepeats.value),
|
|
11610
|
+
[props.dashRepeats]
|
|
11611
|
+
);
|
|
11612
|
+
React.useEffect(
|
|
11613
|
+
() => void (uniforms.dashLength.value = props.dashLength ?? uniforms.dashLength.value),
|
|
11614
|
+
[props.dashLength]
|
|
11615
|
+
);
|
|
11616
|
+
React.useEffect(() => void (uniforms.squeeze.value = !!props.squeeze), [props.squeeze]);
|
|
11617
|
+
React.useEffect(
|
|
11618
|
+
() => void (uniforms.squeezeMin.value = props.squeezeMin ?? uniforms.squeezeMin.value),
|
|
11619
|
+
[props.squeezeMin]
|
|
11620
|
+
);
|
|
11621
|
+
React.useEffect(
|
|
11622
|
+
() => void (uniforms.squeezeMax.value = props.squeezeMax ?? uniforms.squeezeMax.value),
|
|
11623
|
+
[props.squeezeMax]
|
|
11624
|
+
);
|
|
11625
|
+
React.useEffect(
|
|
11626
|
+
() => void (uniforms.stroke.value = props.stroke ? new THREE.Color(props.stroke) : uniforms.stroke.value),
|
|
11627
|
+
[props.stroke]
|
|
11628
|
+
);
|
|
11629
|
+
React.useEffect(
|
|
11630
|
+
() => void (uniforms.fill.value = props.fill ? new THREE.Color(props.fill) : uniforms.fill.value),
|
|
11631
|
+
[props.fill]
|
|
11632
|
+
);
|
|
11633
|
+
React.useEffect(
|
|
11634
|
+
() => void (uniforms.backfaceStroke.value = props.backfaceStroke ? new THREE.Color(props.backfaceStroke) : uniforms.backfaceStroke.value),
|
|
11635
|
+
[props.backfaceStroke]
|
|
11636
|
+
);
|
|
11637
|
+
}
|
|
11638
|
+
|
|
11639
|
+
function isWithGeometry(object) {
|
|
11640
|
+
return !!object?.geometry;
|
|
11641
|
+
}
|
|
11642
|
+
function isGeometry(object) {
|
|
11643
|
+
return !!object?.isBufferGeometry;
|
|
11644
|
+
}
|
|
11645
|
+
function isRefObject(object) {
|
|
11646
|
+
return !!object?.current;
|
|
11647
|
+
}
|
|
11648
|
+
function isRef(object) {
|
|
11649
|
+
return object?.current !== void 0;
|
|
11650
|
+
}
|
|
11651
|
+
function isWireframeGeometry(geometry) {
|
|
11652
|
+
return geometry.type === "WireframeGeometry";
|
|
11653
|
+
}
|
|
11654
|
+
function getUniforms() {
|
|
11655
|
+
const u = {};
|
|
11656
|
+
for (const key in WireframeMaterialShaders.uniforms) {
|
|
11657
|
+
u[key] = { value: WireframeMaterialShaders.uniforms[key] };
|
|
11658
|
+
}
|
|
11659
|
+
return u;
|
|
11660
|
+
}
|
|
11661
|
+
function getBarycentricCoordinates(geometry, removeEdge) {
|
|
11662
|
+
const position = geometry.getAttribute("position");
|
|
11663
|
+
const count = position.count;
|
|
11664
|
+
const barycentric = [];
|
|
11665
|
+
for (let i = 0; i < count; i++) {
|
|
11666
|
+
const even = i % 2 === 0;
|
|
11667
|
+
const Q = removeEdge ? 1 : 0;
|
|
11668
|
+
if (even) {
|
|
11669
|
+
barycentric.push(0, 0, 1, 0, 1, 0, 1, 0, Q);
|
|
11670
|
+
} else {
|
|
11671
|
+
barycentric.push(0, 1, 0, 0, 0, 1, 1, 0, Q);
|
|
11672
|
+
}
|
|
11673
|
+
}
|
|
11674
|
+
return new THREE.BufferAttribute(Float32Array.from(barycentric), 3);
|
|
11675
|
+
}
|
|
11676
|
+
function getInputGeometry(inputGeometry) {
|
|
11677
|
+
const geo = isRefObject(inputGeometry) ? inputGeometry.current : inputGeometry;
|
|
11678
|
+
if (!isGeometry(geo)) {
|
|
11679
|
+
if (isWireframeGeometry(geo)) {
|
|
11680
|
+
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
11681
|
+
}
|
|
11682
|
+
const parent = geo.parent;
|
|
11683
|
+
if (isWithGeometry(parent)) {
|
|
11684
|
+
if (isWireframeGeometry(parent.geometry)) {
|
|
11685
|
+
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
11686
|
+
}
|
|
11687
|
+
return parent.geometry;
|
|
11688
|
+
}
|
|
11689
|
+
} else {
|
|
11690
|
+
return geo;
|
|
11691
|
+
}
|
|
11692
|
+
}
|
|
11693
|
+
function setBarycentricCoordinates(geometry, simplify) {
|
|
11694
|
+
if (geometry.index) {
|
|
11695
|
+
console.warn("Wireframe: Requires non-indexed geometry, converting to non-indexed geometry.");
|
|
11696
|
+
const nonIndexedGeo = geometry.toNonIndexed();
|
|
11697
|
+
geometry.copy(nonIndexedGeo);
|
|
11698
|
+
geometry.setIndex(null);
|
|
11699
|
+
}
|
|
11700
|
+
const newBarycentric = getBarycentricCoordinates(geometry, simplify);
|
|
11701
|
+
geometry.setAttribute("barycentric", newBarycentric);
|
|
11702
|
+
}
|
|
11703
|
+
function WireframeWithCustomGeo({
|
|
11704
|
+
geometry: customGeometry,
|
|
11705
|
+
simplify = false,
|
|
11706
|
+
...props
|
|
11707
|
+
}) {
|
|
11708
|
+
extend({ MeshWireframeMaterial: WireframeMaterial });
|
|
11709
|
+
const [geometry, setGeometry] = React.useState(null);
|
|
11710
|
+
React.useLayoutEffect(() => {
|
|
11711
|
+
const geom = getInputGeometry(customGeometry);
|
|
11712
|
+
if (!geom) {
|
|
11713
|
+
throw new Error("Wireframe: geometry prop must be a BufferGeometry or a ref to a BufferGeometry.");
|
|
11714
|
+
}
|
|
11715
|
+
setBarycentricCoordinates(geom, simplify);
|
|
11716
|
+
if (isRef(customGeometry)) {
|
|
11717
|
+
setGeometry(geom);
|
|
11718
|
+
}
|
|
11719
|
+
}, [simplify, customGeometry]);
|
|
11720
|
+
const drawnGeo = isRef(customGeometry) ? geometry : customGeometry;
|
|
11721
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, drawnGeo && /* @__PURE__ */ React.createElement("mesh", { geometry: drawnGeo }, /* @__PURE__ */ React.createElement(
|
|
11722
|
+
"meshWireframeMaterial",
|
|
11723
|
+
{
|
|
11724
|
+
attach: "material",
|
|
11725
|
+
transparent: true,
|
|
11726
|
+
side: THREE.DoubleSide,
|
|
11727
|
+
polygonOffset: true,
|
|
11728
|
+
polygonOffsetFactor: -4,
|
|
11729
|
+
...props
|
|
11730
|
+
}
|
|
11731
|
+
)));
|
|
11732
|
+
}
|
|
11733
|
+
function WireframeWithoutCustomGeo({
|
|
11734
|
+
simplify = false,
|
|
11735
|
+
...props
|
|
11736
|
+
}) {
|
|
11737
|
+
const objectRef = React.useRef(null);
|
|
11738
|
+
const uniforms = React.useMemo(() => getUniforms(), [WireframeMaterialShaders.uniforms]);
|
|
11739
|
+
useWireframeUniforms(uniforms, props);
|
|
11740
|
+
React.useLayoutEffect(() => {
|
|
11741
|
+
const geom = getInputGeometry(objectRef);
|
|
11742
|
+
if (!geom) {
|
|
11743
|
+
throw new Error("Wireframe: Must be a child of a Mesh, Line or Points object or specify a geometry prop.");
|
|
11744
|
+
}
|
|
11745
|
+
const og = geom.clone();
|
|
11746
|
+
setBarycentricCoordinates(geom, simplify);
|
|
11747
|
+
return () => {
|
|
11748
|
+
geom.copy(og);
|
|
11749
|
+
og.dispose();
|
|
11750
|
+
};
|
|
11751
|
+
}, [simplify]);
|
|
11752
|
+
React.useLayoutEffect(() => {
|
|
11753
|
+
const parentMesh = objectRef.current.parent;
|
|
11754
|
+
const og = parentMesh.material.clone();
|
|
11755
|
+
setWireframeOverride(parentMesh.material, uniforms);
|
|
11756
|
+
return () => {
|
|
11757
|
+
parentMesh.material.dispose();
|
|
11758
|
+
parentMesh.material = og;
|
|
11759
|
+
};
|
|
11760
|
+
}, []);
|
|
11761
|
+
return /* @__PURE__ */ React.createElement("object3D", { ref: objectRef });
|
|
11762
|
+
}
|
|
11763
|
+
function Wireframe({ geometry: customGeometry, ...props }) {
|
|
11764
|
+
if (customGeometry) {
|
|
11765
|
+
return /* @__PURE__ */ React.createElement(WireframeWithCustomGeo, { geometry: customGeometry, ...props });
|
|
11766
|
+
}
|
|
11767
|
+
return /* @__PURE__ */ React.createElement(WireframeWithoutCustomGeo, { ...props });
|
|
11768
|
+
}
|
|
11769
|
+
|
|
11770
|
+
function BakeShadows() {
|
|
11771
|
+
const gl = useThree((state) => state.gl);
|
|
11772
|
+
useEffect(() => {
|
|
11773
|
+
gl.shadowMap.autoUpdate = false;
|
|
11774
|
+
gl.shadowMap.needsUpdate = true;
|
|
11775
|
+
return () => {
|
|
11776
|
+
gl.shadowMap.autoUpdate = gl.shadowMap.needsUpdate = true;
|
|
11777
|
+
};
|
|
11778
|
+
}, [gl.shadowMap]);
|
|
11779
|
+
return null;
|
|
11780
|
+
}
|
|
11781
|
+
|
|
11782
|
+
var GradientType = /* @__PURE__ */ ((GradientType2) => {
|
|
11783
|
+
GradientType2["Linear"] = "linear";
|
|
11784
|
+
GradientType2["Radial"] = "radial";
|
|
11785
|
+
return GradientType2;
|
|
11786
|
+
})(GradientType || {});
|
|
11787
|
+
function GradientTexture({
|
|
11788
|
+
stops,
|
|
11789
|
+
colors,
|
|
11790
|
+
size = 1024,
|
|
11791
|
+
width = 16,
|
|
11792
|
+
type = "linear" /* Linear */,
|
|
11793
|
+
innerCircleRadius = 0,
|
|
11794
|
+
outerCircleRadius = "auto",
|
|
11795
|
+
...props
|
|
11796
|
+
}) {
|
|
11797
|
+
const gl = useThree((state) => state.gl);
|
|
11798
|
+
const canvas = React.useMemo(() => {
|
|
11799
|
+
const canvas2 = document.createElement("canvas");
|
|
11800
|
+
const context = canvas2.getContext("2d");
|
|
11801
|
+
canvas2.width = width;
|
|
11802
|
+
canvas2.height = size;
|
|
11803
|
+
let gradient;
|
|
11804
|
+
if (type === "linear" /* Linear */) {
|
|
11805
|
+
gradient = context.createLinearGradient(0, 0, 0, size);
|
|
11806
|
+
} else {
|
|
11807
|
+
const canvasCenterX = canvas2.width / 2;
|
|
11808
|
+
const canvasCenterY = canvas2.height / 2;
|
|
11809
|
+
const radius = outerCircleRadius !== "auto" ? Math.abs(Number(outerCircleRadius)) : Math.sqrt(canvasCenterX ** 2 + canvasCenterY ** 2);
|
|
11810
|
+
gradient = context.createRadialGradient(
|
|
11811
|
+
canvasCenterX,
|
|
11812
|
+
canvasCenterY,
|
|
11813
|
+
Math.abs(innerCircleRadius),
|
|
11814
|
+
canvasCenterX,
|
|
11815
|
+
canvasCenterY,
|
|
11816
|
+
radius
|
|
11817
|
+
);
|
|
11818
|
+
}
|
|
11819
|
+
const tempColor = new THREE.Color();
|
|
11820
|
+
let i = stops.length;
|
|
11821
|
+
while (i--) {
|
|
11822
|
+
gradient.addColorStop(stops[i], tempColor.set(colors[i]).getStyle());
|
|
11823
|
+
}
|
|
11824
|
+
context.save();
|
|
11825
|
+
context.fillStyle = gradient;
|
|
11826
|
+
context.fillRect(0, 0, width, size);
|
|
11827
|
+
context.restore();
|
|
11828
|
+
return canvas2;
|
|
11829
|
+
}, [stops]);
|
|
11830
|
+
return /* @__PURE__ */ React.createElement("canvasTexture", { colorSpace: gl.outputColorSpace, args: [canvas], attach: "map", ...props });
|
|
11831
|
+
}
|
|
11832
|
+
|
|
11833
|
+
const ImageMaterialImpl = /* @__PURE__ */ shaderMaterial(
|
|
11834
|
+
{
|
|
11835
|
+
color: /* @__PURE__ */ new THREE.Color("white"),
|
|
11836
|
+
scale: /* @__PURE__ */ new THREE.Vector2(1, 1),
|
|
11837
|
+
imageBounds: /* @__PURE__ */ new THREE.Vector2(1, 1),
|
|
11838
|
+
resolution: 1024,
|
|
11839
|
+
map: null,
|
|
11840
|
+
zoom: 1,
|
|
11841
|
+
radius: 0,
|
|
11842
|
+
grayscale: 0,
|
|
11843
|
+
opacity: 1
|
|
11844
|
+
},
|
|
11845
|
+
/* glsl */
|
|
11846
|
+
`
|
|
11182
11847
|
varying vec2 vUv;
|
|
11183
11848
|
varying vec2 vPos;
|
|
11184
11849
|
void main() {
|
|
@@ -11347,8 +12012,8 @@ vec3 highPassRandRGB(vec2 uv) {
|
|
|
11347
12012
|
|
|
11348
12013
|
|
|
11349
12014
|
vec2 vogelDiskSample(int sampleIndex, int sampleCount, float angle) {
|
|
11350
|
-
|
|
11351
|
-
float r = sqrt(float(sampleIndex) + 0.
|
|
12015
|
+
float goldenAngle = 2.399963;
|
|
12016
|
+
float r = sqrt(float(sampleIndex) + 0.5) / sqrt(float(sampleCount));
|
|
11352
12017
|
float theta = float(sampleIndex) * goldenAngle + angle;
|
|
11353
12018
|
float sine = sin(theta);
|
|
11354
12019
|
float cosine = cos(theta);
|
|
@@ -11369,7 +12034,7 @@ float findBlocker(sampler2D shadowMap, vec2 uv, float compare, float angle) {
|
|
|
11369
12034
|
#pragma unroll_loop_start
|
|
11370
12035
|
for(int i = 0; i < ${samples}; i ++) {
|
|
11371
12036
|
offset = (vogelDiskSample(j, ${samples}, angle) * texelSize) * 2.0 * PENUMBRA_FILTER_SIZE;
|
|
11372
|
-
depth =
|
|
12037
|
+
depth = texture2D( shadowMap, uv + offset ).r;
|
|
11373
12038
|
if (depth < compare) {
|
|
11374
12039
|
blockerDepthSum += depth;
|
|
11375
12040
|
blockers++;
|
|
@@ -11387,7 +12052,7 @@ float findBlocker(sampler2D shadowMap, vec2 uv, float compare, float angle) {
|
|
|
11387
12052
|
|
|
11388
12053
|
float vogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRadius, float angle) {
|
|
11389
12054
|
float texelSize = 1.0 / float(textureSize(shadowMap, 0).x);
|
|
11390
|
-
float shadow = 0.
|
|
12055
|
+
float shadow = 0.0;
|
|
11391
12056
|
int j = 0;
|
|
11392
12057
|
vec2 vogelSample = vec2(0.0);
|
|
11393
12058
|
vec2 offset = vec2(0.0);
|
|
@@ -11395,7 +12060,7 @@ float vogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRad
|
|
|
11395
12060
|
for (int i = 0; i < ${samples}; i++) {
|
|
11396
12061
|
vogelSample = vogelDiskSample(j, ${samples}, angle) * texelSize;
|
|
11397
12062
|
offset = vogelSample * (1.0 + filterRadius * float(${size}));
|
|
11398
|
-
shadow += step( zReceiver,
|
|
12063
|
+
shadow += step( zReceiver, texture2D( shadowMap, uv + offset ).r );
|
|
11399
12064
|
j++;
|
|
11400
12065
|
}
|
|
11401
12066
|
#pragma unroll_loop_end
|
|
@@ -11404,7 +12069,7 @@ float vogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRad
|
|
|
11404
12069
|
|
|
11405
12070
|
float PCSS (sampler2D shadowMap, vec4 coords) {
|
|
11406
12071
|
vec2 uv = coords.xy;
|
|
11407
|
-
float zReceiver = coords.z;
|
|
12072
|
+
float zReceiver = coords.z;
|
|
11408
12073
|
float angle = highPassRandRGB(gl_FragCoord.xy).r * PI2;
|
|
11409
12074
|
float avgBlockerDepth = findBlocker(shadowMap, uv, zReceiver, angle);
|
|
11410
12075
|
if (avgBlockerDepth == -1.0) {
|
|
@@ -11428,14 +12093,27 @@ function SoftShadows({ focus = 0, samples = 10, size = 25 }) {
|
|
|
11428
12093
|
const scene = useThree((state) => state.scene);
|
|
11429
12094
|
const camera = useThree((state) => state.camera);
|
|
11430
12095
|
React.useEffect(() => {
|
|
11431
|
-
const
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11435
|
-
);
|
|
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;
|
|
11436
12113
|
reset(gl, scene, camera);
|
|
11437
12114
|
return () => {
|
|
11438
|
-
THREE.ShaderChunk.shadowmap_pars_fragment =
|
|
12115
|
+
THREE.ShaderChunk.shadowmap_pars_fragment = originalShader;
|
|
12116
|
+
gl.shadowMap.type = originalShadowMapType;
|
|
11439
12117
|
reset(gl, scene, camera);
|
|
11440
12118
|
};
|
|
11441
12119
|
}, [focus, size, samples]);
|
|
@@ -11541,6 +12219,60 @@ class SpotLightMaterial extends THREE.ShaderMaterial {
|
|
|
11541
12219
|
}
|
|
11542
12220
|
}
|
|
11543
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
|
+
|
|
11544
12276
|
class StarfieldMaterial extends ShaderMaterial {
|
|
11545
12277
|
constructor() {
|
|
11546
12278
|
super({
|
|
@@ -11615,8 +12347,8 @@ class SparklesMaterial extends ShaderMaterial {
|
|
|
11615
12347
|
modelPosition.z += cos(time * speed + modelPosition.x * noise.y * 100.0) * 0.2;
|
|
11616
12348
|
modelPosition.x += cos(time * speed + modelPosition.x * noise.z * 100.0) * 0.2;
|
|
11617
12349
|
vec4 viewPosition = viewMatrix * modelPosition;
|
|
11618
|
-
vec4
|
|
11619
|
-
gl_Position =
|
|
12350
|
+
vec4 projectionPosition = projectionMatrix * viewPosition;
|
|
12351
|
+
gl_Position = projectionPosition;
|
|
11620
12352
|
gl_PointSize = size * 25. * pixelRatio;
|
|
11621
12353
|
gl_PointSize *= (1.0 / - viewPosition.z);
|
|
11622
12354
|
vColor = color;
|
|
@@ -11631,8 +12363,9 @@ class SparklesMaterial extends ShaderMaterial {
|
|
|
11631
12363
|
varying float vOpacity;
|
|
11632
12364
|
void main() {
|
|
11633
12365
|
float distanceToCenter = distance(gl_PointCoord, vec2(0.5));
|
|
11634
|
-
float strength = 0.05 / distanceToCenter - 0.1;
|
|
12366
|
+
float strength = clamp(0.05 / distanceToCenter - 0.1, 0.0, 1.0);
|
|
11635
12367
|
gl_FragColor = vec4(vColor, strength * vOpacity);
|
|
12368
|
+
// Note: tonemapping may shift hue (e.g. orange \u2192 yellow) compared to the WebGPU version
|
|
11636
12369
|
#include <tonemapping_fragment>
|
|
11637
12370
|
#include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
|
|
11638
12371
|
}
|
|
@@ -12322,4 +13055,4 @@ const Text = /* @__PURE__ */ React.forwardRef(
|
|
|
12322
13055
|
}
|
|
12323
13056
|
);
|
|
12324
13057
|
|
|
12325
|
-
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 };
|