@react-three/drei 11.0.0-alpha.4 → 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 +64 -66
- package/core/index.d.ts +64 -66
- package/core/index.mjs +396 -472
- package/experimental/index.d.mts +4 -4
- package/experimental/index.d.ts +4 -4
- package/experimental/index.mjs +1 -0
- package/external/index.d.mts +4 -4
- package/external/index.d.ts +4 -4
- package/external/index.mjs +1 -0
- package/index.d.mts +65 -67
- package/index.d.ts +65 -67
- package/index.mjs +396 -472
- package/legacy/index.d.mts +141 -94
- package/legacy/index.d.ts +141 -94
- package/legacy/index.mjs +1264 -958
- package/native/index.d.mts +177 -370
- package/native/index.d.ts +177 -370
- package/native/index.mjs +1238 -2434
- package/package.json +2 -3
- package/webgpu/index.d.mts +180 -216
- package/webgpu/index.d.ts +180 -216
- package/webgpu/index.mjs +1228 -1787
package/core/index.mjs
CHANGED
|
@@ -2,9 +2,8 @@ import * as React from 'react';
|
|
|
2
2
|
import { forwardRef, useImperativeHandle, useMemo, useEffect, useCallback, useRef, useLayoutEffect, useState, Fragment, createContext, useContext } from 'react';
|
|
3
3
|
import { useThree, useFrame, extend, createPortal, useInstanceHandle, context as context$9, useLoader, applyProps, addEffect, addAfterEffect } from '@react-three/fiber';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
|
-
import { REVISION, WebGLRenderTarget, Frustum, Matrix4, Vector3, Vector4, Vector2, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, WebGLCubeRenderTarget, HalfFloatType, CubeCamera as CubeCamera$1, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial,
|
|
5
|
+
import { REVISION, WebGLRenderTarget, Frustum, Matrix4, Vector3, Vector4, Vector2, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, WebGLCubeRenderTarget, HalfFloatType, CubeCamera as CubeCamera$1, EventDispatcher, Euler, Quaternion, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial, DynamicDrawUsage, CatmullRomCurve3, CubicBezierCurve3, QuadraticBezierCurve3, Shape as Shape$1, Object3D, CanvasTexture, DoubleSide, PerspectiveCamera as PerspectiveCamera$1, OrthographicCamera as OrthographicCamera$1, AudioListener, AudioLoader, AnimationMixer, BufferAttribute, Box3, Sphere as Sphere$1, InstancedBufferAttribute, DepthTexture, DepthFormat, UnsignedShortType, CubeTextureLoader, DefaultLoadingManager, Ray, Raycaster, Camera, CubeReflectionMapping, EquirectangularReflectionMapping, Scene, RepeatWrapping } 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
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';
|
|
@@ -180,6 +179,7 @@ function shaderMaterial(uniforms, vertexShader, fragmentShader, onInit) {
|
|
|
180
179
|
});
|
|
181
180
|
}
|
|
182
181
|
this.uniforms = THREE.UniformsUtils.clone(this.uniforms);
|
|
182
|
+
Object.assign(this, parameters);
|
|
183
183
|
}
|
|
184
184
|
};
|
|
185
185
|
}
|
|
@@ -196,7 +196,7 @@ const version = /* @__PURE__ */ getVersion();
|
|
|
196
196
|
function isLight(object) {
|
|
197
197
|
return object.isLight;
|
|
198
198
|
}
|
|
199
|
-
function isGeometry
|
|
199
|
+
function isGeometry(object) {
|
|
200
200
|
return !!object.geometry;
|
|
201
201
|
}
|
|
202
202
|
const accumulativeContext = /* @__PURE__ */ React.createContext(
|
|
@@ -441,7 +441,7 @@ vec3 texelOld = texture2D(previousShadowMap, vUv).rgb;
|
|
|
441
441
|
this.lights = [];
|
|
442
442
|
this.meshes = [];
|
|
443
443
|
this.scene.traverse((object) => {
|
|
444
|
-
if (isGeometry
|
|
444
|
+
if (isGeometry(object)) {
|
|
445
445
|
this.meshes.push({ object, material: object.material });
|
|
446
446
|
} else if (isLight(object)) {
|
|
447
447
|
this.lights.push({ object, intensity: object.intensity });
|
|
@@ -1062,6 +1062,81 @@ const ArcballControls = /* @__PURE__ */ forwardRef(
|
|
|
1062
1062
|
}
|
|
1063
1063
|
);
|
|
1064
1064
|
|
|
1065
|
+
let DeviceOrientationControls$1 = class DeviceOrientationControls extends EventDispatcher {
|
|
1066
|
+
object;
|
|
1067
|
+
changeEvent = { type: "change" };
|
|
1068
|
+
EPS = 1e-6;
|
|
1069
|
+
enabled = true;
|
|
1070
|
+
deviceOrientation = { alpha: 0, beta: 0, gamma: 0 };
|
|
1071
|
+
screenOrientation = 0;
|
|
1072
|
+
alphaOffset = 0;
|
|
1073
|
+
// radians
|
|
1074
|
+
constructor(object) {
|
|
1075
|
+
super();
|
|
1076
|
+
this.object = object;
|
|
1077
|
+
this.object.rotation.reorder("YXZ");
|
|
1078
|
+
this.connect();
|
|
1079
|
+
}
|
|
1080
|
+
onDeviceOrientationChangeEvent = (event) => {
|
|
1081
|
+
this.deviceOrientation = event;
|
|
1082
|
+
};
|
|
1083
|
+
onScreenOrientationChangeEvent = () => {
|
|
1084
|
+
this.screenOrientation = window.orientation || 0;
|
|
1085
|
+
};
|
|
1086
|
+
// The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''
|
|
1087
|
+
zee = new Vector3(0, 0, 1);
|
|
1088
|
+
euler = new Euler();
|
|
1089
|
+
q0 = new Quaternion();
|
|
1090
|
+
q1 = new Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));
|
|
1091
|
+
// - PI/2 around the x-axis
|
|
1092
|
+
setObjectQuaternion = (quaternion, alpha, beta, gamma, orient) => {
|
|
1093
|
+
this.euler.set(beta, alpha, -gamma, "YXZ");
|
|
1094
|
+
quaternion.setFromEuler(this.euler);
|
|
1095
|
+
quaternion.multiply(this.q1);
|
|
1096
|
+
quaternion.multiply(this.q0.setFromAxisAngle(this.zee, -orient));
|
|
1097
|
+
};
|
|
1098
|
+
connect = () => {
|
|
1099
|
+
this.onScreenOrientationChangeEvent();
|
|
1100
|
+
if (window.DeviceOrientationEvent !== void 0 && // @ts-ignore
|
|
1101
|
+
typeof window.DeviceOrientationEvent.requestPermission === "function") {
|
|
1102
|
+
window.DeviceOrientationEvent.requestPermission().then((response) => {
|
|
1103
|
+
if (response == "granted") {
|
|
1104
|
+
window.addEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
1105
|
+
window.addEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
1106
|
+
}
|
|
1107
|
+
}).catch((error) => {
|
|
1108
|
+
console.error("THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:", error);
|
|
1109
|
+
});
|
|
1110
|
+
} else {
|
|
1111
|
+
window.addEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
1112
|
+
window.addEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
1113
|
+
}
|
|
1114
|
+
this.enabled = true;
|
|
1115
|
+
};
|
|
1116
|
+
disconnect = () => {
|
|
1117
|
+
window.removeEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
1118
|
+
window.removeEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
1119
|
+
this.enabled = false;
|
|
1120
|
+
};
|
|
1121
|
+
lastQuaternion = new Quaternion();
|
|
1122
|
+
update = () => {
|
|
1123
|
+
if (this.enabled === false) return;
|
|
1124
|
+
const device = this.deviceOrientation;
|
|
1125
|
+
if (device) {
|
|
1126
|
+
const alpha = device.alpha ? MathUtils.degToRad(device.alpha) + this.alphaOffset : 0;
|
|
1127
|
+
const beta = device.beta ? MathUtils.degToRad(device.beta) : 0;
|
|
1128
|
+
const gamma = device.gamma ? MathUtils.degToRad(device.gamma) : 0;
|
|
1129
|
+
const orient = this.screenOrientation ? MathUtils.degToRad(this.screenOrientation) : 0;
|
|
1130
|
+
this.setObjectQuaternion(this.object.quaternion, alpha, beta, gamma, orient);
|
|
1131
|
+
if (8 * (1 - this.lastQuaternion.dot(this.object.quaternion)) > this.EPS) {
|
|
1132
|
+
this.lastQuaternion.copy(this.object.quaternion);
|
|
1133
|
+
this.dispatchEvent(this.changeEvent);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
};
|
|
1137
|
+
dispose = () => this.disconnect();
|
|
1138
|
+
};
|
|
1139
|
+
|
|
1065
1140
|
const DeviceOrientationControls = /* @__PURE__ */ React.forwardRef(
|
|
1066
1141
|
(props, ref) => {
|
|
1067
1142
|
const { camera, onChange, makeDefault, ...rest } = props;
|
|
@@ -1131,8 +1206,9 @@ const DragControls = React.forwardRef(
|
|
|
1131
1206
|
onDragStart && onDragStart(initialModelPosition);
|
|
1132
1207
|
invalidate();
|
|
1133
1208
|
},
|
|
1134
|
-
onDrag: ({ xy: [dragX, dragY], intentional }) => {
|
|
1209
|
+
onDrag: ({ xy: [dragX, dragY], intentional, event }) => {
|
|
1135
1210
|
if (!intentional) return;
|
|
1211
|
+
if (dragConfig && dragConfig.preventOverlap) event.preventDefault();
|
|
1136
1212
|
const normalizedMouseX = (dragX - size.left) / size.width * 2 - 1;
|
|
1137
1213
|
const normalizedMouseY = -((dragY - size.top) / size.height) * 2 + 1;
|
|
1138
1214
|
mousePosition2D.set(normalizedMouseX, normalizedMouseY);
|
|
@@ -1301,12 +1377,21 @@ function KeyboardControls({ map, children, onChange, domElement }) {
|
|
|
1301
1377
|
obj.pressed = false;
|
|
1302
1378
|
if (up) fn(false);
|
|
1303
1379
|
};
|
|
1380
|
+
const blurHandler = () => {
|
|
1381
|
+
const resetState = map.reduce((prev, cur) => ({ ...prev, [cur.name]: false }), {});
|
|
1382
|
+
set(resetState);
|
|
1383
|
+
Object.values(keyMap).forEach((obj) => {
|
|
1384
|
+
obj.pressed = false;
|
|
1385
|
+
});
|
|
1386
|
+
};
|
|
1304
1387
|
const source = domElement || window;
|
|
1305
1388
|
source.addEventListener("keydown", downHandler, { passive: true });
|
|
1306
1389
|
source.addEventListener("keyup", upHandler, { passive: true });
|
|
1390
|
+
window.addEventListener("blur", blurHandler);
|
|
1307
1391
|
return () => {
|
|
1308
1392
|
source.removeEventListener("keydown", downHandler);
|
|
1309
1393
|
source.removeEventListener("keyup", upHandler);
|
|
1394
|
+
window.removeEventListener("blur", blurHandler);
|
|
1310
1395
|
};
|
|
1311
1396
|
}, [domElement, key]);
|
|
1312
1397
|
return /* @__PURE__ */ React.createElement(context$8.Provider, { value: api, children });
|
|
@@ -1657,7 +1742,13 @@ function PresentationControls({
|
|
|
1657
1742
|
return /* @__PURE__ */ React.createElement("group", { ref, ...bind?.() }, children);
|
|
1658
1743
|
}
|
|
1659
1744
|
|
|
1745
|
+
function roundToPixelRatio(value) {
|
|
1746
|
+
const ratio = window.devicePixelRatio || 1;
|
|
1747
|
+
return Math.round(value * ratio) / ratio;
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1660
1750
|
const context$7 = /* @__PURE__ */ React.createContext(null);
|
|
1751
|
+
const rootCache = /* @__PURE__ */ new WeakMap();
|
|
1661
1752
|
function useScroll() {
|
|
1662
1753
|
return React.useContext(context$7);
|
|
1663
1754
|
}
|
|
@@ -1671,6 +1762,7 @@ function ScrollControls({
|
|
|
1671
1762
|
damping = 0.25,
|
|
1672
1763
|
maxSpeed = Infinity,
|
|
1673
1764
|
prepend = false,
|
|
1765
|
+
pixelPerfect = true,
|
|
1674
1766
|
style = {},
|
|
1675
1767
|
children
|
|
1676
1768
|
}) {
|
|
@@ -1692,6 +1784,7 @@ function ScrollControls({
|
|
|
1692
1784
|
delta: 0,
|
|
1693
1785
|
scroll,
|
|
1694
1786
|
pages,
|
|
1787
|
+
pixelPerfect,
|
|
1695
1788
|
// 0-1 for a range between from -> from + distance
|
|
1696
1789
|
range(from, distance2, margin = 0) {
|
|
1697
1790
|
const start = from - margin;
|
|
@@ -1710,7 +1803,7 @@ function ScrollControls({
|
|
|
1710
1803
|
}
|
|
1711
1804
|
};
|
|
1712
1805
|
return state2;
|
|
1713
|
-
}, [eps, damping, horizontal, pages]);
|
|
1806
|
+
}, [eps, damping, horizontal, pages, pixelPerfect]);
|
|
1714
1807
|
React.useEffect(() => {
|
|
1715
1808
|
el.style.position = "absolute";
|
|
1716
1809
|
el.style.width = "100%";
|
|
@@ -1823,10 +1916,23 @@ const ScrollHtml = React.forwardRef(
|
|
|
1823
1916
|
React.useImperativeHandle(ref, () => group.current, []);
|
|
1824
1917
|
const { width, height } = useThree((state2) => state2.size);
|
|
1825
1918
|
const fiberState = React.useContext(context$9);
|
|
1826
|
-
const root = React.useMemo(() =>
|
|
1919
|
+
const root = React.useMemo(() => {
|
|
1920
|
+
let root2 = rootCache.get(state.fixed);
|
|
1921
|
+
if (!root2) {
|
|
1922
|
+
root2 = ReactDOM.createRoot(state.fixed);
|
|
1923
|
+
rootCache.set(state.fixed, root2);
|
|
1924
|
+
}
|
|
1925
|
+
return root2;
|
|
1926
|
+
}, [state.fixed]);
|
|
1827
1927
|
useFrame(() => {
|
|
1828
1928
|
if (state.delta > state.eps) {
|
|
1829
|
-
|
|
1929
|
+
let x = state.horizontal ? -width * (state.pages - 1) * state.offset : 0;
|
|
1930
|
+
let y = state.horizontal ? 0 : height * (state.pages - 1) * -state.offset;
|
|
1931
|
+
if (state.pixelPerfect) {
|
|
1932
|
+
x = roundToPixelRatio(x);
|
|
1933
|
+
y = roundToPixelRatio(y);
|
|
1934
|
+
}
|
|
1935
|
+
group.current.style.transform = `translate3d(${x}px,${y}px,0)`;
|
|
1830
1936
|
}
|
|
1831
1937
|
});
|
|
1832
1938
|
root.render(
|
|
@@ -2755,377 +2861,6 @@ const Text3D = /* @__PURE__ */ React.forwardRef(
|
|
|
2755
2861
|
}
|
|
2756
2862
|
);
|
|
2757
2863
|
|
|
2758
|
-
const WireframeMaterialShaders = {
|
|
2759
|
-
uniforms: {
|
|
2760
|
-
strokeOpacity: 1,
|
|
2761
|
-
fillOpacity: 0.25,
|
|
2762
|
-
fillMix: 0,
|
|
2763
|
-
thickness: 0.05,
|
|
2764
|
-
colorBackfaces: false,
|
|
2765
|
-
dashInvert: true,
|
|
2766
|
-
dash: false,
|
|
2767
|
-
dashRepeats: 4,
|
|
2768
|
-
dashLength: 0.5,
|
|
2769
|
-
squeeze: false,
|
|
2770
|
-
squeezeMin: 0.2,
|
|
2771
|
-
squeezeMax: 1,
|
|
2772
|
-
stroke: /* @__PURE__ */ new THREE.Color("#ff0000"),
|
|
2773
|
-
backfaceStroke: /* @__PURE__ */ new THREE.Color("#0000ff"),
|
|
2774
|
-
fill: /* @__PURE__ */ new THREE.Color("#00ff00")
|
|
2775
|
-
},
|
|
2776
|
-
vertex: (
|
|
2777
|
-
/* glsl */
|
|
2778
|
-
`
|
|
2779
|
-
attribute vec3 barycentric;
|
|
2780
|
-
|
|
2781
|
-
varying vec3 v_edges_Barycentric;
|
|
2782
|
-
varying vec3 v_edges_Position;
|
|
2783
|
-
|
|
2784
|
-
void initWireframe() {
|
|
2785
|
-
v_edges_Barycentric = barycentric;
|
|
2786
|
-
v_edges_Position = position.xyz;
|
|
2787
|
-
}
|
|
2788
|
-
`
|
|
2789
|
-
),
|
|
2790
|
-
fragment: (
|
|
2791
|
-
/* glsl */
|
|
2792
|
-
`
|
|
2793
|
-
#ifndef PI
|
|
2794
|
-
#define PI 3.1415926535897932384626433832795
|
|
2795
|
-
#endif
|
|
2796
|
-
|
|
2797
|
-
varying vec3 v_edges_Barycentric;
|
|
2798
|
-
varying vec3 v_edges_Position;
|
|
2799
|
-
|
|
2800
|
-
uniform float strokeOpacity;
|
|
2801
|
-
uniform float fillOpacity;
|
|
2802
|
-
uniform float fillMix;
|
|
2803
|
-
uniform float thickness;
|
|
2804
|
-
uniform bool colorBackfaces;
|
|
2805
|
-
|
|
2806
|
-
// Dash
|
|
2807
|
-
uniform bool dashInvert;
|
|
2808
|
-
uniform bool dash;
|
|
2809
|
-
uniform bool dashOnly;
|
|
2810
|
-
uniform float dashRepeats;
|
|
2811
|
-
uniform float dashLength;
|
|
2812
|
-
|
|
2813
|
-
// Squeeze
|
|
2814
|
-
uniform bool squeeze;
|
|
2815
|
-
uniform float squeezeMin;
|
|
2816
|
-
uniform float squeezeMax;
|
|
2817
|
-
|
|
2818
|
-
// Colors
|
|
2819
|
-
uniform vec3 stroke;
|
|
2820
|
-
uniform vec3 backfaceStroke;
|
|
2821
|
-
uniform vec3 fill;
|
|
2822
|
-
|
|
2823
|
-
// This is like
|
|
2824
|
-
float wireframe_aastep(float threshold, float dist) {
|
|
2825
|
-
float afwidth = fwidth(dist) * 0.5;
|
|
2826
|
-
return smoothstep(threshold - afwidth, threshold + afwidth, dist);
|
|
2827
|
-
}
|
|
2828
|
-
|
|
2829
|
-
float wireframe_map(float value, float min1, float max1, float min2, float max2) {
|
|
2830
|
-
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
|
|
2831
|
-
}
|
|
2832
|
-
|
|
2833
|
-
float getWireframe() {
|
|
2834
|
-
vec3 barycentric = v_edges_Barycentric;
|
|
2835
|
-
|
|
2836
|
-
// Distance from center of each triangle to its edges.
|
|
2837
|
-
float d = min(min(barycentric.x, barycentric.y), barycentric.z);
|
|
2838
|
-
|
|
2839
|
-
// for dashed rendering, we can use this to get the 0 .. 1 value of the line length
|
|
2840
|
-
float positionAlong = max(barycentric.x, barycentric.y);
|
|
2841
|
-
if (barycentric.y < barycentric.x && barycentric.y < barycentric.z) {
|
|
2842
|
-
positionAlong = 1.0 - positionAlong;
|
|
2843
|
-
}
|
|
2844
|
-
|
|
2845
|
-
// the thickness of the stroke
|
|
2846
|
-
float computedThickness = wireframe_map(thickness, 0.0, 1.0, 0.0, 0.34);
|
|
2847
|
-
|
|
2848
|
-
// if we want to shrink the thickness toward the center of the line segment
|
|
2849
|
-
if (squeeze) {
|
|
2850
|
-
computedThickness *= mix(squeezeMin, squeezeMax, (1.0 - sin(positionAlong * PI)));
|
|
2851
|
-
}
|
|
2852
|
-
|
|
2853
|
-
// Create dash pattern
|
|
2854
|
-
if (dash) {
|
|
2855
|
-
// here we offset the stroke position depending on whether it
|
|
2856
|
-
// should overlap or not
|
|
2857
|
-
float offset = 1.0 / dashRepeats * dashLength / 2.0;
|
|
2858
|
-
if (!dashInvert) {
|
|
2859
|
-
offset += 1.0 / dashRepeats / 2.0;
|
|
2860
|
-
}
|
|
2861
|
-
|
|
2862
|
-
// if we should animate the dash or not
|
|
2863
|
-
// if (dashAnimate) {
|
|
2864
|
-
// offset += time * 0.22;
|
|
2865
|
-
// }
|
|
2866
|
-
|
|
2867
|
-
// create the repeating dash pattern
|
|
2868
|
-
float pattern = fract((positionAlong + offset) * dashRepeats);
|
|
2869
|
-
computedThickness *= 1.0 - wireframe_aastep(dashLength, pattern);
|
|
2870
|
-
}
|
|
2871
|
-
|
|
2872
|
-
// compute the anti-aliased stroke edge
|
|
2873
|
-
float edge = 1.0 - wireframe_aastep(computedThickness, d);
|
|
2874
|
-
|
|
2875
|
-
return edge;
|
|
2876
|
-
}
|
|
2877
|
-
`
|
|
2878
|
-
)
|
|
2879
|
-
};
|
|
2880
|
-
const WireframeMaterial = /* @__PURE__ */ shaderMaterial(
|
|
2881
|
-
WireframeMaterialShaders.uniforms,
|
|
2882
|
-
WireframeMaterialShaders.vertex + /* glsl */
|
|
2883
|
-
`
|
|
2884
|
-
void main() {
|
|
2885
|
-
initWireframe();
|
|
2886
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
2887
|
-
}
|
|
2888
|
-
`,
|
|
2889
|
-
WireframeMaterialShaders.fragment + /* glsl */
|
|
2890
|
-
`
|
|
2891
|
-
void main () {
|
|
2892
|
-
// Compute color
|
|
2893
|
-
|
|
2894
|
-
float edge = getWireframe();
|
|
2895
|
-
vec4 colorStroke = vec4(stroke, edge);
|
|
2896
|
-
|
|
2897
|
-
#ifdef FLIP_SIDED
|
|
2898
|
-
colorStroke.rgb = backfaceStroke;
|
|
2899
|
-
#endif
|
|
2900
|
-
|
|
2901
|
-
vec4 colorFill = vec4(fill, fillOpacity);
|
|
2902
|
-
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
2903
|
-
|
|
2904
|
-
gl_FragColor = outColor;
|
|
2905
|
-
}
|
|
2906
|
-
`
|
|
2907
|
-
);
|
|
2908
|
-
function setWireframeOverride(material, uniforms) {
|
|
2909
|
-
material.onBeforeCompile = (shader) => {
|
|
2910
|
-
shader.uniforms = {
|
|
2911
|
-
...shader.uniforms,
|
|
2912
|
-
...uniforms
|
|
2913
|
-
};
|
|
2914
|
-
shader.vertexShader = shader.vertexShader.replace(
|
|
2915
|
-
"void main() {",
|
|
2916
|
-
`
|
|
2917
|
-
${WireframeMaterialShaders.vertex}
|
|
2918
|
-
void main() {
|
|
2919
|
-
initWireframe();
|
|
2920
|
-
`
|
|
2921
|
-
);
|
|
2922
|
-
shader.fragmentShader = shader.fragmentShader.replace(
|
|
2923
|
-
"void main() {",
|
|
2924
|
-
`
|
|
2925
|
-
${WireframeMaterialShaders.fragment}
|
|
2926
|
-
void main() {
|
|
2927
|
-
`
|
|
2928
|
-
);
|
|
2929
|
-
shader.fragmentShader = shader.fragmentShader.replace(
|
|
2930
|
-
"#include <color_fragment>",
|
|
2931
|
-
/* glsl */
|
|
2932
|
-
`
|
|
2933
|
-
#include <color_fragment>
|
|
2934
|
-
float edge = getWireframe();
|
|
2935
|
-
vec4 colorStroke = vec4(stroke, edge);
|
|
2936
|
-
#ifdef FLIP_SIDED
|
|
2937
|
-
colorStroke.rgb = backfaceStroke;
|
|
2938
|
-
#endif
|
|
2939
|
-
vec4 colorFill = vec4(mix(diffuseColor.rgb, fill, fillMix), mix(diffuseColor.a, fillOpacity, fillMix));
|
|
2940
|
-
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
2941
|
-
|
|
2942
|
-
diffuseColor.rgb = outColor.rgb;
|
|
2943
|
-
diffuseColor.a *= outColor.a;
|
|
2944
|
-
`
|
|
2945
|
-
);
|
|
2946
|
-
};
|
|
2947
|
-
material.side = THREE.DoubleSide;
|
|
2948
|
-
material.transparent = true;
|
|
2949
|
-
}
|
|
2950
|
-
function useWireframeUniforms(uniforms, props) {
|
|
2951
|
-
React.useEffect(
|
|
2952
|
-
() => void (uniforms.fillOpacity.value = props.fillOpacity ?? uniforms.fillOpacity.value),
|
|
2953
|
-
[props.fillOpacity]
|
|
2954
|
-
);
|
|
2955
|
-
React.useEffect(() => void (uniforms.fillMix.value = props.fillMix ?? uniforms.fillMix.value), [props.fillMix]);
|
|
2956
|
-
React.useEffect(
|
|
2957
|
-
() => void (uniforms.strokeOpacity.value = props.strokeOpacity ?? uniforms.strokeOpacity.value),
|
|
2958
|
-
[props.strokeOpacity]
|
|
2959
|
-
);
|
|
2960
|
-
React.useEffect(
|
|
2961
|
-
() => void (uniforms.thickness.value = props.thickness ?? uniforms.thickness.value),
|
|
2962
|
-
[props.thickness]
|
|
2963
|
-
);
|
|
2964
|
-
React.useEffect(() => void (uniforms.colorBackfaces.value = !!props.colorBackfaces), [props.colorBackfaces]);
|
|
2965
|
-
React.useEffect(() => void (uniforms.dash.value = !!props.dash), [props.dash]);
|
|
2966
|
-
React.useEffect(() => void (uniforms.dashInvert.value = !!props.dashInvert), [props.dashInvert]);
|
|
2967
|
-
React.useEffect(
|
|
2968
|
-
() => void (uniforms.dashRepeats.value = props.dashRepeats ?? uniforms.dashRepeats.value),
|
|
2969
|
-
[props.dashRepeats]
|
|
2970
|
-
);
|
|
2971
|
-
React.useEffect(
|
|
2972
|
-
() => void (uniforms.dashLength.value = props.dashLength ?? uniforms.dashLength.value),
|
|
2973
|
-
[props.dashLength]
|
|
2974
|
-
);
|
|
2975
|
-
React.useEffect(() => void (uniforms.squeeze.value = !!props.squeeze), [props.squeeze]);
|
|
2976
|
-
React.useEffect(
|
|
2977
|
-
() => void (uniforms.squeezeMin.value = props.squeezeMin ?? uniforms.squeezeMin.value),
|
|
2978
|
-
[props.squeezeMin]
|
|
2979
|
-
);
|
|
2980
|
-
React.useEffect(
|
|
2981
|
-
() => void (uniforms.squeezeMax.value = props.squeezeMax ?? uniforms.squeezeMax.value),
|
|
2982
|
-
[props.squeezeMax]
|
|
2983
|
-
);
|
|
2984
|
-
React.useEffect(
|
|
2985
|
-
() => void (uniforms.stroke.value = props.stroke ? new THREE.Color(props.stroke) : uniforms.stroke.value),
|
|
2986
|
-
[props.stroke]
|
|
2987
|
-
);
|
|
2988
|
-
React.useEffect(
|
|
2989
|
-
() => void (uniforms.fill.value = props.fill ? new THREE.Color(props.fill) : uniforms.fill.value),
|
|
2990
|
-
[props.fill]
|
|
2991
|
-
);
|
|
2992
|
-
React.useEffect(
|
|
2993
|
-
() => void (uniforms.backfaceStroke.value = props.backfaceStroke ? new THREE.Color(props.backfaceStroke) : uniforms.backfaceStroke.value),
|
|
2994
|
-
[props.backfaceStroke]
|
|
2995
|
-
);
|
|
2996
|
-
}
|
|
2997
|
-
|
|
2998
|
-
function isWithGeometry(object) {
|
|
2999
|
-
return !!object?.geometry;
|
|
3000
|
-
}
|
|
3001
|
-
function isGeometry(object) {
|
|
3002
|
-
return !!object?.isBufferGeometry;
|
|
3003
|
-
}
|
|
3004
|
-
function isRefObject$1(object) {
|
|
3005
|
-
return !!object?.current;
|
|
3006
|
-
}
|
|
3007
|
-
function isRef$1(object) {
|
|
3008
|
-
return object?.current !== void 0;
|
|
3009
|
-
}
|
|
3010
|
-
function isWireframeGeometry(geometry) {
|
|
3011
|
-
return geometry.type === "WireframeGeometry";
|
|
3012
|
-
}
|
|
3013
|
-
function getUniforms() {
|
|
3014
|
-
const u = {};
|
|
3015
|
-
for (const key in WireframeMaterialShaders.uniforms) {
|
|
3016
|
-
u[key] = { value: WireframeMaterialShaders.uniforms[key] };
|
|
3017
|
-
}
|
|
3018
|
-
return u;
|
|
3019
|
-
}
|
|
3020
|
-
function getBarycentricCoordinates(geometry, removeEdge) {
|
|
3021
|
-
const position = geometry.getAttribute("position");
|
|
3022
|
-
const count = position.count;
|
|
3023
|
-
const barycentric = [];
|
|
3024
|
-
for (let i = 0; i < count; i++) {
|
|
3025
|
-
const even = i % 2 === 0;
|
|
3026
|
-
const Q = removeEdge ? 1 : 0;
|
|
3027
|
-
if (even) {
|
|
3028
|
-
barycentric.push(0, 0, 1, 0, 1, 0, 1, 0, Q);
|
|
3029
|
-
} else {
|
|
3030
|
-
barycentric.push(0, 1, 0, 0, 0, 1, 1, 0, Q);
|
|
3031
|
-
}
|
|
3032
|
-
}
|
|
3033
|
-
return new THREE.BufferAttribute(Float32Array.from(barycentric), 3);
|
|
3034
|
-
}
|
|
3035
|
-
function getInputGeometry(inputGeometry) {
|
|
3036
|
-
const geo = isRefObject$1(inputGeometry) ? inputGeometry.current : inputGeometry;
|
|
3037
|
-
if (!isGeometry(geo)) {
|
|
3038
|
-
if (isWireframeGeometry(geo)) {
|
|
3039
|
-
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
3040
|
-
}
|
|
3041
|
-
const parent = geo.parent;
|
|
3042
|
-
if (isWithGeometry(parent)) {
|
|
3043
|
-
if (isWireframeGeometry(parent.geometry)) {
|
|
3044
|
-
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
3045
|
-
}
|
|
3046
|
-
return parent.geometry;
|
|
3047
|
-
}
|
|
3048
|
-
} else {
|
|
3049
|
-
return geo;
|
|
3050
|
-
}
|
|
3051
|
-
}
|
|
3052
|
-
function setBarycentricCoordinates(geometry, simplify) {
|
|
3053
|
-
if (geometry.index) {
|
|
3054
|
-
console.warn("Wireframe: Requires non-indexed geometry, converting to non-indexed geometry.");
|
|
3055
|
-
const nonIndexedGeo = geometry.toNonIndexed();
|
|
3056
|
-
geometry.copy(nonIndexedGeo);
|
|
3057
|
-
geometry.setIndex(null);
|
|
3058
|
-
}
|
|
3059
|
-
const newBarycentric = getBarycentricCoordinates(geometry, simplify);
|
|
3060
|
-
geometry.setAttribute("barycentric", newBarycentric);
|
|
3061
|
-
}
|
|
3062
|
-
function WireframeWithCustomGeo({
|
|
3063
|
-
geometry: customGeometry,
|
|
3064
|
-
simplify = false,
|
|
3065
|
-
...props
|
|
3066
|
-
}) {
|
|
3067
|
-
extend({ MeshWireframeMaterial: WireframeMaterial });
|
|
3068
|
-
const [geometry, setGeometry] = React.useState(null);
|
|
3069
|
-
React.useLayoutEffect(() => {
|
|
3070
|
-
const geom = getInputGeometry(customGeometry);
|
|
3071
|
-
if (!geom) {
|
|
3072
|
-
throw new Error("Wireframe: geometry prop must be a BufferGeometry or a ref to a BufferGeometry.");
|
|
3073
|
-
}
|
|
3074
|
-
setBarycentricCoordinates(geom, simplify);
|
|
3075
|
-
if (isRef$1(customGeometry)) {
|
|
3076
|
-
setGeometry(geom);
|
|
3077
|
-
}
|
|
3078
|
-
}, [simplify, customGeometry]);
|
|
3079
|
-
const drawnGeo = isRef$1(customGeometry) ? geometry : customGeometry;
|
|
3080
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, drawnGeo && /* @__PURE__ */ React.createElement("mesh", { geometry: drawnGeo }, /* @__PURE__ */ React.createElement(
|
|
3081
|
-
"meshWireframeMaterial",
|
|
3082
|
-
{
|
|
3083
|
-
attach: "material",
|
|
3084
|
-
transparent: true,
|
|
3085
|
-
side: THREE.DoubleSide,
|
|
3086
|
-
polygonOffset: true,
|
|
3087
|
-
polygonOffsetFactor: -4,
|
|
3088
|
-
...props
|
|
3089
|
-
}
|
|
3090
|
-
)));
|
|
3091
|
-
}
|
|
3092
|
-
function WireframeWithoutCustomGeo({
|
|
3093
|
-
simplify = false,
|
|
3094
|
-
...props
|
|
3095
|
-
}) {
|
|
3096
|
-
const objectRef = React.useRef(null);
|
|
3097
|
-
const uniforms = React.useMemo(() => getUniforms(), [WireframeMaterialShaders.uniforms]);
|
|
3098
|
-
useWireframeUniforms(uniforms, props);
|
|
3099
|
-
React.useLayoutEffect(() => {
|
|
3100
|
-
const geom = getInputGeometry(objectRef);
|
|
3101
|
-
if (!geom) {
|
|
3102
|
-
throw new Error("Wireframe: Must be a child of a Mesh, Line or Points object or specify a geometry prop.");
|
|
3103
|
-
}
|
|
3104
|
-
const og = geom.clone();
|
|
3105
|
-
setBarycentricCoordinates(geom, simplify);
|
|
3106
|
-
return () => {
|
|
3107
|
-
geom.copy(og);
|
|
3108
|
-
og.dispose();
|
|
3109
|
-
};
|
|
3110
|
-
}, [simplify]);
|
|
3111
|
-
React.useLayoutEffect(() => {
|
|
3112
|
-
const parentMesh = objectRef.current.parent;
|
|
3113
|
-
const og = parentMesh.material.clone();
|
|
3114
|
-
setWireframeOverride(parentMesh.material, uniforms);
|
|
3115
|
-
return () => {
|
|
3116
|
-
parentMesh.material.dispose();
|
|
3117
|
-
parentMesh.material = og;
|
|
3118
|
-
};
|
|
3119
|
-
}, []);
|
|
3120
|
-
return /* @__PURE__ */ React.createElement("object3D", { ref: objectRef });
|
|
3121
|
-
}
|
|
3122
|
-
function Wireframe({ geometry: customGeometry, ...props }) {
|
|
3123
|
-
if (customGeometry) {
|
|
3124
|
-
return /* @__PURE__ */ React.createElement(WireframeWithCustomGeo, { geometry: customGeometry, ...props });
|
|
3125
|
-
}
|
|
3126
|
-
return /* @__PURE__ */ React.createElement(WireframeWithoutCustomGeo, { ...props });
|
|
3127
|
-
}
|
|
3128
|
-
|
|
3129
2864
|
const Context = /* @__PURE__ */ React.createContext({});
|
|
3130
2865
|
const useGizmoContext = () => {
|
|
3131
2866
|
return React.useContext(Context);
|
|
@@ -3421,6 +3156,11 @@ const GizmoViewport = ({
|
|
|
3421
3156
|
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 }))));
|
|
3422
3157
|
};
|
|
3423
3158
|
|
|
3159
|
+
const roundEven = (n) => {
|
|
3160
|
+
const rounded = Math.ceil(n);
|
|
3161
|
+
return rounded % 2 === 0 ? rounded : rounded + 1;
|
|
3162
|
+
};
|
|
3163
|
+
|
|
3424
3164
|
const v1 = /* @__PURE__ */ new Vector3();
|
|
3425
3165
|
const v2 = /* @__PURE__ */ new Vector3();
|
|
3426
3166
|
const v3 = /* @__PURE__ */ new Vector3();
|
|
@@ -3519,9 +3259,11 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3519
3259
|
as = "div",
|
|
3520
3260
|
wrapperClass,
|
|
3521
3261
|
pointerEvents = "auto",
|
|
3262
|
+
pixelPerfect = true,
|
|
3522
3263
|
...props
|
|
3523
3264
|
}, ref) => {
|
|
3524
3265
|
const { gl, camera, scene, size, raycaster, events, viewport } = useThree();
|
|
3266
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
3525
3267
|
const [el] = React.useState(() => document.createElement(as));
|
|
3526
3268
|
const root = React.useRef(null);
|
|
3527
3269
|
const group = React.useRef(null);
|
|
@@ -3546,38 +3288,54 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3546
3288
|
el2.style.position = null;
|
|
3547
3289
|
el2.style.pointerEvents = null;
|
|
3548
3290
|
}
|
|
3549
|
-
}, [occlude]);
|
|
3291
|
+
}, [occlude, zIndexRange, gl.domElement]);
|
|
3550
3292
|
React.useLayoutEffect(() => {
|
|
3551
3293
|
if (group.current) {
|
|
3552
|
-
|
|
3294
|
+
if (!root.current) {
|
|
3295
|
+
root.current = ReactDOM.createRoot(el);
|
|
3296
|
+
}
|
|
3553
3297
|
scene.updateMatrixWorld();
|
|
3554
3298
|
if (transform) {
|
|
3555
3299
|
el.style.cssText = `position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;`;
|
|
3556
3300
|
} else {
|
|
3557
|
-
|
|
3558
|
-
el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(${vec[0]}px,${vec[1]}px,0);transform-origin:0 0;`;
|
|
3301
|
+
el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(0,-9999px,0);transform-origin:0 0;`;
|
|
3559
3302
|
}
|
|
3560
3303
|
if (target) {
|
|
3561
3304
|
if (prepend) target.prepend(el);
|
|
3562
3305
|
else target.appendChild(el);
|
|
3563
3306
|
}
|
|
3564
3307
|
return () => {
|
|
3565
|
-
if (
|
|
3566
|
-
|
|
3308
|
+
if (root.current) {
|
|
3309
|
+
root.current.unmount();
|
|
3310
|
+
root.current = null;
|
|
3311
|
+
}
|
|
3312
|
+
if (target && target.contains(el)) {
|
|
3313
|
+
target.removeChild(el);
|
|
3314
|
+
}
|
|
3567
3315
|
};
|
|
3568
3316
|
}
|
|
3569
|
-
}, [target, transform]);
|
|
3317
|
+
}, [target, transform, el, prepend, scene]);
|
|
3570
3318
|
React.useLayoutEffect(() => {
|
|
3571
3319
|
if (wrapperClass) el.className = wrapperClass;
|
|
3572
|
-
}, [wrapperClass]);
|
|
3320
|
+
}, [wrapperClass, el]);
|
|
3321
|
+
React.useLayoutEffect(() => {
|
|
3322
|
+
return () => {
|
|
3323
|
+
if (root.current) {
|
|
3324
|
+
root.current.unmount();
|
|
3325
|
+
root.current = null;
|
|
3326
|
+
}
|
|
3327
|
+
};
|
|
3328
|
+
}, []);
|
|
3573
3329
|
const styles = React.useMemo(() => {
|
|
3330
|
+
const width = forceEven ? roundEven(size.width) : size.width;
|
|
3331
|
+
const height = forceEven ? roundEven(size.height) : size.height;
|
|
3574
3332
|
if (transform) {
|
|
3575
3333
|
return {
|
|
3576
3334
|
position: "absolute",
|
|
3577
3335
|
top: 0,
|
|
3578
3336
|
left: 0,
|
|
3579
|
-
width
|
|
3580
|
-
height
|
|
3337
|
+
width,
|
|
3338
|
+
height,
|
|
3581
3339
|
transformStyle: "preserve-3d",
|
|
3582
3340
|
pointerEvents: "none"
|
|
3583
3341
|
};
|
|
@@ -3586,15 +3344,15 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3586
3344
|
position: "absolute",
|
|
3587
3345
|
transform: center ? "translate3d(-50%,-50%,0)" : "none",
|
|
3588
3346
|
...fullscreen && {
|
|
3589
|
-
top: -size.height / 2,
|
|
3590
|
-
left: -size.width / 2,
|
|
3591
|
-
width
|
|
3592
|
-
height
|
|
3347
|
+
top: forceEven ? roundEven(-size.height / 2) : -size.height / 2,
|
|
3348
|
+
left: forceEven ? roundEven(-size.width / 2) : -size.width / 2,
|
|
3349
|
+
width,
|
|
3350
|
+
height
|
|
3593
3351
|
},
|
|
3594
3352
|
...style
|
|
3595
3353
|
};
|
|
3596
3354
|
}
|
|
3597
|
-
}, [style, center, fullscreen, size, transform]);
|
|
3355
|
+
}, [style, center, fullscreen, size, transform, forceEven]);
|
|
3598
3356
|
const transformInnerStyles = React.useMemo(
|
|
3599
3357
|
() => ({ position: "absolute", pointerEvents }),
|
|
3600
3358
|
[pointerEvents]
|
|
@@ -3608,7 +3366,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3608
3366
|
} else {
|
|
3609
3367
|
root.current?.render(/* @__PURE__ */ React.createElement("div", { ref, style: styles, className, children }));
|
|
3610
3368
|
}
|
|
3611
|
-
});
|
|
3369
|
+
}, [transform, styles, transformInnerStyles, ref, className, style, children]);
|
|
3612
3370
|
const visible = React.useRef(true);
|
|
3613
3371
|
useFrame((gl2) => {
|
|
3614
3372
|
if (group.current) {
|
|
@@ -3640,7 +3398,12 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3640
3398
|
const zRange = occlude ? isRayCastOcclusion ? [zIndexRange[0], halfRange] : [halfRange - 1, 0] : zIndexRange;
|
|
3641
3399
|
el.style.zIndex = `${objectZIndex(group.current, camera, zRange)}`;
|
|
3642
3400
|
if (transform) {
|
|
3643
|
-
|
|
3401
|
+
let widthHalf = forceEven ? roundEven(size.width / 2) : size.width / 2;
|
|
3402
|
+
let heightHalf = forceEven ? roundEven(size.height / 2) : size.height / 2;
|
|
3403
|
+
if (pixelPerfect) {
|
|
3404
|
+
widthHalf = roundToPixelRatio(widthHalf);
|
|
3405
|
+
heightHalf = roundToPixelRatio(heightHalf);
|
|
3406
|
+
}
|
|
3644
3407
|
const fov = camera.projectionMatrix.elements[5] * heightHalf;
|
|
3645
3408
|
const { isOrthographicCamera, top, left, bottom, right } = camera;
|
|
3646
3409
|
const cameraMatrix = getCameraCSSMatrix(camera.matrixWorldInverse);
|
|
@@ -3651,8 +3414,10 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3651
3414
|
matrix.elements[3] = matrix.elements[7] = matrix.elements[11] = 0;
|
|
3652
3415
|
matrix.elements[15] = 1;
|
|
3653
3416
|
}
|
|
3654
|
-
|
|
3655
|
-
|
|
3417
|
+
const elWidth = forceEven ? roundEven(size.width) : size.width;
|
|
3418
|
+
const elHeight = forceEven ? roundEven(size.height) : size.height;
|
|
3419
|
+
el.style.width = elWidth + "px";
|
|
3420
|
+
el.style.height = elHeight + "px";
|
|
3656
3421
|
el.style.perspective = isOrthographicCamera ? "" : `${fov}px`;
|
|
3657
3422
|
if (transformOuterRef.current && transformInnerRef.current) {
|
|
3658
3423
|
transformOuterRef.current.style.transform = `${cameraTransform}${cameraMatrix}translate(${widthHalf}px,${heightHalf}px)`;
|
|
@@ -3660,7 +3425,13 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3660
3425
|
}
|
|
3661
3426
|
} else {
|
|
3662
3427
|
const scale = distanceFactor === void 0 ? 1 : objectScale(group.current, camera) * distanceFactor;
|
|
3663
|
-
|
|
3428
|
+
let x = forceEven ? roundEven(vec[0]) : vec[0];
|
|
3429
|
+
let y = forceEven ? roundEven(vec[1]) : vec[1];
|
|
3430
|
+
if (pixelPerfect) {
|
|
3431
|
+
x = roundToPixelRatio(x);
|
|
3432
|
+
y = roundToPixelRatio(y);
|
|
3433
|
+
}
|
|
3434
|
+
el.style.transform = `translate3d(${x}px,${y}px,0) scale(${scale})`;
|
|
3664
3435
|
}
|
|
3665
3436
|
oldPosition.current = vec;
|
|
3666
3437
|
oldZoom.current = camera.zoom;
|
|
@@ -3766,6 +3537,11 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3766
3537
|
);
|
|
3767
3538
|
|
|
3768
3539
|
const context$4 = /* @__PURE__ */ React.createContext(null);
|
|
3540
|
+
const resolveObject = (object, fallback) => {
|
|
3541
|
+
if (!object) return fallback;
|
|
3542
|
+
if ("current" in object) return object.current;
|
|
3543
|
+
return object;
|
|
3544
|
+
};
|
|
3769
3545
|
|
|
3770
3546
|
const vec1$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
3771
3547
|
const vec2$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
@@ -3800,6 +3576,8 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
3800
3576
|
onDragStart,
|
|
3801
3577
|
onDrag,
|
|
3802
3578
|
onDragEnd,
|
|
3579
|
+
onHover,
|
|
3580
|
+
dragState,
|
|
3803
3581
|
userData,
|
|
3804
3582
|
LineComponent: Line
|
|
3805
3583
|
} = React.useContext(context$4);
|
|
@@ -3831,7 +3609,13 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
3831
3609
|
const onPointerMove = React.useCallback(
|
|
3832
3610
|
(e) => {
|
|
3833
3611
|
e.stopPropagation();
|
|
3834
|
-
if (!isHovered)
|
|
3612
|
+
if (!isHovered) {
|
|
3613
|
+
const drag = dragState.current;
|
|
3614
|
+
if (drag === null || drag.component === "Arrow" && drag.axis === axis) {
|
|
3615
|
+
setIsHovered(true);
|
|
3616
|
+
onHover({ component: "Arrow", axis, hovering: true });
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3835
3619
|
if (clickInfo.current) {
|
|
3836
3620
|
const { clickPoint, dir } = clickInfo.current;
|
|
3837
3621
|
const [min, max] = translationLimits?.[axis] || [void 0, void 0];
|
|
@@ -3850,7 +3634,7 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
3850
3634
|
onDrag(offsetMatrix$1);
|
|
3851
3635
|
}
|
|
3852
3636
|
},
|
|
3853
|
-
[annotations, onDrag, isHovered, translation, translationLimits, axis]
|
|
3637
|
+
[annotations, onDrag, onHover, dragState, isHovered, translation, translationLimits, axis]
|
|
3854
3638
|
);
|
|
3855
3639
|
const onPointerUp = React.useCallback(
|
|
3856
3640
|
(e) => {
|
|
@@ -3865,10 +3649,16 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
3865
3649
|
},
|
|
3866
3650
|
[annotations, camControls, onDragEnd]
|
|
3867
3651
|
);
|
|
3868
|
-
const onPointerOut = React.useCallback(
|
|
3869
|
-
e
|
|
3870
|
-
|
|
3871
|
-
|
|
3652
|
+
const onPointerOut = React.useCallback(
|
|
3653
|
+
(e) => {
|
|
3654
|
+
e.stopPropagation();
|
|
3655
|
+
if (isHovered) {
|
|
3656
|
+
setIsHovered(false);
|
|
3657
|
+
onHover({ component: "Arrow", axis, hovering: false });
|
|
3658
|
+
}
|
|
3659
|
+
},
|
|
3660
|
+
[onHover, axis, isHovered]
|
|
3661
|
+
);
|
|
3872
3662
|
const { cylinderLength, coneWidth, coneLength, matrixL } = React.useMemo(() => {
|
|
3873
3663
|
const coneWidth2 = fixed ? lineWidth / scale * 1.6 : scale / 20;
|
|
3874
3664
|
const coneLength2 = fixed ? 0.2 : scale / 5;
|
|
@@ -3972,6 +3762,8 @@ const rotMatrix = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
3972
3762
|
const posNew = /* @__PURE__ */ new THREE.Vector3();
|
|
3973
3763
|
const ray$1 = /* @__PURE__ */ new THREE.Ray();
|
|
3974
3764
|
const intersection$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
3765
|
+
const viewPlane = /* @__PURE__ */ new THREE.Plane();
|
|
3766
|
+
const viewIntersection = /* @__PURE__ */ new THREE.Vector3();
|
|
3975
3767
|
const AxisRotator = ({
|
|
3976
3768
|
dir1,
|
|
3977
3769
|
dir2,
|
|
@@ -3992,6 +3784,8 @@ const AxisRotator = ({
|
|
|
3992
3784
|
onDragStart,
|
|
3993
3785
|
onDrag,
|
|
3994
3786
|
onDragEnd,
|
|
3787
|
+
onHover,
|
|
3788
|
+
dragState,
|
|
3995
3789
|
userData,
|
|
3996
3790
|
LineComponent: Line
|
|
3997
3791
|
} = React.useContext(context$4);
|
|
@@ -4025,14 +3819,29 @@ const AxisRotator = ({
|
|
|
4025
3819
|
const onPointerMove = React.useCallback(
|
|
4026
3820
|
(e) => {
|
|
4027
3821
|
e.stopPropagation();
|
|
4028
|
-
if (!isHovered)
|
|
3822
|
+
if (!isHovered) {
|
|
3823
|
+
const drag = dragState.current;
|
|
3824
|
+
if (drag === null || drag.component === "Rotator" && drag.axis === axis) {
|
|
3825
|
+
setIsHovered(true);
|
|
3826
|
+
onHover({ component: "Rotator", axis, hovering: true });
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
4029
3829
|
if (clickInfo.current) {
|
|
4030
3830
|
const { clickPoint, origin, e1, e2, normal, plane } = clickInfo.current;
|
|
4031
3831
|
const [min, max] = rotationLimits?.[axis] || [void 0, void 0];
|
|
4032
3832
|
ray$1.copy(e.ray);
|
|
4033
|
-
ray$1.
|
|
4034
|
-
|
|
4035
|
-
|
|
3833
|
+
const dotProduct = Math.abs(ray$1.direction.dot(normal));
|
|
3834
|
+
if (dotProduct < 0.1) {
|
|
3835
|
+
viewPlane.setFromNormalAndCoplanarPoint(ray$1.direction.clone().negate(), origin);
|
|
3836
|
+
ray$1.intersectPlane(viewPlane, viewIntersection);
|
|
3837
|
+
const toIntersection = viewIntersection.clone().sub(origin);
|
|
3838
|
+
const projectedDist = toIntersection.dot(normal);
|
|
3839
|
+
intersection$1.copy(viewIntersection).sub(normal.clone().multiplyScalar(projectedDist));
|
|
3840
|
+
} else {
|
|
3841
|
+
ray$1.intersectPlane(plane, intersection$1);
|
|
3842
|
+
ray$1.direction.negate();
|
|
3843
|
+
ray$1.intersectPlane(plane, intersection$1);
|
|
3844
|
+
}
|
|
4036
3845
|
let deltaAngle = calculateAngle(clickPoint, intersection$1, origin, e1, e2);
|
|
4037
3846
|
let degrees = toDegrees(deltaAngle);
|
|
4038
3847
|
if (e.shiftKey) {
|
|
@@ -4058,7 +3867,7 @@ const AxisRotator = ({
|
|
|
4058
3867
|
onDrag(rotMatrix);
|
|
4059
3868
|
}
|
|
4060
3869
|
},
|
|
4061
|
-
[annotations, onDrag, isHovered, rotationLimits, axis]
|
|
3870
|
+
[annotations, onDrag, onHover, dragState, isHovered, rotationLimits, axis]
|
|
4062
3871
|
);
|
|
4063
3872
|
const onPointerUp = React.useCallback(
|
|
4064
3873
|
(e) => {
|
|
@@ -4074,10 +3883,16 @@ const AxisRotator = ({
|
|
|
4074
3883
|
},
|
|
4075
3884
|
[annotations, camControls, onDragEnd]
|
|
4076
3885
|
);
|
|
4077
|
-
const onPointerOut = React.useCallback(
|
|
4078
|
-
e
|
|
4079
|
-
|
|
4080
|
-
|
|
3886
|
+
const onPointerOut = React.useCallback(
|
|
3887
|
+
(e) => {
|
|
3888
|
+
e.stopPropagation();
|
|
3889
|
+
if (isHovered) {
|
|
3890
|
+
setIsHovered(false);
|
|
3891
|
+
onHover({ component: "Rotator", axis, hovering: false });
|
|
3892
|
+
}
|
|
3893
|
+
},
|
|
3894
|
+
[onHover, axis, isHovered]
|
|
3895
|
+
);
|
|
4081
3896
|
const matrixL = React.useMemo(() => {
|
|
4082
3897
|
const dir1N = dir1.clone().normalize();
|
|
4083
3898
|
const dir2N = dir2.clone().normalize();
|
|
@@ -4178,6 +3993,8 @@ const PlaneSlider = ({
|
|
|
4178
3993
|
onDragStart,
|
|
4179
3994
|
onDrag,
|
|
4180
3995
|
onDragEnd,
|
|
3996
|
+
onHover,
|
|
3997
|
+
dragState,
|
|
4181
3998
|
userData,
|
|
4182
3999
|
LineComponent: Line
|
|
4183
4000
|
} = React.useContext(context$4);
|
|
@@ -4213,7 +4030,13 @@ const PlaneSlider = ({
|
|
|
4213
4030
|
const onPointerMove = React.useCallback(
|
|
4214
4031
|
(e) => {
|
|
4215
4032
|
e.stopPropagation();
|
|
4216
|
-
if (!isHovered)
|
|
4033
|
+
if (!isHovered) {
|
|
4034
|
+
const drag = dragState.current;
|
|
4035
|
+
if (drag === null || drag.component === "Slider" && drag.axis === axis) {
|
|
4036
|
+
setIsHovered(true);
|
|
4037
|
+
onHover({ component: "Slider", axis, hovering: true });
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
4217
4040
|
if (clickInfo.current) {
|
|
4218
4041
|
const { clickPoint, e1, e2, plane } = clickInfo.current;
|
|
4219
4042
|
const [minX, maxX] = translationLimits?.[(axis + 1) % 3] || [void 0, void 0];
|
|
@@ -4249,7 +4072,7 @@ const PlaneSlider = ({
|
|
|
4249
4072
|
onDrag(offsetMatrix);
|
|
4250
4073
|
}
|
|
4251
4074
|
},
|
|
4252
|
-
[annotations, onDrag, isHovered, translation, translationLimits, axis]
|
|
4075
|
+
[annotations, onDrag, onHover, dragState, isHovered, translation, translationLimits, axis]
|
|
4253
4076
|
);
|
|
4254
4077
|
const onPointerUp = React.useCallback(
|
|
4255
4078
|
(e) => {
|
|
@@ -4264,10 +4087,16 @@ const PlaneSlider = ({
|
|
|
4264
4087
|
},
|
|
4265
4088
|
[annotations, camControls, onDragEnd]
|
|
4266
4089
|
);
|
|
4267
|
-
const onPointerOut = React.useCallback(
|
|
4268
|
-
e
|
|
4269
|
-
|
|
4270
|
-
|
|
4090
|
+
const onPointerOut = React.useCallback(
|
|
4091
|
+
(e) => {
|
|
4092
|
+
e.stopPropagation();
|
|
4093
|
+
if (isHovered) {
|
|
4094
|
+
setIsHovered(false);
|
|
4095
|
+
onHover({ component: "Slider", axis, hovering: false });
|
|
4096
|
+
}
|
|
4097
|
+
},
|
|
4098
|
+
[onHover, axis, isHovered]
|
|
4099
|
+
);
|
|
4271
4100
|
const matrixL = React.useMemo(() => {
|
|
4272
4101
|
const dir1N = dir1.clone().normalize();
|
|
4273
4102
|
const dir2N = dir2.clone().normalize();
|
|
@@ -4405,6 +4234,8 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
4405
4234
|
onDragStart,
|
|
4406
4235
|
onDrag,
|
|
4407
4236
|
onDragEnd,
|
|
4237
|
+
onHover,
|
|
4238
|
+
dragState,
|
|
4408
4239
|
userData
|
|
4409
4240
|
} = React.useContext(context$4);
|
|
4410
4241
|
const size = useThree((state) => state.size);
|
|
@@ -4441,7 +4272,13 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
4441
4272
|
const onPointerMove = React.useCallback(
|
|
4442
4273
|
(e) => {
|
|
4443
4274
|
e.stopPropagation();
|
|
4444
|
-
if (!isHovered)
|
|
4275
|
+
if (!isHovered) {
|
|
4276
|
+
const drag = dragState.current;
|
|
4277
|
+
if (drag === null || drag.component === "Sphere" && drag.axis === axis) {
|
|
4278
|
+
setIsHovered(true);
|
|
4279
|
+
onHover({ component: "Sphere", axis, hovering: true });
|
|
4280
|
+
}
|
|
4281
|
+
}
|
|
4445
4282
|
if (clickInfo.current) {
|
|
4446
4283
|
const { clickPoint, dir, mPLG, mPLGInv, offsetMultiplier } = clickInfo.current;
|
|
4447
4284
|
const [min, max] = scaleLimits?.[axis] || [1e-5, void 0];
|
|
@@ -4467,7 +4304,7 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
4467
4304
|
onDrag(scaleMatrix);
|
|
4468
4305
|
}
|
|
4469
4306
|
},
|
|
4470
|
-
[annotations, position, onDrag, isHovered, scaleLimits, axis]
|
|
4307
|
+
[annotations, position, onDrag, onHover, dragState, isHovered, scaleLimits, axis]
|
|
4471
4308
|
);
|
|
4472
4309
|
const onPointerUp = React.useCallback(
|
|
4473
4310
|
(e) => {
|
|
@@ -4484,10 +4321,16 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
4484
4321
|
},
|
|
4485
4322
|
[annotations, camControls, onDragEnd, position]
|
|
4486
4323
|
);
|
|
4487
|
-
const onPointerOut = React.useCallback(
|
|
4488
|
-
e
|
|
4489
|
-
|
|
4490
|
-
|
|
4324
|
+
const onPointerOut = React.useCallback(
|
|
4325
|
+
(e) => {
|
|
4326
|
+
e.stopPropagation();
|
|
4327
|
+
if (isHovered) {
|
|
4328
|
+
setIsHovered(false);
|
|
4329
|
+
onHover({ component: "Sphere", axis, hovering: false });
|
|
4330
|
+
}
|
|
4331
|
+
},
|
|
4332
|
+
[onHover, axis, isHovered]
|
|
4333
|
+
);
|
|
4491
4334
|
const { radius, matrixL } = React.useMemo(() => {
|
|
4492
4335
|
const radius2 = fixed ? lineWidth / scale * 1.8 : scale / 22.5;
|
|
4493
4336
|
const quaternion = new THREE.Quaternion().setFromUnitVectors(upV, direction.clone().normalize());
|
|
@@ -4557,9 +4400,11 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4557
4400
|
({
|
|
4558
4401
|
enabled = true,
|
|
4559
4402
|
matrix,
|
|
4403
|
+
object,
|
|
4560
4404
|
onDragStart,
|
|
4561
4405
|
onDrag,
|
|
4562
4406
|
onDragEnd,
|
|
4407
|
+
onHover,
|
|
4563
4408
|
autoTransform = true,
|
|
4564
4409
|
anchor,
|
|
4565
4410
|
disableAxes = false,
|
|
@@ -4595,14 +4440,35 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4595
4440
|
const gizmoRef = React.useRef(null);
|
|
4596
4441
|
const childrenRef = React.useRef(null);
|
|
4597
4442
|
const translation = React.useRef([0, 0, 0]);
|
|
4443
|
+
const dragState = React.useRef(null);
|
|
4598
4444
|
const cameraScale = React.useRef(new THREE.Vector3(1, 1, 1));
|
|
4599
4445
|
const gizmoScale = React.useRef(new THREE.Vector3(1, 1, 1));
|
|
4446
|
+
React.useEffect(() => {
|
|
4447
|
+
if (object) {
|
|
4448
|
+
const target = resolveObject(object);
|
|
4449
|
+
if (target) {
|
|
4450
|
+
const pivot = ref.current;
|
|
4451
|
+
const didAutoUpdate = target.matrixAutoUpdate;
|
|
4452
|
+
target.updateWorldMatrix(true, true);
|
|
4453
|
+
target.matrixAutoUpdate = false;
|
|
4454
|
+
pivot.matrix.copy(target.matrix);
|
|
4455
|
+
return () => {
|
|
4456
|
+
if (didAutoUpdate) {
|
|
4457
|
+
target.matrixAutoUpdate = true;
|
|
4458
|
+
target.matrix.decompose(target.position, target.quaternion, target.scale);
|
|
4459
|
+
}
|
|
4460
|
+
};
|
|
4461
|
+
}
|
|
4462
|
+
}
|
|
4463
|
+
}, [object]);
|
|
4600
4464
|
React.useLayoutEffect(() => {
|
|
4601
4465
|
if (!anchor) return;
|
|
4602
|
-
childrenRef.current
|
|
4603
|
-
|
|
4466
|
+
const anchorTarget = resolveObject(object, childrenRef.current);
|
|
4467
|
+
if (!anchorTarget) return;
|
|
4468
|
+
anchorTarget.updateWorldMatrix(true, true);
|
|
4469
|
+
mPInv.copy(anchorTarget.matrixWorld).invert();
|
|
4604
4470
|
bb.makeEmpty();
|
|
4605
|
-
|
|
4471
|
+
anchorTarget.traverse((obj) => {
|
|
4606
4472
|
if (!obj.geometry) return;
|
|
4607
4473
|
if (!obj.geometry.boundingBox) obj.geometry.computeBoundingBox();
|
|
4608
4474
|
mL.copy(obj.matrixWorld).premultiply(mPInv);
|
|
@@ -4617,9 +4483,17 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4617
4483
|
gizmoRef.current.position.copy(vPosition);
|
|
4618
4484
|
invalidate();
|
|
4619
4485
|
});
|
|
4486
|
+
const mergedUserData = React.useMemo(
|
|
4487
|
+
() => ({
|
|
4488
|
+
...userData,
|
|
4489
|
+
...depthTest === false && { interactivePriority: 1 }
|
|
4490
|
+
}),
|
|
4491
|
+
[userData, depthTest]
|
|
4492
|
+
);
|
|
4620
4493
|
const config = React.useMemo(
|
|
4621
4494
|
() => ({
|
|
4622
4495
|
onDragStart: (props2) => {
|
|
4496
|
+
dragState.current = props2;
|
|
4623
4497
|
mL0.copy(ref.current.matrix);
|
|
4624
4498
|
mW0.copy(ref.current.matrixWorld);
|
|
4625
4499
|
onDragStart && onDragStart(props2);
|
|
@@ -4635,13 +4509,20 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4635
4509
|
if (autoTransform) {
|
|
4636
4510
|
ref.current.matrix.copy(mL);
|
|
4637
4511
|
}
|
|
4512
|
+
const target = resolveObject(object);
|
|
4513
|
+
if (target) target.matrix.copy(mL);
|
|
4638
4514
|
onDrag && onDrag(mL, mdL, mW, mdW);
|
|
4639
4515
|
invalidate();
|
|
4640
4516
|
},
|
|
4641
4517
|
onDragEnd: () => {
|
|
4518
|
+
dragState.current = null;
|
|
4642
4519
|
if (onDragEnd) onDragEnd();
|
|
4643
4520
|
invalidate();
|
|
4644
4521
|
},
|
|
4522
|
+
onHover: (props2) => {
|
|
4523
|
+
if (onHover) onHover(props2);
|
|
4524
|
+
},
|
|
4525
|
+
dragState,
|
|
4645
4526
|
translation,
|
|
4646
4527
|
translationLimits,
|
|
4647
4528
|
rotationLimits,
|
|
@@ -4653,7 +4534,7 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4653
4534
|
fixed,
|
|
4654
4535
|
depthTest,
|
|
4655
4536
|
renderOrder,
|
|
4656
|
-
userData,
|
|
4537
|
+
userData: mergedUserData,
|
|
4657
4538
|
annotations,
|
|
4658
4539
|
annotationsClass,
|
|
4659
4540
|
LineComponent: LineComp
|
|
@@ -4662,6 +4543,7 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4662
4543
|
onDragStart,
|
|
4663
4544
|
onDrag,
|
|
4664
4545
|
onDragEnd,
|
|
4546
|
+
onHover,
|
|
4665
4547
|
translation,
|
|
4666
4548
|
translationLimits,
|
|
4667
4549
|
rotationLimits,
|
|
@@ -4673,11 +4555,12 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4673
4555
|
...axisColors,
|
|
4674
4556
|
hoveredColor,
|
|
4675
4557
|
opacity,
|
|
4676
|
-
|
|
4558
|
+
mergedUserData,
|
|
4677
4559
|
autoTransform,
|
|
4678
4560
|
annotations,
|
|
4679
4561
|
annotationsClass,
|
|
4680
|
-
LineComp
|
|
4562
|
+
LineComp,
|
|
4563
|
+
object
|
|
4681
4564
|
]
|
|
4682
4565
|
);
|
|
4683
4566
|
const vec = new THREE.Vector3();
|
|
@@ -5039,7 +4922,7 @@ function createInstances() {
|
|
|
5039
4922
|
];
|
|
5040
4923
|
}
|
|
5041
4924
|
const InstancedAttribute = React.forwardRef(
|
|
5042
|
-
({ name, defaultValue, normalized, usage = THREE.DynamicDrawUsage }, fref) => {
|
|
4925
|
+
({ name, defaultValue, normalized, usage = THREE.DynamicDrawUsage, type = "float" }, fref) => {
|
|
5043
4926
|
const ref = React.useRef(null);
|
|
5044
4927
|
React.useImperativeHandle(fref, () => ref.current, []);
|
|
5045
4928
|
React.useLayoutEffect(() => {
|
|
@@ -5047,7 +4930,26 @@ const InstancedAttribute = React.forwardRef(
|
|
|
5047
4930
|
parent.geometry.attributes[name] = ref.current;
|
|
5048
4931
|
const value = Array.isArray(defaultValue) ? defaultValue : [defaultValue];
|
|
5049
4932
|
const array = Array.from({ length: parent.userData.limit }, () => value).flat();
|
|
5050
|
-
|
|
4933
|
+
switch (type) {
|
|
4934
|
+
case "float":
|
|
4935
|
+
ref.current.array = new Float32Array(array);
|
|
4936
|
+
break;
|
|
4937
|
+
case "int":
|
|
4938
|
+
ref.current.array = new Int32Array(array);
|
|
4939
|
+
break;
|
|
4940
|
+
case "uint":
|
|
4941
|
+
ref.current.array = new Uint32Array(array);
|
|
4942
|
+
break;
|
|
4943
|
+
case "short":
|
|
4944
|
+
ref.current.array = new Int16Array(array);
|
|
4945
|
+
break;
|
|
4946
|
+
case "ushort":
|
|
4947
|
+
ref.current.array = new Uint16Array(array);
|
|
4948
|
+
break;
|
|
4949
|
+
case "byte":
|
|
4950
|
+
ref.current.array = new Uint8Array(array);
|
|
4951
|
+
break;
|
|
4952
|
+
}
|
|
5051
4953
|
ref.current.itemSize = value.length;
|
|
5052
4954
|
ref.current.count = array.length / ref.current.itemSize;
|
|
5053
4955
|
return () => {
|
|
@@ -6572,12 +6474,17 @@ const Gltf = /* @__PURE__ */ React.forwardRef(
|
|
|
6572
6474
|
}
|
|
6573
6475
|
);
|
|
6574
6476
|
|
|
6575
|
-
|
|
6576
|
-
function useKTX2(input, basisPath =
|
|
6477
|
+
let transcoderPath = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
|
|
6478
|
+
function useKTX2(input, basisPath = true, extendLoader) {
|
|
6577
6479
|
const renderer = useThree((state) => state.renderer);
|
|
6578
6480
|
const textures = useLoader(KTX2Loader, IsObject(input) ? Object.values(input) : input, (loader) => {
|
|
6481
|
+
if (extendLoader) {
|
|
6482
|
+
extendLoader(loader);
|
|
6483
|
+
}
|
|
6484
|
+
if (basisPath) {
|
|
6485
|
+
loader.setTranscoderPath(typeof basisPath === "string" ? basisPath : transcoderPath);
|
|
6486
|
+
}
|
|
6579
6487
|
loader.detectSupport(renderer);
|
|
6580
|
-
loader.setTranscoderPath(basisPath);
|
|
6581
6488
|
});
|
|
6582
6489
|
useEffect(() => {
|
|
6583
6490
|
const array = Array.isArray(textures) ? textures : [textures];
|
|
@@ -6592,16 +6499,20 @@ function useKTX2(input, basisPath = `${cdn}/basis/`) {
|
|
|
6592
6499
|
return textures;
|
|
6593
6500
|
}
|
|
6594
6501
|
}
|
|
6595
|
-
useKTX2.preload = (url, basisPath =
|
|
6596
|
-
|
|
6502
|
+
useKTX2.preload = (url, basisPath = true, extendLoader) => useLoader.preload(KTX2Loader, url, (loader) => {
|
|
6503
|
+
if (extendLoader) {
|
|
6504
|
+
extendLoader(loader);
|
|
6505
|
+
}
|
|
6506
|
+
if (basisPath) {
|
|
6507
|
+
loader.setTranscoderPath(typeof basisPath === "string" ? basisPath : transcoderPath);
|
|
6508
|
+
}
|
|
6597
6509
|
});
|
|
6598
6510
|
useKTX2.clear = (input) => useLoader.clear(KTX2Loader, input);
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
const texture = useKTX2(input, basisPath);
|
|
6511
|
+
useKTX2.setTranscoderPath = (path) => {
|
|
6512
|
+
transcoderPath = path;
|
|
6513
|
+
};
|
|
6514
|
+
const Ktx2 = ({ children, input, basisPath, extendLoader }) => {
|
|
6515
|
+
const texture = useKTX2(input, basisPath, extendLoader);
|
|
6605
6516
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(texture));
|
|
6606
6517
|
};
|
|
6607
6518
|
|
|
@@ -7077,18 +6988,21 @@ function Fisheye({
|
|
|
7077
6988
|
const normal = new THREE.Vector3();
|
|
7078
6989
|
const sph = new THREE.Sphere(new THREE.Vector3(), radius);
|
|
7079
6990
|
const normalMatrix = new THREE.Matrix3();
|
|
7080
|
-
const compute = React.useCallback(
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
6991
|
+
const compute = React.useCallback(
|
|
6992
|
+
(event, state, prev) => {
|
|
6993
|
+
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
6994
|
+
state.raycaster.setFromCamera(state.pointer, orthoC);
|
|
6995
|
+
if (!state.raycaster.ray.intersectSphere(sph, normal)) return;
|
|
6996
|
+
else normal.normalize();
|
|
6997
|
+
normalMatrix.getNormalMatrix(cubeApi.current.camera.matrixWorld);
|
|
6998
|
+
cubeApi.current.camera.getWorldPosition(state.raycaster.ray.origin);
|
|
6999
|
+
state.raycaster.ray.direction.set(0, 0, 1).reflect(normal);
|
|
7000
|
+
state.raycaster.ray.direction.x *= -1;
|
|
7001
|
+
state.raycaster.ray.direction.applyNormalMatrix(normalMatrix).multiplyScalar(-1);
|
|
7002
|
+
return void 0;
|
|
7003
|
+
},
|
|
7004
|
+
[width, height]
|
|
7005
|
+
);
|
|
7092
7006
|
useFrame(
|
|
7093
7007
|
({ gl }) => {
|
|
7094
7008
|
if (renderPriority) gl.render(sphere.current, orthoC);
|
|
@@ -7223,14 +7137,22 @@ const isWebGPURenderer = (def) => !!def.isWebGPURenderer;
|
|
|
7223
7137
|
const col = /* @__PURE__ */ new THREE.Color();
|
|
7224
7138
|
const TUNNEL_KEY = "__drei_view_tunnel__";
|
|
7225
7139
|
const tracked = globalThis[TUNNEL_KEY] || (globalThis[TUNNEL_KEY] = tunnel());
|
|
7226
|
-
function computeContainerPosition(canvasSize, trackRect) {
|
|
7140
|
+
function computeContainerPosition(canvasSize, trackRect, forceEven) {
|
|
7227
7141
|
const { right, top: trackTop, left: trackLeft, bottom: trackBottom, width, height } = trackRect;
|
|
7228
7142
|
const isOffscreen = trackRect.bottom < 0 || trackTop > canvasSize.height || right < 0 || trackRect.left > canvasSize.width;
|
|
7229
7143
|
const canvasBottom = canvasSize.top + canvasSize.height;
|
|
7230
|
-
const
|
|
7231
|
-
const
|
|
7232
|
-
const
|
|
7233
|
-
|
|
7144
|
+
const rawBottom = canvasBottom - trackBottom;
|
|
7145
|
+
const rawLeft = trackLeft - canvasSize.left;
|
|
7146
|
+
const rawTop = trackTop - canvasSize.top;
|
|
7147
|
+
const position = forceEven ? {
|
|
7148
|
+
width: roundEven(width),
|
|
7149
|
+
height: roundEven(height),
|
|
7150
|
+
left: roundEven(rawLeft),
|
|
7151
|
+
top: roundEven(rawTop),
|
|
7152
|
+
bottom: roundEven(rawBottom),
|
|
7153
|
+
right: roundEven(right)
|
|
7154
|
+
} : { width, height, left: rawLeft, top: rawTop, bottom: rawBottom, right };
|
|
7155
|
+
return { position, isOffscreen };
|
|
7234
7156
|
}
|
|
7235
7157
|
function prepareSkissor(renderer, camera, {
|
|
7236
7158
|
left,
|
|
@@ -7270,6 +7192,7 @@ function clear(renderer) {
|
|
|
7270
7192
|
}
|
|
7271
7193
|
function Container({ visible = true, canvasSize, scene, index, children, frames, rect, track }) {
|
|
7272
7194
|
const { scene: portalScene, camera: portalCamera, renderer, get, setEvents } = useThree();
|
|
7195
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
7273
7196
|
const [isOffscreen, setOffscreen] = React.useState(false);
|
|
7274
7197
|
const mountedRef = React.useRef(true);
|
|
7275
7198
|
React.useEffect(() => {
|
|
@@ -7287,7 +7210,7 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
7287
7210
|
frameCount++;
|
|
7288
7211
|
}
|
|
7289
7212
|
if (rect.current) {
|
|
7290
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, rect.current);
|
|
7213
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, rect.current, forceEven);
|
|
7291
7214
|
if (isOffscreen !== _isOffscreen) setOffscreen(_isOffscreen);
|
|
7292
7215
|
if (visible && !_isOffscreen && rect.current) {
|
|
7293
7216
|
const targetScene = children ? portalScene : scene;
|
|
@@ -7309,14 +7232,14 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
7309
7232
|
React.useLayoutEffect(() => {
|
|
7310
7233
|
const curRect = rect.current;
|
|
7311
7234
|
if (curRect && (!visible || !isOffscreen)) {
|
|
7312
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect);
|
|
7235
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect, forceEven);
|
|
7313
7236
|
if (!_isOffscreen) {
|
|
7314
7237
|
const autoClear = prepareSkissor(renderer, portalCamera, position);
|
|
7315
7238
|
clear(renderer);
|
|
7316
7239
|
finishSkissor(renderer, autoClear);
|
|
7317
7240
|
}
|
|
7318
7241
|
}
|
|
7319
|
-
}, [visible, isOffscreen, renderer, portalCamera, canvasSize]);
|
|
7242
|
+
}, [visible, isOffscreen, renderer, portalCamera, canvasSize, forceEven]);
|
|
7320
7243
|
React.useEffect(() => {
|
|
7321
7244
|
if (!track) return;
|
|
7322
7245
|
const curRect = rect.current;
|
|
@@ -7324,7 +7247,7 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
7324
7247
|
setEvents({ connected: track.current });
|
|
7325
7248
|
return () => {
|
|
7326
7249
|
if (curRect) {
|
|
7327
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect);
|
|
7250
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect, forceEven);
|
|
7328
7251
|
if (!_isOffscreen) {
|
|
7329
7252
|
const autoClear = prepareSkissor(renderer, portalCamera, position);
|
|
7330
7253
|
clear(renderer);
|
|
@@ -7333,13 +7256,14 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
7333
7256
|
}
|
|
7334
7257
|
setEvents({ connected: old });
|
|
7335
7258
|
};
|
|
7336
|
-
}, [track, renderer, portalCamera, canvasSize, get, setEvents]);
|
|
7259
|
+
}, [track, renderer, portalCamera, canvasSize, get, setEvents, forceEven]);
|
|
7337
7260
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children, /* @__PURE__ */ React.createElement("group", { onPointerOver: () => null }));
|
|
7338
7261
|
}
|
|
7339
7262
|
const CanvasView = /* @__PURE__ */ React.forwardRef(
|
|
7340
7263
|
({ track, visible = true, index = 1, id, style, className, frames = Infinity, children, ...props }, fref) => {
|
|
7341
7264
|
const rect = React.useRef(null);
|
|
7342
7265
|
const { size, scene } = useThree();
|
|
7266
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
7343
7267
|
const [virtualScene] = React.useState(() => new THREE.Scene());
|
|
7344
7268
|
const [ready, toggle] = React.useReducer(() => true, false);
|
|
7345
7269
|
const compute = React.useCallback(
|
|
@@ -7376,12 +7300,12 @@ const CanvasView = /* @__PURE__ */ React.forwardRef(
|
|
|
7376
7300
|
{
|
|
7377
7301
|
events: { compute, priority: index },
|
|
7378
7302
|
size: {
|
|
7379
|
-
width: rect.current?.width,
|
|
7380
|
-
height: rect.current?.height,
|
|
7303
|
+
width: forceEven && rect.current?.width ? roundEven(rect.current.width) : rect.current?.width,
|
|
7304
|
+
height: forceEven && rect.current?.height ? roundEven(rect.current.height) : rect.current?.height,
|
|
7381
7305
|
// @ts-ignore
|
|
7382
|
-
top: rect.current?.top,
|
|
7306
|
+
top: forceEven && rect.current?.top ? roundEven(rect.current.top) : rect.current?.top,
|
|
7383
7307
|
// @ts-ignore
|
|
7384
|
-
left: rect.current?.left
|
|
7308
|
+
left: forceEven && rect.current?.left ? roundEven(rect.current.left) : rect.current?.left
|
|
7385
7309
|
}
|
|
7386
7310
|
}
|
|
7387
7311
|
));
|
|
@@ -8556,4 +8480,4 @@ function useSelect() {
|
|
|
8556
8480
|
return React.useContext(context);
|
|
8557
8481
|
}
|
|
8558
8482
|
|
|
8559
|
-
export { AdaptiveDpr, AdaptiveEvents, ArcballControls, BBAnchor, Backdrop, Billboard, Bounds, Box, CameraShake, Capsule, CatmullRomLine, Center, Circle, Clone, Cloud, CloudInstance, Clouds, ComputedAttribute, Cone, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, Dodecahedron, DragControls, Edges, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, Helper, Html, Hud, Icosahedron, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Loader, MapControls, Mask, MatcapTexture, Merged, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Select, Shadow, Shape, Sky, Sphere, SpriteAnimator, Stage, Stats, StatsGl, Svg, Tetrahedron, Text3D, Texture, Torus, TorusKnot, TrackballControls, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture,
|
|
8483
|
+
export { AdaptiveDpr, AdaptiveEvents, ArcballControls, BBAnchor, Backdrop, Billboard, Bounds, Box, CameraShake, Capsule, CatmullRomLine, Center, Circle, Clone, Cloud, CloudInstance, Clouds, ComputedAttribute, Cone, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, Dodecahedron, DragControls, Edges, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, Helper, Html, Hud, Icosahedron, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Loader, MapControls, Mask, MatcapTexture, Merged, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Select, Shadow, Shape, Sky, Sphere, SpriteAnimator, Stage, Stats, StatsGl, Svg, Tetrahedron, Text3D, Texture, Torus, TorusKnot, TrackballControls, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture, calcPosFromAngles, checkIfFrameIsEmpty, createInstances, getFirstFrame, meshBounds, presetsObj, useAnimations, useAspect, useBounds, useContextBridge, useCubeCamera, useCubeTexture, useCursor, useCustomRaycast, useDepthBuffer, useDetectGPU, useEnvironment, useFBO, useFBX, useFont, useGLTF, useGizmoContext, useHelper, useIntersect, useKTX2, useKeyboardControls, useMask, useMatcapTexture, useMotion, useNormalTexture, usePerformanceMonitor, useProgress, useScroll, useSelect, useSpriteAnimator, useSpriteLoader, useSurfaceSampler, useTexture, useTrailTexture, useVideoTexture };
|