@react-three/drei 11.0.0-alpha.3 → 11.0.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/index.d.mts +76 -78
- package/core/index.d.ts +76 -78
- package/core/index.mjs +414 -490
- package/experimental/index.d.mts +8 -8
- package/experimental/index.d.ts +8 -8
- package/experimental/index.mjs +3 -2
- package/external/index.d.mts +7 -7
- package/external/index.d.ts +7 -7
- package/external/index.mjs +1 -0
- package/index.d.mts +77 -79
- package/index.d.ts +77 -79
- package/index.mjs +415 -491
- package/legacy/index.d.mts +152 -105
- package/legacy/index.d.ts +152 -105
- package/legacy/index.mjs +1290 -985
- package/native/index.d.mts +185 -378
- package/native/index.d.ts +185 -378
- package/native/index.mjs +1244 -2440
- package/package.json +2 -3
- package/webgpu/index.d.mts +187 -223
- package/webgpu/index.d.ts +187 -223
- package/webgpu/index.mjs +1244 -1803
package/legacy/index.mjs
CHANGED
|
@@ -2,11 +2,10 @@ 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, DoubleSide, OrthographicCamera as OrthographicCamera$1, AudioListener, AudioLoader, AnimationMixer, Box3, Sphere as Sphere$1, InstancedBufferAttribute, 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
7
|
import { useGesture } from '@use-gesture/react';
|
|
9
|
-
import { FirstPersonControls as FirstPersonControls$1 } from 'three/examples/jsm/controls/FirstPersonControls';
|
|
8
|
+
import { FirstPersonControls as FirstPersonControls$1 } from 'three/examples/jsm/controls/FirstPersonControls.js';
|
|
10
9
|
import { FlyControls as FlyControls$1 } from 'three/examples/jsm/controls/FlyControls.js';
|
|
11
10
|
import { create as create$1 } from 'zustand';
|
|
12
11
|
import { subscribeWithSelector } from 'zustand/middleware';
|
|
@@ -22,44 +21,43 @@ import { LineSegments2 } from 'three/examples/jsm/lines/LineSegments2.js';
|
|
|
22
21
|
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js';
|
|
23
22
|
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js';
|
|
24
23
|
import { LineSegmentsGeometry } from 'three/examples/jsm/lines/LineSegmentsGeometry.js';
|
|
25
|
-
import { Flow } from 'three/examples/jsm/modifiers/CurveModifier';
|
|
24
|
+
import { Flow } from 'three/examples/jsm/modifiers/CurveModifier.js';
|
|
26
25
|
import { DecalGeometry } from 'three/examples/jsm/geometries/DecalGeometry.js';
|
|
27
|
-
import { toCreasedNormals, mergeVertices } from 'three/examples/jsm/utils/BufferGeometryUtils';
|
|
28
|
-
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
|
|
29
|
-
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';
|
|
26
|
+
import { toCreasedNormals, mergeVertices } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
|
|
27
|
+
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';
|
|
28
|
+
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js';
|
|
30
29
|
import { suspend, preload, clear as clear$1 } from 'suspend-react';
|
|
31
|
-
import { TransformControls as TransformControls$1 } from 'three/examples/jsm/controls/TransformControls';
|
|
32
|
-
import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils';
|
|
30
|
+
import { TransformControls as TransformControls$1 } from 'three/examples/jsm/controls/TransformControls.js';
|
|
31
|
+
import * as SkeletonUtils from 'three/examples/jsm/utils/SkeletonUtils.js';
|
|
33
32
|
import { MeshSurfaceSampler } from 'three/examples/jsm/math/MeshSurfaceSampler.js';
|
|
34
|
-
import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader';
|
|
33
|
+
import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader.js';
|
|
35
34
|
import { Events } from 'hls.js';
|
|
36
|
-
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
|
|
37
|
-
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
38
|
-
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
|
|
35
|
+
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
|
|
36
|
+
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
37
|
+
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
39
38
|
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';
|
|
40
|
-
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader';
|
|
39
|
+
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
|
|
41
40
|
import { getGPUTier } from 'detect-gpu';
|
|
42
41
|
import StatsImpl from 'stats.js';
|
|
43
42
|
import Stats$1 from 'stats-gl';
|
|
44
43
|
import tunnel from 'tunnel-rat';
|
|
45
|
-
import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox';
|
|
46
|
-
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';
|
|
47
|
-
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader';
|
|
44
|
+
import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
|
|
45
|
+
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
|
|
46
|
+
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
|
|
48
47
|
import { HDRJPGLoader, GainMapLoader } from '@monogrid/gainmap-js';
|
|
49
48
|
import { Sky as Sky$1 } from 'three/examples/jsm/objects/Sky.js';
|
|
50
49
|
import { SkyMesh } from 'three/examples/jsm/objects/SkyMesh.js';
|
|
51
|
-
import { HorizontalBlurShader } from 'three/examples/jsm/shaders/HorizontalBlurShader';
|
|
52
|
-
import { VerticalBlurShader } from 'three/examples/jsm/shaders/VerticalBlurShader';
|
|
53
|
-
import { SelectionBox } from 'three/examples/jsm/interactive/SelectionBox';
|
|
50
|
+
import { HorizontalBlurShader } from 'three/examples/jsm/shaders/HorizontalBlurShader.js';
|
|
51
|
+
import { VerticalBlurShader } from 'three/examples/jsm/shaders/VerticalBlurShader.js';
|
|
52
|
+
import { SelectionBox } from 'three/examples/jsm/interactive/SelectionBox.js';
|
|
54
53
|
import { shallow } from 'zustand/shallow';
|
|
55
|
-
import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader';
|
|
56
|
-
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
|
|
57
|
-
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass';
|
|
58
|
-
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
|
|
59
|
-
import { AsciiEffect } from 'three/examples/jsm/effects/AsciiEffect';
|
|
60
|
-
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass';
|
|
54
|
+
import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader.js';
|
|
55
|
+
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
|
|
56
|
+
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
|
|
57
|
+
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
58
|
+
import { AsciiEffect } from 'three/examples/jsm/effects/AsciiEffect.js';
|
|
59
|
+
import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass.js';
|
|
61
60
|
import { shaderStructs, shaderIntersectFunction, MeshBVHUniformStruct } from 'three-mesh-bvh';
|
|
62
|
-
import { FullScreenQuad as FullScreenQuad$1 } from 'three/examples/jsm/postprocessing/Pass.js';
|
|
63
61
|
import { Text as Text$1, preloadFont } from 'troika-three-text';
|
|
64
62
|
|
|
65
63
|
const ContactShadows = /* @__PURE__ */ React.forwardRef(
|
|
@@ -189,6 +187,7 @@ function shaderMaterial(uniforms, vertexShader, fragmentShader, onInit) {
|
|
|
189
187
|
});
|
|
190
188
|
}
|
|
191
189
|
this.uniforms = THREE.UniformsUtils.clone(this.uniforms);
|
|
190
|
+
Object.assign(this, parameters);
|
|
192
191
|
onInit?.(this);
|
|
193
192
|
}
|
|
194
193
|
};
|
|
@@ -1518,6 +1517,7 @@ let MeshReflectorMaterial$1 = class MeshReflectorMaterial extends MeshStandardMa
|
|
|
1518
1517
|
uniform float depthScale;
|
|
1519
1518
|
uniform float depthToBlurRatioBias;
|
|
1520
1519
|
varying vec4 my_vUv;
|
|
1520
|
+
#include <tonemapping_pars_fragment>
|
|
1521
1521
|
${shader.fragmentShader}`;
|
|
1522
1522
|
shader.fragmentShader = shader.fragmentShader.replace(
|
|
1523
1523
|
"#include <emissivemap_fragment>",
|
|
@@ -1578,6 +1578,9 @@ let MeshReflectorMaterial$1 = class MeshReflectorMaterial extends MeshStandardMa
|
|
|
1578
1578
|
merge = mix(merge, blur, blurFactor);
|
|
1579
1579
|
#endif
|
|
1580
1580
|
|
|
1581
|
+
// Apply tone mapping to HDR reflection values before contrast adjustment
|
|
1582
|
+
merge.rgb = toneMapping(merge.rgb);
|
|
1583
|
+
|
|
1581
1584
|
vec4 newMerge = vec4(0.0, 0.0, 0.0, 1.0);
|
|
1582
1585
|
newMerge.r = (merge.r - 0.5) * mixContrast + 0.5;
|
|
1583
1586
|
newMerge.g = (merge.g - 0.5) * mixContrast + 0.5;
|
|
@@ -1836,6 +1839,7 @@ const MeshReflectorMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
1836
1839
|
useFrame(() => {
|
|
1837
1840
|
const parent = materialRef.current.parent || materialRef.current?.__r3f.parent?.object;
|
|
1838
1841
|
if (!parent) return;
|
|
1842
|
+
if (gl.xr.isPresenting) return;
|
|
1839
1843
|
parent.visible = false;
|
|
1840
1844
|
const currentXrEnabled = gl.xr.enabled;
|
|
1841
1845
|
const currentShadowAutoUpdate = gl.shadowMap.autoUpdate;
|
|
@@ -2249,6 +2253,8 @@ const MeshPortalMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
2249
2253
|
children,
|
|
2250
2254
|
events = void 0,
|
|
2251
2255
|
blur = 0,
|
|
2256
|
+
blend = 0,
|
|
2257
|
+
samples = 8,
|
|
2252
2258
|
eventPriority = 0,
|
|
2253
2259
|
renderPriority = 0,
|
|
2254
2260
|
worldUnits = false,
|
|
@@ -2261,7 +2267,7 @@ const MeshPortalMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
2261
2267
|
const maskRenderTarget = useFBO(resolution, resolution);
|
|
2262
2268
|
const [priority, setPriority] = React.useState(0);
|
|
2263
2269
|
useFrame(() => {
|
|
2264
|
-
const p = ref.current.blend > 0 ? Math.max(1, renderPriority) : 0;
|
|
2270
|
+
const p = (ref.current.blend ?? 0) > 0 ? Math.max(1, renderPriority) : 0;
|
|
2265
2271
|
if (priority !== p) setPriority(p);
|
|
2266
2272
|
});
|
|
2267
2273
|
React.useEffect(() => {
|
|
@@ -2335,7 +2341,8 @@ const MeshPortalMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
2335
2341
|
frames: visible ? Infinity : 0,
|
|
2336
2342
|
eventPriority,
|
|
2337
2343
|
renderPriority,
|
|
2338
|
-
compute
|
|
2344
|
+
compute,
|
|
2345
|
+
samples
|
|
2339
2346
|
},
|
|
2340
2347
|
children,
|
|
2341
2348
|
/* @__PURE__ */ React.createElement(
|
|
@@ -2415,7 +2422,7 @@ function ManagePortalScene({
|
|
|
2415
2422
|
scene.matrixWorld.copy(parent.matrixWorld);
|
|
2416
2423
|
} else scene.matrixWorld.identity();
|
|
2417
2424
|
if (priority) {
|
|
2418
|
-
if (material.current?.blend > 0 && material.current?.blend < 1) {
|
|
2425
|
+
if (material.current?.blend && material.current?.blend > 0 && material.current?.blend < 1) {
|
|
2419
2426
|
blend.value = material.current.blend;
|
|
2420
2427
|
state.gl.setRenderTarget(buffer1);
|
|
2421
2428
|
state.gl.render(scene, state.camera);
|
|
@@ -3208,12 +3215,12 @@ const Segments = /* @__PURE__ */ React.forwardRef((props, forwardedRef) => {
|
|
|
3208
3215
|
for (let i = 0; i < limit; i++) {
|
|
3209
3216
|
const segment = segments[i]?.current;
|
|
3210
3217
|
if (segment) {
|
|
3211
|
-
positions[i * 6 + 0] = segment.start
|
|
3212
|
-
positions[i * 6 + 1] = segment.start
|
|
3213
|
-
positions[i * 6 + 2] = segment.start
|
|
3214
|
-
positions[i * 6 + 3] = segment.end
|
|
3215
|
-
positions[i * 6 + 4] = segment.end
|
|
3216
|
-
positions[i * 6 + 5] = segment.end
|
|
3218
|
+
positions[i * 6 + 0] = segment.start?.x || 0;
|
|
3219
|
+
positions[i * 6 + 1] = segment.start?.y || 0;
|
|
3220
|
+
positions[i * 6 + 2] = segment.start?.z || 0;
|
|
3221
|
+
positions[i * 6 + 3] = segment.end?.x || 0;
|
|
3222
|
+
positions[i * 6 + 4] = segment.end?.y || 0;
|
|
3223
|
+
positions[i * 6 + 5] = segment.end?.z || 0;
|
|
3217
3224
|
colors[i * 6 + 0] = segment.color.r;
|
|
3218
3225
|
colors[i * 6 + 1] = segment.color.g;
|
|
3219
3226
|
colors[i * 6 + 2] = segment.color.b;
|
|
@@ -3248,7 +3255,10 @@ class SegmentObject {
|
|
|
3248
3255
|
this.end = new THREE.Vector3(0, 0, 0);
|
|
3249
3256
|
}
|
|
3250
3257
|
}
|
|
3251
|
-
const normPos = (pos) =>
|
|
3258
|
+
const normPos = (pos) => {
|
|
3259
|
+
if (!pos) return new THREE.Vector3(0, 0, 0);
|
|
3260
|
+
return pos instanceof THREE.Vector3 ? pos : new THREE.Vector3(...typeof pos === "number" ? [pos, pos, pos] : pos);
|
|
3261
|
+
};
|
|
3252
3262
|
const Segment = /* @__PURE__ */ React.forwardRef(({ color, start, end }, forwardedRef) => {
|
|
3253
3263
|
const api = React.useContext(context$9);
|
|
3254
3264
|
if (!api) throw "Segment must used inside Segments component.";
|
|
@@ -3570,6 +3580,81 @@ const ArcballControls = /* @__PURE__ */ forwardRef(
|
|
|
3570
3580
|
}
|
|
3571
3581
|
);
|
|
3572
3582
|
|
|
3583
|
+
let DeviceOrientationControls$1 = class DeviceOrientationControls extends EventDispatcher {
|
|
3584
|
+
object;
|
|
3585
|
+
changeEvent = { type: "change" };
|
|
3586
|
+
EPS = 1e-6;
|
|
3587
|
+
enabled = true;
|
|
3588
|
+
deviceOrientation = { alpha: 0, beta: 0, gamma: 0 };
|
|
3589
|
+
screenOrientation = 0;
|
|
3590
|
+
alphaOffset = 0;
|
|
3591
|
+
// radians
|
|
3592
|
+
constructor(object) {
|
|
3593
|
+
super();
|
|
3594
|
+
this.object = object;
|
|
3595
|
+
this.object.rotation.reorder("YXZ");
|
|
3596
|
+
this.connect();
|
|
3597
|
+
}
|
|
3598
|
+
onDeviceOrientationChangeEvent = (event) => {
|
|
3599
|
+
this.deviceOrientation = event;
|
|
3600
|
+
};
|
|
3601
|
+
onScreenOrientationChangeEvent = () => {
|
|
3602
|
+
this.screenOrientation = window.orientation || 0;
|
|
3603
|
+
};
|
|
3604
|
+
// The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''
|
|
3605
|
+
zee = new Vector3(0, 0, 1);
|
|
3606
|
+
euler = new Euler();
|
|
3607
|
+
q0 = new Quaternion();
|
|
3608
|
+
q1 = new Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));
|
|
3609
|
+
// - PI/2 around the x-axis
|
|
3610
|
+
setObjectQuaternion = (quaternion, alpha, beta, gamma, orient) => {
|
|
3611
|
+
this.euler.set(beta, alpha, -gamma, "YXZ");
|
|
3612
|
+
quaternion.setFromEuler(this.euler);
|
|
3613
|
+
quaternion.multiply(this.q1);
|
|
3614
|
+
quaternion.multiply(this.q0.setFromAxisAngle(this.zee, -orient));
|
|
3615
|
+
};
|
|
3616
|
+
connect = () => {
|
|
3617
|
+
this.onScreenOrientationChangeEvent();
|
|
3618
|
+
if (window.DeviceOrientationEvent !== void 0 && // @ts-ignore
|
|
3619
|
+
typeof window.DeviceOrientationEvent.requestPermission === "function") {
|
|
3620
|
+
window.DeviceOrientationEvent.requestPermission().then((response) => {
|
|
3621
|
+
if (response == "granted") {
|
|
3622
|
+
window.addEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
3623
|
+
window.addEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
3624
|
+
}
|
|
3625
|
+
}).catch((error) => {
|
|
3626
|
+
console.error("THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:", error);
|
|
3627
|
+
});
|
|
3628
|
+
} else {
|
|
3629
|
+
window.addEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
3630
|
+
window.addEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
3631
|
+
}
|
|
3632
|
+
this.enabled = true;
|
|
3633
|
+
};
|
|
3634
|
+
disconnect = () => {
|
|
3635
|
+
window.removeEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
3636
|
+
window.removeEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
3637
|
+
this.enabled = false;
|
|
3638
|
+
};
|
|
3639
|
+
lastQuaternion = new Quaternion();
|
|
3640
|
+
update = () => {
|
|
3641
|
+
if (this.enabled === false) return;
|
|
3642
|
+
const device = this.deviceOrientation;
|
|
3643
|
+
if (device) {
|
|
3644
|
+
const alpha = device.alpha ? MathUtils.degToRad(device.alpha) + this.alphaOffset : 0;
|
|
3645
|
+
const beta = device.beta ? MathUtils.degToRad(device.beta) : 0;
|
|
3646
|
+
const gamma = device.gamma ? MathUtils.degToRad(device.gamma) : 0;
|
|
3647
|
+
const orient = this.screenOrientation ? MathUtils.degToRad(this.screenOrientation) : 0;
|
|
3648
|
+
this.setObjectQuaternion(this.object.quaternion, alpha, beta, gamma, orient);
|
|
3649
|
+
if (8 * (1 - this.lastQuaternion.dot(this.object.quaternion)) > this.EPS) {
|
|
3650
|
+
this.lastQuaternion.copy(this.object.quaternion);
|
|
3651
|
+
this.dispatchEvent(this.changeEvent);
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
};
|
|
3655
|
+
dispose = () => this.disconnect();
|
|
3656
|
+
};
|
|
3657
|
+
|
|
3573
3658
|
const DeviceOrientationControls = /* @__PURE__ */ React.forwardRef(
|
|
3574
3659
|
(props, ref) => {
|
|
3575
3660
|
const { camera, onChange, makeDefault, ...rest } = props;
|
|
@@ -3639,8 +3724,9 @@ const DragControls = React.forwardRef(
|
|
|
3639
3724
|
onDragStart && onDragStart(initialModelPosition);
|
|
3640
3725
|
invalidate();
|
|
3641
3726
|
},
|
|
3642
|
-
onDrag: ({ xy: [dragX, dragY], intentional }) => {
|
|
3727
|
+
onDrag: ({ xy: [dragX, dragY], intentional, event }) => {
|
|
3643
3728
|
if (!intentional) return;
|
|
3729
|
+
if (dragConfig && dragConfig.preventOverlap) event.preventDefault();
|
|
3644
3730
|
const normalizedMouseX = (dragX - size.left) / size.width * 2 - 1;
|
|
3645
3731
|
const normalizedMouseY = -((dragY - size.top) / size.height) * 2 + 1;
|
|
3646
3732
|
mousePosition2D.set(normalizedMouseX, normalizedMouseY);
|
|
@@ -3809,12 +3895,21 @@ function KeyboardControls({ map, children, onChange, domElement }) {
|
|
|
3809
3895
|
obj.pressed = false;
|
|
3810
3896
|
if (up) fn(false);
|
|
3811
3897
|
};
|
|
3898
|
+
const blurHandler = () => {
|
|
3899
|
+
const resetState = map.reduce((prev, cur) => ({ ...prev, [cur.name]: false }), {});
|
|
3900
|
+
set(resetState);
|
|
3901
|
+
Object.values(keyMap).forEach((obj) => {
|
|
3902
|
+
obj.pressed = false;
|
|
3903
|
+
});
|
|
3904
|
+
};
|
|
3812
3905
|
const source = domElement || window;
|
|
3813
3906
|
source.addEventListener("keydown", downHandler, { passive: true });
|
|
3814
3907
|
source.addEventListener("keyup", upHandler, { passive: true });
|
|
3908
|
+
window.addEventListener("blur", blurHandler);
|
|
3815
3909
|
return () => {
|
|
3816
3910
|
source.removeEventListener("keydown", downHandler);
|
|
3817
3911
|
source.removeEventListener("keyup", upHandler);
|
|
3912
|
+
window.removeEventListener("blur", blurHandler);
|
|
3818
3913
|
};
|
|
3819
3914
|
}, [domElement, key]);
|
|
3820
3915
|
return /* @__PURE__ */ React.createElement(context$8.Provider, { value: api, children });
|
|
@@ -4165,7 +4260,13 @@ function PresentationControls({
|
|
|
4165
4260
|
return /* @__PURE__ */ React.createElement("group", { ref, ...bind?.() }, children);
|
|
4166
4261
|
}
|
|
4167
4262
|
|
|
4263
|
+
function roundToPixelRatio(value) {
|
|
4264
|
+
const ratio = window.devicePixelRatio || 1;
|
|
4265
|
+
return Math.round(value * ratio) / ratio;
|
|
4266
|
+
}
|
|
4267
|
+
|
|
4168
4268
|
const context$7 = /* @__PURE__ */ React.createContext(null);
|
|
4269
|
+
const rootCache = /* @__PURE__ */ new WeakMap();
|
|
4169
4270
|
function useScroll() {
|
|
4170
4271
|
return React.useContext(context$7);
|
|
4171
4272
|
}
|
|
@@ -4179,6 +4280,7 @@ function ScrollControls({
|
|
|
4179
4280
|
damping = 0.25,
|
|
4180
4281
|
maxSpeed = Infinity,
|
|
4181
4282
|
prepend = false,
|
|
4283
|
+
pixelPerfect = true,
|
|
4182
4284
|
style = {},
|
|
4183
4285
|
children
|
|
4184
4286
|
}) {
|
|
@@ -4200,6 +4302,7 @@ function ScrollControls({
|
|
|
4200
4302
|
delta: 0,
|
|
4201
4303
|
scroll,
|
|
4202
4304
|
pages,
|
|
4305
|
+
pixelPerfect,
|
|
4203
4306
|
// 0-1 for a range between from -> from + distance
|
|
4204
4307
|
range(from, distance2, margin = 0) {
|
|
4205
4308
|
const start = from - margin;
|
|
@@ -4218,7 +4321,7 @@ function ScrollControls({
|
|
|
4218
4321
|
}
|
|
4219
4322
|
};
|
|
4220
4323
|
return state2;
|
|
4221
|
-
}, [eps, damping, horizontal, pages]);
|
|
4324
|
+
}, [eps, damping, horizontal, pages, pixelPerfect]);
|
|
4222
4325
|
React.useEffect(() => {
|
|
4223
4326
|
el.style.position = "absolute";
|
|
4224
4327
|
el.style.width = "100%";
|
|
@@ -4331,10 +4434,23 @@ const ScrollHtml = React.forwardRef(
|
|
|
4331
4434
|
React.useImperativeHandle(ref, () => group.current, []);
|
|
4332
4435
|
const { width, height } = useThree((state2) => state2.size);
|
|
4333
4436
|
const fiberState = React.useContext(context$a);
|
|
4334
|
-
const root = React.useMemo(() =>
|
|
4437
|
+
const root = React.useMemo(() => {
|
|
4438
|
+
let root2 = rootCache.get(state.fixed);
|
|
4439
|
+
if (!root2) {
|
|
4440
|
+
root2 = ReactDOM.createRoot(state.fixed);
|
|
4441
|
+
rootCache.set(state.fixed, root2);
|
|
4442
|
+
}
|
|
4443
|
+
return root2;
|
|
4444
|
+
}, [state.fixed]);
|
|
4335
4445
|
useFrame(() => {
|
|
4336
4446
|
if (state.delta > state.eps) {
|
|
4337
|
-
|
|
4447
|
+
let x = state.horizontal ? -width * (state.pages - 1) * state.offset : 0;
|
|
4448
|
+
let y = state.horizontal ? 0 : height * (state.pages - 1) * -state.offset;
|
|
4449
|
+
if (state.pixelPerfect) {
|
|
4450
|
+
x = roundToPixelRatio(x);
|
|
4451
|
+
y = roundToPixelRatio(y);
|
|
4452
|
+
}
|
|
4453
|
+
group.current.style.transform = `translate3d(${x}px,${y}px,0)`;
|
|
4338
4454
|
}
|
|
4339
4455
|
});
|
|
4340
4456
|
root.render(
|
|
@@ -5263,460 +5379,89 @@ const Text3D = /* @__PURE__ */ React.forwardRef(
|
|
|
5263
5379
|
}
|
|
5264
5380
|
);
|
|
5265
5381
|
|
|
5266
|
-
const
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
)
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
if (barycentric.y < barycentric.x && barycentric.y < barycentric.z) {
|
|
5350
|
-
positionAlong = 1.0 - positionAlong;
|
|
5351
|
-
}
|
|
5352
|
-
|
|
5353
|
-
// the thickness of the stroke
|
|
5354
|
-
float computedThickness = wireframe_map(thickness, 0.0, 1.0, 0.0, 0.34);
|
|
5355
|
-
|
|
5356
|
-
// if we want to shrink the thickness toward the center of the line segment
|
|
5357
|
-
if (squeeze) {
|
|
5358
|
-
computedThickness *= mix(squeezeMin, squeezeMax, (1.0 - sin(positionAlong * PI)));
|
|
5359
|
-
}
|
|
5360
|
-
|
|
5361
|
-
// Create dash pattern
|
|
5362
|
-
if (dash) {
|
|
5363
|
-
// here we offset the stroke position depending on whether it
|
|
5364
|
-
// should overlap or not
|
|
5365
|
-
float offset = 1.0 / dashRepeats * dashLength / 2.0;
|
|
5366
|
-
if (!dashInvert) {
|
|
5367
|
-
offset += 1.0 / dashRepeats / 2.0;
|
|
5368
|
-
}
|
|
5369
|
-
|
|
5370
|
-
// if we should animate the dash or not
|
|
5371
|
-
// if (dashAnimate) {
|
|
5372
|
-
// offset += time * 0.22;
|
|
5373
|
-
// }
|
|
5374
|
-
|
|
5375
|
-
// create the repeating dash pattern
|
|
5376
|
-
float pattern = fract((positionAlong + offset) * dashRepeats);
|
|
5377
|
-
computedThickness *= 1.0 - wireframe_aastep(dashLength, pattern);
|
|
5378
|
-
}
|
|
5379
|
-
|
|
5380
|
-
// compute the anti-aliased stroke edge
|
|
5381
|
-
float edge = 1.0 - wireframe_aastep(computedThickness, d);
|
|
5382
|
-
|
|
5383
|
-
return edge;
|
|
5384
|
-
}
|
|
5385
|
-
`
|
|
5386
|
-
)
|
|
5387
|
-
};
|
|
5388
|
-
const WireframeMaterial = /* @__PURE__ */ shaderMaterial(
|
|
5389
|
-
WireframeMaterialShaders.uniforms,
|
|
5390
|
-
WireframeMaterialShaders.vertex + /* glsl */
|
|
5391
|
-
`
|
|
5392
|
-
void main() {
|
|
5393
|
-
initWireframe();
|
|
5394
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
5395
|
-
}
|
|
5396
|
-
`,
|
|
5397
|
-
WireframeMaterialShaders.fragment + /* glsl */
|
|
5398
|
-
`
|
|
5399
|
-
void main () {
|
|
5400
|
-
// Compute color
|
|
5401
|
-
|
|
5402
|
-
float edge = getWireframe();
|
|
5403
|
-
vec4 colorStroke = vec4(stroke, edge);
|
|
5404
|
-
|
|
5405
|
-
#ifdef FLIP_SIDED
|
|
5406
|
-
colorStroke.rgb = backfaceStroke;
|
|
5407
|
-
#endif
|
|
5408
|
-
|
|
5409
|
-
vec4 colorFill = vec4(fill, fillOpacity);
|
|
5410
|
-
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
5411
|
-
|
|
5412
|
-
gl_FragColor = outColor;
|
|
5413
|
-
}
|
|
5414
|
-
`
|
|
5415
|
-
);
|
|
5416
|
-
function setWireframeOverride(material, uniforms) {
|
|
5417
|
-
material.onBeforeCompile = (shader) => {
|
|
5418
|
-
shader.uniforms = {
|
|
5419
|
-
...shader.uniforms,
|
|
5420
|
-
...uniforms
|
|
5421
|
-
};
|
|
5422
|
-
shader.vertexShader = shader.vertexShader.replace(
|
|
5423
|
-
"void main() {",
|
|
5424
|
-
`
|
|
5425
|
-
${WireframeMaterialShaders.vertex}
|
|
5426
|
-
void main() {
|
|
5427
|
-
initWireframe();
|
|
5428
|
-
`
|
|
5429
|
-
);
|
|
5430
|
-
shader.fragmentShader = shader.fragmentShader.replace(
|
|
5431
|
-
"void main() {",
|
|
5432
|
-
`
|
|
5433
|
-
${WireframeMaterialShaders.fragment}
|
|
5434
|
-
void main() {
|
|
5435
|
-
`
|
|
5436
|
-
);
|
|
5437
|
-
shader.fragmentShader = shader.fragmentShader.replace(
|
|
5438
|
-
"#include <color_fragment>",
|
|
5439
|
-
/* glsl */
|
|
5440
|
-
`
|
|
5441
|
-
#include <color_fragment>
|
|
5442
|
-
float edge = getWireframe();
|
|
5443
|
-
vec4 colorStroke = vec4(stroke, edge);
|
|
5444
|
-
#ifdef FLIP_SIDED
|
|
5445
|
-
colorStroke.rgb = backfaceStroke;
|
|
5446
|
-
#endif
|
|
5447
|
-
vec4 colorFill = vec4(mix(diffuseColor.rgb, fill, fillMix), mix(diffuseColor.a, fillOpacity, fillMix));
|
|
5448
|
-
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
5449
|
-
|
|
5450
|
-
diffuseColor.rgb = outColor.rgb;
|
|
5451
|
-
diffuseColor.a *= outColor.a;
|
|
5452
|
-
`
|
|
5453
|
-
);
|
|
5454
|
-
};
|
|
5455
|
-
material.side = THREE.DoubleSide;
|
|
5456
|
-
material.transparent = true;
|
|
5457
|
-
}
|
|
5458
|
-
function useWireframeUniforms(uniforms, props) {
|
|
5459
|
-
React.useEffect(
|
|
5460
|
-
() => void (uniforms.fillOpacity.value = props.fillOpacity ?? uniforms.fillOpacity.value),
|
|
5461
|
-
[props.fillOpacity]
|
|
5462
|
-
);
|
|
5463
|
-
React.useEffect(() => void (uniforms.fillMix.value = props.fillMix ?? uniforms.fillMix.value), [props.fillMix]);
|
|
5464
|
-
React.useEffect(
|
|
5465
|
-
() => void (uniforms.strokeOpacity.value = props.strokeOpacity ?? uniforms.strokeOpacity.value),
|
|
5466
|
-
[props.strokeOpacity]
|
|
5467
|
-
);
|
|
5468
|
-
React.useEffect(
|
|
5469
|
-
() => void (uniforms.thickness.value = props.thickness ?? uniforms.thickness.value),
|
|
5470
|
-
[props.thickness]
|
|
5471
|
-
);
|
|
5472
|
-
React.useEffect(() => void (uniforms.colorBackfaces.value = !!props.colorBackfaces), [props.colorBackfaces]);
|
|
5473
|
-
React.useEffect(() => void (uniforms.dash.value = !!props.dash), [props.dash]);
|
|
5474
|
-
React.useEffect(() => void (uniforms.dashInvert.value = !!props.dashInvert), [props.dashInvert]);
|
|
5475
|
-
React.useEffect(
|
|
5476
|
-
() => void (uniforms.dashRepeats.value = props.dashRepeats ?? uniforms.dashRepeats.value),
|
|
5477
|
-
[props.dashRepeats]
|
|
5478
|
-
);
|
|
5479
|
-
React.useEffect(
|
|
5480
|
-
() => void (uniforms.dashLength.value = props.dashLength ?? uniforms.dashLength.value),
|
|
5481
|
-
[props.dashLength]
|
|
5482
|
-
);
|
|
5483
|
-
React.useEffect(() => void (uniforms.squeeze.value = !!props.squeeze), [props.squeeze]);
|
|
5484
|
-
React.useEffect(
|
|
5485
|
-
() => void (uniforms.squeezeMin.value = props.squeezeMin ?? uniforms.squeezeMin.value),
|
|
5486
|
-
[props.squeezeMin]
|
|
5487
|
-
);
|
|
5488
|
-
React.useEffect(
|
|
5489
|
-
() => void (uniforms.squeezeMax.value = props.squeezeMax ?? uniforms.squeezeMax.value),
|
|
5490
|
-
[props.squeezeMax]
|
|
5491
|
-
);
|
|
5492
|
-
React.useEffect(
|
|
5493
|
-
() => void (uniforms.stroke.value = props.stroke ? new THREE.Color(props.stroke) : uniforms.stroke.value),
|
|
5494
|
-
[props.stroke]
|
|
5495
|
-
);
|
|
5496
|
-
React.useEffect(
|
|
5497
|
-
() => void (uniforms.fill.value = props.fill ? new THREE.Color(props.fill) : uniforms.fill.value),
|
|
5498
|
-
[props.fill]
|
|
5499
|
-
);
|
|
5500
|
-
React.useEffect(
|
|
5501
|
-
() => void (uniforms.backfaceStroke.value = props.backfaceStroke ? new THREE.Color(props.backfaceStroke) : uniforms.backfaceStroke.value),
|
|
5502
|
-
[props.backfaceStroke]
|
|
5503
|
-
);
|
|
5504
|
-
}
|
|
5505
|
-
|
|
5506
|
-
function isWithGeometry(object) {
|
|
5507
|
-
return !!object?.geometry;
|
|
5508
|
-
}
|
|
5509
|
-
function isGeometry(object) {
|
|
5510
|
-
return !!object?.isBufferGeometry;
|
|
5511
|
-
}
|
|
5512
|
-
function isRefObject$1(object) {
|
|
5513
|
-
return !!object?.current;
|
|
5514
|
-
}
|
|
5515
|
-
function isRef$1(object) {
|
|
5516
|
-
return object?.current !== void 0;
|
|
5517
|
-
}
|
|
5518
|
-
function isWireframeGeometry(geometry) {
|
|
5519
|
-
return geometry.type === "WireframeGeometry";
|
|
5520
|
-
}
|
|
5521
|
-
function getUniforms() {
|
|
5522
|
-
const u = {};
|
|
5523
|
-
for (const key in WireframeMaterialShaders.uniforms) {
|
|
5524
|
-
u[key] = { value: WireframeMaterialShaders.uniforms[key] };
|
|
5525
|
-
}
|
|
5526
|
-
return u;
|
|
5527
|
-
}
|
|
5528
|
-
function getBarycentricCoordinates(geometry, removeEdge) {
|
|
5529
|
-
const position = geometry.getAttribute("position");
|
|
5530
|
-
const count = position.count;
|
|
5531
|
-
const barycentric = [];
|
|
5532
|
-
for (let i = 0; i < count; i++) {
|
|
5533
|
-
const even = i % 2 === 0;
|
|
5534
|
-
const Q = removeEdge ? 1 : 0;
|
|
5535
|
-
if (even) {
|
|
5536
|
-
barycentric.push(0, 0, 1, 0, 1, 0, 1, 0, Q);
|
|
5537
|
-
} else {
|
|
5538
|
-
barycentric.push(0, 1, 0, 0, 0, 1, 1, 0, Q);
|
|
5539
|
-
}
|
|
5540
|
-
}
|
|
5541
|
-
return new THREE.BufferAttribute(Float32Array.from(barycentric), 3);
|
|
5542
|
-
}
|
|
5543
|
-
function getInputGeometry(inputGeometry) {
|
|
5544
|
-
const geo = isRefObject$1(inputGeometry) ? inputGeometry.current : inputGeometry;
|
|
5545
|
-
if (!isGeometry(geo)) {
|
|
5546
|
-
if (isWireframeGeometry(geo)) {
|
|
5547
|
-
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
5548
|
-
}
|
|
5549
|
-
const parent = geo.parent;
|
|
5550
|
-
if (isWithGeometry(parent)) {
|
|
5551
|
-
if (isWireframeGeometry(parent.geometry)) {
|
|
5552
|
-
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
5553
|
-
}
|
|
5554
|
-
return parent.geometry;
|
|
5555
|
-
}
|
|
5556
|
-
} else {
|
|
5557
|
-
return geo;
|
|
5558
|
-
}
|
|
5559
|
-
}
|
|
5560
|
-
function setBarycentricCoordinates(geometry, simplify) {
|
|
5561
|
-
if (geometry.index) {
|
|
5562
|
-
console.warn("Wireframe: Requires non-indexed geometry, converting to non-indexed geometry.");
|
|
5563
|
-
const nonIndexedGeo = geometry.toNonIndexed();
|
|
5564
|
-
geometry.copy(nonIndexedGeo);
|
|
5565
|
-
geometry.setIndex(null);
|
|
5566
|
-
}
|
|
5567
|
-
const newBarycentric = getBarycentricCoordinates(geometry, simplify);
|
|
5568
|
-
geometry.setAttribute("barycentric", newBarycentric);
|
|
5569
|
-
}
|
|
5570
|
-
function WireframeWithCustomGeo({
|
|
5571
|
-
geometry: customGeometry,
|
|
5572
|
-
simplify = false,
|
|
5573
|
-
...props
|
|
5574
|
-
}) {
|
|
5575
|
-
extend({ MeshWireframeMaterial: WireframeMaterial });
|
|
5576
|
-
const [geometry, setGeometry] = React.useState(null);
|
|
5577
|
-
React.useLayoutEffect(() => {
|
|
5578
|
-
const geom = getInputGeometry(customGeometry);
|
|
5579
|
-
if (!geom) {
|
|
5580
|
-
throw new Error("Wireframe: geometry prop must be a BufferGeometry or a ref to a BufferGeometry.");
|
|
5581
|
-
}
|
|
5582
|
-
setBarycentricCoordinates(geom, simplify);
|
|
5583
|
-
if (isRef$1(customGeometry)) {
|
|
5584
|
-
setGeometry(geom);
|
|
5585
|
-
}
|
|
5586
|
-
}, [simplify, customGeometry]);
|
|
5587
|
-
const drawnGeo = isRef$1(customGeometry) ? geometry : customGeometry;
|
|
5588
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, drawnGeo && /* @__PURE__ */ React.createElement("mesh", { geometry: drawnGeo }, /* @__PURE__ */ React.createElement(
|
|
5589
|
-
"meshWireframeMaterial",
|
|
5590
|
-
{
|
|
5591
|
-
attach: "material",
|
|
5592
|
-
transparent: true,
|
|
5593
|
-
side: THREE.DoubleSide,
|
|
5594
|
-
polygonOffset: true,
|
|
5595
|
-
polygonOffsetFactor: -4,
|
|
5596
|
-
...props
|
|
5597
|
-
}
|
|
5598
|
-
)));
|
|
5599
|
-
}
|
|
5600
|
-
function WireframeWithoutCustomGeo({
|
|
5601
|
-
simplify = false,
|
|
5602
|
-
...props
|
|
5603
|
-
}) {
|
|
5604
|
-
const objectRef = React.useRef(null);
|
|
5605
|
-
const uniforms = React.useMemo(() => getUniforms(), [WireframeMaterialShaders.uniforms]);
|
|
5606
|
-
useWireframeUniforms(uniforms, props);
|
|
5607
|
-
React.useLayoutEffect(() => {
|
|
5608
|
-
const geom = getInputGeometry(objectRef);
|
|
5609
|
-
if (!geom) {
|
|
5610
|
-
throw new Error("Wireframe: Must be a child of a Mesh, Line or Points object or specify a geometry prop.");
|
|
5611
|
-
}
|
|
5612
|
-
const og = geom.clone();
|
|
5613
|
-
setBarycentricCoordinates(geom, simplify);
|
|
5614
|
-
return () => {
|
|
5615
|
-
geom.copy(og);
|
|
5616
|
-
og.dispose();
|
|
5617
|
-
};
|
|
5618
|
-
}, [simplify]);
|
|
5619
|
-
React.useLayoutEffect(() => {
|
|
5620
|
-
const parentMesh = objectRef.current.parent;
|
|
5621
|
-
const og = parentMesh.material.clone();
|
|
5622
|
-
setWireframeOverride(parentMesh.material, uniforms);
|
|
5623
|
-
return () => {
|
|
5624
|
-
parentMesh.material.dispose();
|
|
5625
|
-
parentMesh.material = og;
|
|
5626
|
-
};
|
|
5627
|
-
}, []);
|
|
5628
|
-
return /* @__PURE__ */ React.createElement("object3D", { ref: objectRef });
|
|
5629
|
-
}
|
|
5630
|
-
function Wireframe({ geometry: customGeometry, ...props }) {
|
|
5631
|
-
if (customGeometry) {
|
|
5632
|
-
return /* @__PURE__ */ React.createElement(WireframeWithCustomGeo, { geometry: customGeometry, ...props });
|
|
5633
|
-
}
|
|
5634
|
-
return /* @__PURE__ */ React.createElement(WireframeWithoutCustomGeo, { ...props });
|
|
5635
|
-
}
|
|
5636
|
-
|
|
5637
|
-
const Context = /* @__PURE__ */ React.createContext({});
|
|
5638
|
-
const useGizmoContext = () => {
|
|
5639
|
-
return React.useContext(Context);
|
|
5640
|
-
};
|
|
5641
|
-
const turnRate = 2 * Math.PI;
|
|
5642
|
-
const dummy = /* @__PURE__ */ new Object3D();
|
|
5643
|
-
const matrix = /* @__PURE__ */ new Matrix4();
|
|
5644
|
-
const [q1, q2] = [/* @__PURE__ */ new Quaternion(), /* @__PURE__ */ new Quaternion()];
|
|
5645
|
-
const target = /* @__PURE__ */ new Vector3();
|
|
5646
|
-
const targetPosition = /* @__PURE__ */ new Vector3();
|
|
5647
|
-
const isOrbitControls = (controls) => {
|
|
5648
|
-
return "minPolarAngle" in controls;
|
|
5649
|
-
};
|
|
5650
|
-
const isCameraControls = (controls) => {
|
|
5651
|
-
return "getTarget" in controls;
|
|
5652
|
-
};
|
|
5653
|
-
const GizmoHelper = ({
|
|
5654
|
-
alignment = "bottom-right",
|
|
5655
|
-
margin = [80, 80],
|
|
5656
|
-
renderPriority = 1,
|
|
5657
|
-
onUpdate,
|
|
5658
|
-
onTarget,
|
|
5659
|
-
children
|
|
5660
|
-
}) => {
|
|
5661
|
-
const size = useThree((state) => state.size);
|
|
5662
|
-
const mainCamera = useThree((state) => state.camera);
|
|
5663
|
-
const defaultControls = useThree((state) => state.controls);
|
|
5664
|
-
const invalidate = useThree((state) => state.invalidate);
|
|
5665
|
-
const gizmoRef = React.useRef(null);
|
|
5666
|
-
const virtualCam = React.useRef(null);
|
|
5667
|
-
const animating = React.useRef(false);
|
|
5668
|
-
const radius = React.useRef(0);
|
|
5669
|
-
const focusPoint = React.useRef(new Vector3(0, 0, 0));
|
|
5670
|
-
const defaultUp = React.useRef(new Vector3(0, 0, 0));
|
|
5671
|
-
React.useEffect(() => {
|
|
5672
|
-
defaultUp.current.copy(mainCamera.up);
|
|
5673
|
-
dummy.up.copy(mainCamera.up);
|
|
5674
|
-
}, [mainCamera]);
|
|
5675
|
-
const tweenCamera = React.useCallback(
|
|
5676
|
-
(direction) => {
|
|
5677
|
-
animating.current = true;
|
|
5678
|
-
if (defaultControls || onTarget) {
|
|
5679
|
-
focusPoint.current = onTarget?.() || (isCameraControls(defaultControls) ? defaultControls.getTarget(focusPoint.current) : defaultControls?.target);
|
|
5680
|
-
}
|
|
5681
|
-
radius.current = mainCamera.position.distanceTo(target);
|
|
5682
|
-
q1.copy(mainCamera.quaternion);
|
|
5683
|
-
targetPosition.copy(direction).multiplyScalar(radius.current).add(target);
|
|
5684
|
-
dummy.lookAt(targetPosition);
|
|
5685
|
-
q2.copy(dummy.quaternion);
|
|
5686
|
-
invalidate();
|
|
5687
|
-
},
|
|
5688
|
-
[defaultControls, mainCamera, onTarget, invalidate]
|
|
5689
|
-
);
|
|
5690
|
-
useFrame((_, delta) => {
|
|
5691
|
-
if (virtualCam.current && gizmoRef.current) {
|
|
5692
|
-
if (animating.current) {
|
|
5693
|
-
if (q1.angleTo(q2) < 0.01) {
|
|
5694
|
-
animating.current = false;
|
|
5695
|
-
if (isOrbitControls(defaultControls)) {
|
|
5696
|
-
mainCamera.up.copy(defaultUp.current);
|
|
5697
|
-
}
|
|
5698
|
-
} else {
|
|
5699
|
-
const step = delta * turnRate;
|
|
5700
|
-
q1.rotateTowards(q2, step);
|
|
5701
|
-
mainCamera.position.set(0, 0, 1).applyQuaternion(q1).multiplyScalar(radius.current).add(focusPoint.current);
|
|
5702
|
-
mainCamera.up.set(0, 1, 0).applyQuaternion(q1).normalize();
|
|
5703
|
-
mainCamera.quaternion.copy(q1);
|
|
5704
|
-
if (isCameraControls(defaultControls))
|
|
5705
|
-
defaultControls.setPosition(mainCamera.position.x, mainCamera.position.y, mainCamera.position.z);
|
|
5706
|
-
if (onUpdate) onUpdate();
|
|
5707
|
-
else if (defaultControls) defaultControls.update(delta);
|
|
5708
|
-
invalidate();
|
|
5709
|
-
}
|
|
5710
|
-
}
|
|
5711
|
-
matrix.copy(mainCamera.matrix).invert();
|
|
5712
|
-
gizmoRef.current?.quaternion.setFromRotationMatrix(matrix);
|
|
5713
|
-
}
|
|
5714
|
-
});
|
|
5715
|
-
const gizmoHelperContext = React.useMemo(() => ({ tweenCamera }), [tweenCamera]);
|
|
5716
|
-
const [marginX, marginY] = margin;
|
|
5717
|
-
const x = alignment.endsWith("-center") ? 0 : alignment.endsWith("-left") ? -size.width / 2 + marginX : size.width / 2 - marginX;
|
|
5718
|
-
const y = alignment.startsWith("center-") ? 0 : alignment.startsWith("top-") ? size.height / 2 - marginY : -size.height / 2 + marginY;
|
|
5719
|
-
return /* @__PURE__ */ React.createElement(Hud$1, { renderPriority }, /* @__PURE__ */ React.createElement(Context.Provider, { value: gizmoHelperContext }, /* @__PURE__ */ React.createElement(OrthographicCamera, { makeDefault: true, ref: virtualCam, position: [0, 0, 200] }), /* @__PURE__ */ React.createElement("group", { ref: gizmoRef, position: [x, y, 0] }, children)));
|
|
5382
|
+
const Context = /* @__PURE__ */ React.createContext({});
|
|
5383
|
+
const useGizmoContext = () => {
|
|
5384
|
+
return React.useContext(Context);
|
|
5385
|
+
};
|
|
5386
|
+
const turnRate = 2 * Math.PI;
|
|
5387
|
+
const dummy = /* @__PURE__ */ new Object3D();
|
|
5388
|
+
const matrix = /* @__PURE__ */ new Matrix4();
|
|
5389
|
+
const [q1, q2] = [/* @__PURE__ */ new Quaternion(), /* @__PURE__ */ new Quaternion()];
|
|
5390
|
+
const target = /* @__PURE__ */ new Vector3();
|
|
5391
|
+
const targetPosition = /* @__PURE__ */ new Vector3();
|
|
5392
|
+
const isOrbitControls = (controls) => {
|
|
5393
|
+
return "minPolarAngle" in controls;
|
|
5394
|
+
};
|
|
5395
|
+
const isCameraControls = (controls) => {
|
|
5396
|
+
return "getTarget" in controls;
|
|
5397
|
+
};
|
|
5398
|
+
const GizmoHelper = ({
|
|
5399
|
+
alignment = "bottom-right",
|
|
5400
|
+
margin = [80, 80],
|
|
5401
|
+
renderPriority = 1,
|
|
5402
|
+
onUpdate,
|
|
5403
|
+
onTarget,
|
|
5404
|
+
children
|
|
5405
|
+
}) => {
|
|
5406
|
+
const size = useThree((state) => state.size);
|
|
5407
|
+
const mainCamera = useThree((state) => state.camera);
|
|
5408
|
+
const defaultControls = useThree((state) => state.controls);
|
|
5409
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
5410
|
+
const gizmoRef = React.useRef(null);
|
|
5411
|
+
const virtualCam = React.useRef(null);
|
|
5412
|
+
const animating = React.useRef(false);
|
|
5413
|
+
const radius = React.useRef(0);
|
|
5414
|
+
const focusPoint = React.useRef(new Vector3(0, 0, 0));
|
|
5415
|
+
const defaultUp = React.useRef(new Vector3(0, 0, 0));
|
|
5416
|
+
React.useEffect(() => {
|
|
5417
|
+
defaultUp.current.copy(mainCamera.up);
|
|
5418
|
+
dummy.up.copy(mainCamera.up);
|
|
5419
|
+
}, [mainCamera]);
|
|
5420
|
+
const tweenCamera = React.useCallback(
|
|
5421
|
+
(direction) => {
|
|
5422
|
+
animating.current = true;
|
|
5423
|
+
if (defaultControls || onTarget) {
|
|
5424
|
+
focusPoint.current = onTarget?.() || (isCameraControls(defaultControls) ? defaultControls.getTarget(focusPoint.current) : defaultControls?.target);
|
|
5425
|
+
}
|
|
5426
|
+
radius.current = mainCamera.position.distanceTo(target);
|
|
5427
|
+
q1.copy(mainCamera.quaternion);
|
|
5428
|
+
targetPosition.copy(direction).multiplyScalar(radius.current).add(target);
|
|
5429
|
+
dummy.lookAt(targetPosition);
|
|
5430
|
+
q2.copy(dummy.quaternion);
|
|
5431
|
+
invalidate();
|
|
5432
|
+
},
|
|
5433
|
+
[defaultControls, mainCamera, onTarget, invalidate]
|
|
5434
|
+
);
|
|
5435
|
+
useFrame((_, delta) => {
|
|
5436
|
+
if (virtualCam.current && gizmoRef.current) {
|
|
5437
|
+
if (animating.current) {
|
|
5438
|
+
if (q1.angleTo(q2) < 0.01) {
|
|
5439
|
+
animating.current = false;
|
|
5440
|
+
if (isOrbitControls(defaultControls)) {
|
|
5441
|
+
mainCamera.up.copy(defaultUp.current);
|
|
5442
|
+
}
|
|
5443
|
+
} else {
|
|
5444
|
+
const step = delta * turnRate;
|
|
5445
|
+
q1.rotateTowards(q2, step);
|
|
5446
|
+
mainCamera.position.set(0, 0, 1).applyQuaternion(q1).multiplyScalar(radius.current).add(focusPoint.current);
|
|
5447
|
+
mainCamera.up.set(0, 1, 0).applyQuaternion(q1).normalize();
|
|
5448
|
+
mainCamera.quaternion.copy(q1);
|
|
5449
|
+
if (isCameraControls(defaultControls))
|
|
5450
|
+
defaultControls.setPosition(mainCamera.position.x, mainCamera.position.y, mainCamera.position.z);
|
|
5451
|
+
if (onUpdate) onUpdate();
|
|
5452
|
+
else if (defaultControls) defaultControls.update(delta);
|
|
5453
|
+
invalidate();
|
|
5454
|
+
}
|
|
5455
|
+
}
|
|
5456
|
+
matrix.copy(mainCamera.matrix).invert();
|
|
5457
|
+
gizmoRef.current?.quaternion.setFromRotationMatrix(matrix);
|
|
5458
|
+
}
|
|
5459
|
+
});
|
|
5460
|
+
const gizmoHelperContext = React.useMemo(() => ({ tweenCamera }), [tweenCamera]);
|
|
5461
|
+
const [marginX, marginY] = margin;
|
|
5462
|
+
const x = alignment.endsWith("-center") ? 0 : alignment.endsWith("-left") ? -size.width / 2 + marginX : size.width / 2 - marginX;
|
|
5463
|
+
const y = alignment.startsWith("center-") ? 0 : alignment.startsWith("top-") ? size.height / 2 - marginY : -size.height / 2 + marginY;
|
|
5464
|
+
return /* @__PURE__ */ React.createElement(Hud$1, { renderPriority }, /* @__PURE__ */ React.createElement(Context.Provider, { value: gizmoHelperContext }, /* @__PURE__ */ React.createElement(OrthographicCamera, { makeDefault: true, ref: virtualCam, position: [0, 0, 200] }), /* @__PURE__ */ React.createElement("group", { ref: gizmoRef, position: [x, y, 0] }, children)));
|
|
5720
5465
|
};
|
|
5721
5466
|
|
|
5722
5467
|
const colors = { bg: "#f0f0f0", hover: "#999", text: "black", stroke: "black" };
|
|
@@ -5929,6 +5674,11 @@ const GizmoViewport = ({
|
|
|
5929
5674
|
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 }))));
|
|
5930
5675
|
};
|
|
5931
5676
|
|
|
5677
|
+
const roundEven = (n) => {
|
|
5678
|
+
const rounded = Math.ceil(n);
|
|
5679
|
+
return rounded % 2 === 0 ? rounded : rounded + 1;
|
|
5680
|
+
};
|
|
5681
|
+
|
|
5932
5682
|
const v1 = /* @__PURE__ */ new Vector3();
|
|
5933
5683
|
const v2 = /* @__PURE__ */ new Vector3();
|
|
5934
5684
|
const v3 = /* @__PURE__ */ new Vector3();
|
|
@@ -6000,7 +5750,7 @@ const getCameraCSSMatrix = /* @__PURE__ */ ((multipliers) => {
|
|
|
6000
5750
|
const getObjectCSSMatrix = /* @__PURE__ */ ((scaleMultipliers) => {
|
|
6001
5751
|
return (matrix, factor) => getCSSMatrix(matrix, scaleMultipliers(factor), "translate(-50%,-50%)");
|
|
6002
5752
|
})((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]);
|
|
6003
|
-
function isRefObject(ref) {
|
|
5753
|
+
function isRefObject$1(ref) {
|
|
6004
5754
|
return ref && typeof ref === "object" && "current" in ref;
|
|
6005
5755
|
}
|
|
6006
5756
|
const Html = /* @__PURE__ */ React.forwardRef(
|
|
@@ -6027,9 +5777,11 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6027
5777
|
as = "div",
|
|
6028
5778
|
wrapperClass,
|
|
6029
5779
|
pointerEvents = "auto",
|
|
5780
|
+
pixelPerfect = true,
|
|
6030
5781
|
...props
|
|
6031
5782
|
}, ref) => {
|
|
6032
5783
|
const { gl, camera, scene, size, raycaster, events, viewport } = useThree();
|
|
5784
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
6033
5785
|
const [el] = React.useState(() => document.createElement(as));
|
|
6034
5786
|
const root = React.useRef(null);
|
|
6035
5787
|
const group = React.useRef(null);
|
|
@@ -6041,7 +5793,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6041
5793
|
const occlusionMeshRef = React.useRef(null);
|
|
6042
5794
|
const isMeshSizeSet = React.useRef(false);
|
|
6043
5795
|
const isRayCastOcclusion = React.useMemo(() => {
|
|
6044
|
-
return occlude && occlude !== "blending" || Array.isArray(occlude) && occlude.length && isRefObject(occlude[0]);
|
|
5796
|
+
return occlude && occlude !== "blending" || Array.isArray(occlude) && occlude.length && isRefObject$1(occlude[0]);
|
|
6045
5797
|
}, [occlude]);
|
|
6046
5798
|
React.useLayoutEffect(() => {
|
|
6047
5799
|
const el2 = gl.domElement;
|
|
@@ -6054,38 +5806,54 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6054
5806
|
el2.style.position = null;
|
|
6055
5807
|
el2.style.pointerEvents = null;
|
|
6056
5808
|
}
|
|
6057
|
-
}, [occlude]);
|
|
5809
|
+
}, [occlude, zIndexRange, gl.domElement]);
|
|
6058
5810
|
React.useLayoutEffect(() => {
|
|
6059
5811
|
if (group.current) {
|
|
6060
|
-
|
|
5812
|
+
if (!root.current) {
|
|
5813
|
+
root.current = ReactDOM.createRoot(el);
|
|
5814
|
+
}
|
|
6061
5815
|
scene.updateMatrixWorld();
|
|
6062
5816
|
if (transform) {
|
|
6063
5817
|
el.style.cssText = `position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;`;
|
|
6064
5818
|
} else {
|
|
6065
|
-
|
|
6066
|
-
el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(${vec[0]}px,${vec[1]}px,0);transform-origin:0 0;`;
|
|
5819
|
+
el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(0,-9999px,0);transform-origin:0 0;`;
|
|
6067
5820
|
}
|
|
6068
5821
|
if (target) {
|
|
6069
5822
|
if (prepend) target.prepend(el);
|
|
6070
5823
|
else target.appendChild(el);
|
|
6071
5824
|
}
|
|
6072
5825
|
return () => {
|
|
6073
|
-
if (
|
|
6074
|
-
|
|
5826
|
+
if (root.current) {
|
|
5827
|
+
root.current.unmount();
|
|
5828
|
+
root.current = null;
|
|
5829
|
+
}
|
|
5830
|
+
if (target && target.contains(el)) {
|
|
5831
|
+
target.removeChild(el);
|
|
5832
|
+
}
|
|
6075
5833
|
};
|
|
6076
5834
|
}
|
|
6077
|
-
}, [target, transform]);
|
|
5835
|
+
}, [target, transform, el, prepend, scene]);
|
|
6078
5836
|
React.useLayoutEffect(() => {
|
|
6079
5837
|
if (wrapperClass) el.className = wrapperClass;
|
|
6080
|
-
}, [wrapperClass]);
|
|
5838
|
+
}, [wrapperClass, el]);
|
|
5839
|
+
React.useLayoutEffect(() => {
|
|
5840
|
+
return () => {
|
|
5841
|
+
if (root.current) {
|
|
5842
|
+
root.current.unmount();
|
|
5843
|
+
root.current = null;
|
|
5844
|
+
}
|
|
5845
|
+
};
|
|
5846
|
+
}, []);
|
|
6081
5847
|
const styles = React.useMemo(() => {
|
|
5848
|
+
const width = forceEven ? roundEven(size.width) : size.width;
|
|
5849
|
+
const height = forceEven ? roundEven(size.height) : size.height;
|
|
6082
5850
|
if (transform) {
|
|
6083
5851
|
return {
|
|
6084
5852
|
position: "absolute",
|
|
6085
5853
|
top: 0,
|
|
6086
5854
|
left: 0,
|
|
6087
|
-
width
|
|
6088
|
-
height
|
|
5855
|
+
width,
|
|
5856
|
+
height,
|
|
6089
5857
|
transformStyle: "preserve-3d",
|
|
6090
5858
|
pointerEvents: "none"
|
|
6091
5859
|
};
|
|
@@ -6094,15 +5862,15 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6094
5862
|
position: "absolute",
|
|
6095
5863
|
transform: center ? "translate3d(-50%,-50%,0)" : "none",
|
|
6096
5864
|
...fullscreen && {
|
|
6097
|
-
top: -size.height / 2,
|
|
6098
|
-
left: -size.width / 2,
|
|
6099
|
-
width
|
|
6100
|
-
height
|
|
5865
|
+
top: forceEven ? roundEven(-size.height / 2) : -size.height / 2,
|
|
5866
|
+
left: forceEven ? roundEven(-size.width / 2) : -size.width / 2,
|
|
5867
|
+
width,
|
|
5868
|
+
height
|
|
6101
5869
|
},
|
|
6102
5870
|
...style
|
|
6103
5871
|
};
|
|
6104
5872
|
}
|
|
6105
|
-
}, [style, center, fullscreen, size, transform]);
|
|
5873
|
+
}, [style, center, fullscreen, size, transform, forceEven]);
|
|
6106
5874
|
const transformInnerStyles = React.useMemo(
|
|
6107
5875
|
() => ({ position: "absolute", pointerEvents }),
|
|
6108
5876
|
[pointerEvents]
|
|
@@ -6116,7 +5884,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6116
5884
|
} else {
|
|
6117
5885
|
root.current?.render(/* @__PURE__ */ React.createElement("div", { ref, style: styles, className, children }));
|
|
6118
5886
|
}
|
|
6119
|
-
});
|
|
5887
|
+
}, [transform, styles, transformInnerStyles, ref, className, style, children]);
|
|
6120
5888
|
const visible = React.useRef(true);
|
|
6121
5889
|
useFrame((gl2) => {
|
|
6122
5890
|
if (group.current) {
|
|
@@ -6148,7 +5916,12 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6148
5916
|
const zRange = occlude ? isRayCastOcclusion ? [zIndexRange[0], halfRange] : [halfRange - 1, 0] : zIndexRange;
|
|
6149
5917
|
el.style.zIndex = `${objectZIndex(group.current, camera, zRange)}`;
|
|
6150
5918
|
if (transform) {
|
|
6151
|
-
|
|
5919
|
+
let widthHalf = forceEven ? roundEven(size.width / 2) : size.width / 2;
|
|
5920
|
+
let heightHalf = forceEven ? roundEven(size.height / 2) : size.height / 2;
|
|
5921
|
+
if (pixelPerfect) {
|
|
5922
|
+
widthHalf = roundToPixelRatio(widthHalf);
|
|
5923
|
+
heightHalf = roundToPixelRatio(heightHalf);
|
|
5924
|
+
}
|
|
6152
5925
|
const fov = camera.projectionMatrix.elements[5] * heightHalf;
|
|
6153
5926
|
const { isOrthographicCamera, top, left, bottom, right } = camera;
|
|
6154
5927
|
const cameraMatrix = getCameraCSSMatrix(camera.matrixWorldInverse);
|
|
@@ -6159,8 +5932,10 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6159
5932
|
matrix.elements[3] = matrix.elements[7] = matrix.elements[11] = 0;
|
|
6160
5933
|
matrix.elements[15] = 1;
|
|
6161
5934
|
}
|
|
6162
|
-
|
|
6163
|
-
|
|
5935
|
+
const elWidth = forceEven ? roundEven(size.width) : size.width;
|
|
5936
|
+
const elHeight = forceEven ? roundEven(size.height) : size.height;
|
|
5937
|
+
el.style.width = elWidth + "px";
|
|
5938
|
+
el.style.height = elHeight + "px";
|
|
6164
5939
|
el.style.perspective = isOrthographicCamera ? "" : `${fov}px`;
|
|
6165
5940
|
if (transformOuterRef.current && transformInnerRef.current) {
|
|
6166
5941
|
transformOuterRef.current.style.transform = `${cameraTransform}${cameraMatrix}translate(${widthHalf}px,${heightHalf}px)`;
|
|
@@ -6168,7 +5943,13 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6168
5943
|
}
|
|
6169
5944
|
} else {
|
|
6170
5945
|
const scale = distanceFactor === void 0 ? 1 : objectScale(group.current, camera) * distanceFactor;
|
|
6171
|
-
|
|
5946
|
+
let x = forceEven ? roundEven(vec[0]) : vec[0];
|
|
5947
|
+
let y = forceEven ? roundEven(vec[1]) : vec[1];
|
|
5948
|
+
if (pixelPerfect) {
|
|
5949
|
+
x = roundToPixelRatio(x);
|
|
5950
|
+
y = roundToPixelRatio(y);
|
|
5951
|
+
}
|
|
5952
|
+
el.style.transform = `translate3d(${x}px,${y}px,0) scale(${scale})`;
|
|
6172
5953
|
}
|
|
6173
5954
|
oldPosition.current = vec;
|
|
6174
5955
|
oldZoom.current = camera.zoom;
|
|
@@ -6274,6 +6055,11 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
6274
6055
|
);
|
|
6275
6056
|
|
|
6276
6057
|
const context$4 = /* @__PURE__ */ React.createContext(null);
|
|
6058
|
+
const resolveObject = (object, fallback) => {
|
|
6059
|
+
if (!object) return fallback;
|
|
6060
|
+
if ("current" in object) return object.current;
|
|
6061
|
+
return object;
|
|
6062
|
+
};
|
|
6277
6063
|
|
|
6278
6064
|
const vec1$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
6279
6065
|
const vec2$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
@@ -6308,6 +6094,8 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
6308
6094
|
onDragStart,
|
|
6309
6095
|
onDrag,
|
|
6310
6096
|
onDragEnd,
|
|
6097
|
+
onHover,
|
|
6098
|
+
dragState,
|
|
6311
6099
|
userData,
|
|
6312
6100
|
LineComponent: Line
|
|
6313
6101
|
} = React.useContext(context$4);
|
|
@@ -6339,7 +6127,13 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
6339
6127
|
const onPointerMove = React.useCallback(
|
|
6340
6128
|
(e) => {
|
|
6341
6129
|
e.stopPropagation();
|
|
6342
|
-
if (!isHovered)
|
|
6130
|
+
if (!isHovered) {
|
|
6131
|
+
const drag = dragState.current;
|
|
6132
|
+
if (drag === null || drag.component === "Arrow" && drag.axis === axis) {
|
|
6133
|
+
setIsHovered(true);
|
|
6134
|
+
onHover({ component: "Arrow", axis, hovering: true });
|
|
6135
|
+
}
|
|
6136
|
+
}
|
|
6343
6137
|
if (clickInfo.current) {
|
|
6344
6138
|
const { clickPoint, dir } = clickInfo.current;
|
|
6345
6139
|
const [min, max] = translationLimits?.[axis] || [void 0, void 0];
|
|
@@ -6358,7 +6152,7 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
6358
6152
|
onDrag(offsetMatrix$1);
|
|
6359
6153
|
}
|
|
6360
6154
|
},
|
|
6361
|
-
[annotations, onDrag, isHovered, translation, translationLimits, axis]
|
|
6155
|
+
[annotations, onDrag, onHover, dragState, isHovered, translation, translationLimits, axis]
|
|
6362
6156
|
);
|
|
6363
6157
|
const onPointerUp = React.useCallback(
|
|
6364
6158
|
(e) => {
|
|
@@ -6373,10 +6167,16 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
6373
6167
|
},
|
|
6374
6168
|
[annotations, camControls, onDragEnd]
|
|
6375
6169
|
);
|
|
6376
|
-
const onPointerOut = React.useCallback(
|
|
6377
|
-
e
|
|
6378
|
-
|
|
6379
|
-
|
|
6170
|
+
const onPointerOut = React.useCallback(
|
|
6171
|
+
(e) => {
|
|
6172
|
+
e.stopPropagation();
|
|
6173
|
+
if (isHovered) {
|
|
6174
|
+
setIsHovered(false);
|
|
6175
|
+
onHover({ component: "Arrow", axis, hovering: false });
|
|
6176
|
+
}
|
|
6177
|
+
},
|
|
6178
|
+
[onHover, axis, isHovered]
|
|
6179
|
+
);
|
|
6380
6180
|
const { cylinderLength, coneWidth, coneLength, matrixL } = React.useMemo(() => {
|
|
6381
6181
|
const coneWidth2 = fixed ? lineWidth / scale * 1.6 : scale / 20;
|
|
6382
6182
|
const coneLength2 = fixed ? 0.2 : scale / 5;
|
|
@@ -6480,6 +6280,8 @@ const rotMatrix = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
6480
6280
|
const posNew = /* @__PURE__ */ new THREE.Vector3();
|
|
6481
6281
|
const ray$1 = /* @__PURE__ */ new THREE.Ray();
|
|
6482
6282
|
const intersection$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
6283
|
+
const viewPlane = /* @__PURE__ */ new THREE.Plane();
|
|
6284
|
+
const viewIntersection = /* @__PURE__ */ new THREE.Vector3();
|
|
6483
6285
|
const AxisRotator = ({
|
|
6484
6286
|
dir1,
|
|
6485
6287
|
dir2,
|
|
@@ -6500,6 +6302,8 @@ const AxisRotator = ({
|
|
|
6500
6302
|
onDragStart,
|
|
6501
6303
|
onDrag,
|
|
6502
6304
|
onDragEnd,
|
|
6305
|
+
onHover,
|
|
6306
|
+
dragState,
|
|
6503
6307
|
userData,
|
|
6504
6308
|
LineComponent: Line
|
|
6505
6309
|
} = React.useContext(context$4);
|
|
@@ -6533,14 +6337,29 @@ const AxisRotator = ({
|
|
|
6533
6337
|
const onPointerMove = React.useCallback(
|
|
6534
6338
|
(e) => {
|
|
6535
6339
|
e.stopPropagation();
|
|
6536
|
-
if (!isHovered)
|
|
6340
|
+
if (!isHovered) {
|
|
6341
|
+
const drag = dragState.current;
|
|
6342
|
+
if (drag === null || drag.component === "Rotator" && drag.axis === axis) {
|
|
6343
|
+
setIsHovered(true);
|
|
6344
|
+
onHover({ component: "Rotator", axis, hovering: true });
|
|
6345
|
+
}
|
|
6346
|
+
}
|
|
6537
6347
|
if (clickInfo.current) {
|
|
6538
6348
|
const { clickPoint, origin, e1, e2, normal, plane } = clickInfo.current;
|
|
6539
6349
|
const [min, max] = rotationLimits?.[axis] || [void 0, void 0];
|
|
6540
6350
|
ray$1.copy(e.ray);
|
|
6541
|
-
ray$1.
|
|
6542
|
-
|
|
6543
|
-
|
|
6351
|
+
const dotProduct = Math.abs(ray$1.direction.dot(normal));
|
|
6352
|
+
if (dotProduct < 0.1) {
|
|
6353
|
+
viewPlane.setFromNormalAndCoplanarPoint(ray$1.direction.clone().negate(), origin);
|
|
6354
|
+
ray$1.intersectPlane(viewPlane, viewIntersection);
|
|
6355
|
+
const toIntersection = viewIntersection.clone().sub(origin);
|
|
6356
|
+
const projectedDist = toIntersection.dot(normal);
|
|
6357
|
+
intersection$1.copy(viewIntersection).sub(normal.clone().multiplyScalar(projectedDist));
|
|
6358
|
+
} else {
|
|
6359
|
+
ray$1.intersectPlane(plane, intersection$1);
|
|
6360
|
+
ray$1.direction.negate();
|
|
6361
|
+
ray$1.intersectPlane(plane, intersection$1);
|
|
6362
|
+
}
|
|
6544
6363
|
let deltaAngle = calculateAngle(clickPoint, intersection$1, origin, e1, e2);
|
|
6545
6364
|
let degrees = toDegrees(deltaAngle);
|
|
6546
6365
|
if (e.shiftKey) {
|
|
@@ -6566,7 +6385,7 @@ const AxisRotator = ({
|
|
|
6566
6385
|
onDrag(rotMatrix);
|
|
6567
6386
|
}
|
|
6568
6387
|
},
|
|
6569
|
-
[annotations, onDrag, isHovered, rotationLimits, axis]
|
|
6388
|
+
[annotations, onDrag, onHover, dragState, isHovered, rotationLimits, axis]
|
|
6570
6389
|
);
|
|
6571
6390
|
const onPointerUp = React.useCallback(
|
|
6572
6391
|
(e) => {
|
|
@@ -6582,10 +6401,16 @@ const AxisRotator = ({
|
|
|
6582
6401
|
},
|
|
6583
6402
|
[annotations, camControls, onDragEnd]
|
|
6584
6403
|
);
|
|
6585
|
-
const onPointerOut = React.useCallback(
|
|
6586
|
-
e
|
|
6587
|
-
|
|
6588
|
-
|
|
6404
|
+
const onPointerOut = React.useCallback(
|
|
6405
|
+
(e) => {
|
|
6406
|
+
e.stopPropagation();
|
|
6407
|
+
if (isHovered) {
|
|
6408
|
+
setIsHovered(false);
|
|
6409
|
+
onHover({ component: "Rotator", axis, hovering: false });
|
|
6410
|
+
}
|
|
6411
|
+
},
|
|
6412
|
+
[onHover, axis, isHovered]
|
|
6413
|
+
);
|
|
6589
6414
|
const matrixL = React.useMemo(() => {
|
|
6590
6415
|
const dir1N = dir1.clone().normalize();
|
|
6591
6416
|
const dir2N = dir2.clone().normalize();
|
|
@@ -6686,6 +6511,8 @@ const PlaneSlider = ({
|
|
|
6686
6511
|
onDragStart,
|
|
6687
6512
|
onDrag,
|
|
6688
6513
|
onDragEnd,
|
|
6514
|
+
onHover,
|
|
6515
|
+
dragState,
|
|
6689
6516
|
userData,
|
|
6690
6517
|
LineComponent: Line
|
|
6691
6518
|
} = React.useContext(context$4);
|
|
@@ -6721,7 +6548,13 @@ const PlaneSlider = ({
|
|
|
6721
6548
|
const onPointerMove = React.useCallback(
|
|
6722
6549
|
(e) => {
|
|
6723
6550
|
e.stopPropagation();
|
|
6724
|
-
if (!isHovered)
|
|
6551
|
+
if (!isHovered) {
|
|
6552
|
+
const drag = dragState.current;
|
|
6553
|
+
if (drag === null || drag.component === "Slider" && drag.axis === axis) {
|
|
6554
|
+
setIsHovered(true);
|
|
6555
|
+
onHover({ component: "Slider", axis, hovering: true });
|
|
6556
|
+
}
|
|
6557
|
+
}
|
|
6725
6558
|
if (clickInfo.current) {
|
|
6726
6559
|
const { clickPoint, e1, e2, plane } = clickInfo.current;
|
|
6727
6560
|
const [minX, maxX] = translationLimits?.[(axis + 1) % 3] || [void 0, void 0];
|
|
@@ -6757,7 +6590,7 @@ const PlaneSlider = ({
|
|
|
6757
6590
|
onDrag(offsetMatrix);
|
|
6758
6591
|
}
|
|
6759
6592
|
},
|
|
6760
|
-
[annotations, onDrag, isHovered, translation, translationLimits, axis]
|
|
6593
|
+
[annotations, onDrag, onHover, dragState, isHovered, translation, translationLimits, axis]
|
|
6761
6594
|
);
|
|
6762
6595
|
const onPointerUp = React.useCallback(
|
|
6763
6596
|
(e) => {
|
|
@@ -6772,10 +6605,16 @@ const PlaneSlider = ({
|
|
|
6772
6605
|
},
|
|
6773
6606
|
[annotations, camControls, onDragEnd]
|
|
6774
6607
|
);
|
|
6775
|
-
const onPointerOut = React.useCallback(
|
|
6776
|
-
e
|
|
6777
|
-
|
|
6778
|
-
|
|
6608
|
+
const onPointerOut = React.useCallback(
|
|
6609
|
+
(e) => {
|
|
6610
|
+
e.stopPropagation();
|
|
6611
|
+
if (isHovered) {
|
|
6612
|
+
setIsHovered(false);
|
|
6613
|
+
onHover({ component: "Slider", axis, hovering: false });
|
|
6614
|
+
}
|
|
6615
|
+
},
|
|
6616
|
+
[onHover, axis, isHovered]
|
|
6617
|
+
);
|
|
6779
6618
|
const matrixL = React.useMemo(() => {
|
|
6780
6619
|
const dir1N = dir1.clone().normalize();
|
|
6781
6620
|
const dir2N = dir2.clone().normalize();
|
|
@@ -6913,6 +6752,8 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
6913
6752
|
onDragStart,
|
|
6914
6753
|
onDrag,
|
|
6915
6754
|
onDragEnd,
|
|
6755
|
+
onHover,
|
|
6756
|
+
dragState,
|
|
6916
6757
|
userData
|
|
6917
6758
|
} = React.useContext(context$4);
|
|
6918
6759
|
const size = useThree((state) => state.size);
|
|
@@ -6949,7 +6790,13 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
6949
6790
|
const onPointerMove = React.useCallback(
|
|
6950
6791
|
(e) => {
|
|
6951
6792
|
e.stopPropagation();
|
|
6952
|
-
if (!isHovered)
|
|
6793
|
+
if (!isHovered) {
|
|
6794
|
+
const drag = dragState.current;
|
|
6795
|
+
if (drag === null || drag.component === "Sphere" && drag.axis === axis) {
|
|
6796
|
+
setIsHovered(true);
|
|
6797
|
+
onHover({ component: "Sphere", axis, hovering: true });
|
|
6798
|
+
}
|
|
6799
|
+
}
|
|
6953
6800
|
if (clickInfo.current) {
|
|
6954
6801
|
const { clickPoint, dir, mPLG, mPLGInv, offsetMultiplier } = clickInfo.current;
|
|
6955
6802
|
const [min, max] = scaleLimits?.[axis] || [1e-5, void 0];
|
|
@@ -6975,7 +6822,7 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
6975
6822
|
onDrag(scaleMatrix);
|
|
6976
6823
|
}
|
|
6977
6824
|
},
|
|
6978
|
-
[annotations, position, onDrag, isHovered, scaleLimits, axis]
|
|
6825
|
+
[annotations, position, onDrag, onHover, dragState, isHovered, scaleLimits, axis]
|
|
6979
6826
|
);
|
|
6980
6827
|
const onPointerUp = React.useCallback(
|
|
6981
6828
|
(e) => {
|
|
@@ -6992,10 +6839,16 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
6992
6839
|
},
|
|
6993
6840
|
[annotations, camControls, onDragEnd, position]
|
|
6994
6841
|
);
|
|
6995
|
-
const onPointerOut = React.useCallback(
|
|
6996
|
-
e
|
|
6997
|
-
|
|
6998
|
-
|
|
6842
|
+
const onPointerOut = React.useCallback(
|
|
6843
|
+
(e) => {
|
|
6844
|
+
e.stopPropagation();
|
|
6845
|
+
if (isHovered) {
|
|
6846
|
+
setIsHovered(false);
|
|
6847
|
+
onHover({ component: "Sphere", axis, hovering: false });
|
|
6848
|
+
}
|
|
6849
|
+
},
|
|
6850
|
+
[onHover, axis, isHovered]
|
|
6851
|
+
);
|
|
6999
6852
|
const { radius, matrixL } = React.useMemo(() => {
|
|
7000
6853
|
const radius2 = fixed ? lineWidth / scale * 1.8 : scale / 22.5;
|
|
7001
6854
|
const quaternion = new THREE.Quaternion().setFromUnitVectors(upV, direction.clone().normalize());
|
|
@@ -7065,9 +6918,11 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7065
6918
|
({
|
|
7066
6919
|
enabled = true,
|
|
7067
6920
|
matrix,
|
|
6921
|
+
object,
|
|
7068
6922
|
onDragStart,
|
|
7069
6923
|
onDrag,
|
|
7070
6924
|
onDragEnd,
|
|
6925
|
+
onHover,
|
|
7071
6926
|
autoTransform = true,
|
|
7072
6927
|
anchor,
|
|
7073
6928
|
disableAxes = false,
|
|
@@ -7103,14 +6958,35 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7103
6958
|
const gizmoRef = React.useRef(null);
|
|
7104
6959
|
const childrenRef = React.useRef(null);
|
|
7105
6960
|
const translation = React.useRef([0, 0, 0]);
|
|
6961
|
+
const dragState = React.useRef(null);
|
|
7106
6962
|
const cameraScale = React.useRef(new THREE.Vector3(1, 1, 1));
|
|
7107
6963
|
const gizmoScale = React.useRef(new THREE.Vector3(1, 1, 1));
|
|
6964
|
+
React.useEffect(() => {
|
|
6965
|
+
if (object) {
|
|
6966
|
+
const target = resolveObject(object);
|
|
6967
|
+
if (target) {
|
|
6968
|
+
const pivot = ref.current;
|
|
6969
|
+
const didAutoUpdate = target.matrixAutoUpdate;
|
|
6970
|
+
target.updateWorldMatrix(true, true);
|
|
6971
|
+
target.matrixAutoUpdate = false;
|
|
6972
|
+
pivot.matrix.copy(target.matrix);
|
|
6973
|
+
return () => {
|
|
6974
|
+
if (didAutoUpdate) {
|
|
6975
|
+
target.matrixAutoUpdate = true;
|
|
6976
|
+
target.matrix.decompose(target.position, target.quaternion, target.scale);
|
|
6977
|
+
}
|
|
6978
|
+
};
|
|
6979
|
+
}
|
|
6980
|
+
}
|
|
6981
|
+
}, [object]);
|
|
7108
6982
|
React.useLayoutEffect(() => {
|
|
7109
6983
|
if (!anchor) return;
|
|
7110
|
-
childrenRef.current
|
|
7111
|
-
|
|
6984
|
+
const anchorTarget = resolveObject(object, childrenRef.current);
|
|
6985
|
+
if (!anchorTarget) return;
|
|
6986
|
+
anchorTarget.updateWorldMatrix(true, true);
|
|
6987
|
+
mPInv.copy(anchorTarget.matrixWorld).invert();
|
|
7112
6988
|
bb.makeEmpty();
|
|
7113
|
-
|
|
6989
|
+
anchorTarget.traverse((obj) => {
|
|
7114
6990
|
if (!obj.geometry) return;
|
|
7115
6991
|
if (!obj.geometry.boundingBox) obj.geometry.computeBoundingBox();
|
|
7116
6992
|
mL.copy(obj.matrixWorld).premultiply(mPInv);
|
|
@@ -7125,9 +7001,17 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7125
7001
|
gizmoRef.current.position.copy(vPosition);
|
|
7126
7002
|
invalidate();
|
|
7127
7003
|
});
|
|
7004
|
+
const mergedUserData = React.useMemo(
|
|
7005
|
+
() => ({
|
|
7006
|
+
...userData,
|
|
7007
|
+
...depthTest === false && { interactivePriority: 1 }
|
|
7008
|
+
}),
|
|
7009
|
+
[userData, depthTest]
|
|
7010
|
+
);
|
|
7128
7011
|
const config = React.useMemo(
|
|
7129
7012
|
() => ({
|
|
7130
7013
|
onDragStart: (props2) => {
|
|
7014
|
+
dragState.current = props2;
|
|
7131
7015
|
mL0.copy(ref.current.matrix);
|
|
7132
7016
|
mW0.copy(ref.current.matrixWorld);
|
|
7133
7017
|
onDragStart && onDragStart(props2);
|
|
@@ -7143,13 +7027,20 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7143
7027
|
if (autoTransform) {
|
|
7144
7028
|
ref.current.matrix.copy(mL);
|
|
7145
7029
|
}
|
|
7030
|
+
const target = resolveObject(object);
|
|
7031
|
+
if (target) target.matrix.copy(mL);
|
|
7146
7032
|
onDrag && onDrag(mL, mdL, mW, mdW);
|
|
7147
7033
|
invalidate();
|
|
7148
7034
|
},
|
|
7149
7035
|
onDragEnd: () => {
|
|
7036
|
+
dragState.current = null;
|
|
7150
7037
|
if (onDragEnd) onDragEnd();
|
|
7151
7038
|
invalidate();
|
|
7152
7039
|
},
|
|
7040
|
+
onHover: (props2) => {
|
|
7041
|
+
if (onHover) onHover(props2);
|
|
7042
|
+
},
|
|
7043
|
+
dragState,
|
|
7153
7044
|
translation,
|
|
7154
7045
|
translationLimits,
|
|
7155
7046
|
rotationLimits,
|
|
@@ -7161,7 +7052,7 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7161
7052
|
fixed,
|
|
7162
7053
|
depthTest,
|
|
7163
7054
|
renderOrder,
|
|
7164
|
-
userData,
|
|
7055
|
+
userData: mergedUserData,
|
|
7165
7056
|
annotations,
|
|
7166
7057
|
annotationsClass,
|
|
7167
7058
|
LineComponent: LineComp
|
|
@@ -7170,6 +7061,7 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7170
7061
|
onDragStart,
|
|
7171
7062
|
onDrag,
|
|
7172
7063
|
onDragEnd,
|
|
7064
|
+
onHover,
|
|
7173
7065
|
translation,
|
|
7174
7066
|
translationLimits,
|
|
7175
7067
|
rotationLimits,
|
|
@@ -7181,11 +7073,12 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
7181
7073
|
...axisColors,
|
|
7182
7074
|
hoveredColor,
|
|
7183
7075
|
opacity,
|
|
7184
|
-
|
|
7076
|
+
mergedUserData,
|
|
7185
7077
|
autoTransform,
|
|
7186
7078
|
annotations,
|
|
7187
7079
|
annotationsClass,
|
|
7188
|
-
LineComp
|
|
7080
|
+
LineComp,
|
|
7081
|
+
object
|
|
7189
7082
|
]
|
|
7190
7083
|
);
|
|
7191
7084
|
const vec = new THREE.Vector3();
|
|
@@ -7547,7 +7440,7 @@ function createInstances() {
|
|
|
7547
7440
|
];
|
|
7548
7441
|
}
|
|
7549
7442
|
const InstancedAttribute = React.forwardRef(
|
|
7550
|
-
({ name, defaultValue, normalized, usage = THREE.DynamicDrawUsage }, fref) => {
|
|
7443
|
+
({ name, defaultValue, normalized, usage = THREE.DynamicDrawUsage, type = "float" }, fref) => {
|
|
7551
7444
|
const ref = React.useRef(null);
|
|
7552
7445
|
React.useImperativeHandle(fref, () => ref.current, []);
|
|
7553
7446
|
React.useLayoutEffect(() => {
|
|
@@ -7555,7 +7448,26 @@ const InstancedAttribute = React.forwardRef(
|
|
|
7555
7448
|
parent.geometry.attributes[name] = ref.current;
|
|
7556
7449
|
const value = Array.isArray(defaultValue) ? defaultValue : [defaultValue];
|
|
7557
7450
|
const array = Array.from({ length: parent.userData.limit }, () => value).flat();
|
|
7558
|
-
|
|
7451
|
+
switch (type) {
|
|
7452
|
+
case "float":
|
|
7453
|
+
ref.current.array = new Float32Array(array);
|
|
7454
|
+
break;
|
|
7455
|
+
case "int":
|
|
7456
|
+
ref.current.array = new Int32Array(array);
|
|
7457
|
+
break;
|
|
7458
|
+
case "uint":
|
|
7459
|
+
ref.current.array = new Uint32Array(array);
|
|
7460
|
+
break;
|
|
7461
|
+
case "short":
|
|
7462
|
+
ref.current.array = new Int16Array(array);
|
|
7463
|
+
break;
|
|
7464
|
+
case "ushort":
|
|
7465
|
+
ref.current.array = new Uint16Array(array);
|
|
7466
|
+
break;
|
|
7467
|
+
case "byte":
|
|
7468
|
+
ref.current.array = new Uint8Array(array);
|
|
7469
|
+
break;
|
|
7470
|
+
}
|
|
7559
7471
|
ref.current.itemSize = value.length;
|
|
7560
7472
|
ref.current.count = array.length / ref.current.itemSize;
|
|
7561
7473
|
return () => {
|
|
@@ -9080,12 +8992,17 @@ const Gltf = /* @__PURE__ */ React.forwardRef(
|
|
|
9080
8992
|
}
|
|
9081
8993
|
);
|
|
9082
8994
|
|
|
9083
|
-
|
|
9084
|
-
function useKTX2(input, basisPath =
|
|
8995
|
+
let transcoderPath = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
|
|
8996
|
+
function useKTX2(input, basisPath = true, extendLoader) {
|
|
9085
8997
|
const renderer = useThree((state) => state.renderer);
|
|
9086
8998
|
const textures = useLoader(KTX2Loader, IsObject(input) ? Object.values(input) : input, (loader) => {
|
|
8999
|
+
if (extendLoader) {
|
|
9000
|
+
extendLoader(loader);
|
|
9001
|
+
}
|
|
9002
|
+
if (basisPath) {
|
|
9003
|
+
loader.setTranscoderPath(typeof basisPath === "string" ? basisPath : transcoderPath);
|
|
9004
|
+
}
|
|
9087
9005
|
loader.detectSupport(renderer);
|
|
9088
|
-
loader.setTranscoderPath(basisPath);
|
|
9089
9006
|
});
|
|
9090
9007
|
useEffect(() => {
|
|
9091
9008
|
const array = Array.isArray(textures) ? textures : [textures];
|
|
@@ -9100,16 +9017,20 @@ function useKTX2(input, basisPath = `${cdn}/basis/`) {
|
|
|
9100
9017
|
return textures;
|
|
9101
9018
|
}
|
|
9102
9019
|
}
|
|
9103
|
-
useKTX2.preload = (url, basisPath =
|
|
9104
|
-
|
|
9020
|
+
useKTX2.preload = (url, basisPath = true, extendLoader) => useLoader.preload(KTX2Loader, url, (loader) => {
|
|
9021
|
+
if (extendLoader) {
|
|
9022
|
+
extendLoader(loader);
|
|
9023
|
+
}
|
|
9024
|
+
if (basisPath) {
|
|
9025
|
+
loader.setTranscoderPath(typeof basisPath === "string" ? basisPath : transcoderPath);
|
|
9026
|
+
}
|
|
9105
9027
|
});
|
|
9106
9028
|
useKTX2.clear = (input) => useLoader.clear(KTX2Loader, input);
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
const texture = useKTX2(input, basisPath);
|
|
9029
|
+
useKTX2.setTranscoderPath = (path) => {
|
|
9030
|
+
transcoderPath = path;
|
|
9031
|
+
};
|
|
9032
|
+
const Ktx2 = ({ children, input, basisPath, extendLoader }) => {
|
|
9033
|
+
const texture = useKTX2(input, basisPath, extendLoader);
|
|
9113
9034
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(texture));
|
|
9114
9035
|
};
|
|
9115
9036
|
|
|
@@ -9585,18 +9506,21 @@ function Fisheye({
|
|
|
9585
9506
|
const normal = new THREE.Vector3();
|
|
9586
9507
|
const sph = new THREE.Sphere(new THREE.Vector3(), radius);
|
|
9587
9508
|
const normalMatrix = new THREE.Matrix3();
|
|
9588
|
-
const compute = React.useCallback(
|
|
9589
|
-
|
|
9590
|
-
|
|
9591
|
-
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9509
|
+
const compute = React.useCallback(
|
|
9510
|
+
(event, state, prev) => {
|
|
9511
|
+
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
9512
|
+
state.raycaster.setFromCamera(state.pointer, orthoC);
|
|
9513
|
+
if (!state.raycaster.ray.intersectSphere(sph, normal)) return;
|
|
9514
|
+
else normal.normalize();
|
|
9515
|
+
normalMatrix.getNormalMatrix(cubeApi.current.camera.matrixWorld);
|
|
9516
|
+
cubeApi.current.camera.getWorldPosition(state.raycaster.ray.origin);
|
|
9517
|
+
state.raycaster.ray.direction.set(0, 0, 1).reflect(normal);
|
|
9518
|
+
state.raycaster.ray.direction.x *= -1;
|
|
9519
|
+
state.raycaster.ray.direction.applyNormalMatrix(normalMatrix).multiplyScalar(-1);
|
|
9520
|
+
return void 0;
|
|
9521
|
+
},
|
|
9522
|
+
[width, height]
|
|
9523
|
+
);
|
|
9600
9524
|
useFrame(
|
|
9601
9525
|
({ gl }) => {
|
|
9602
9526
|
if (renderPriority) gl.render(sphere.current, orthoC);
|
|
@@ -9731,14 +9655,22 @@ const isWebGPURenderer = (def) => !!def.isWebGPURenderer;
|
|
|
9731
9655
|
const col = /* @__PURE__ */ new THREE.Color();
|
|
9732
9656
|
const TUNNEL_KEY = "__drei_view_tunnel__";
|
|
9733
9657
|
const tracked = globalThis[TUNNEL_KEY] || (globalThis[TUNNEL_KEY] = tunnel());
|
|
9734
|
-
function computeContainerPosition(canvasSize, trackRect) {
|
|
9658
|
+
function computeContainerPosition(canvasSize, trackRect, forceEven) {
|
|
9735
9659
|
const { right, top: trackTop, left: trackLeft, bottom: trackBottom, width, height } = trackRect;
|
|
9736
9660
|
const isOffscreen = trackRect.bottom < 0 || trackTop > canvasSize.height || right < 0 || trackRect.left > canvasSize.width;
|
|
9737
9661
|
const canvasBottom = canvasSize.top + canvasSize.height;
|
|
9738
|
-
const
|
|
9739
|
-
const
|
|
9740
|
-
const
|
|
9741
|
-
|
|
9662
|
+
const rawBottom = canvasBottom - trackBottom;
|
|
9663
|
+
const rawLeft = trackLeft - canvasSize.left;
|
|
9664
|
+
const rawTop = trackTop - canvasSize.top;
|
|
9665
|
+
const position = forceEven ? {
|
|
9666
|
+
width: roundEven(width),
|
|
9667
|
+
height: roundEven(height),
|
|
9668
|
+
left: roundEven(rawLeft),
|
|
9669
|
+
top: roundEven(rawTop),
|
|
9670
|
+
bottom: roundEven(rawBottom),
|
|
9671
|
+
right: roundEven(right)
|
|
9672
|
+
} : { width, height, left: rawLeft, top: rawTop, bottom: rawBottom, right };
|
|
9673
|
+
return { position, isOffscreen };
|
|
9742
9674
|
}
|
|
9743
9675
|
function prepareSkissor(renderer, camera, {
|
|
9744
9676
|
left,
|
|
@@ -9778,6 +9710,7 @@ function clear(renderer) {
|
|
|
9778
9710
|
}
|
|
9779
9711
|
function Container({ visible = true, canvasSize, scene, index, children, frames, rect, track }) {
|
|
9780
9712
|
const { scene: portalScene, camera: portalCamera, renderer, get, setEvents } = useThree();
|
|
9713
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
9781
9714
|
const [isOffscreen, setOffscreen] = React.useState(false);
|
|
9782
9715
|
const mountedRef = React.useRef(true);
|
|
9783
9716
|
React.useEffect(() => {
|
|
@@ -9795,7 +9728,7 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
9795
9728
|
frameCount++;
|
|
9796
9729
|
}
|
|
9797
9730
|
if (rect.current) {
|
|
9798
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, rect.current);
|
|
9731
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, rect.current, forceEven);
|
|
9799
9732
|
if (isOffscreen !== _isOffscreen) setOffscreen(_isOffscreen);
|
|
9800
9733
|
if (visible && !_isOffscreen && rect.current) {
|
|
9801
9734
|
const targetScene = children ? portalScene : scene;
|
|
@@ -9817,14 +9750,14 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
9817
9750
|
React.useLayoutEffect(() => {
|
|
9818
9751
|
const curRect = rect.current;
|
|
9819
9752
|
if (curRect && (!visible || !isOffscreen)) {
|
|
9820
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect);
|
|
9753
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect, forceEven);
|
|
9821
9754
|
if (!_isOffscreen) {
|
|
9822
9755
|
const autoClear = prepareSkissor(renderer, portalCamera, position);
|
|
9823
9756
|
clear(renderer);
|
|
9824
9757
|
finishSkissor(renderer, autoClear);
|
|
9825
9758
|
}
|
|
9826
9759
|
}
|
|
9827
|
-
}, [visible, isOffscreen, renderer, portalCamera, canvasSize]);
|
|
9760
|
+
}, [visible, isOffscreen, renderer, portalCamera, canvasSize, forceEven]);
|
|
9828
9761
|
React.useEffect(() => {
|
|
9829
9762
|
if (!track) return;
|
|
9830
9763
|
const curRect = rect.current;
|
|
@@ -9832,7 +9765,7 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
9832
9765
|
setEvents({ connected: track.current });
|
|
9833
9766
|
return () => {
|
|
9834
9767
|
if (curRect) {
|
|
9835
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect);
|
|
9768
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect, forceEven);
|
|
9836
9769
|
if (!_isOffscreen) {
|
|
9837
9770
|
const autoClear = prepareSkissor(renderer, portalCamera, position);
|
|
9838
9771
|
clear(renderer);
|
|
@@ -9841,13 +9774,14 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
9841
9774
|
}
|
|
9842
9775
|
setEvents({ connected: old });
|
|
9843
9776
|
};
|
|
9844
|
-
}, [track, renderer, portalCamera, canvasSize, get, setEvents]);
|
|
9777
|
+
}, [track, renderer, portalCamera, canvasSize, get, setEvents, forceEven]);
|
|
9845
9778
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children, /* @__PURE__ */ React.createElement("group", { onPointerOver: () => null }));
|
|
9846
9779
|
}
|
|
9847
9780
|
const CanvasView = /* @__PURE__ */ React.forwardRef(
|
|
9848
9781
|
({ track, visible = true, index = 1, id, style, className, frames = Infinity, children, ...props }, fref) => {
|
|
9849
9782
|
const rect = React.useRef(null);
|
|
9850
9783
|
const { size, scene } = useThree();
|
|
9784
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
9851
9785
|
const [virtualScene] = React.useState(() => new THREE.Scene());
|
|
9852
9786
|
const [ready, toggle] = React.useReducer(() => true, false);
|
|
9853
9787
|
const compute = React.useCallback(
|
|
@@ -9884,12 +9818,12 @@ const CanvasView = /* @__PURE__ */ React.forwardRef(
|
|
|
9884
9818
|
{
|
|
9885
9819
|
events: { compute, priority: index },
|
|
9886
9820
|
size: {
|
|
9887
|
-
width: rect.current?.width,
|
|
9888
|
-
height: rect.current?.height,
|
|
9821
|
+
width: forceEven && rect.current?.width ? roundEven(rect.current.width) : rect.current?.width,
|
|
9822
|
+
height: forceEven && rect.current?.height ? roundEven(rect.current.height) : rect.current?.height,
|
|
9889
9823
|
// @ts-ignore
|
|
9890
|
-
top: rect.current?.top,
|
|
9824
|
+
top: forceEven && rect.current?.top ? roundEven(rect.current.top) : rect.current?.top,
|
|
9891
9825
|
// @ts-ignore
|
|
9892
|
-
left: rect.current?.left
|
|
9826
|
+
left: forceEven && rect.current?.left ? roundEven(rect.current.left) : rect.current?.left
|
|
9893
9827
|
}
|
|
9894
9828
|
}
|
|
9895
9829
|
));
|
|
@@ -10316,8 +10250,8 @@ function getLoader(extension) {
|
|
|
10316
10250
|
return loader;
|
|
10317
10251
|
}
|
|
10318
10252
|
|
|
10319
|
-
const isRef = (obj) => obj.current && obj.current.isScene;
|
|
10320
|
-
const resolveScene = (scene) => isRef(scene) ? scene.current : scene;
|
|
10253
|
+
const isRef$1 = (obj) => obj.current && obj.current.isScene;
|
|
10254
|
+
const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
|
|
10321
10255
|
function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
|
|
10322
10256
|
sceneProps = {
|
|
10323
10257
|
backgroundBlurriness: 0,
|
|
@@ -10674,433 +10608,804 @@ const Sky = /* @__PURE__ */ React.forwardRef(
|
|
|
10674
10608
|
}
|
|
10675
10609
|
);
|
|
10676
10610
|
|
|
10677
|
-
const presets = {
|
|
10678
|
-
rembrandt: {
|
|
10679
|
-
main: [1, 2, 1],
|
|
10680
|
-
fill: [-2, -0.5, -2]
|
|
10681
|
-
},
|
|
10682
|
-
portrait: {
|
|
10683
|
-
main: [-1, 2, 0.5],
|
|
10684
|
-
fill: [-1, 0.5, -1.5]
|
|
10685
|
-
},
|
|
10686
|
-
upfront: {
|
|
10687
|
-
main: [0, 2, 1],
|
|
10688
|
-
fill: [-1, 0.5, -1.5]
|
|
10689
|
-
},
|
|
10690
|
-
soft: {
|
|
10691
|
-
main: [-2, 4, 4],
|
|
10692
|
-
fill: [-1, 0.5, -1.5]
|
|
10693
|
-
}
|
|
10611
|
+
const presets = {
|
|
10612
|
+
rembrandt: {
|
|
10613
|
+
main: [1, 2, 1],
|
|
10614
|
+
fill: [-2, -0.5, -2]
|
|
10615
|
+
},
|
|
10616
|
+
portrait: {
|
|
10617
|
+
main: [-1, 2, 0.5],
|
|
10618
|
+
fill: [-1, 0.5, -1.5]
|
|
10619
|
+
},
|
|
10620
|
+
upfront: {
|
|
10621
|
+
main: [0, 2, 1],
|
|
10622
|
+
fill: [-1, 0.5, -1.5]
|
|
10623
|
+
},
|
|
10624
|
+
soft: {
|
|
10625
|
+
main: [-2, 4, 4],
|
|
10626
|
+
fill: [-1, 0.5, -1.5]
|
|
10627
|
+
}
|
|
10628
|
+
};
|
|
10629
|
+
function Refit({ radius, adjustCamera }) {
|
|
10630
|
+
const api = useBounds();
|
|
10631
|
+
React.useEffect(() => {
|
|
10632
|
+
if (adjustCamera) api.refresh().clip().fit();
|
|
10633
|
+
}, [radius, adjustCamera]);
|
|
10634
|
+
return null;
|
|
10635
|
+
}
|
|
10636
|
+
function Stage({
|
|
10637
|
+
children,
|
|
10638
|
+
center,
|
|
10639
|
+
adjustCamera = true,
|
|
10640
|
+
intensity = 0.5,
|
|
10641
|
+
shadows = "contact",
|
|
10642
|
+
environment = "city",
|
|
10643
|
+
preset = "rembrandt",
|
|
10644
|
+
...props
|
|
10645
|
+
}) {
|
|
10646
|
+
const config = typeof preset === "string" ? presets[preset] : preset;
|
|
10647
|
+
const [{ radius, height }, set] = React.useState({ radius: 0, width: 0, height: 0, depth: 0 });
|
|
10648
|
+
const shadowBias = shadows?.bias ?? -1e-4;
|
|
10649
|
+
const normalBias = shadows?.normalBias ?? 0;
|
|
10650
|
+
const shadowSize = shadows?.size ?? 1024;
|
|
10651
|
+
const shadowOffset = shadows?.offset ?? 0;
|
|
10652
|
+
const contactShadow = shadows === "contact" || shadows?.type === "contact";
|
|
10653
|
+
const accumulativeShadow = shadows === "accumulative" || shadows?.type === "accumulative";
|
|
10654
|
+
const shadowSpread = { ...typeof shadows === "object" ? shadows : {} };
|
|
10655
|
+
const environmentProps = !environment ? null : typeof environment === "string" ? { preset: environment } : environment;
|
|
10656
|
+
const onCentered = React.useCallback((props2) => {
|
|
10657
|
+
const { width, height: height2, depth, boundingSphere } = props2;
|
|
10658
|
+
set({ radius: boundingSphere.radius, width, height: height2, depth });
|
|
10659
|
+
if (center?.onCentered) center.onCentered(props2);
|
|
10660
|
+
}, []);
|
|
10661
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("ambientLight", { intensity: intensity / 3 }), /* @__PURE__ */ React.createElement(
|
|
10662
|
+
"spotLight",
|
|
10663
|
+
{
|
|
10664
|
+
penumbra: 1,
|
|
10665
|
+
position: [config.main[0] * radius, config.main[1] * radius, config.main[2] * radius],
|
|
10666
|
+
intensity: intensity * 2,
|
|
10667
|
+
castShadow: !!shadows,
|
|
10668
|
+
"shadow-bias": shadowBias,
|
|
10669
|
+
"shadow-normalBias": normalBias,
|
|
10670
|
+
"shadow-mapSize": shadowSize
|
|
10671
|
+
}
|
|
10672
|
+
), /* @__PURE__ */ React.createElement(
|
|
10673
|
+
"pointLight",
|
|
10674
|
+
{
|
|
10675
|
+
position: [config.fill[0] * radius, config.fill[1] * radius, config.fill[2] * radius],
|
|
10676
|
+
intensity
|
|
10677
|
+
}
|
|
10678
|
+
), /* @__PURE__ */ React.createElement(Bounds, { fit: !!adjustCamera, clip: !!adjustCamera, margin: Number(adjustCamera), observe: true, ...props }, /* @__PURE__ */ React.createElement(Refit, { radius, adjustCamera }), /* @__PURE__ */ React.createElement(Center, { ...center, position: [0, shadowOffset / 2, 0], onCentered }, children)), /* @__PURE__ */ React.createElement("group", { position: [0, -height / 2 - shadowOffset / 2, 0] }, contactShadow && /* @__PURE__ */ React.createElement(ContactShadows, { scale: radius * 4, far: radius, blur: 2, ...shadowSpread }), accumulativeShadow && /* @__PURE__ */ React.createElement(
|
|
10679
|
+
AccumulativeShadows,
|
|
10680
|
+
{
|
|
10681
|
+
temporal: true,
|
|
10682
|
+
frames: 100,
|
|
10683
|
+
alphaTest: 0.9,
|
|
10684
|
+
toneMapped: true,
|
|
10685
|
+
scale: radius * 4,
|
|
10686
|
+
...shadowSpread
|
|
10687
|
+
},
|
|
10688
|
+
/* @__PURE__ */ React.createElement(
|
|
10689
|
+
RandomizedLight,
|
|
10690
|
+
{
|
|
10691
|
+
amount: shadowSpread.amount ?? 8,
|
|
10692
|
+
radius: shadowSpread.radius ?? radius,
|
|
10693
|
+
ambient: shadowSpread.ambient ?? 0.5,
|
|
10694
|
+
intensity: shadowSpread.intensity ?? 1,
|
|
10695
|
+
position: [config.main[0] * radius, config.main[1] * radius, config.main[2] * radius],
|
|
10696
|
+
size: radius * 4,
|
|
10697
|
+
bias: -shadowBias,
|
|
10698
|
+
mapSize: shadowSize
|
|
10699
|
+
}
|
|
10700
|
+
)
|
|
10701
|
+
)), environment && /* @__PURE__ */ React.createElement(Environment, { ...environmentProps }));
|
|
10702
|
+
}
|
|
10703
|
+
|
|
10704
|
+
function getFormatString(format) {
|
|
10705
|
+
switch (format) {
|
|
10706
|
+
case 64:
|
|
10707
|
+
return "-64px";
|
|
10708
|
+
case 128:
|
|
10709
|
+
return "-128px";
|
|
10710
|
+
case 256:
|
|
10711
|
+
return "-256px";
|
|
10712
|
+
case 512:
|
|
10713
|
+
return "-512px";
|
|
10714
|
+
default:
|
|
10715
|
+
return "";
|
|
10716
|
+
}
|
|
10717
|
+
}
|
|
10718
|
+
const LIST_URL$1 = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/matcaps.json";
|
|
10719
|
+
const MATCAP_ROOT = "https://rawcdn.githack.com/emmelleppi/matcaps/9b36ccaaf0a24881a39062d05566c9e92be4aa0d";
|
|
10720
|
+
function useMatcapTexture(id = 0, format = 1024, onLoad) {
|
|
10721
|
+
const matcapList = suspend(() => fetch(LIST_URL$1).then((res) => res.json()), ["matcapList"]);
|
|
10722
|
+
const DEFAULT_MATCAP = matcapList[0];
|
|
10723
|
+
const numTot = React.useMemo(() => Object.keys(matcapList).length, []);
|
|
10724
|
+
const fileHash = React.useMemo(() => {
|
|
10725
|
+
if (typeof id === "string") {
|
|
10726
|
+
return id;
|
|
10727
|
+
} else if (typeof id === "number") {
|
|
10728
|
+
return matcapList[id];
|
|
10729
|
+
}
|
|
10730
|
+
return null;
|
|
10731
|
+
}, [id]);
|
|
10732
|
+
const fileName = `${fileHash || DEFAULT_MATCAP}${getFormatString(format)}.png`;
|
|
10733
|
+
const url = `${MATCAP_ROOT}/${format}/${fileName}`;
|
|
10734
|
+
const matcapTexture = useTexture(url, onLoad);
|
|
10735
|
+
return [matcapTexture, url, numTot];
|
|
10736
|
+
}
|
|
10737
|
+
const MatcapTexture = ({
|
|
10738
|
+
children,
|
|
10739
|
+
id,
|
|
10740
|
+
format,
|
|
10741
|
+
onLoad
|
|
10742
|
+
}) => {
|
|
10743
|
+
const texture = useMatcapTexture(id, format, onLoad);
|
|
10744
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(texture));
|
|
10745
|
+
};
|
|
10746
|
+
|
|
10747
|
+
const NORMAL_ROOT = "https://rawcdn.githack.com/pmndrs/drei-assets/7a3104997e1576f83472829815b00880d88b32fb";
|
|
10748
|
+
const LIST_URL = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/normals/normals.json";
|
|
10749
|
+
function useNormalTexture(id = 0, settings = {}, onLoad) {
|
|
10750
|
+
const { repeat = [1, 1], anisotropy = 1, offset = [0, 0] } = settings;
|
|
10751
|
+
const normalsList = suspend(() => fetch(LIST_URL).then((res) => res.json()), ["normalsList"]);
|
|
10752
|
+
const numTot = React.useMemo(() => Object.keys(normalsList).length, []);
|
|
10753
|
+
const DEFAULT_NORMAL = normalsList[0];
|
|
10754
|
+
const imageName = normalsList[id] || DEFAULT_NORMAL;
|
|
10755
|
+
const url = `${NORMAL_ROOT}/normals/${imageName}`;
|
|
10756
|
+
const normalTexture = useTexture(url, onLoad);
|
|
10757
|
+
React.useLayoutEffect(() => {
|
|
10758
|
+
if (!normalTexture) return;
|
|
10759
|
+
normalTexture.wrapS = normalTexture.wrapT = RepeatWrapping;
|
|
10760
|
+
normalTexture.repeat = new Vector2(repeat[0], repeat[1]);
|
|
10761
|
+
normalTexture.offset = new Vector2(offset[0], offset[1]);
|
|
10762
|
+
normalTexture.anisotropy = anisotropy;
|
|
10763
|
+
}, [normalTexture, anisotropy, repeat, offset]);
|
|
10764
|
+
return [normalTexture, url, numTot];
|
|
10765
|
+
}
|
|
10766
|
+
const NormalTexture = ({
|
|
10767
|
+
children,
|
|
10768
|
+
id,
|
|
10769
|
+
onLoad,
|
|
10770
|
+
...settings
|
|
10771
|
+
}) => {
|
|
10772
|
+
const ret = useNormalTexture(id, settings, onLoad);
|
|
10773
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(ret));
|
|
10694
10774
|
};
|
|
10695
|
-
|
|
10696
|
-
|
|
10775
|
+
|
|
10776
|
+
function CycleRaycast({
|
|
10777
|
+
onChanged,
|
|
10778
|
+
portal,
|
|
10779
|
+
preventDefault = true,
|
|
10780
|
+
scroll = true,
|
|
10781
|
+
keyCode = 9
|
|
10782
|
+
}) {
|
|
10783
|
+
const cycle = React.useRef(0);
|
|
10784
|
+
const setEvents = useThree((state) => state.setEvents);
|
|
10785
|
+
const get = useThree((state) => state.get);
|
|
10786
|
+
const gl = useThree((state) => state.gl);
|
|
10697
10787
|
React.useEffect(() => {
|
|
10698
|
-
|
|
10699
|
-
|
|
10788
|
+
let hits = [];
|
|
10789
|
+
let lastEvent = void 0;
|
|
10790
|
+
const prev = get().events.filter;
|
|
10791
|
+
const target = portal?.current ?? gl.domElement.parentNode;
|
|
10792
|
+
const renderStatus = () => target && onChanged && onChanged(hits, Math.round(cycle.current) % hits.length);
|
|
10793
|
+
setEvents({
|
|
10794
|
+
filter: (intersections, state) => {
|
|
10795
|
+
let clone = [...intersections];
|
|
10796
|
+
if (clone.length !== hits.length || !hits.every((hit) => clone.map((e) => e.object.uuid).includes(hit.object.uuid))) {
|
|
10797
|
+
cycle.current = 0;
|
|
10798
|
+
hits = clone;
|
|
10799
|
+
renderStatus();
|
|
10800
|
+
}
|
|
10801
|
+
if (prev) clone = prev(clone, state);
|
|
10802
|
+
for (let i = 0; i < Math.round(cycle.current) % clone.length; i++) {
|
|
10803
|
+
const first = clone.shift();
|
|
10804
|
+
clone = [...clone, first];
|
|
10805
|
+
}
|
|
10806
|
+
return clone;
|
|
10807
|
+
}
|
|
10808
|
+
});
|
|
10809
|
+
const refresh = (fn) => {
|
|
10810
|
+
cycle.current = fn(cycle.current);
|
|
10811
|
+
get().events.handlers?.onPointerCancel(void 0);
|
|
10812
|
+
get().events.handlers?.onPointerMove(lastEvent);
|
|
10813
|
+
renderStatus();
|
|
10814
|
+
};
|
|
10815
|
+
const tabEvent = (event) => {
|
|
10816
|
+
if ((event.keyCode || event.which) === keyCode) {
|
|
10817
|
+
if (preventDefault) event.preventDefault();
|
|
10818
|
+
if (hits.length > 1) refresh((current) => current + 1);
|
|
10819
|
+
}
|
|
10820
|
+
};
|
|
10821
|
+
const wheelEvent = (event) => {
|
|
10822
|
+
if (preventDefault) event.preventDefault();
|
|
10823
|
+
let delta = 0;
|
|
10824
|
+
if (!event) event = window.event;
|
|
10825
|
+
if (event.wheelDelta) delta = event.wheelDelta / 120;
|
|
10826
|
+
else if (event.detail) delta = -event.detail / 3;
|
|
10827
|
+
if (hits.length > 1) refresh((current) => Math.abs(current - delta));
|
|
10828
|
+
};
|
|
10829
|
+
const moveEvent = (event) => lastEvent = event;
|
|
10830
|
+
document.addEventListener("pointermove", moveEvent, { passive: true });
|
|
10831
|
+
if (scroll) document.addEventListener("wheel", wheelEvent);
|
|
10832
|
+
if (keyCode !== void 0) document.addEventListener("keydown", tabEvent);
|
|
10833
|
+
return () => {
|
|
10834
|
+
setEvents({ filter: prev });
|
|
10835
|
+
if (keyCode !== void 0) document.removeEventListener("keydown", tabEvent);
|
|
10836
|
+
if (scroll) document.removeEventListener("wheel", wheelEvent);
|
|
10837
|
+
document.removeEventListener("pointermove", moveEvent);
|
|
10838
|
+
};
|
|
10839
|
+
}, [gl, get, setEvents, preventDefault, scroll, keyCode]);
|
|
10700
10840
|
return null;
|
|
10701
10841
|
}
|
|
10702
|
-
|
|
10842
|
+
|
|
10843
|
+
function useAspect(width, height, factor = 1) {
|
|
10844
|
+
const v = useThree((state) => state.viewport);
|
|
10845
|
+
const adaptedHeight = height * (v.aspect > width / height ? v.width / width : v.height / height);
|
|
10846
|
+
const adaptedWidth = width * (v.aspect > width / height ? v.width / width : v.height / height);
|
|
10847
|
+
return [adaptedWidth * factor, adaptedHeight * factor, 1];
|
|
10848
|
+
}
|
|
10849
|
+
|
|
10850
|
+
function useCursor(hovered, onPointerOver = "pointer", onPointerOut = "auto", container = document.body) {
|
|
10851
|
+
React.useEffect(() => {
|
|
10852
|
+
if (hovered) {
|
|
10853
|
+
container.style.cursor = onPointerOver;
|
|
10854
|
+
return () => void (container.style.cursor = onPointerOut);
|
|
10855
|
+
}
|
|
10856
|
+
}, [hovered]);
|
|
10857
|
+
}
|
|
10858
|
+
|
|
10859
|
+
const ScreenSpace = /* @__PURE__ */ React.forwardRef(({ children, depth = -1, ...rest }, ref) => {
|
|
10860
|
+
const localRef = React.useRef(null);
|
|
10861
|
+
React.useImperativeHandle(ref, () => localRef.current, []);
|
|
10862
|
+
useFrame(({ camera }) => {
|
|
10863
|
+
localRef.current.quaternion.copy(camera.quaternion);
|
|
10864
|
+
localRef.current.position.copy(camera.position);
|
|
10865
|
+
});
|
|
10866
|
+
return /* @__PURE__ */ React.createElement("group", { ref: localRef, ...rest }, /* @__PURE__ */ React.createElement("group", { "position-z": -depth }, children));
|
|
10867
|
+
});
|
|
10868
|
+
|
|
10869
|
+
const context = /* @__PURE__ */ React.createContext([]);
|
|
10870
|
+
function Select({
|
|
10871
|
+
box,
|
|
10872
|
+
multiple,
|
|
10703
10873
|
children,
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
|
|
10707
|
-
|
|
10708
|
-
|
|
10709
|
-
preset = "rembrandt",
|
|
10874
|
+
onChange,
|
|
10875
|
+
onChangePointerUp,
|
|
10876
|
+
border = "1px solid #55aaff",
|
|
10877
|
+
backgroundColor = "rgba(75, 160, 255, 0.1)",
|
|
10878
|
+
filter: customFilter = (item) => item,
|
|
10710
10879
|
...props
|
|
10711
10880
|
}) {
|
|
10712
|
-
const
|
|
10713
|
-
const
|
|
10714
|
-
const
|
|
10715
|
-
const
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10881
|
+
const [downed, down] = React.useState(false);
|
|
10882
|
+
const { setEvents, camera, raycaster, gl, controls, size, get } = useThree();
|
|
10883
|
+
const [hovered, hover] = React.useState(false);
|
|
10884
|
+
const [active, dispatch] = React.useReducer(
|
|
10885
|
+
// @ts-expect-error
|
|
10886
|
+
(state, { object, shift }) => {
|
|
10887
|
+
if (object === void 0) return [];
|
|
10888
|
+
else if (Array.isArray(object)) return object;
|
|
10889
|
+
else if (!shift) return state[0] === object ? [] : [object];
|
|
10890
|
+
else if (state.includes(object)) return state.filter((o) => o !== object);
|
|
10891
|
+
else return [object, ...state];
|
|
10892
|
+
},
|
|
10893
|
+
[]
|
|
10894
|
+
);
|
|
10895
|
+
React.useEffect(() => {
|
|
10896
|
+
if (downed) onChange?.(active);
|
|
10897
|
+
else onChangePointerUp?.(active);
|
|
10898
|
+
}, [active, downed]);
|
|
10899
|
+
const onClick = React.useCallback((e) => {
|
|
10900
|
+
e.stopPropagation();
|
|
10901
|
+
dispatch({ object: customFilter([e.object])[0], shift: multiple && e.shiftKey });
|
|
10726
10902
|
}, []);
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
|
|
10903
|
+
const onPointerMissed = React.useCallback((e) => !hovered && dispatch({}), [hovered]);
|
|
10904
|
+
const ref = React.useRef(null);
|
|
10905
|
+
React.useEffect(() => {
|
|
10906
|
+
if (!box || !multiple) return;
|
|
10907
|
+
const selBox = new SelectionBox(camera, ref.current);
|
|
10908
|
+
const element = document.createElement("div");
|
|
10909
|
+
element.style.pointerEvents = "none";
|
|
10910
|
+
element.style.border = border;
|
|
10911
|
+
element.style.backgroundColor = backgroundColor;
|
|
10912
|
+
element.style.position = "fixed";
|
|
10913
|
+
const startPoint = new THREE.Vector2();
|
|
10914
|
+
const pointTopLeft = new THREE.Vector2();
|
|
10915
|
+
const pointBottomRight = new THREE.Vector2();
|
|
10916
|
+
const oldRaycasterEnabled = get().events.enabled;
|
|
10917
|
+
const oldControlsEnabled = controls?.enabled;
|
|
10918
|
+
let isDown = false;
|
|
10919
|
+
function prepareRay(event, vec) {
|
|
10920
|
+
const { offsetX, offsetY } = event;
|
|
10921
|
+
const { width, height } = size;
|
|
10922
|
+
vec.set(offsetX / width * 2 - 1, -(offsetY / height) * 2 + 1);
|
|
10923
|
+
}
|
|
10924
|
+
function onSelectStart(event) {
|
|
10925
|
+
if (controls) controls.enabled = false;
|
|
10926
|
+
setEvents({ enabled: false });
|
|
10927
|
+
down(isDown = true);
|
|
10928
|
+
gl.domElement.parentElement?.appendChild(element);
|
|
10929
|
+
element.style.left = `${event.clientX}px`;
|
|
10930
|
+
element.style.top = `${event.clientY}px`;
|
|
10931
|
+
element.style.width = "0px";
|
|
10932
|
+
element.style.height = "0px";
|
|
10933
|
+
startPoint.x = event.clientX;
|
|
10934
|
+
startPoint.y = event.clientY;
|
|
10935
|
+
}
|
|
10936
|
+
function onSelectMove(event) {
|
|
10937
|
+
pointBottomRight.x = Math.max(startPoint.x, event.clientX);
|
|
10938
|
+
pointBottomRight.y = Math.max(startPoint.y, event.clientY);
|
|
10939
|
+
pointTopLeft.x = Math.min(startPoint.x, event.clientX);
|
|
10940
|
+
pointTopLeft.y = Math.min(startPoint.y, event.clientY);
|
|
10941
|
+
element.style.left = `${pointTopLeft.x}px`;
|
|
10942
|
+
element.style.top = `${pointTopLeft.y}px`;
|
|
10943
|
+
element.style.width = `${pointBottomRight.x - pointTopLeft.x}px`;
|
|
10944
|
+
element.style.height = `${pointBottomRight.y - pointTopLeft.y}px`;
|
|
10945
|
+
}
|
|
10946
|
+
function onSelectOver() {
|
|
10947
|
+
if (isDown) {
|
|
10948
|
+
if (controls) controls.enabled = oldControlsEnabled;
|
|
10949
|
+
setEvents({ enabled: oldRaycasterEnabled });
|
|
10950
|
+
down(isDown = false);
|
|
10951
|
+
element.parentElement?.removeChild(element);
|
|
10952
|
+
}
|
|
10737
10953
|
}
|
|
10738
|
-
|
|
10739
|
-
|
|
10740
|
-
|
|
10741
|
-
|
|
10742
|
-
|
|
10954
|
+
function pointerDown(event) {
|
|
10955
|
+
if (event.shiftKey) {
|
|
10956
|
+
onSelectStart(event);
|
|
10957
|
+
prepareRay(event, selBox.startPoint);
|
|
10958
|
+
}
|
|
10743
10959
|
}
|
|
10744
|
-
|
|
10745
|
-
|
|
10960
|
+
let previous = [];
|
|
10961
|
+
function pointerMove(event) {
|
|
10962
|
+
if (isDown) {
|
|
10963
|
+
onSelectMove(event);
|
|
10964
|
+
prepareRay(event, selBox.endPoint);
|
|
10965
|
+
const allSelected = selBox.select().sort((o) => o.uuid).filter((o) => o.isMesh);
|
|
10966
|
+
if (!shallow(allSelected, previous)) {
|
|
10967
|
+
previous = allSelected;
|
|
10968
|
+
dispatch({ object: customFilter(allSelected) });
|
|
10969
|
+
}
|
|
10970
|
+
}
|
|
10971
|
+
}
|
|
10972
|
+
function pointerUp(event) {
|
|
10973
|
+
if (isDown) onSelectOver();
|
|
10974
|
+
}
|
|
10975
|
+
document.addEventListener("pointerdown", pointerDown, { passive: true });
|
|
10976
|
+
document.addEventListener("pointermove", pointerMove, { passive: true, capture: true });
|
|
10977
|
+
document.addEventListener("pointerup", pointerUp, { passive: true });
|
|
10978
|
+
return () => {
|
|
10979
|
+
document.removeEventListener("pointerdown", pointerDown);
|
|
10980
|
+
document.removeEventListener("pointermove", pointerMove, true);
|
|
10981
|
+
document.removeEventListener("pointerup", pointerUp);
|
|
10982
|
+
};
|
|
10983
|
+
}, [size.width, size.height, raycaster, camera, controls, gl]);
|
|
10984
|
+
return /* @__PURE__ */ React.createElement(
|
|
10985
|
+
"group",
|
|
10746
10986
|
{
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
...
|
|
10987
|
+
ref,
|
|
10988
|
+
onClick,
|
|
10989
|
+
onPointerOver: () => hover(true),
|
|
10990
|
+
onPointerOut: () => hover(false),
|
|
10991
|
+
onPointerMissed,
|
|
10992
|
+
...props
|
|
10753
10993
|
},
|
|
10754
|
-
/* @__PURE__ */ React.createElement(
|
|
10755
|
-
|
|
10756
|
-
{
|
|
10757
|
-
amount: shadowSpread.amount ?? 8,
|
|
10758
|
-
radius: shadowSpread.radius ?? radius,
|
|
10759
|
-
ambient: shadowSpread.ambient ?? 0.5,
|
|
10760
|
-
intensity: shadowSpread.intensity ?? 1,
|
|
10761
|
-
position: [config.main[0] * radius, config.main[1] * radius, config.main[2] * radius],
|
|
10762
|
-
size: radius * 4,
|
|
10763
|
-
bias: -shadowBias,
|
|
10764
|
-
mapSize: shadowSize
|
|
10765
|
-
}
|
|
10766
|
-
)
|
|
10767
|
-
)), environment && /* @__PURE__ */ React.createElement(Environment, { ...environmentProps }));
|
|
10994
|
+
/* @__PURE__ */ React.createElement(context.Provider, { value: active }, children)
|
|
10995
|
+
);
|
|
10768
10996
|
}
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
switch (format) {
|
|
10772
|
-
case 64:
|
|
10773
|
-
return "-64px";
|
|
10774
|
-
case 128:
|
|
10775
|
-
return "-128px";
|
|
10776
|
-
case 256:
|
|
10777
|
-
return "-256px";
|
|
10778
|
-
case 512:
|
|
10779
|
-
return "-512px";
|
|
10780
|
-
default:
|
|
10781
|
-
return "";
|
|
10782
|
-
}
|
|
10997
|
+
function useSelect() {
|
|
10998
|
+
return React.useContext(context);
|
|
10783
10999
|
}
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
|
|
10793
|
-
|
|
10794
|
-
|
|
10795
|
-
|
|
10796
|
-
|
|
10797
|
-
|
|
10798
|
-
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
|
|
11000
|
+
|
|
11001
|
+
function AsciiRenderer({
|
|
11002
|
+
renderIndex = 1,
|
|
11003
|
+
bgColor = "black",
|
|
11004
|
+
fgColor = "white",
|
|
11005
|
+
characters = " .:-+*=%@#",
|
|
11006
|
+
invert = true,
|
|
11007
|
+
color = false,
|
|
11008
|
+
resolution = 0.15
|
|
11009
|
+
}) {
|
|
11010
|
+
const { size, gl, scene, camera } = useThree();
|
|
11011
|
+
const effect = React.useMemo(() => {
|
|
11012
|
+
const effect2 = new AsciiEffect(gl, characters, { invert, color, resolution });
|
|
11013
|
+
effect2.domElement.style.position = "absolute";
|
|
11014
|
+
effect2.domElement.style.top = "0px";
|
|
11015
|
+
effect2.domElement.style.left = "0px";
|
|
11016
|
+
effect2.domElement.style.pointerEvents = "none";
|
|
11017
|
+
return effect2;
|
|
11018
|
+
}, [characters, invert, color, resolution]);
|
|
11019
|
+
React.useLayoutEffect(() => {
|
|
11020
|
+
effect.domElement.style.color = fgColor;
|
|
11021
|
+
effect.domElement.style.backgroundColor = bgColor;
|
|
11022
|
+
}, [fgColor, bgColor]);
|
|
11023
|
+
React.useEffect(() => {
|
|
11024
|
+
gl.domElement.style.opacity = "0";
|
|
11025
|
+
gl.domElement.parentNode.appendChild(effect.domElement);
|
|
11026
|
+
return () => {
|
|
11027
|
+
gl.domElement.style.opacity = "1";
|
|
11028
|
+
gl.domElement.parentNode.removeChild(effect.domElement);
|
|
11029
|
+
};
|
|
11030
|
+
}, [effect]);
|
|
11031
|
+
React.useEffect(() => {
|
|
11032
|
+
effect.setSize(size.width, size.height);
|
|
11033
|
+
}, [effect, size]);
|
|
11034
|
+
useFrame((state) => {
|
|
11035
|
+
effect.render(scene, camera);
|
|
11036
|
+
}, renderIndex);
|
|
11037
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null);
|
|
10802
11038
|
}
|
|
10803
|
-
const MatcapTexture = ({
|
|
10804
|
-
children,
|
|
10805
|
-
id,
|
|
10806
|
-
format,
|
|
10807
|
-
onLoad
|
|
10808
|
-
}) => {
|
|
10809
|
-
const texture = useMatcapTexture(id, format, onLoad);
|
|
10810
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(texture));
|
|
10811
|
-
};
|
|
10812
11039
|
|
|
10813
|
-
const
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
|
|
10818
|
-
|
|
10819
|
-
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
|
|
10823
|
-
|
|
10824
|
-
|
|
10825
|
-
|
|
10826
|
-
|
|
10827
|
-
|
|
10828
|
-
|
|
10829
|
-
|
|
10830
|
-
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
|
|
10834
|
-
|
|
10835
|
-
|
|
10836
|
-
|
|
10837
|
-
|
|
10838
|
-
|
|
10839
|
-
|
|
10840
|
-
|
|
11040
|
+
const WireframeMaterialShaders = {
|
|
11041
|
+
uniforms: {
|
|
11042
|
+
strokeOpacity: 1,
|
|
11043
|
+
fillOpacity: 0.25,
|
|
11044
|
+
fillMix: 0,
|
|
11045
|
+
thickness: 0.05,
|
|
11046
|
+
colorBackfaces: false,
|
|
11047
|
+
dashInvert: true,
|
|
11048
|
+
dash: false,
|
|
11049
|
+
dashRepeats: 4,
|
|
11050
|
+
dashLength: 0.5,
|
|
11051
|
+
squeeze: false,
|
|
11052
|
+
squeezeMin: 0.2,
|
|
11053
|
+
squeezeMax: 1,
|
|
11054
|
+
stroke: /* @__PURE__ */ new THREE.Color("#ff0000"),
|
|
11055
|
+
backfaceStroke: /* @__PURE__ */ new THREE.Color("#0000ff"),
|
|
11056
|
+
fill: /* @__PURE__ */ new THREE.Color("#00ff00")
|
|
11057
|
+
},
|
|
11058
|
+
vertex: (
|
|
11059
|
+
/* glsl */
|
|
11060
|
+
`
|
|
11061
|
+
attribute vec3 barycentric;
|
|
11062
|
+
|
|
11063
|
+
varying vec3 v_edges_Barycentric;
|
|
11064
|
+
varying vec3 v_edges_Position;
|
|
11065
|
+
|
|
11066
|
+
void initWireframe() {
|
|
11067
|
+
v_edges_Barycentric = barycentric;
|
|
11068
|
+
v_edges_Position = position.xyz;
|
|
11069
|
+
}
|
|
11070
|
+
`
|
|
11071
|
+
),
|
|
11072
|
+
fragment: (
|
|
11073
|
+
/* glsl */
|
|
11074
|
+
`
|
|
11075
|
+
#ifndef PI
|
|
11076
|
+
#define PI 3.1415926535897932384626433832795
|
|
11077
|
+
#endif
|
|
11078
|
+
|
|
11079
|
+
varying vec3 v_edges_Barycentric;
|
|
11080
|
+
varying vec3 v_edges_Position;
|
|
11081
|
+
|
|
11082
|
+
uniform float strokeOpacity;
|
|
11083
|
+
uniform float fillOpacity;
|
|
11084
|
+
uniform float fillMix;
|
|
11085
|
+
uniform float thickness;
|
|
11086
|
+
uniform bool colorBackfaces;
|
|
11087
|
+
|
|
11088
|
+
// Dash
|
|
11089
|
+
uniform bool dashInvert;
|
|
11090
|
+
uniform bool dash;
|
|
11091
|
+
uniform bool dashOnly;
|
|
11092
|
+
uniform float dashRepeats;
|
|
11093
|
+
uniform float dashLength;
|
|
11094
|
+
|
|
11095
|
+
// Squeeze
|
|
11096
|
+
uniform bool squeeze;
|
|
11097
|
+
uniform float squeezeMin;
|
|
11098
|
+
uniform float squeezeMax;
|
|
11099
|
+
|
|
11100
|
+
// Colors
|
|
11101
|
+
uniform vec3 stroke;
|
|
11102
|
+
uniform vec3 backfaceStroke;
|
|
11103
|
+
uniform vec3 fill;
|
|
11104
|
+
|
|
11105
|
+
// This is like
|
|
11106
|
+
float wireframe_aastep(float threshold, float dist) {
|
|
11107
|
+
float afwidth = fwidth(dist) * 0.5;
|
|
11108
|
+
return smoothstep(threshold - afwidth, threshold + afwidth, dist);
|
|
11109
|
+
}
|
|
11110
|
+
|
|
11111
|
+
float wireframe_map(float value, float min1, float max1, float min2, float max2) {
|
|
11112
|
+
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
|
|
11113
|
+
}
|
|
11114
|
+
|
|
11115
|
+
float getWireframe() {
|
|
11116
|
+
vec3 barycentric = v_edges_Barycentric;
|
|
11117
|
+
|
|
11118
|
+
// Distance from center of each triangle to its edges.
|
|
11119
|
+
float d = min(min(barycentric.x, barycentric.y), barycentric.z);
|
|
11120
|
+
|
|
11121
|
+
// for dashed rendering, we can use this to get the 0 .. 1 value of the line length
|
|
11122
|
+
float positionAlong = max(barycentric.x, barycentric.y);
|
|
11123
|
+
if (barycentric.y < barycentric.x && barycentric.y < barycentric.z) {
|
|
11124
|
+
positionAlong = 1.0 - positionAlong;
|
|
11125
|
+
}
|
|
11126
|
+
|
|
11127
|
+
// the thickness of the stroke
|
|
11128
|
+
float computedThickness = wireframe_map(thickness, 0.0, 1.0, 0.0, 0.34);
|
|
11129
|
+
|
|
11130
|
+
// if we want to shrink the thickness toward the center of the line segment
|
|
11131
|
+
if (squeeze) {
|
|
11132
|
+
computedThickness *= mix(squeezeMin, squeezeMax, (1.0 - sin(positionAlong * PI)));
|
|
11133
|
+
}
|
|
11134
|
+
|
|
11135
|
+
// Create dash pattern
|
|
11136
|
+
if (dash) {
|
|
11137
|
+
// here we offset the stroke position depending on whether it
|
|
11138
|
+
// should overlap or not
|
|
11139
|
+
float offset = 1.0 / dashRepeats * dashLength / 2.0;
|
|
11140
|
+
if (!dashInvert) {
|
|
11141
|
+
offset += 1.0 / dashRepeats / 2.0;
|
|
11142
|
+
}
|
|
11143
|
+
|
|
11144
|
+
// if we should animate the dash or not
|
|
11145
|
+
// if (dashAnimate) {
|
|
11146
|
+
// offset += time * 0.22;
|
|
11147
|
+
// }
|
|
11148
|
+
|
|
11149
|
+
// create the repeating dash pattern
|
|
11150
|
+
float pattern = fract((positionAlong + offset) * dashRepeats);
|
|
11151
|
+
computedThickness *= 1.0 - wireframe_aastep(dashLength, pattern);
|
|
11152
|
+
}
|
|
10841
11153
|
|
|
10842
|
-
|
|
10843
|
-
|
|
10844
|
-
portal,
|
|
10845
|
-
preventDefault = true,
|
|
10846
|
-
scroll = true,
|
|
10847
|
-
keyCode = 9
|
|
10848
|
-
}) {
|
|
10849
|
-
const cycle = React.useRef(0);
|
|
10850
|
-
const setEvents = useThree((state) => state.setEvents);
|
|
10851
|
-
const get = useThree((state) => state.get);
|
|
10852
|
-
const gl = useThree((state) => state.gl);
|
|
10853
|
-
React.useEffect(() => {
|
|
10854
|
-
let hits = [];
|
|
10855
|
-
let lastEvent = void 0;
|
|
10856
|
-
const prev = get().events.filter;
|
|
10857
|
-
const target = portal?.current ?? gl.domElement.parentNode;
|
|
10858
|
-
const renderStatus = () => target && onChanged && onChanged(hits, Math.round(cycle.current) % hits.length);
|
|
10859
|
-
setEvents({
|
|
10860
|
-
filter: (intersections, state) => {
|
|
10861
|
-
let clone = [...intersections];
|
|
10862
|
-
if (clone.length !== hits.length || !hits.every((hit) => clone.map((e) => e.object.uuid).includes(hit.object.uuid))) {
|
|
10863
|
-
cycle.current = 0;
|
|
10864
|
-
hits = clone;
|
|
10865
|
-
renderStatus();
|
|
10866
|
-
}
|
|
10867
|
-
if (prev) clone = prev(clone, state);
|
|
10868
|
-
for (let i = 0; i < Math.round(cycle.current) % clone.length; i++) {
|
|
10869
|
-
const first = clone.shift();
|
|
10870
|
-
clone = [...clone, first];
|
|
10871
|
-
}
|
|
10872
|
-
return clone;
|
|
10873
|
-
}
|
|
10874
|
-
});
|
|
10875
|
-
const refresh = (fn) => {
|
|
10876
|
-
cycle.current = fn(cycle.current);
|
|
10877
|
-
get().events.handlers?.onPointerCancel(void 0);
|
|
10878
|
-
get().events.handlers?.onPointerMove(lastEvent);
|
|
10879
|
-
renderStatus();
|
|
10880
|
-
};
|
|
10881
|
-
const tabEvent = (event) => {
|
|
10882
|
-
if ((event.keyCode || event.which) === keyCode) {
|
|
10883
|
-
if (preventDefault) event.preventDefault();
|
|
10884
|
-
if (hits.length > 1) refresh((current) => current + 1);
|
|
10885
|
-
}
|
|
10886
|
-
};
|
|
10887
|
-
const wheelEvent = (event) => {
|
|
10888
|
-
if (preventDefault) event.preventDefault();
|
|
10889
|
-
let delta = 0;
|
|
10890
|
-
if (!event) event = window.event;
|
|
10891
|
-
if (event.wheelDelta) delta = event.wheelDelta / 120;
|
|
10892
|
-
else if (event.detail) delta = -event.detail / 3;
|
|
10893
|
-
if (hits.length > 1) refresh((current) => Math.abs(current - delta));
|
|
10894
|
-
};
|
|
10895
|
-
const moveEvent = (event) => lastEvent = event;
|
|
10896
|
-
document.addEventListener("pointermove", moveEvent, { passive: true });
|
|
10897
|
-
if (scroll) document.addEventListener("wheel", wheelEvent);
|
|
10898
|
-
if (keyCode !== void 0) document.addEventListener("keydown", tabEvent);
|
|
10899
|
-
return () => {
|
|
10900
|
-
setEvents({ filter: prev });
|
|
10901
|
-
if (keyCode !== void 0) document.removeEventListener("keydown", tabEvent);
|
|
10902
|
-
if (scroll) document.removeEventListener("wheel", wheelEvent);
|
|
10903
|
-
document.removeEventListener("pointermove", moveEvent);
|
|
10904
|
-
};
|
|
10905
|
-
}, [gl, get, setEvents, preventDefault, scroll, keyCode]);
|
|
10906
|
-
return null;
|
|
10907
|
-
}
|
|
11154
|
+
// compute the anti-aliased stroke edge
|
|
11155
|
+
float edge = 1.0 - wireframe_aastep(computedThickness, d);
|
|
10908
11156
|
|
|
10909
|
-
|
|
10910
|
-
|
|
10911
|
-
|
|
10912
|
-
|
|
10913
|
-
|
|
10914
|
-
|
|
11157
|
+
return edge;
|
|
11158
|
+
}
|
|
11159
|
+
`
|
|
11160
|
+
)
|
|
11161
|
+
};
|
|
11162
|
+
const WireframeMaterial = /* @__PURE__ */ shaderMaterial(
|
|
11163
|
+
WireframeMaterialShaders.uniforms,
|
|
11164
|
+
WireframeMaterialShaders.vertex + /* glsl */
|
|
11165
|
+
`
|
|
11166
|
+
void main() {
|
|
11167
|
+
initWireframe();
|
|
11168
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
11169
|
+
}
|
|
11170
|
+
`,
|
|
11171
|
+
WireframeMaterialShaders.fragment + /* glsl */
|
|
11172
|
+
`
|
|
11173
|
+
void main () {
|
|
11174
|
+
// Compute color
|
|
10915
11175
|
|
|
10916
|
-
|
|
10917
|
-
|
|
10918
|
-
if (hovered) {
|
|
10919
|
-
container.style.cursor = onPointerOver;
|
|
10920
|
-
return () => void (container.style.cursor = onPointerOut);
|
|
10921
|
-
}
|
|
10922
|
-
}, [hovered]);
|
|
10923
|
-
}
|
|
11176
|
+
float edge = getWireframe();
|
|
11177
|
+
vec4 colorStroke = vec4(stroke, edge);
|
|
10924
11178
|
|
|
10925
|
-
|
|
10926
|
-
|
|
10927
|
-
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
});
|
|
10932
|
-
return /* @__PURE__ */ React.createElement("group", { ref: localRef, ...rest }, /* @__PURE__ */ React.createElement("group", { "position-z": -depth }, children));
|
|
10933
|
-
});
|
|
11179
|
+
#ifdef FLIP_SIDED
|
|
11180
|
+
colorStroke.rgb = backfaceStroke;
|
|
11181
|
+
#endif
|
|
11182
|
+
|
|
11183
|
+
vec4 colorFill = vec4(fill, fillOpacity);
|
|
11184
|
+
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
10934
11185
|
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
|
|
10955
|
-
|
|
10956
|
-
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
|
|
11186
|
+
gl_FragColor = outColor;
|
|
11187
|
+
}
|
|
11188
|
+
`
|
|
11189
|
+
);
|
|
11190
|
+
function setWireframeOverride(material, uniforms) {
|
|
11191
|
+
material.onBeforeCompile = (shader) => {
|
|
11192
|
+
shader.uniforms = {
|
|
11193
|
+
...shader.uniforms,
|
|
11194
|
+
...uniforms
|
|
11195
|
+
};
|
|
11196
|
+
shader.vertexShader = shader.vertexShader.replace(
|
|
11197
|
+
"void main() {",
|
|
11198
|
+
`
|
|
11199
|
+
${WireframeMaterialShaders.vertex}
|
|
11200
|
+
void main() {
|
|
11201
|
+
initWireframe();
|
|
11202
|
+
`
|
|
11203
|
+
);
|
|
11204
|
+
shader.fragmentShader = shader.fragmentShader.replace(
|
|
11205
|
+
"void main() {",
|
|
11206
|
+
`
|
|
11207
|
+
${WireframeMaterialShaders.fragment}
|
|
11208
|
+
void main() {
|
|
11209
|
+
`
|
|
11210
|
+
);
|
|
11211
|
+
shader.fragmentShader = shader.fragmentShader.replace(
|
|
11212
|
+
"#include <color_fragment>",
|
|
11213
|
+
/* glsl */
|
|
11214
|
+
`
|
|
11215
|
+
#include <color_fragment>
|
|
11216
|
+
float edge = getWireframe();
|
|
11217
|
+
vec4 colorStroke = vec4(stroke, edge);
|
|
11218
|
+
#ifdef FLIP_SIDED
|
|
11219
|
+
colorStroke.rgb = backfaceStroke;
|
|
11220
|
+
#endif
|
|
11221
|
+
vec4 colorFill = vec4(mix(diffuseColor.rgb, fill, fillMix), mix(diffuseColor.a, fillOpacity, fillMix));
|
|
11222
|
+
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
11223
|
+
|
|
11224
|
+
diffuseColor.rgb = outColor.rgb;
|
|
11225
|
+
diffuseColor.a *= outColor.a;
|
|
11226
|
+
`
|
|
11227
|
+
);
|
|
11228
|
+
};
|
|
11229
|
+
material.side = THREE.DoubleSide;
|
|
11230
|
+
material.transparent = true;
|
|
11231
|
+
}
|
|
11232
|
+
function useWireframeUniforms(uniforms, props) {
|
|
11233
|
+
React.useEffect(
|
|
11234
|
+
() => void (uniforms.fillOpacity.value = props.fillOpacity ?? uniforms.fillOpacity.value),
|
|
11235
|
+
[props.fillOpacity]
|
|
11236
|
+
);
|
|
11237
|
+
React.useEffect(() => void (uniforms.fillMix.value = props.fillMix ?? uniforms.fillMix.value), [props.fillMix]);
|
|
11238
|
+
React.useEffect(
|
|
11239
|
+
() => void (uniforms.strokeOpacity.value = props.strokeOpacity ?? uniforms.strokeOpacity.value),
|
|
11240
|
+
[props.strokeOpacity]
|
|
11241
|
+
);
|
|
11242
|
+
React.useEffect(
|
|
11243
|
+
() => void (uniforms.thickness.value = props.thickness ?? uniforms.thickness.value),
|
|
11244
|
+
[props.thickness]
|
|
11245
|
+
);
|
|
11246
|
+
React.useEffect(() => void (uniforms.colorBackfaces.value = !!props.colorBackfaces), [props.colorBackfaces]);
|
|
11247
|
+
React.useEffect(() => void (uniforms.dash.value = !!props.dash), [props.dash]);
|
|
11248
|
+
React.useEffect(() => void (uniforms.dashInvert.value = !!props.dashInvert), [props.dashInvert]);
|
|
11249
|
+
React.useEffect(
|
|
11250
|
+
() => void (uniforms.dashRepeats.value = props.dashRepeats ?? uniforms.dashRepeats.value),
|
|
11251
|
+
[props.dashRepeats]
|
|
11252
|
+
);
|
|
11253
|
+
React.useEffect(
|
|
11254
|
+
() => void (uniforms.dashLength.value = props.dashLength ?? uniforms.dashLength.value),
|
|
11255
|
+
[props.dashLength]
|
|
11256
|
+
);
|
|
11257
|
+
React.useEffect(() => void (uniforms.squeeze.value = !!props.squeeze), [props.squeeze]);
|
|
11258
|
+
React.useEffect(
|
|
11259
|
+
() => void (uniforms.squeezeMin.value = props.squeezeMin ?? uniforms.squeezeMin.value),
|
|
11260
|
+
[props.squeezeMin]
|
|
11261
|
+
);
|
|
11262
|
+
React.useEffect(
|
|
11263
|
+
() => void (uniforms.squeezeMax.value = props.squeezeMax ?? uniforms.squeezeMax.value),
|
|
11264
|
+
[props.squeezeMax]
|
|
10960
11265
|
);
|
|
10961
|
-
React.useEffect(
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
|
|
10989
|
-
|
|
10990
|
-
|
|
10991
|
-
|
|
10992
|
-
|
|
10993
|
-
|
|
10994
|
-
|
|
10995
|
-
|
|
10996
|
-
|
|
10997
|
-
|
|
10998
|
-
|
|
10999
|
-
|
|
11000
|
-
|
|
11001
|
-
|
|
11002
|
-
|
|
11003
|
-
|
|
11004
|
-
|
|
11005
|
-
|
|
11006
|
-
|
|
11007
|
-
|
|
11008
|
-
element.style.top = `${pointTopLeft.y}px`;
|
|
11009
|
-
element.style.width = `${pointBottomRight.x - pointTopLeft.x}px`;
|
|
11010
|
-
element.style.height = `${pointBottomRight.y - pointTopLeft.y}px`;
|
|
11266
|
+
React.useEffect(
|
|
11267
|
+
() => void (uniforms.stroke.value = props.stroke ? new THREE.Color(props.stroke) : uniforms.stroke.value),
|
|
11268
|
+
[props.stroke]
|
|
11269
|
+
);
|
|
11270
|
+
React.useEffect(
|
|
11271
|
+
() => void (uniforms.fill.value = props.fill ? new THREE.Color(props.fill) : uniforms.fill.value),
|
|
11272
|
+
[props.fill]
|
|
11273
|
+
);
|
|
11274
|
+
React.useEffect(
|
|
11275
|
+
() => void (uniforms.backfaceStroke.value = props.backfaceStroke ? new THREE.Color(props.backfaceStroke) : uniforms.backfaceStroke.value),
|
|
11276
|
+
[props.backfaceStroke]
|
|
11277
|
+
);
|
|
11278
|
+
}
|
|
11279
|
+
|
|
11280
|
+
function isWithGeometry(object) {
|
|
11281
|
+
return !!object?.geometry;
|
|
11282
|
+
}
|
|
11283
|
+
function isGeometry(object) {
|
|
11284
|
+
return !!object?.isBufferGeometry;
|
|
11285
|
+
}
|
|
11286
|
+
function isRefObject(object) {
|
|
11287
|
+
return !!object?.current;
|
|
11288
|
+
}
|
|
11289
|
+
function isRef(object) {
|
|
11290
|
+
return object?.current !== void 0;
|
|
11291
|
+
}
|
|
11292
|
+
function isWireframeGeometry(geometry) {
|
|
11293
|
+
return geometry.type === "WireframeGeometry";
|
|
11294
|
+
}
|
|
11295
|
+
function getUniforms() {
|
|
11296
|
+
const u = {};
|
|
11297
|
+
for (const key in WireframeMaterialShaders.uniforms) {
|
|
11298
|
+
u[key] = { value: WireframeMaterialShaders.uniforms[key] };
|
|
11299
|
+
}
|
|
11300
|
+
return u;
|
|
11301
|
+
}
|
|
11302
|
+
function getBarycentricCoordinates(geometry, removeEdge) {
|
|
11303
|
+
const position = geometry.getAttribute("position");
|
|
11304
|
+
const count = position.count;
|
|
11305
|
+
const barycentric = [];
|
|
11306
|
+
for (let i = 0; i < count; i++) {
|
|
11307
|
+
const even = i % 2 === 0;
|
|
11308
|
+
const Q = removeEdge ? 1 : 0;
|
|
11309
|
+
if (even) {
|
|
11310
|
+
barycentric.push(0, 0, 1, 0, 1, 0, 1, 0, Q);
|
|
11311
|
+
} else {
|
|
11312
|
+
barycentric.push(0, 1, 0, 0, 0, 1, 1, 0, Q);
|
|
11011
11313
|
}
|
|
11012
|
-
|
|
11013
|
-
|
|
11014
|
-
|
|
11015
|
-
|
|
11016
|
-
|
|
11017
|
-
|
|
11018
|
-
|
|
11314
|
+
}
|
|
11315
|
+
return new THREE.BufferAttribute(Float32Array.from(barycentric), 3);
|
|
11316
|
+
}
|
|
11317
|
+
function getInputGeometry(inputGeometry) {
|
|
11318
|
+
const geo = isRefObject(inputGeometry) ? inputGeometry.current : inputGeometry;
|
|
11319
|
+
if (!isGeometry(geo)) {
|
|
11320
|
+
if (isWireframeGeometry(geo)) {
|
|
11321
|
+
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
11019
11322
|
}
|
|
11020
|
-
|
|
11021
|
-
|
|
11022
|
-
|
|
11023
|
-
|
|
11323
|
+
const parent = geo.parent;
|
|
11324
|
+
if (isWithGeometry(parent)) {
|
|
11325
|
+
if (isWireframeGeometry(parent.geometry)) {
|
|
11326
|
+
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
11024
11327
|
}
|
|
11328
|
+
return parent.geometry;
|
|
11025
11329
|
}
|
|
11026
|
-
|
|
11027
|
-
|
|
11028
|
-
|
|
11029
|
-
|
|
11030
|
-
|
|
11031
|
-
|
|
11032
|
-
|
|
11033
|
-
|
|
11034
|
-
|
|
11035
|
-
|
|
11036
|
-
|
|
11330
|
+
} else {
|
|
11331
|
+
return geo;
|
|
11332
|
+
}
|
|
11333
|
+
}
|
|
11334
|
+
function setBarycentricCoordinates(geometry, simplify) {
|
|
11335
|
+
if (geometry.index) {
|
|
11336
|
+
console.warn("Wireframe: Requires non-indexed geometry, converting to non-indexed geometry.");
|
|
11337
|
+
const nonIndexedGeo = geometry.toNonIndexed();
|
|
11338
|
+
geometry.copy(nonIndexedGeo);
|
|
11339
|
+
geometry.setIndex(null);
|
|
11340
|
+
}
|
|
11341
|
+
const newBarycentric = getBarycentricCoordinates(geometry, simplify);
|
|
11342
|
+
geometry.setAttribute("barycentric", newBarycentric);
|
|
11343
|
+
}
|
|
11344
|
+
function WireframeWithCustomGeo({
|
|
11345
|
+
geometry: customGeometry,
|
|
11346
|
+
simplify = false,
|
|
11347
|
+
...props
|
|
11348
|
+
}) {
|
|
11349
|
+
extend({ MeshWireframeMaterial: WireframeMaterial });
|
|
11350
|
+
const [geometry, setGeometry] = React.useState(null);
|
|
11351
|
+
React.useLayoutEffect(() => {
|
|
11352
|
+
const geom = getInputGeometry(customGeometry);
|
|
11353
|
+
if (!geom) {
|
|
11354
|
+
throw new Error("Wireframe: geometry prop must be a BufferGeometry or a ref to a BufferGeometry.");
|
|
11037
11355
|
}
|
|
11038
|
-
|
|
11039
|
-
|
|
11356
|
+
setBarycentricCoordinates(geom, simplify);
|
|
11357
|
+
if (isRef(customGeometry)) {
|
|
11358
|
+
setGeometry(geom);
|
|
11040
11359
|
}
|
|
11041
|
-
|
|
11042
|
-
|
|
11043
|
-
|
|
11044
|
-
|
|
11045
|
-
document.removeEventListener("pointerdown", pointerDown);
|
|
11046
|
-
document.removeEventListener("pointermove", pointerMove, true);
|
|
11047
|
-
document.removeEventListener("pointerup", pointerUp);
|
|
11048
|
-
};
|
|
11049
|
-
}, [size.width, size.height, raycaster, camera, controls, gl]);
|
|
11050
|
-
return /* @__PURE__ */ React.createElement(
|
|
11051
|
-
"group",
|
|
11360
|
+
}, [simplify, customGeometry]);
|
|
11361
|
+
const drawnGeo = isRef(customGeometry) ? geometry : customGeometry;
|
|
11362
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, drawnGeo && /* @__PURE__ */ React.createElement("mesh", { geometry: drawnGeo }, /* @__PURE__ */ React.createElement(
|
|
11363
|
+
"meshWireframeMaterial",
|
|
11052
11364
|
{
|
|
11053
|
-
|
|
11054
|
-
|
|
11055
|
-
|
|
11056
|
-
|
|
11057
|
-
|
|
11365
|
+
attach: "material",
|
|
11366
|
+
transparent: true,
|
|
11367
|
+
side: THREE.DoubleSide,
|
|
11368
|
+
polygonOffset: true,
|
|
11369
|
+
polygonOffsetFactor: -4,
|
|
11058
11370
|
...props
|
|
11059
|
-
}
|
|
11060
|
-
|
|
11061
|
-
);
|
|
11062
|
-
}
|
|
11063
|
-
function useSelect() {
|
|
11064
|
-
return React.useContext(context);
|
|
11371
|
+
}
|
|
11372
|
+
)));
|
|
11065
11373
|
}
|
|
11066
|
-
|
|
11067
|
-
|
|
11068
|
-
|
|
11069
|
-
bgColor = "black",
|
|
11070
|
-
fgColor = "white",
|
|
11071
|
-
characters = " .:-+*=%@#",
|
|
11072
|
-
invert = true,
|
|
11073
|
-
color = false,
|
|
11074
|
-
resolution = 0.15
|
|
11374
|
+
function WireframeWithoutCustomGeo({
|
|
11375
|
+
simplify = false,
|
|
11376
|
+
...props
|
|
11075
11377
|
}) {
|
|
11076
|
-
const
|
|
11077
|
-
const
|
|
11078
|
-
|
|
11079
|
-
effect2.domElement.style.position = "absolute";
|
|
11080
|
-
effect2.domElement.style.top = "0px";
|
|
11081
|
-
effect2.domElement.style.left = "0px";
|
|
11082
|
-
effect2.domElement.style.pointerEvents = "none";
|
|
11083
|
-
return effect2;
|
|
11084
|
-
}, [characters, invert, color, resolution]);
|
|
11378
|
+
const objectRef = React.useRef(null);
|
|
11379
|
+
const uniforms = React.useMemo(() => getUniforms(), [WireframeMaterialShaders.uniforms]);
|
|
11380
|
+
useWireframeUniforms(uniforms, props);
|
|
11085
11381
|
React.useLayoutEffect(() => {
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
|
|
11090
|
-
|
|
11091
|
-
|
|
11382
|
+
const geom = getInputGeometry(objectRef);
|
|
11383
|
+
if (!geom) {
|
|
11384
|
+
throw new Error("Wireframe: Must be a child of a Mesh, Line or Points object or specify a geometry prop.");
|
|
11385
|
+
}
|
|
11386
|
+
const og = geom.clone();
|
|
11387
|
+
setBarycentricCoordinates(geom, simplify);
|
|
11092
11388
|
return () => {
|
|
11093
|
-
|
|
11094
|
-
|
|
11389
|
+
geom.copy(og);
|
|
11390
|
+
og.dispose();
|
|
11095
11391
|
};
|
|
11096
|
-
}, [
|
|
11097
|
-
React.
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11392
|
+
}, [simplify]);
|
|
11393
|
+
React.useLayoutEffect(() => {
|
|
11394
|
+
const parentMesh = objectRef.current.parent;
|
|
11395
|
+
const og = parentMesh.material.clone();
|
|
11396
|
+
setWireframeOverride(parentMesh.material, uniforms);
|
|
11397
|
+
return () => {
|
|
11398
|
+
parentMesh.material.dispose();
|
|
11399
|
+
parentMesh.material = og;
|
|
11400
|
+
};
|
|
11401
|
+
}, []);
|
|
11402
|
+
return /* @__PURE__ */ React.createElement("object3D", { ref: objectRef });
|
|
11403
|
+
}
|
|
11404
|
+
function Wireframe({ geometry: customGeometry, ...props }) {
|
|
11405
|
+
if (customGeometry) {
|
|
11406
|
+
return /* @__PURE__ */ React.createElement(WireframeWithCustomGeo, { geometry: customGeometry, ...props });
|
|
11407
|
+
}
|
|
11408
|
+
return /* @__PURE__ */ React.createElement(WireframeWithoutCustomGeo, { ...props });
|
|
11104
11409
|
}
|
|
11105
11410
|
|
|
11106
11411
|
function BakeShadows() {
|
|
@@ -11850,7 +12155,7 @@ function VolumetricMesh({
|
|
|
11850
12155
|
depthWrite: true,
|
|
11851
12156
|
depthTest: false
|
|
11852
12157
|
});
|
|
11853
|
-
const copyQuad = new FullScreenQuad
|
|
12158
|
+
const copyQuad = new FullScreenQuad(copyMaterial);
|
|
11854
12159
|
return { depthCopyTarget, copyMaterial, copyQuad };
|
|
11855
12160
|
}, [depthBuffer]);
|
|
11856
12161
|
React.useEffect(() => {
|
|
@@ -11964,7 +12269,7 @@ function SpotlightShadowWithShader({
|
|
|
11964
12269
|
});
|
|
11965
12270
|
React.useEffect(() => void (uniforms.current.uShadowMap.value = map), [map]);
|
|
11966
12271
|
const fsQuad = React.useMemo(
|
|
11967
|
-
() => new FullScreenQuad
|
|
12272
|
+
() => new FullScreenQuad(
|
|
11968
12273
|
new ShaderMaterial({
|
|
11969
12274
|
uniforms: uniforms.current,
|
|
11970
12275
|
vertexShader: (
|