@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/index.mjs
CHANGED
|
@@ -2,9 +2,8 @@ import * as React from 'react';
|
|
|
2
2
|
import { forwardRef, useImperativeHandle, useMemo, useEffect, useCallback, useRef, useLayoutEffect, useState, Fragment, createContext, useContext, Suspense } from 'react';
|
|
3
3
|
import { useThree, useFrame, extend, createPortal, applyProps, useInstanceHandle, context as context$9, useLoader, addEffect, addAfterEffect } from '@react-three/fiber';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
|
-
import { REVISION, WebGLRenderTarget, Frustum, Matrix4, Vector3, Vector4, Vector2, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, Object3D, WebGLCubeRenderTarget, HalfFloatType, CubeCamera as CubeCamera$1, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial,
|
|
5
|
+
import { REVISION, WebGLRenderTarget, Frustum, Matrix4, Vector3, Vector4, Vector2, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, Object3D, WebGLCubeRenderTarget, HalfFloatType, CubeCamera as CubeCamera$1, EventDispatcher, Euler, Quaternion, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial, DynamicDrawUsage, CatmullRomCurve3, CubicBezierCurve3, QuadraticBezierCurve3, Shape as Shape$1, CanvasTexture, 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, Mesh, 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
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';
|
|
@@ -184,6 +183,7 @@ function shaderMaterial(uniforms, vertexShader, fragmentShader, onInit) {
|
|
|
184
183
|
});
|
|
185
184
|
}
|
|
186
185
|
this.uniforms = THREE.UniformsUtils.clone(this.uniforms);
|
|
186
|
+
Object.assign(this, parameters);
|
|
187
187
|
}
|
|
188
188
|
};
|
|
189
189
|
}
|
|
@@ -200,7 +200,7 @@ const version = /* @__PURE__ */ getVersion();
|
|
|
200
200
|
function isLight(object) {
|
|
201
201
|
return object.isLight;
|
|
202
202
|
}
|
|
203
|
-
function isGeometry
|
|
203
|
+
function isGeometry(object) {
|
|
204
204
|
return !!object.geometry;
|
|
205
205
|
}
|
|
206
206
|
const accumulativeContext = /* @__PURE__ */ React.createContext(
|
|
@@ -445,7 +445,7 @@ vec3 texelOld = texture2D(previousShadowMap, vUv).rgb;
|
|
|
445
445
|
this.lights = [];
|
|
446
446
|
this.meshes = [];
|
|
447
447
|
this.scene.traverse((object) => {
|
|
448
|
-
if (isGeometry
|
|
448
|
+
if (isGeometry(object)) {
|
|
449
449
|
this.meshes.push({ object, material: object.material });
|
|
450
450
|
} else if (isLight(object)) {
|
|
451
451
|
this.lights.push({ object, intensity: object.intensity });
|
|
@@ -1334,6 +1334,81 @@ const ArcballControls = /* @__PURE__ */ forwardRef(
|
|
|
1334
1334
|
}
|
|
1335
1335
|
);
|
|
1336
1336
|
|
|
1337
|
+
let DeviceOrientationControls$1 = class DeviceOrientationControls extends EventDispatcher {
|
|
1338
|
+
object;
|
|
1339
|
+
changeEvent = { type: "change" };
|
|
1340
|
+
EPS = 1e-6;
|
|
1341
|
+
enabled = true;
|
|
1342
|
+
deviceOrientation = { alpha: 0, beta: 0, gamma: 0 };
|
|
1343
|
+
screenOrientation = 0;
|
|
1344
|
+
alphaOffset = 0;
|
|
1345
|
+
// radians
|
|
1346
|
+
constructor(object) {
|
|
1347
|
+
super();
|
|
1348
|
+
this.object = object;
|
|
1349
|
+
this.object.rotation.reorder("YXZ");
|
|
1350
|
+
this.connect();
|
|
1351
|
+
}
|
|
1352
|
+
onDeviceOrientationChangeEvent = (event) => {
|
|
1353
|
+
this.deviceOrientation = event;
|
|
1354
|
+
};
|
|
1355
|
+
onScreenOrientationChangeEvent = () => {
|
|
1356
|
+
this.screenOrientation = window.orientation || 0;
|
|
1357
|
+
};
|
|
1358
|
+
// The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''
|
|
1359
|
+
zee = new Vector3(0, 0, 1);
|
|
1360
|
+
euler = new Euler();
|
|
1361
|
+
q0 = new Quaternion();
|
|
1362
|
+
q1 = new Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));
|
|
1363
|
+
// - PI/2 around the x-axis
|
|
1364
|
+
setObjectQuaternion = (quaternion, alpha, beta, gamma, orient) => {
|
|
1365
|
+
this.euler.set(beta, alpha, -gamma, "YXZ");
|
|
1366
|
+
quaternion.setFromEuler(this.euler);
|
|
1367
|
+
quaternion.multiply(this.q1);
|
|
1368
|
+
quaternion.multiply(this.q0.setFromAxisAngle(this.zee, -orient));
|
|
1369
|
+
};
|
|
1370
|
+
connect = () => {
|
|
1371
|
+
this.onScreenOrientationChangeEvent();
|
|
1372
|
+
if (window.DeviceOrientationEvent !== void 0 && // @ts-ignore
|
|
1373
|
+
typeof window.DeviceOrientationEvent.requestPermission === "function") {
|
|
1374
|
+
window.DeviceOrientationEvent.requestPermission().then((response) => {
|
|
1375
|
+
if (response == "granted") {
|
|
1376
|
+
window.addEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
1377
|
+
window.addEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
1378
|
+
}
|
|
1379
|
+
}).catch((error) => {
|
|
1380
|
+
console.error("THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:", error);
|
|
1381
|
+
});
|
|
1382
|
+
} else {
|
|
1383
|
+
window.addEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
1384
|
+
window.addEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
1385
|
+
}
|
|
1386
|
+
this.enabled = true;
|
|
1387
|
+
};
|
|
1388
|
+
disconnect = () => {
|
|
1389
|
+
window.removeEventListener("orientationchange", this.onScreenOrientationChangeEvent);
|
|
1390
|
+
window.removeEventListener("deviceorientation", this.onDeviceOrientationChangeEvent);
|
|
1391
|
+
this.enabled = false;
|
|
1392
|
+
};
|
|
1393
|
+
lastQuaternion = new Quaternion();
|
|
1394
|
+
update = () => {
|
|
1395
|
+
if (this.enabled === false) return;
|
|
1396
|
+
const device = this.deviceOrientation;
|
|
1397
|
+
if (device) {
|
|
1398
|
+
const alpha = device.alpha ? MathUtils.degToRad(device.alpha) + this.alphaOffset : 0;
|
|
1399
|
+
const beta = device.beta ? MathUtils.degToRad(device.beta) : 0;
|
|
1400
|
+
const gamma = device.gamma ? MathUtils.degToRad(device.gamma) : 0;
|
|
1401
|
+
const orient = this.screenOrientation ? MathUtils.degToRad(this.screenOrientation) : 0;
|
|
1402
|
+
this.setObjectQuaternion(this.object.quaternion, alpha, beta, gamma, orient);
|
|
1403
|
+
if (8 * (1 - this.lastQuaternion.dot(this.object.quaternion)) > this.EPS) {
|
|
1404
|
+
this.lastQuaternion.copy(this.object.quaternion);
|
|
1405
|
+
this.dispatchEvent(this.changeEvent);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1409
|
+
dispose = () => this.disconnect();
|
|
1410
|
+
};
|
|
1411
|
+
|
|
1337
1412
|
const DeviceOrientationControls = /* @__PURE__ */ React.forwardRef(
|
|
1338
1413
|
(props, ref) => {
|
|
1339
1414
|
const { camera, onChange, makeDefault, ...rest } = props;
|
|
@@ -1403,8 +1478,9 @@ const DragControls = React.forwardRef(
|
|
|
1403
1478
|
onDragStart && onDragStart(initialModelPosition);
|
|
1404
1479
|
invalidate();
|
|
1405
1480
|
},
|
|
1406
|
-
onDrag: ({ xy: [dragX, dragY], intentional }) => {
|
|
1481
|
+
onDrag: ({ xy: [dragX, dragY], intentional, event }) => {
|
|
1407
1482
|
if (!intentional) return;
|
|
1483
|
+
if (dragConfig && dragConfig.preventOverlap) event.preventDefault();
|
|
1408
1484
|
const normalizedMouseX = (dragX - size.left) / size.width * 2 - 1;
|
|
1409
1485
|
const normalizedMouseY = -((dragY - size.top) / size.height) * 2 + 1;
|
|
1410
1486
|
mousePosition2D.set(normalizedMouseX, normalizedMouseY);
|
|
@@ -1573,12 +1649,21 @@ function KeyboardControls({ map, children, onChange, domElement }) {
|
|
|
1573
1649
|
obj.pressed = false;
|
|
1574
1650
|
if (up) fn(false);
|
|
1575
1651
|
};
|
|
1652
|
+
const blurHandler = () => {
|
|
1653
|
+
const resetState = map.reduce((prev, cur) => ({ ...prev, [cur.name]: false }), {});
|
|
1654
|
+
set(resetState);
|
|
1655
|
+
Object.values(keyMap).forEach((obj) => {
|
|
1656
|
+
obj.pressed = false;
|
|
1657
|
+
});
|
|
1658
|
+
};
|
|
1576
1659
|
const source = domElement || window;
|
|
1577
1660
|
source.addEventListener("keydown", downHandler, { passive: true });
|
|
1578
1661
|
source.addEventListener("keyup", upHandler, { passive: true });
|
|
1662
|
+
window.addEventListener("blur", blurHandler);
|
|
1579
1663
|
return () => {
|
|
1580
1664
|
source.removeEventListener("keydown", downHandler);
|
|
1581
1665
|
source.removeEventListener("keyup", upHandler);
|
|
1666
|
+
window.removeEventListener("blur", blurHandler);
|
|
1582
1667
|
};
|
|
1583
1668
|
}, [domElement, key]);
|
|
1584
1669
|
return /* @__PURE__ */ React.createElement(context$8.Provider, { value: api, children });
|
|
@@ -1929,7 +2014,13 @@ function PresentationControls({
|
|
|
1929
2014
|
return /* @__PURE__ */ React.createElement("group", { ref, ...bind?.() }, children);
|
|
1930
2015
|
}
|
|
1931
2016
|
|
|
2017
|
+
function roundToPixelRatio(value) {
|
|
2018
|
+
const ratio = window.devicePixelRatio || 1;
|
|
2019
|
+
return Math.round(value * ratio) / ratio;
|
|
2020
|
+
}
|
|
2021
|
+
|
|
1932
2022
|
const context$7 = /* @__PURE__ */ React.createContext(null);
|
|
2023
|
+
const rootCache = /* @__PURE__ */ new WeakMap();
|
|
1933
2024
|
function useScroll() {
|
|
1934
2025
|
return React.useContext(context$7);
|
|
1935
2026
|
}
|
|
@@ -1943,6 +2034,7 @@ function ScrollControls({
|
|
|
1943
2034
|
damping = 0.25,
|
|
1944
2035
|
maxSpeed = Infinity,
|
|
1945
2036
|
prepend = false,
|
|
2037
|
+
pixelPerfect = true,
|
|
1946
2038
|
style = {},
|
|
1947
2039
|
children
|
|
1948
2040
|
}) {
|
|
@@ -1964,6 +2056,7 @@ function ScrollControls({
|
|
|
1964
2056
|
delta: 0,
|
|
1965
2057
|
scroll,
|
|
1966
2058
|
pages,
|
|
2059
|
+
pixelPerfect,
|
|
1967
2060
|
// 0-1 for a range between from -> from + distance
|
|
1968
2061
|
range(from, distance2, margin = 0) {
|
|
1969
2062
|
const start = from - margin;
|
|
@@ -1982,7 +2075,7 @@ function ScrollControls({
|
|
|
1982
2075
|
}
|
|
1983
2076
|
};
|
|
1984
2077
|
return state2;
|
|
1985
|
-
}, [eps, damping, horizontal, pages]);
|
|
2078
|
+
}, [eps, damping, horizontal, pages, pixelPerfect]);
|
|
1986
2079
|
React.useEffect(() => {
|
|
1987
2080
|
el.style.position = "absolute";
|
|
1988
2081
|
el.style.width = "100%";
|
|
@@ -2095,10 +2188,23 @@ const ScrollHtml = React.forwardRef(
|
|
|
2095
2188
|
React.useImperativeHandle(ref, () => group.current, []);
|
|
2096
2189
|
const { width, height } = useThree((state2) => state2.size);
|
|
2097
2190
|
const fiberState = React.useContext(context$9);
|
|
2098
|
-
const root = React.useMemo(() =>
|
|
2191
|
+
const root = React.useMemo(() => {
|
|
2192
|
+
let root2 = rootCache.get(state.fixed);
|
|
2193
|
+
if (!root2) {
|
|
2194
|
+
root2 = ReactDOM.createRoot(state.fixed);
|
|
2195
|
+
rootCache.set(state.fixed, root2);
|
|
2196
|
+
}
|
|
2197
|
+
return root2;
|
|
2198
|
+
}, [state.fixed]);
|
|
2099
2199
|
useFrame(() => {
|
|
2100
2200
|
if (state.delta > state.eps) {
|
|
2101
|
-
|
|
2201
|
+
let x = state.horizontal ? -width * (state.pages - 1) * state.offset : 0;
|
|
2202
|
+
let y = state.horizontal ? 0 : height * (state.pages - 1) * -state.offset;
|
|
2203
|
+
if (state.pixelPerfect) {
|
|
2204
|
+
x = roundToPixelRatio(x);
|
|
2205
|
+
y = roundToPixelRatio(y);
|
|
2206
|
+
}
|
|
2207
|
+
group.current.style.transform = `translate3d(${x}px,${y}px,0)`;
|
|
2102
2208
|
}
|
|
2103
2209
|
});
|
|
2104
2210
|
root.render(
|
|
@@ -3027,377 +3133,6 @@ const Text3D = /* @__PURE__ */ React.forwardRef(
|
|
|
3027
3133
|
}
|
|
3028
3134
|
);
|
|
3029
3135
|
|
|
3030
|
-
const WireframeMaterialShaders = {
|
|
3031
|
-
uniforms: {
|
|
3032
|
-
strokeOpacity: 1,
|
|
3033
|
-
fillOpacity: 0.25,
|
|
3034
|
-
fillMix: 0,
|
|
3035
|
-
thickness: 0.05,
|
|
3036
|
-
colorBackfaces: false,
|
|
3037
|
-
dashInvert: true,
|
|
3038
|
-
dash: false,
|
|
3039
|
-
dashRepeats: 4,
|
|
3040
|
-
dashLength: 0.5,
|
|
3041
|
-
squeeze: false,
|
|
3042
|
-
squeezeMin: 0.2,
|
|
3043
|
-
squeezeMax: 1,
|
|
3044
|
-
stroke: /* @__PURE__ */ new THREE.Color("#ff0000"),
|
|
3045
|
-
backfaceStroke: /* @__PURE__ */ new THREE.Color("#0000ff"),
|
|
3046
|
-
fill: /* @__PURE__ */ new THREE.Color("#00ff00")
|
|
3047
|
-
},
|
|
3048
|
-
vertex: (
|
|
3049
|
-
/* glsl */
|
|
3050
|
-
`
|
|
3051
|
-
attribute vec3 barycentric;
|
|
3052
|
-
|
|
3053
|
-
varying vec3 v_edges_Barycentric;
|
|
3054
|
-
varying vec3 v_edges_Position;
|
|
3055
|
-
|
|
3056
|
-
void initWireframe() {
|
|
3057
|
-
v_edges_Barycentric = barycentric;
|
|
3058
|
-
v_edges_Position = position.xyz;
|
|
3059
|
-
}
|
|
3060
|
-
`
|
|
3061
|
-
),
|
|
3062
|
-
fragment: (
|
|
3063
|
-
/* glsl */
|
|
3064
|
-
`
|
|
3065
|
-
#ifndef PI
|
|
3066
|
-
#define PI 3.1415926535897932384626433832795
|
|
3067
|
-
#endif
|
|
3068
|
-
|
|
3069
|
-
varying vec3 v_edges_Barycentric;
|
|
3070
|
-
varying vec3 v_edges_Position;
|
|
3071
|
-
|
|
3072
|
-
uniform float strokeOpacity;
|
|
3073
|
-
uniform float fillOpacity;
|
|
3074
|
-
uniform float fillMix;
|
|
3075
|
-
uniform float thickness;
|
|
3076
|
-
uniform bool colorBackfaces;
|
|
3077
|
-
|
|
3078
|
-
// Dash
|
|
3079
|
-
uniform bool dashInvert;
|
|
3080
|
-
uniform bool dash;
|
|
3081
|
-
uniform bool dashOnly;
|
|
3082
|
-
uniform float dashRepeats;
|
|
3083
|
-
uniform float dashLength;
|
|
3084
|
-
|
|
3085
|
-
// Squeeze
|
|
3086
|
-
uniform bool squeeze;
|
|
3087
|
-
uniform float squeezeMin;
|
|
3088
|
-
uniform float squeezeMax;
|
|
3089
|
-
|
|
3090
|
-
// Colors
|
|
3091
|
-
uniform vec3 stroke;
|
|
3092
|
-
uniform vec3 backfaceStroke;
|
|
3093
|
-
uniform vec3 fill;
|
|
3094
|
-
|
|
3095
|
-
// This is like
|
|
3096
|
-
float wireframe_aastep(float threshold, float dist) {
|
|
3097
|
-
float afwidth = fwidth(dist) * 0.5;
|
|
3098
|
-
return smoothstep(threshold - afwidth, threshold + afwidth, dist);
|
|
3099
|
-
}
|
|
3100
|
-
|
|
3101
|
-
float wireframe_map(float value, float min1, float max1, float min2, float max2) {
|
|
3102
|
-
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
|
|
3103
|
-
}
|
|
3104
|
-
|
|
3105
|
-
float getWireframe() {
|
|
3106
|
-
vec3 barycentric = v_edges_Barycentric;
|
|
3107
|
-
|
|
3108
|
-
// Distance from center of each triangle to its edges.
|
|
3109
|
-
float d = min(min(barycentric.x, barycentric.y), barycentric.z);
|
|
3110
|
-
|
|
3111
|
-
// for dashed rendering, we can use this to get the 0 .. 1 value of the line length
|
|
3112
|
-
float positionAlong = max(barycentric.x, barycentric.y);
|
|
3113
|
-
if (barycentric.y < barycentric.x && barycentric.y < barycentric.z) {
|
|
3114
|
-
positionAlong = 1.0 - positionAlong;
|
|
3115
|
-
}
|
|
3116
|
-
|
|
3117
|
-
// the thickness of the stroke
|
|
3118
|
-
float computedThickness = wireframe_map(thickness, 0.0, 1.0, 0.0, 0.34);
|
|
3119
|
-
|
|
3120
|
-
// if we want to shrink the thickness toward the center of the line segment
|
|
3121
|
-
if (squeeze) {
|
|
3122
|
-
computedThickness *= mix(squeezeMin, squeezeMax, (1.0 - sin(positionAlong * PI)));
|
|
3123
|
-
}
|
|
3124
|
-
|
|
3125
|
-
// Create dash pattern
|
|
3126
|
-
if (dash) {
|
|
3127
|
-
// here we offset the stroke position depending on whether it
|
|
3128
|
-
// should overlap or not
|
|
3129
|
-
float offset = 1.0 / dashRepeats * dashLength / 2.0;
|
|
3130
|
-
if (!dashInvert) {
|
|
3131
|
-
offset += 1.0 / dashRepeats / 2.0;
|
|
3132
|
-
}
|
|
3133
|
-
|
|
3134
|
-
// if we should animate the dash or not
|
|
3135
|
-
// if (dashAnimate) {
|
|
3136
|
-
// offset += time * 0.22;
|
|
3137
|
-
// }
|
|
3138
|
-
|
|
3139
|
-
// create the repeating dash pattern
|
|
3140
|
-
float pattern = fract((positionAlong + offset) * dashRepeats);
|
|
3141
|
-
computedThickness *= 1.0 - wireframe_aastep(dashLength, pattern);
|
|
3142
|
-
}
|
|
3143
|
-
|
|
3144
|
-
// compute the anti-aliased stroke edge
|
|
3145
|
-
float edge = 1.0 - wireframe_aastep(computedThickness, d);
|
|
3146
|
-
|
|
3147
|
-
return edge;
|
|
3148
|
-
}
|
|
3149
|
-
`
|
|
3150
|
-
)
|
|
3151
|
-
};
|
|
3152
|
-
const WireframeMaterial = /* @__PURE__ */ shaderMaterial(
|
|
3153
|
-
WireframeMaterialShaders.uniforms,
|
|
3154
|
-
WireframeMaterialShaders.vertex + /* glsl */
|
|
3155
|
-
`
|
|
3156
|
-
void main() {
|
|
3157
|
-
initWireframe();
|
|
3158
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
3159
|
-
}
|
|
3160
|
-
`,
|
|
3161
|
-
WireframeMaterialShaders.fragment + /* glsl */
|
|
3162
|
-
`
|
|
3163
|
-
void main () {
|
|
3164
|
-
// Compute color
|
|
3165
|
-
|
|
3166
|
-
float edge = getWireframe();
|
|
3167
|
-
vec4 colorStroke = vec4(stroke, edge);
|
|
3168
|
-
|
|
3169
|
-
#ifdef FLIP_SIDED
|
|
3170
|
-
colorStroke.rgb = backfaceStroke;
|
|
3171
|
-
#endif
|
|
3172
|
-
|
|
3173
|
-
vec4 colorFill = vec4(fill, fillOpacity);
|
|
3174
|
-
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
3175
|
-
|
|
3176
|
-
gl_FragColor = outColor;
|
|
3177
|
-
}
|
|
3178
|
-
`
|
|
3179
|
-
);
|
|
3180
|
-
function setWireframeOverride(material, uniforms) {
|
|
3181
|
-
material.onBeforeCompile = (shader) => {
|
|
3182
|
-
shader.uniforms = {
|
|
3183
|
-
...shader.uniforms,
|
|
3184
|
-
...uniforms
|
|
3185
|
-
};
|
|
3186
|
-
shader.vertexShader = shader.vertexShader.replace(
|
|
3187
|
-
"void main() {",
|
|
3188
|
-
`
|
|
3189
|
-
${WireframeMaterialShaders.vertex}
|
|
3190
|
-
void main() {
|
|
3191
|
-
initWireframe();
|
|
3192
|
-
`
|
|
3193
|
-
);
|
|
3194
|
-
shader.fragmentShader = shader.fragmentShader.replace(
|
|
3195
|
-
"void main() {",
|
|
3196
|
-
`
|
|
3197
|
-
${WireframeMaterialShaders.fragment}
|
|
3198
|
-
void main() {
|
|
3199
|
-
`
|
|
3200
|
-
);
|
|
3201
|
-
shader.fragmentShader = shader.fragmentShader.replace(
|
|
3202
|
-
"#include <color_fragment>",
|
|
3203
|
-
/* glsl */
|
|
3204
|
-
`
|
|
3205
|
-
#include <color_fragment>
|
|
3206
|
-
float edge = getWireframe();
|
|
3207
|
-
vec4 colorStroke = vec4(stroke, edge);
|
|
3208
|
-
#ifdef FLIP_SIDED
|
|
3209
|
-
colorStroke.rgb = backfaceStroke;
|
|
3210
|
-
#endif
|
|
3211
|
-
vec4 colorFill = vec4(mix(diffuseColor.rgb, fill, fillMix), mix(diffuseColor.a, fillOpacity, fillMix));
|
|
3212
|
-
vec4 outColor = mix(colorFill, colorStroke, edge * strokeOpacity);
|
|
3213
|
-
|
|
3214
|
-
diffuseColor.rgb = outColor.rgb;
|
|
3215
|
-
diffuseColor.a *= outColor.a;
|
|
3216
|
-
`
|
|
3217
|
-
);
|
|
3218
|
-
};
|
|
3219
|
-
material.side = THREE.DoubleSide;
|
|
3220
|
-
material.transparent = true;
|
|
3221
|
-
}
|
|
3222
|
-
function useWireframeUniforms(uniforms, props) {
|
|
3223
|
-
React.useEffect(
|
|
3224
|
-
() => void (uniforms.fillOpacity.value = props.fillOpacity ?? uniforms.fillOpacity.value),
|
|
3225
|
-
[props.fillOpacity]
|
|
3226
|
-
);
|
|
3227
|
-
React.useEffect(() => void (uniforms.fillMix.value = props.fillMix ?? uniforms.fillMix.value), [props.fillMix]);
|
|
3228
|
-
React.useEffect(
|
|
3229
|
-
() => void (uniforms.strokeOpacity.value = props.strokeOpacity ?? uniforms.strokeOpacity.value),
|
|
3230
|
-
[props.strokeOpacity]
|
|
3231
|
-
);
|
|
3232
|
-
React.useEffect(
|
|
3233
|
-
() => void (uniforms.thickness.value = props.thickness ?? uniforms.thickness.value),
|
|
3234
|
-
[props.thickness]
|
|
3235
|
-
);
|
|
3236
|
-
React.useEffect(() => void (uniforms.colorBackfaces.value = !!props.colorBackfaces), [props.colorBackfaces]);
|
|
3237
|
-
React.useEffect(() => void (uniforms.dash.value = !!props.dash), [props.dash]);
|
|
3238
|
-
React.useEffect(() => void (uniforms.dashInvert.value = !!props.dashInvert), [props.dashInvert]);
|
|
3239
|
-
React.useEffect(
|
|
3240
|
-
() => void (uniforms.dashRepeats.value = props.dashRepeats ?? uniforms.dashRepeats.value),
|
|
3241
|
-
[props.dashRepeats]
|
|
3242
|
-
);
|
|
3243
|
-
React.useEffect(
|
|
3244
|
-
() => void (uniforms.dashLength.value = props.dashLength ?? uniforms.dashLength.value),
|
|
3245
|
-
[props.dashLength]
|
|
3246
|
-
);
|
|
3247
|
-
React.useEffect(() => void (uniforms.squeeze.value = !!props.squeeze), [props.squeeze]);
|
|
3248
|
-
React.useEffect(
|
|
3249
|
-
() => void (uniforms.squeezeMin.value = props.squeezeMin ?? uniforms.squeezeMin.value),
|
|
3250
|
-
[props.squeezeMin]
|
|
3251
|
-
);
|
|
3252
|
-
React.useEffect(
|
|
3253
|
-
() => void (uniforms.squeezeMax.value = props.squeezeMax ?? uniforms.squeezeMax.value),
|
|
3254
|
-
[props.squeezeMax]
|
|
3255
|
-
);
|
|
3256
|
-
React.useEffect(
|
|
3257
|
-
() => void (uniforms.stroke.value = props.stroke ? new THREE.Color(props.stroke) : uniforms.stroke.value),
|
|
3258
|
-
[props.stroke]
|
|
3259
|
-
);
|
|
3260
|
-
React.useEffect(
|
|
3261
|
-
() => void (uniforms.fill.value = props.fill ? new THREE.Color(props.fill) : uniforms.fill.value),
|
|
3262
|
-
[props.fill]
|
|
3263
|
-
);
|
|
3264
|
-
React.useEffect(
|
|
3265
|
-
() => void (uniforms.backfaceStroke.value = props.backfaceStroke ? new THREE.Color(props.backfaceStroke) : uniforms.backfaceStroke.value),
|
|
3266
|
-
[props.backfaceStroke]
|
|
3267
|
-
);
|
|
3268
|
-
}
|
|
3269
|
-
|
|
3270
|
-
function isWithGeometry(object) {
|
|
3271
|
-
return !!object?.geometry;
|
|
3272
|
-
}
|
|
3273
|
-
function isGeometry(object) {
|
|
3274
|
-
return !!object?.isBufferGeometry;
|
|
3275
|
-
}
|
|
3276
|
-
function isRefObject$1(object) {
|
|
3277
|
-
return !!object?.current;
|
|
3278
|
-
}
|
|
3279
|
-
function isRef$1(object) {
|
|
3280
|
-
return object?.current !== void 0;
|
|
3281
|
-
}
|
|
3282
|
-
function isWireframeGeometry(geometry) {
|
|
3283
|
-
return geometry.type === "WireframeGeometry";
|
|
3284
|
-
}
|
|
3285
|
-
function getUniforms() {
|
|
3286
|
-
const u = {};
|
|
3287
|
-
for (const key in WireframeMaterialShaders.uniforms) {
|
|
3288
|
-
u[key] = { value: WireframeMaterialShaders.uniforms[key] };
|
|
3289
|
-
}
|
|
3290
|
-
return u;
|
|
3291
|
-
}
|
|
3292
|
-
function getBarycentricCoordinates(geometry, removeEdge) {
|
|
3293
|
-
const position = geometry.getAttribute("position");
|
|
3294
|
-
const count = position.count;
|
|
3295
|
-
const barycentric = [];
|
|
3296
|
-
for (let i = 0; i < count; i++) {
|
|
3297
|
-
const even = i % 2 === 0;
|
|
3298
|
-
const Q = removeEdge ? 1 : 0;
|
|
3299
|
-
if (even) {
|
|
3300
|
-
barycentric.push(0, 0, 1, 0, 1, 0, 1, 0, Q);
|
|
3301
|
-
} else {
|
|
3302
|
-
barycentric.push(0, 1, 0, 0, 0, 1, 1, 0, Q);
|
|
3303
|
-
}
|
|
3304
|
-
}
|
|
3305
|
-
return new THREE.BufferAttribute(Float32Array.from(barycentric), 3);
|
|
3306
|
-
}
|
|
3307
|
-
function getInputGeometry(inputGeometry) {
|
|
3308
|
-
const geo = isRefObject$1(inputGeometry) ? inputGeometry.current : inputGeometry;
|
|
3309
|
-
if (!isGeometry(geo)) {
|
|
3310
|
-
if (isWireframeGeometry(geo)) {
|
|
3311
|
-
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
3312
|
-
}
|
|
3313
|
-
const parent = geo.parent;
|
|
3314
|
-
if (isWithGeometry(parent)) {
|
|
3315
|
-
if (isWireframeGeometry(parent.geometry)) {
|
|
3316
|
-
throw new Error("Wireframe: WireframeGeometry is not supported.");
|
|
3317
|
-
}
|
|
3318
|
-
return parent.geometry;
|
|
3319
|
-
}
|
|
3320
|
-
} else {
|
|
3321
|
-
return geo;
|
|
3322
|
-
}
|
|
3323
|
-
}
|
|
3324
|
-
function setBarycentricCoordinates(geometry, simplify) {
|
|
3325
|
-
if (geometry.index) {
|
|
3326
|
-
console.warn("Wireframe: Requires non-indexed geometry, converting to non-indexed geometry.");
|
|
3327
|
-
const nonIndexedGeo = geometry.toNonIndexed();
|
|
3328
|
-
geometry.copy(nonIndexedGeo);
|
|
3329
|
-
geometry.setIndex(null);
|
|
3330
|
-
}
|
|
3331
|
-
const newBarycentric = getBarycentricCoordinates(geometry, simplify);
|
|
3332
|
-
geometry.setAttribute("barycentric", newBarycentric);
|
|
3333
|
-
}
|
|
3334
|
-
function WireframeWithCustomGeo({
|
|
3335
|
-
geometry: customGeometry,
|
|
3336
|
-
simplify = false,
|
|
3337
|
-
...props
|
|
3338
|
-
}) {
|
|
3339
|
-
extend({ MeshWireframeMaterial: WireframeMaterial });
|
|
3340
|
-
const [geometry, setGeometry] = React.useState(null);
|
|
3341
|
-
React.useLayoutEffect(() => {
|
|
3342
|
-
const geom = getInputGeometry(customGeometry);
|
|
3343
|
-
if (!geom) {
|
|
3344
|
-
throw new Error("Wireframe: geometry prop must be a BufferGeometry or a ref to a BufferGeometry.");
|
|
3345
|
-
}
|
|
3346
|
-
setBarycentricCoordinates(geom, simplify);
|
|
3347
|
-
if (isRef$1(customGeometry)) {
|
|
3348
|
-
setGeometry(geom);
|
|
3349
|
-
}
|
|
3350
|
-
}, [simplify, customGeometry]);
|
|
3351
|
-
const drawnGeo = isRef$1(customGeometry) ? geometry : customGeometry;
|
|
3352
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, drawnGeo && /* @__PURE__ */ React.createElement("mesh", { geometry: drawnGeo }, /* @__PURE__ */ React.createElement(
|
|
3353
|
-
"meshWireframeMaterial",
|
|
3354
|
-
{
|
|
3355
|
-
attach: "material",
|
|
3356
|
-
transparent: true,
|
|
3357
|
-
side: THREE.DoubleSide,
|
|
3358
|
-
polygonOffset: true,
|
|
3359
|
-
polygonOffsetFactor: -4,
|
|
3360
|
-
...props
|
|
3361
|
-
}
|
|
3362
|
-
)));
|
|
3363
|
-
}
|
|
3364
|
-
function WireframeWithoutCustomGeo({
|
|
3365
|
-
simplify = false,
|
|
3366
|
-
...props
|
|
3367
|
-
}) {
|
|
3368
|
-
const objectRef = React.useRef(null);
|
|
3369
|
-
const uniforms = React.useMemo(() => getUniforms(), [WireframeMaterialShaders.uniforms]);
|
|
3370
|
-
useWireframeUniforms(uniforms, props);
|
|
3371
|
-
React.useLayoutEffect(() => {
|
|
3372
|
-
const geom = getInputGeometry(objectRef);
|
|
3373
|
-
if (!geom) {
|
|
3374
|
-
throw new Error("Wireframe: Must be a child of a Mesh, Line or Points object or specify a geometry prop.");
|
|
3375
|
-
}
|
|
3376
|
-
const og = geom.clone();
|
|
3377
|
-
setBarycentricCoordinates(geom, simplify);
|
|
3378
|
-
return () => {
|
|
3379
|
-
geom.copy(og);
|
|
3380
|
-
og.dispose();
|
|
3381
|
-
};
|
|
3382
|
-
}, [simplify]);
|
|
3383
|
-
React.useLayoutEffect(() => {
|
|
3384
|
-
const parentMesh = objectRef.current.parent;
|
|
3385
|
-
const og = parentMesh.material.clone();
|
|
3386
|
-
setWireframeOverride(parentMesh.material, uniforms);
|
|
3387
|
-
return () => {
|
|
3388
|
-
parentMesh.material.dispose();
|
|
3389
|
-
parentMesh.material = og;
|
|
3390
|
-
};
|
|
3391
|
-
}, []);
|
|
3392
|
-
return /* @__PURE__ */ React.createElement("object3D", { ref: objectRef });
|
|
3393
|
-
}
|
|
3394
|
-
function Wireframe({ geometry: customGeometry, ...props }) {
|
|
3395
|
-
if (customGeometry) {
|
|
3396
|
-
return /* @__PURE__ */ React.createElement(WireframeWithCustomGeo, { geometry: customGeometry, ...props });
|
|
3397
|
-
}
|
|
3398
|
-
return /* @__PURE__ */ React.createElement(WireframeWithoutCustomGeo, { ...props });
|
|
3399
|
-
}
|
|
3400
|
-
|
|
3401
3136
|
const Context = /* @__PURE__ */ React.createContext({});
|
|
3402
3137
|
const useGizmoContext = () => {
|
|
3403
3138
|
return React.useContext(Context);
|
|
@@ -3693,6 +3428,11 @@ const GizmoViewport = ({
|
|
|
3693
3428
|
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 }))));
|
|
3694
3429
|
};
|
|
3695
3430
|
|
|
3431
|
+
const roundEven = (n) => {
|
|
3432
|
+
const rounded = Math.ceil(n);
|
|
3433
|
+
return rounded % 2 === 0 ? rounded : rounded + 1;
|
|
3434
|
+
};
|
|
3435
|
+
|
|
3696
3436
|
const v1 = /* @__PURE__ */ new Vector3();
|
|
3697
3437
|
const v2 = /* @__PURE__ */ new Vector3();
|
|
3698
3438
|
const v3 = /* @__PURE__ */ new Vector3();
|
|
@@ -3791,9 +3531,11 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3791
3531
|
as = "div",
|
|
3792
3532
|
wrapperClass,
|
|
3793
3533
|
pointerEvents = "auto",
|
|
3534
|
+
pixelPerfect = true,
|
|
3794
3535
|
...props
|
|
3795
3536
|
}, ref) => {
|
|
3796
3537
|
const { gl, camera, scene, size, raycaster, events, viewport } = useThree();
|
|
3538
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
3797
3539
|
const [el] = React.useState(() => document.createElement(as));
|
|
3798
3540
|
const root = React.useRef(null);
|
|
3799
3541
|
const group = React.useRef(null);
|
|
@@ -3818,38 +3560,54 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3818
3560
|
el2.style.position = null;
|
|
3819
3561
|
el2.style.pointerEvents = null;
|
|
3820
3562
|
}
|
|
3821
|
-
}, [occlude]);
|
|
3563
|
+
}, [occlude, zIndexRange, gl.domElement]);
|
|
3822
3564
|
React.useLayoutEffect(() => {
|
|
3823
3565
|
if (group.current) {
|
|
3824
|
-
|
|
3566
|
+
if (!root.current) {
|
|
3567
|
+
root.current = ReactDOM.createRoot(el);
|
|
3568
|
+
}
|
|
3825
3569
|
scene.updateMatrixWorld();
|
|
3826
3570
|
if (transform) {
|
|
3827
3571
|
el.style.cssText = `position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;`;
|
|
3828
3572
|
} else {
|
|
3829
|
-
|
|
3830
|
-
el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(${vec[0]}px,${vec[1]}px,0);transform-origin:0 0;`;
|
|
3573
|
+
el.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(0,-9999px,0);transform-origin:0 0;`;
|
|
3831
3574
|
}
|
|
3832
3575
|
if (target) {
|
|
3833
3576
|
if (prepend) target.prepend(el);
|
|
3834
3577
|
else target.appendChild(el);
|
|
3835
3578
|
}
|
|
3836
3579
|
return () => {
|
|
3837
|
-
if (
|
|
3838
|
-
|
|
3580
|
+
if (root.current) {
|
|
3581
|
+
root.current.unmount();
|
|
3582
|
+
root.current = null;
|
|
3583
|
+
}
|
|
3584
|
+
if (target && target.contains(el)) {
|
|
3585
|
+
target.removeChild(el);
|
|
3586
|
+
}
|
|
3839
3587
|
};
|
|
3840
3588
|
}
|
|
3841
|
-
}, [target, transform]);
|
|
3589
|
+
}, [target, transform, el, prepend, scene]);
|
|
3842
3590
|
React.useLayoutEffect(() => {
|
|
3843
3591
|
if (wrapperClass) el.className = wrapperClass;
|
|
3844
|
-
}, [wrapperClass]);
|
|
3592
|
+
}, [wrapperClass, el]);
|
|
3593
|
+
React.useLayoutEffect(() => {
|
|
3594
|
+
return () => {
|
|
3595
|
+
if (root.current) {
|
|
3596
|
+
root.current.unmount();
|
|
3597
|
+
root.current = null;
|
|
3598
|
+
}
|
|
3599
|
+
};
|
|
3600
|
+
}, []);
|
|
3845
3601
|
const styles = React.useMemo(() => {
|
|
3602
|
+
const width = forceEven ? roundEven(size.width) : size.width;
|
|
3603
|
+
const height = forceEven ? roundEven(size.height) : size.height;
|
|
3846
3604
|
if (transform) {
|
|
3847
3605
|
return {
|
|
3848
3606
|
position: "absolute",
|
|
3849
3607
|
top: 0,
|
|
3850
3608
|
left: 0,
|
|
3851
|
-
width
|
|
3852
|
-
height
|
|
3609
|
+
width,
|
|
3610
|
+
height,
|
|
3853
3611
|
transformStyle: "preserve-3d",
|
|
3854
3612
|
pointerEvents: "none"
|
|
3855
3613
|
};
|
|
@@ -3858,15 +3616,15 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3858
3616
|
position: "absolute",
|
|
3859
3617
|
transform: center ? "translate3d(-50%,-50%,0)" : "none",
|
|
3860
3618
|
...fullscreen && {
|
|
3861
|
-
top: -size.height / 2,
|
|
3862
|
-
left: -size.width / 2,
|
|
3863
|
-
width
|
|
3864
|
-
height
|
|
3619
|
+
top: forceEven ? roundEven(-size.height / 2) : -size.height / 2,
|
|
3620
|
+
left: forceEven ? roundEven(-size.width / 2) : -size.width / 2,
|
|
3621
|
+
width,
|
|
3622
|
+
height
|
|
3865
3623
|
},
|
|
3866
3624
|
...style
|
|
3867
3625
|
};
|
|
3868
3626
|
}
|
|
3869
|
-
}, [style, center, fullscreen, size, transform]);
|
|
3627
|
+
}, [style, center, fullscreen, size, transform, forceEven]);
|
|
3870
3628
|
const transformInnerStyles = React.useMemo(
|
|
3871
3629
|
() => ({ position: "absolute", pointerEvents }),
|
|
3872
3630
|
[pointerEvents]
|
|
@@ -3880,7 +3638,7 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3880
3638
|
} else {
|
|
3881
3639
|
root.current?.render(/* @__PURE__ */ React.createElement("div", { ref, style: styles, className, children }));
|
|
3882
3640
|
}
|
|
3883
|
-
});
|
|
3641
|
+
}, [transform, styles, transformInnerStyles, ref, className, style, children]);
|
|
3884
3642
|
const visible = React.useRef(true);
|
|
3885
3643
|
useFrame((gl2) => {
|
|
3886
3644
|
if (group.current) {
|
|
@@ -3912,7 +3670,12 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3912
3670
|
const zRange = occlude ? isRayCastOcclusion ? [zIndexRange[0], halfRange] : [halfRange - 1, 0] : zIndexRange;
|
|
3913
3671
|
el.style.zIndex = `${objectZIndex(group.current, camera, zRange)}`;
|
|
3914
3672
|
if (transform) {
|
|
3915
|
-
|
|
3673
|
+
let widthHalf = forceEven ? roundEven(size.width / 2) : size.width / 2;
|
|
3674
|
+
let heightHalf = forceEven ? roundEven(size.height / 2) : size.height / 2;
|
|
3675
|
+
if (pixelPerfect) {
|
|
3676
|
+
widthHalf = roundToPixelRatio(widthHalf);
|
|
3677
|
+
heightHalf = roundToPixelRatio(heightHalf);
|
|
3678
|
+
}
|
|
3916
3679
|
const fov = camera.projectionMatrix.elements[5] * heightHalf;
|
|
3917
3680
|
const { isOrthographicCamera, top, left, bottom, right } = camera;
|
|
3918
3681
|
const cameraMatrix = getCameraCSSMatrix(camera.matrixWorldInverse);
|
|
@@ -3923,8 +3686,10 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3923
3686
|
matrix.elements[3] = matrix.elements[7] = matrix.elements[11] = 0;
|
|
3924
3687
|
matrix.elements[15] = 1;
|
|
3925
3688
|
}
|
|
3926
|
-
|
|
3927
|
-
|
|
3689
|
+
const elWidth = forceEven ? roundEven(size.width) : size.width;
|
|
3690
|
+
const elHeight = forceEven ? roundEven(size.height) : size.height;
|
|
3691
|
+
el.style.width = elWidth + "px";
|
|
3692
|
+
el.style.height = elHeight + "px";
|
|
3928
3693
|
el.style.perspective = isOrthographicCamera ? "" : `${fov}px`;
|
|
3929
3694
|
if (transformOuterRef.current && transformInnerRef.current) {
|
|
3930
3695
|
transformOuterRef.current.style.transform = `${cameraTransform}${cameraMatrix}translate(${widthHalf}px,${heightHalf}px)`;
|
|
@@ -3932,7 +3697,13 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
3932
3697
|
}
|
|
3933
3698
|
} else {
|
|
3934
3699
|
const scale = distanceFactor === void 0 ? 1 : objectScale(group.current, camera) * distanceFactor;
|
|
3935
|
-
|
|
3700
|
+
let x = forceEven ? roundEven(vec[0]) : vec[0];
|
|
3701
|
+
let y = forceEven ? roundEven(vec[1]) : vec[1];
|
|
3702
|
+
if (pixelPerfect) {
|
|
3703
|
+
x = roundToPixelRatio(x);
|
|
3704
|
+
y = roundToPixelRatio(y);
|
|
3705
|
+
}
|
|
3706
|
+
el.style.transform = `translate3d(${x}px,${y}px,0) scale(${scale})`;
|
|
3936
3707
|
}
|
|
3937
3708
|
oldPosition.current = vec;
|
|
3938
3709
|
oldZoom.current = camera.zoom;
|
|
@@ -4038,6 +3809,11 @@ const Html = /* @__PURE__ */ React.forwardRef(
|
|
|
4038
3809
|
);
|
|
4039
3810
|
|
|
4040
3811
|
const context$4 = /* @__PURE__ */ React.createContext(null);
|
|
3812
|
+
const resolveObject = (object, fallback) => {
|
|
3813
|
+
if (!object) return fallback;
|
|
3814
|
+
if ("current" in object) return object.current;
|
|
3815
|
+
return object;
|
|
3816
|
+
};
|
|
4041
3817
|
|
|
4042
3818
|
const vec1$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
4043
3819
|
const vec2$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
@@ -4072,6 +3848,8 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
4072
3848
|
onDragStart,
|
|
4073
3849
|
onDrag,
|
|
4074
3850
|
onDragEnd,
|
|
3851
|
+
onHover,
|
|
3852
|
+
dragState,
|
|
4075
3853
|
userData,
|
|
4076
3854
|
LineComponent: Line
|
|
4077
3855
|
} = React.useContext(context$4);
|
|
@@ -4103,7 +3881,13 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
4103
3881
|
const onPointerMove = React.useCallback(
|
|
4104
3882
|
(e) => {
|
|
4105
3883
|
e.stopPropagation();
|
|
4106
|
-
if (!isHovered)
|
|
3884
|
+
if (!isHovered) {
|
|
3885
|
+
const drag = dragState.current;
|
|
3886
|
+
if (drag === null || drag.component === "Arrow" && drag.axis === axis) {
|
|
3887
|
+
setIsHovered(true);
|
|
3888
|
+
onHover({ component: "Arrow", axis, hovering: true });
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
4107
3891
|
if (clickInfo.current) {
|
|
4108
3892
|
const { clickPoint, dir } = clickInfo.current;
|
|
4109
3893
|
const [min, max] = translationLimits?.[axis] || [void 0, void 0];
|
|
@@ -4122,7 +3906,7 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
4122
3906
|
onDrag(offsetMatrix$1);
|
|
4123
3907
|
}
|
|
4124
3908
|
},
|
|
4125
|
-
[annotations, onDrag, isHovered, translation, translationLimits, axis]
|
|
3909
|
+
[annotations, onDrag, onHover, dragState, isHovered, translation, translationLimits, axis]
|
|
4126
3910
|
);
|
|
4127
3911
|
const onPointerUp = React.useCallback(
|
|
4128
3912
|
(e) => {
|
|
@@ -4137,10 +3921,16 @@ const AxisArrow = ({ direction, axis }) => {
|
|
|
4137
3921
|
},
|
|
4138
3922
|
[annotations, camControls, onDragEnd]
|
|
4139
3923
|
);
|
|
4140
|
-
const onPointerOut = React.useCallback(
|
|
4141
|
-
e
|
|
4142
|
-
|
|
4143
|
-
|
|
3924
|
+
const onPointerOut = React.useCallback(
|
|
3925
|
+
(e) => {
|
|
3926
|
+
e.stopPropagation();
|
|
3927
|
+
if (isHovered) {
|
|
3928
|
+
setIsHovered(false);
|
|
3929
|
+
onHover({ component: "Arrow", axis, hovering: false });
|
|
3930
|
+
}
|
|
3931
|
+
},
|
|
3932
|
+
[onHover, axis, isHovered]
|
|
3933
|
+
);
|
|
4144
3934
|
const { cylinderLength, coneWidth, coneLength, matrixL } = React.useMemo(() => {
|
|
4145
3935
|
const coneWidth2 = fixed ? lineWidth / scale * 1.6 : scale / 20;
|
|
4146
3936
|
const coneLength2 = fixed ? 0.2 : scale / 5;
|
|
@@ -4244,6 +4034,8 @@ const rotMatrix = /* @__PURE__ */ new THREE.Matrix4();
|
|
|
4244
4034
|
const posNew = /* @__PURE__ */ new THREE.Vector3();
|
|
4245
4035
|
const ray$1 = /* @__PURE__ */ new THREE.Ray();
|
|
4246
4036
|
const intersection$1 = /* @__PURE__ */ new THREE.Vector3();
|
|
4037
|
+
const viewPlane = /* @__PURE__ */ new THREE.Plane();
|
|
4038
|
+
const viewIntersection = /* @__PURE__ */ new THREE.Vector3();
|
|
4247
4039
|
const AxisRotator = ({
|
|
4248
4040
|
dir1,
|
|
4249
4041
|
dir2,
|
|
@@ -4264,6 +4056,8 @@ const AxisRotator = ({
|
|
|
4264
4056
|
onDragStart,
|
|
4265
4057
|
onDrag,
|
|
4266
4058
|
onDragEnd,
|
|
4059
|
+
onHover,
|
|
4060
|
+
dragState,
|
|
4267
4061
|
userData,
|
|
4268
4062
|
LineComponent: Line
|
|
4269
4063
|
} = React.useContext(context$4);
|
|
@@ -4297,14 +4091,29 @@ const AxisRotator = ({
|
|
|
4297
4091
|
const onPointerMove = React.useCallback(
|
|
4298
4092
|
(e) => {
|
|
4299
4093
|
e.stopPropagation();
|
|
4300
|
-
if (!isHovered)
|
|
4094
|
+
if (!isHovered) {
|
|
4095
|
+
const drag = dragState.current;
|
|
4096
|
+
if (drag === null || drag.component === "Rotator" && drag.axis === axis) {
|
|
4097
|
+
setIsHovered(true);
|
|
4098
|
+
onHover({ component: "Rotator", axis, hovering: true });
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4301
4101
|
if (clickInfo.current) {
|
|
4302
4102
|
const { clickPoint, origin, e1, e2, normal, plane } = clickInfo.current;
|
|
4303
4103
|
const [min, max] = rotationLimits?.[axis] || [void 0, void 0];
|
|
4304
4104
|
ray$1.copy(e.ray);
|
|
4305
|
-
ray$1.
|
|
4306
|
-
|
|
4307
|
-
|
|
4105
|
+
const dotProduct = Math.abs(ray$1.direction.dot(normal));
|
|
4106
|
+
if (dotProduct < 0.1) {
|
|
4107
|
+
viewPlane.setFromNormalAndCoplanarPoint(ray$1.direction.clone().negate(), origin);
|
|
4108
|
+
ray$1.intersectPlane(viewPlane, viewIntersection);
|
|
4109
|
+
const toIntersection = viewIntersection.clone().sub(origin);
|
|
4110
|
+
const projectedDist = toIntersection.dot(normal);
|
|
4111
|
+
intersection$1.copy(viewIntersection).sub(normal.clone().multiplyScalar(projectedDist));
|
|
4112
|
+
} else {
|
|
4113
|
+
ray$1.intersectPlane(plane, intersection$1);
|
|
4114
|
+
ray$1.direction.negate();
|
|
4115
|
+
ray$1.intersectPlane(plane, intersection$1);
|
|
4116
|
+
}
|
|
4308
4117
|
let deltaAngle = calculateAngle(clickPoint, intersection$1, origin, e1, e2);
|
|
4309
4118
|
let degrees = toDegrees(deltaAngle);
|
|
4310
4119
|
if (e.shiftKey) {
|
|
@@ -4330,7 +4139,7 @@ const AxisRotator = ({
|
|
|
4330
4139
|
onDrag(rotMatrix);
|
|
4331
4140
|
}
|
|
4332
4141
|
},
|
|
4333
|
-
[annotations, onDrag, isHovered, rotationLimits, axis]
|
|
4142
|
+
[annotations, onDrag, onHover, dragState, isHovered, rotationLimits, axis]
|
|
4334
4143
|
);
|
|
4335
4144
|
const onPointerUp = React.useCallback(
|
|
4336
4145
|
(e) => {
|
|
@@ -4346,10 +4155,16 @@ const AxisRotator = ({
|
|
|
4346
4155
|
},
|
|
4347
4156
|
[annotations, camControls, onDragEnd]
|
|
4348
4157
|
);
|
|
4349
|
-
const onPointerOut = React.useCallback(
|
|
4350
|
-
e
|
|
4351
|
-
|
|
4352
|
-
|
|
4158
|
+
const onPointerOut = React.useCallback(
|
|
4159
|
+
(e) => {
|
|
4160
|
+
e.stopPropagation();
|
|
4161
|
+
if (isHovered) {
|
|
4162
|
+
setIsHovered(false);
|
|
4163
|
+
onHover({ component: "Rotator", axis, hovering: false });
|
|
4164
|
+
}
|
|
4165
|
+
},
|
|
4166
|
+
[onHover, axis, isHovered]
|
|
4167
|
+
);
|
|
4353
4168
|
const matrixL = React.useMemo(() => {
|
|
4354
4169
|
const dir1N = dir1.clone().normalize();
|
|
4355
4170
|
const dir2N = dir2.clone().normalize();
|
|
@@ -4450,6 +4265,8 @@ const PlaneSlider = ({
|
|
|
4450
4265
|
onDragStart,
|
|
4451
4266
|
onDrag,
|
|
4452
4267
|
onDragEnd,
|
|
4268
|
+
onHover,
|
|
4269
|
+
dragState,
|
|
4453
4270
|
userData,
|
|
4454
4271
|
LineComponent: Line
|
|
4455
4272
|
} = React.useContext(context$4);
|
|
@@ -4485,7 +4302,13 @@ const PlaneSlider = ({
|
|
|
4485
4302
|
const onPointerMove = React.useCallback(
|
|
4486
4303
|
(e) => {
|
|
4487
4304
|
e.stopPropagation();
|
|
4488
|
-
if (!isHovered)
|
|
4305
|
+
if (!isHovered) {
|
|
4306
|
+
const drag = dragState.current;
|
|
4307
|
+
if (drag === null || drag.component === "Slider" && drag.axis === axis) {
|
|
4308
|
+
setIsHovered(true);
|
|
4309
|
+
onHover({ component: "Slider", axis, hovering: true });
|
|
4310
|
+
}
|
|
4311
|
+
}
|
|
4489
4312
|
if (clickInfo.current) {
|
|
4490
4313
|
const { clickPoint, e1, e2, plane } = clickInfo.current;
|
|
4491
4314
|
const [minX, maxX] = translationLimits?.[(axis + 1) % 3] || [void 0, void 0];
|
|
@@ -4521,7 +4344,7 @@ const PlaneSlider = ({
|
|
|
4521
4344
|
onDrag(offsetMatrix);
|
|
4522
4345
|
}
|
|
4523
4346
|
},
|
|
4524
|
-
[annotations, onDrag, isHovered, translation, translationLimits, axis]
|
|
4347
|
+
[annotations, onDrag, onHover, dragState, isHovered, translation, translationLimits, axis]
|
|
4525
4348
|
);
|
|
4526
4349
|
const onPointerUp = React.useCallback(
|
|
4527
4350
|
(e) => {
|
|
@@ -4536,10 +4359,16 @@ const PlaneSlider = ({
|
|
|
4536
4359
|
},
|
|
4537
4360
|
[annotations, camControls, onDragEnd]
|
|
4538
4361
|
);
|
|
4539
|
-
const onPointerOut = React.useCallback(
|
|
4540
|
-
e
|
|
4541
|
-
|
|
4542
|
-
|
|
4362
|
+
const onPointerOut = React.useCallback(
|
|
4363
|
+
(e) => {
|
|
4364
|
+
e.stopPropagation();
|
|
4365
|
+
if (isHovered) {
|
|
4366
|
+
setIsHovered(false);
|
|
4367
|
+
onHover({ component: "Slider", axis, hovering: false });
|
|
4368
|
+
}
|
|
4369
|
+
},
|
|
4370
|
+
[onHover, axis, isHovered]
|
|
4371
|
+
);
|
|
4543
4372
|
const matrixL = React.useMemo(() => {
|
|
4544
4373
|
const dir1N = dir1.clone().normalize();
|
|
4545
4374
|
const dir2N = dir2.clone().normalize();
|
|
@@ -4677,6 +4506,8 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
4677
4506
|
onDragStart,
|
|
4678
4507
|
onDrag,
|
|
4679
4508
|
onDragEnd,
|
|
4509
|
+
onHover,
|
|
4510
|
+
dragState,
|
|
4680
4511
|
userData
|
|
4681
4512
|
} = React.useContext(context$4);
|
|
4682
4513
|
const size = useThree((state) => state.size);
|
|
@@ -4713,7 +4544,13 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
4713
4544
|
const onPointerMove = React.useCallback(
|
|
4714
4545
|
(e) => {
|
|
4715
4546
|
e.stopPropagation();
|
|
4716
|
-
if (!isHovered)
|
|
4547
|
+
if (!isHovered) {
|
|
4548
|
+
const drag = dragState.current;
|
|
4549
|
+
if (drag === null || drag.component === "Sphere" && drag.axis === axis) {
|
|
4550
|
+
setIsHovered(true);
|
|
4551
|
+
onHover({ component: "Sphere", axis, hovering: true });
|
|
4552
|
+
}
|
|
4553
|
+
}
|
|
4717
4554
|
if (clickInfo.current) {
|
|
4718
4555
|
const { clickPoint, dir, mPLG, mPLGInv, offsetMultiplier } = clickInfo.current;
|
|
4719
4556
|
const [min, max] = scaleLimits?.[axis] || [1e-5, void 0];
|
|
@@ -4739,7 +4576,7 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
4739
4576
|
onDrag(scaleMatrix);
|
|
4740
4577
|
}
|
|
4741
4578
|
},
|
|
4742
|
-
[annotations, position, onDrag, isHovered, scaleLimits, axis]
|
|
4579
|
+
[annotations, position, onDrag, onHover, dragState, isHovered, scaleLimits, axis]
|
|
4743
4580
|
);
|
|
4744
4581
|
const onPointerUp = React.useCallback(
|
|
4745
4582
|
(e) => {
|
|
@@ -4756,10 +4593,16 @@ const ScalingSphere = ({ direction, axis }) => {
|
|
|
4756
4593
|
},
|
|
4757
4594
|
[annotations, camControls, onDragEnd, position]
|
|
4758
4595
|
);
|
|
4759
|
-
const onPointerOut = React.useCallback(
|
|
4760
|
-
e
|
|
4761
|
-
|
|
4762
|
-
|
|
4596
|
+
const onPointerOut = React.useCallback(
|
|
4597
|
+
(e) => {
|
|
4598
|
+
e.stopPropagation();
|
|
4599
|
+
if (isHovered) {
|
|
4600
|
+
setIsHovered(false);
|
|
4601
|
+
onHover({ component: "Sphere", axis, hovering: false });
|
|
4602
|
+
}
|
|
4603
|
+
},
|
|
4604
|
+
[onHover, axis, isHovered]
|
|
4605
|
+
);
|
|
4763
4606
|
const { radius, matrixL } = React.useMemo(() => {
|
|
4764
4607
|
const radius2 = fixed ? lineWidth / scale * 1.8 : scale / 22.5;
|
|
4765
4608
|
const quaternion = new THREE.Quaternion().setFromUnitVectors(upV, direction.clone().normalize());
|
|
@@ -4829,9 +4672,11 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4829
4672
|
({
|
|
4830
4673
|
enabled = true,
|
|
4831
4674
|
matrix,
|
|
4675
|
+
object,
|
|
4832
4676
|
onDragStart,
|
|
4833
4677
|
onDrag,
|
|
4834
4678
|
onDragEnd,
|
|
4679
|
+
onHover,
|
|
4835
4680
|
autoTransform = true,
|
|
4836
4681
|
anchor,
|
|
4837
4682
|
disableAxes = false,
|
|
@@ -4867,14 +4712,35 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4867
4712
|
const gizmoRef = React.useRef(null);
|
|
4868
4713
|
const childrenRef = React.useRef(null);
|
|
4869
4714
|
const translation = React.useRef([0, 0, 0]);
|
|
4715
|
+
const dragState = React.useRef(null);
|
|
4870
4716
|
const cameraScale = React.useRef(new THREE.Vector3(1, 1, 1));
|
|
4871
4717
|
const gizmoScale = React.useRef(new THREE.Vector3(1, 1, 1));
|
|
4718
|
+
React.useEffect(() => {
|
|
4719
|
+
if (object) {
|
|
4720
|
+
const target = resolveObject(object);
|
|
4721
|
+
if (target) {
|
|
4722
|
+
const pivot = ref.current;
|
|
4723
|
+
const didAutoUpdate = target.matrixAutoUpdate;
|
|
4724
|
+
target.updateWorldMatrix(true, true);
|
|
4725
|
+
target.matrixAutoUpdate = false;
|
|
4726
|
+
pivot.matrix.copy(target.matrix);
|
|
4727
|
+
return () => {
|
|
4728
|
+
if (didAutoUpdate) {
|
|
4729
|
+
target.matrixAutoUpdate = true;
|
|
4730
|
+
target.matrix.decompose(target.position, target.quaternion, target.scale);
|
|
4731
|
+
}
|
|
4732
|
+
};
|
|
4733
|
+
}
|
|
4734
|
+
}
|
|
4735
|
+
}, [object]);
|
|
4872
4736
|
React.useLayoutEffect(() => {
|
|
4873
4737
|
if (!anchor) return;
|
|
4874
|
-
childrenRef.current
|
|
4875
|
-
|
|
4738
|
+
const anchorTarget = resolveObject(object, childrenRef.current);
|
|
4739
|
+
if (!anchorTarget) return;
|
|
4740
|
+
anchorTarget.updateWorldMatrix(true, true);
|
|
4741
|
+
mPInv.copy(anchorTarget.matrixWorld).invert();
|
|
4876
4742
|
bb.makeEmpty();
|
|
4877
|
-
|
|
4743
|
+
anchorTarget.traverse((obj) => {
|
|
4878
4744
|
if (!obj.geometry) return;
|
|
4879
4745
|
if (!obj.geometry.boundingBox) obj.geometry.computeBoundingBox();
|
|
4880
4746
|
mL.copy(obj.matrixWorld).premultiply(mPInv);
|
|
@@ -4889,9 +4755,17 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4889
4755
|
gizmoRef.current.position.copy(vPosition);
|
|
4890
4756
|
invalidate();
|
|
4891
4757
|
});
|
|
4758
|
+
const mergedUserData = React.useMemo(
|
|
4759
|
+
() => ({
|
|
4760
|
+
...userData,
|
|
4761
|
+
...depthTest === false && { interactivePriority: 1 }
|
|
4762
|
+
}),
|
|
4763
|
+
[userData, depthTest]
|
|
4764
|
+
);
|
|
4892
4765
|
const config = React.useMemo(
|
|
4893
4766
|
() => ({
|
|
4894
4767
|
onDragStart: (props2) => {
|
|
4768
|
+
dragState.current = props2;
|
|
4895
4769
|
mL0.copy(ref.current.matrix);
|
|
4896
4770
|
mW0.copy(ref.current.matrixWorld);
|
|
4897
4771
|
onDragStart && onDragStart(props2);
|
|
@@ -4907,13 +4781,20 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4907
4781
|
if (autoTransform) {
|
|
4908
4782
|
ref.current.matrix.copy(mL);
|
|
4909
4783
|
}
|
|
4784
|
+
const target = resolveObject(object);
|
|
4785
|
+
if (target) target.matrix.copy(mL);
|
|
4910
4786
|
onDrag && onDrag(mL, mdL, mW, mdW);
|
|
4911
4787
|
invalidate();
|
|
4912
4788
|
},
|
|
4913
4789
|
onDragEnd: () => {
|
|
4790
|
+
dragState.current = null;
|
|
4914
4791
|
if (onDragEnd) onDragEnd();
|
|
4915
4792
|
invalidate();
|
|
4916
4793
|
},
|
|
4794
|
+
onHover: (props2) => {
|
|
4795
|
+
if (onHover) onHover(props2);
|
|
4796
|
+
},
|
|
4797
|
+
dragState,
|
|
4917
4798
|
translation,
|
|
4918
4799
|
translationLimits,
|
|
4919
4800
|
rotationLimits,
|
|
@@ -4925,7 +4806,7 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4925
4806
|
fixed,
|
|
4926
4807
|
depthTest,
|
|
4927
4808
|
renderOrder,
|
|
4928
|
-
userData,
|
|
4809
|
+
userData: mergedUserData,
|
|
4929
4810
|
annotations,
|
|
4930
4811
|
annotationsClass,
|
|
4931
4812
|
LineComponent: LineComp
|
|
@@ -4934,6 +4815,7 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4934
4815
|
onDragStart,
|
|
4935
4816
|
onDrag,
|
|
4936
4817
|
onDragEnd,
|
|
4818
|
+
onHover,
|
|
4937
4819
|
translation,
|
|
4938
4820
|
translationLimits,
|
|
4939
4821
|
rotationLimits,
|
|
@@ -4945,11 +4827,12 @@ const PivotControls = /* @__PURE__ */ React.forwardRef(
|
|
|
4945
4827
|
...axisColors,
|
|
4946
4828
|
hoveredColor,
|
|
4947
4829
|
opacity,
|
|
4948
|
-
|
|
4830
|
+
mergedUserData,
|
|
4949
4831
|
autoTransform,
|
|
4950
4832
|
annotations,
|
|
4951
4833
|
annotationsClass,
|
|
4952
|
-
LineComp
|
|
4834
|
+
LineComp,
|
|
4835
|
+
object
|
|
4953
4836
|
]
|
|
4954
4837
|
);
|
|
4955
4838
|
const vec = new THREE.Vector3();
|
|
@@ -5311,7 +5194,7 @@ function createInstances() {
|
|
|
5311
5194
|
];
|
|
5312
5195
|
}
|
|
5313
5196
|
const InstancedAttribute = React.forwardRef(
|
|
5314
|
-
({ name, defaultValue, normalized, usage = THREE.DynamicDrawUsage }, fref) => {
|
|
5197
|
+
({ name, defaultValue, normalized, usage = THREE.DynamicDrawUsage, type = "float" }, fref) => {
|
|
5315
5198
|
const ref = React.useRef(null);
|
|
5316
5199
|
React.useImperativeHandle(fref, () => ref.current, []);
|
|
5317
5200
|
React.useLayoutEffect(() => {
|
|
@@ -5319,7 +5202,26 @@ const InstancedAttribute = React.forwardRef(
|
|
|
5319
5202
|
parent.geometry.attributes[name] = ref.current;
|
|
5320
5203
|
const value = Array.isArray(defaultValue) ? defaultValue : [defaultValue];
|
|
5321
5204
|
const array = Array.from({ length: parent.userData.limit }, () => value).flat();
|
|
5322
|
-
|
|
5205
|
+
switch (type) {
|
|
5206
|
+
case "float":
|
|
5207
|
+
ref.current.array = new Float32Array(array);
|
|
5208
|
+
break;
|
|
5209
|
+
case "int":
|
|
5210
|
+
ref.current.array = new Int32Array(array);
|
|
5211
|
+
break;
|
|
5212
|
+
case "uint":
|
|
5213
|
+
ref.current.array = new Uint32Array(array);
|
|
5214
|
+
break;
|
|
5215
|
+
case "short":
|
|
5216
|
+
ref.current.array = new Int16Array(array);
|
|
5217
|
+
break;
|
|
5218
|
+
case "ushort":
|
|
5219
|
+
ref.current.array = new Uint16Array(array);
|
|
5220
|
+
break;
|
|
5221
|
+
case "byte":
|
|
5222
|
+
ref.current.array = new Uint8Array(array);
|
|
5223
|
+
break;
|
|
5224
|
+
}
|
|
5323
5225
|
ref.current.itemSize = value.length;
|
|
5324
5226
|
ref.current.count = array.length / ref.current.itemSize;
|
|
5325
5227
|
return () => {
|
|
@@ -6844,12 +6746,17 @@ const Gltf = /* @__PURE__ */ React.forwardRef(
|
|
|
6844
6746
|
}
|
|
6845
6747
|
);
|
|
6846
6748
|
|
|
6847
|
-
|
|
6848
|
-
function useKTX2(input, basisPath =
|
|
6749
|
+
let transcoderPath = "https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/";
|
|
6750
|
+
function useKTX2(input, basisPath = true, extendLoader) {
|
|
6849
6751
|
const renderer = useThree((state) => state.renderer);
|
|
6850
6752
|
const textures = useLoader(KTX2Loader, IsObject(input) ? Object.values(input) : input, (loader) => {
|
|
6753
|
+
if (extendLoader) {
|
|
6754
|
+
extendLoader(loader);
|
|
6755
|
+
}
|
|
6756
|
+
if (basisPath) {
|
|
6757
|
+
loader.setTranscoderPath(typeof basisPath === "string" ? basisPath : transcoderPath);
|
|
6758
|
+
}
|
|
6851
6759
|
loader.detectSupport(renderer);
|
|
6852
|
-
loader.setTranscoderPath(basisPath);
|
|
6853
6760
|
});
|
|
6854
6761
|
useEffect(() => {
|
|
6855
6762
|
const array = Array.isArray(textures) ? textures : [textures];
|
|
@@ -6864,16 +6771,20 @@ function useKTX2(input, basisPath = `${cdn}/basis/`) {
|
|
|
6864
6771
|
return textures;
|
|
6865
6772
|
}
|
|
6866
6773
|
}
|
|
6867
|
-
useKTX2.preload = (url, basisPath =
|
|
6868
|
-
|
|
6774
|
+
useKTX2.preload = (url, basisPath = true, extendLoader) => useLoader.preload(KTX2Loader, url, (loader) => {
|
|
6775
|
+
if (extendLoader) {
|
|
6776
|
+
extendLoader(loader);
|
|
6777
|
+
}
|
|
6778
|
+
if (basisPath) {
|
|
6779
|
+
loader.setTranscoderPath(typeof basisPath === "string" ? basisPath : transcoderPath);
|
|
6780
|
+
}
|
|
6869
6781
|
});
|
|
6870
6782
|
useKTX2.clear = (input) => useLoader.clear(KTX2Loader, input);
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
const texture = useKTX2(input, basisPath);
|
|
6783
|
+
useKTX2.setTranscoderPath = (path) => {
|
|
6784
|
+
transcoderPath = path;
|
|
6785
|
+
};
|
|
6786
|
+
const Ktx2 = ({ children, input, basisPath, extendLoader }) => {
|
|
6787
|
+
const texture = useKTX2(input, basisPath, extendLoader);
|
|
6877
6788
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children?.(texture));
|
|
6878
6789
|
};
|
|
6879
6790
|
|
|
@@ -7349,18 +7260,21 @@ function Fisheye({
|
|
|
7349
7260
|
const normal = new THREE.Vector3();
|
|
7350
7261
|
const sph = new THREE.Sphere(new THREE.Vector3(), radius);
|
|
7351
7262
|
const normalMatrix = new THREE.Matrix3();
|
|
7352
|
-
const compute = React.useCallback(
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7263
|
+
const compute = React.useCallback(
|
|
7264
|
+
(event, state, prev) => {
|
|
7265
|
+
state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
|
|
7266
|
+
state.raycaster.setFromCamera(state.pointer, orthoC);
|
|
7267
|
+
if (!state.raycaster.ray.intersectSphere(sph, normal)) return;
|
|
7268
|
+
else normal.normalize();
|
|
7269
|
+
normalMatrix.getNormalMatrix(cubeApi.current.camera.matrixWorld);
|
|
7270
|
+
cubeApi.current.camera.getWorldPosition(state.raycaster.ray.origin);
|
|
7271
|
+
state.raycaster.ray.direction.set(0, 0, 1).reflect(normal);
|
|
7272
|
+
state.raycaster.ray.direction.x *= -1;
|
|
7273
|
+
state.raycaster.ray.direction.applyNormalMatrix(normalMatrix).multiplyScalar(-1);
|
|
7274
|
+
return void 0;
|
|
7275
|
+
},
|
|
7276
|
+
[width, height]
|
|
7277
|
+
);
|
|
7364
7278
|
useFrame(
|
|
7365
7279
|
({ gl }) => {
|
|
7366
7280
|
if (renderPriority) gl.render(sphere.current, orthoC);
|
|
@@ -7495,14 +7409,22 @@ const isWebGPURenderer = (def) => !!def.isWebGPURenderer;
|
|
|
7495
7409
|
const col = /* @__PURE__ */ new THREE.Color();
|
|
7496
7410
|
const TUNNEL_KEY = "__drei_view_tunnel__";
|
|
7497
7411
|
const tracked = globalThis[TUNNEL_KEY] || (globalThis[TUNNEL_KEY] = tunnel());
|
|
7498
|
-
function computeContainerPosition(canvasSize, trackRect) {
|
|
7412
|
+
function computeContainerPosition(canvasSize, trackRect, forceEven) {
|
|
7499
7413
|
const { right, top: trackTop, left: trackLeft, bottom: trackBottom, width, height } = trackRect;
|
|
7500
7414
|
const isOffscreen = trackRect.bottom < 0 || trackTop > canvasSize.height || right < 0 || trackRect.left > canvasSize.width;
|
|
7501
7415
|
const canvasBottom = canvasSize.top + canvasSize.height;
|
|
7502
|
-
const
|
|
7503
|
-
const
|
|
7504
|
-
const
|
|
7505
|
-
|
|
7416
|
+
const rawBottom = canvasBottom - trackBottom;
|
|
7417
|
+
const rawLeft = trackLeft - canvasSize.left;
|
|
7418
|
+
const rawTop = trackTop - canvasSize.top;
|
|
7419
|
+
const position = forceEven ? {
|
|
7420
|
+
width: roundEven(width),
|
|
7421
|
+
height: roundEven(height),
|
|
7422
|
+
left: roundEven(rawLeft),
|
|
7423
|
+
top: roundEven(rawTop),
|
|
7424
|
+
bottom: roundEven(rawBottom),
|
|
7425
|
+
right: roundEven(right)
|
|
7426
|
+
} : { width, height, left: rawLeft, top: rawTop, bottom: rawBottom, right };
|
|
7427
|
+
return { position, isOffscreen };
|
|
7506
7428
|
}
|
|
7507
7429
|
function prepareSkissor(renderer, camera, {
|
|
7508
7430
|
left,
|
|
@@ -7542,6 +7464,7 @@ function clear(renderer) {
|
|
|
7542
7464
|
}
|
|
7543
7465
|
function Container({ visible = true, canvasSize, scene, index, children, frames, rect, track }) {
|
|
7544
7466
|
const { scene: portalScene, camera: portalCamera, renderer, get, setEvents } = useThree();
|
|
7467
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
7545
7468
|
const [isOffscreen, setOffscreen] = React.useState(false);
|
|
7546
7469
|
const mountedRef = React.useRef(true);
|
|
7547
7470
|
React.useEffect(() => {
|
|
@@ -7559,7 +7482,7 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
7559
7482
|
frameCount++;
|
|
7560
7483
|
}
|
|
7561
7484
|
if (rect.current) {
|
|
7562
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, rect.current);
|
|
7485
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, rect.current, forceEven);
|
|
7563
7486
|
if (isOffscreen !== _isOffscreen) setOffscreen(_isOffscreen);
|
|
7564
7487
|
if (visible && !_isOffscreen && rect.current) {
|
|
7565
7488
|
const targetScene = children ? portalScene : scene;
|
|
@@ -7581,14 +7504,14 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
7581
7504
|
React.useLayoutEffect(() => {
|
|
7582
7505
|
const curRect = rect.current;
|
|
7583
7506
|
if (curRect && (!visible || !isOffscreen)) {
|
|
7584
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect);
|
|
7507
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect, forceEven);
|
|
7585
7508
|
if (!_isOffscreen) {
|
|
7586
7509
|
const autoClear = prepareSkissor(renderer, portalCamera, position);
|
|
7587
7510
|
clear(renderer);
|
|
7588
7511
|
finishSkissor(renderer, autoClear);
|
|
7589
7512
|
}
|
|
7590
7513
|
}
|
|
7591
|
-
}, [visible, isOffscreen, renderer, portalCamera, canvasSize]);
|
|
7514
|
+
}, [visible, isOffscreen, renderer, portalCamera, canvasSize, forceEven]);
|
|
7592
7515
|
React.useEffect(() => {
|
|
7593
7516
|
if (!track) return;
|
|
7594
7517
|
const curRect = rect.current;
|
|
@@ -7596,7 +7519,7 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
7596
7519
|
setEvents({ connected: track.current });
|
|
7597
7520
|
return () => {
|
|
7598
7521
|
if (curRect) {
|
|
7599
|
-
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect);
|
|
7522
|
+
const { position, isOffscreen: _isOffscreen } = computeContainerPosition(canvasSize, curRect, forceEven);
|
|
7600
7523
|
if (!_isOffscreen) {
|
|
7601
7524
|
const autoClear = prepareSkissor(renderer, portalCamera, position);
|
|
7602
7525
|
clear(renderer);
|
|
@@ -7605,13 +7528,14 @@ function Container({ visible = true, canvasSize, scene, index, children, frames,
|
|
|
7605
7528
|
}
|
|
7606
7529
|
setEvents({ connected: old });
|
|
7607
7530
|
};
|
|
7608
|
-
}, [track, renderer, portalCamera, canvasSize, get, setEvents]);
|
|
7531
|
+
}, [track, renderer, portalCamera, canvasSize, get, setEvents, forceEven]);
|
|
7609
7532
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children, /* @__PURE__ */ React.createElement("group", { onPointerOver: () => null }));
|
|
7610
7533
|
}
|
|
7611
7534
|
const CanvasView = /* @__PURE__ */ React.forwardRef(
|
|
7612
7535
|
({ track, visible = true, index = 1, id, style, className, frames = Infinity, children, ...props }, fref) => {
|
|
7613
7536
|
const rect = React.useRef(null);
|
|
7614
7537
|
const { size, scene } = useThree();
|
|
7538
|
+
const forceEven = useThree((state) => state.internal.forceEven);
|
|
7615
7539
|
const [virtualScene] = React.useState(() => new THREE.Scene());
|
|
7616
7540
|
const [ready, toggle] = React.useReducer(() => true, false);
|
|
7617
7541
|
const compute = React.useCallback(
|
|
@@ -7648,12 +7572,12 @@ const CanvasView = /* @__PURE__ */ React.forwardRef(
|
|
|
7648
7572
|
{
|
|
7649
7573
|
events: { compute, priority: index },
|
|
7650
7574
|
size: {
|
|
7651
|
-
width: rect.current?.width,
|
|
7652
|
-
height: rect.current?.height,
|
|
7575
|
+
width: forceEven && rect.current?.width ? roundEven(rect.current.width) : rect.current?.width,
|
|
7576
|
+
height: forceEven && rect.current?.height ? roundEven(rect.current.height) : rect.current?.height,
|
|
7653
7577
|
// @ts-ignore
|
|
7654
|
-
top: rect.current?.top,
|
|
7578
|
+
top: forceEven && rect.current?.top ? roundEven(rect.current.top) : rect.current?.top,
|
|
7655
7579
|
// @ts-ignore
|
|
7656
|
-
left: rect.current?.left
|
|
7580
|
+
left: forceEven && rect.current?.left ? roundEven(rect.current.left) : rect.current?.left
|
|
7657
7581
|
}
|
|
7658
7582
|
}
|
|
7659
7583
|
));
|
|
@@ -13742,4 +13666,4 @@ const MarchingPlane = /* @__PURE__ */ React.forwardRef(
|
|
|
13742
13666
|
}
|
|
13743
13667
|
);
|
|
13744
13668
|
|
|
13745
|
-
export { AdaptiveDpr, AdaptiveEvents, ArcballControls, BBAnchor, Backdrop, Billboard, Bounds, Box, Bvh, CameraControls, CameraShake, Capsule, CatmullRomLine, Center, Circle, Clone, Cloud, CloudInstance, Clouds, ComputedAttribute, Cone, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, Dodecahedron, DragControls, Edges, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, FaceControls, FaceLandmarker, FaceLandmarkerDefaults, Facemesh, FacemeshDatas, FacemeshEye, FacemeshEyeDefaults, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, Helper, Html, Hud, Icosahedron, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Loader, MapControls, MarchingCube, MarchingCubes, MarchingPlane, Mask, MatcapTexture, Merged, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, Outlines, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Select, Shadow, Shape, Sky, Sphere, Splat, SpriteAnimator, Stage, Stats, StatsGl, Svg, Tetrahedron, Text3D, Texture, Torus, TorusKnot, TrackballControls, Trail, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture,
|
|
13669
|
+
export { AdaptiveDpr, AdaptiveEvents, ArcballControls, BBAnchor, Backdrop, Billboard, Bounds, Box, Bvh, CameraControls, CameraShake, Capsule, CatmullRomLine, Center, Circle, Clone, Cloud, CloudInstance, Clouds, ComputedAttribute, Cone, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, Dodecahedron, DragControls, Edges, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, FaceControls, FaceLandmarker, FaceLandmarkerDefaults, Facemesh, FacemeshDatas, FacemeshEye, FacemeshEyeDefaults, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, Helper, Html, Hud, Icosahedron, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Loader, MapControls, MarchingCube, MarchingCubes, MarchingPlane, Mask, MatcapTexture, Merged, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, Outlines, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Select, Shadow, Shape, Sky, Sphere, Splat, SpriteAnimator, Stage, Stats, StatsGl, Svg, Tetrahedron, Text3D, Texture, Torus, TorusKnot, TrackballControls, Trail, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture, calcPosFromAngles, checkIfFrameIsEmpty, createInstances, getFirstFrame, meshBounds, presetsObj, useAnimations, useAspect, useBVH, useBounds, useContextBridge, useCubeCamera, useCubeTexture, useCursor, useCustomRaycast, useDepthBuffer, useDetectGPU, useEnvironment, useFBO, useFBX, useFaceControls, useFaceLandmarker, useFont, useGLTF, useGizmoContext, useHelper, useIntersect, useKTX2, useKeyboardControls, useMask, useMatcapTexture, useMotion, useNormalTexture, usePerformanceMonitor, useProgress, useScroll, useSelect, useSpriteAnimator, useSpriteLoader, useSurfaceSampler, useTexture, useTrail, useTrailTexture, useVideoTexture };
|