summit/frontend/node_modules/@react-three/drei/web/pivotControls/index.js

212 lines
7.6 KiB
JavaScript

import _extends from '@babel/runtime/helpers/esm/extends';
import { useThree, useFrame } from '@react-three/fiber';
import * as React from 'react';
import * as THREE from 'three';
import { AxisArrow } from './AxisArrow.js';
import { AxisRotator } from './AxisRotator.js';
import { PlaneSlider } from './PlaneSlider.js';
import { ScalingSphere } from './ScalingSphere.js';
import { context } from './context.js';
import { calculateScaleFactor } from '../../core/calculateScaleFactor.js';
const mL0 = /* @__PURE__ */new THREE.Matrix4();
const mW0 = /* @__PURE__ */new THREE.Matrix4();
const mP = /* @__PURE__ */new THREE.Matrix4();
const mPInv = /* @__PURE__ */new THREE.Matrix4();
const mW = /* @__PURE__ */new THREE.Matrix4();
const mL = /* @__PURE__ */new THREE.Matrix4();
const mL0Inv = /* @__PURE__ */new THREE.Matrix4();
const mdL = /* @__PURE__ */new THREE.Matrix4();
const mG = /* @__PURE__ */new THREE.Matrix4();
const bb = /* @__PURE__ */new THREE.Box3();
const bbObj = /* @__PURE__ */new THREE.Box3();
const vCenter = /* @__PURE__ */new THREE.Vector3();
const vSize = /* @__PURE__ */new THREE.Vector3();
const vAnchorOffset = /* @__PURE__ */new THREE.Vector3();
const vPosition = /* @__PURE__ */new THREE.Vector3();
const vScale = /* @__PURE__ */new THREE.Vector3();
const xDir = /* @__PURE__ */new THREE.Vector3(1, 0, 0);
const yDir = /* @__PURE__ */new THREE.Vector3(0, 1, 0);
const zDir = /* @__PURE__ */new THREE.Vector3(0, 0, 1);
const PivotControls = /* @__PURE__ */React.forwardRef(({
enabled = true,
matrix,
onDragStart,
onDrag,
onDragEnd,
autoTransform = true,
anchor,
disableAxes = false,
disableSliders = false,
disableRotations = false,
disableScaling = false,
activeAxes = [true, true, true],
offset = [0, 0, 0],
rotation = [0, 0, 0],
scale = 1,
lineWidth = 4,
fixed = false,
translationLimits,
rotationLimits,
scaleLimits,
depthTest = true,
axisColors = ['#ff2060', '#20df80', '#2080ff'],
hoveredColor = '#ffff40',
annotations = false,
annotationsClass,
opacity = 1,
visible = true,
userData,
children,
...props
}, fRef) => {
const invalidate = useThree(state => state.invalidate);
const parentRef = React.useRef(null);
const ref = React.useRef(null);
const gizmoRef = React.useRef(null);
const childrenRef = React.useRef(null);
const translation = React.useRef([0, 0, 0]);
const cameraScale = React.useRef(new THREE.Vector3(1, 1, 1));
const gizmoScale = React.useRef(new THREE.Vector3(1, 1, 1));
React.useLayoutEffect(() => {
if (!anchor) return;
childrenRef.current.updateWorldMatrix(true, true);
mPInv.copy(childrenRef.current.matrixWorld).invert();
bb.makeEmpty();
childrenRef.current.traverse(obj => {
if (!obj.geometry) return;
if (!obj.geometry.boundingBox) obj.geometry.computeBoundingBox();
mL.copy(obj.matrixWorld).premultiply(mPInv);
bbObj.copy(obj.geometry.boundingBox);
bbObj.applyMatrix4(mL);
bb.union(bbObj);
});
vCenter.copy(bb.max).add(bb.min).multiplyScalar(0.5);
vSize.copy(bb.max).sub(bb.min).multiplyScalar(0.5);
vAnchorOffset.copy(vSize).multiply(new THREE.Vector3(...anchor)).add(vCenter);
vPosition.set(...offset).add(vAnchorOffset);
gizmoRef.current.position.copy(vPosition);
invalidate();
});
const config = React.useMemo(() => ({
onDragStart: props => {
mL0.copy(ref.current.matrix);
mW0.copy(ref.current.matrixWorld);
onDragStart && onDragStart(props);
invalidate();
},
onDrag: mdW => {
mP.copy(parentRef.current.matrixWorld);
mPInv.copy(mP).invert();
// After applying the delta
mW.copy(mW0).premultiply(mdW);
mL.copy(mW).premultiply(mPInv);
mL0Inv.copy(mL0).invert();
mdL.copy(mL).multiply(mL0Inv);
if (autoTransform) {
ref.current.matrix.copy(mL);
}
onDrag && onDrag(mL, mdL, mW, mdW);
invalidate();
},
onDragEnd: () => {
if (onDragEnd) onDragEnd();
invalidate();
},
translation,
translationLimits,
rotationLimits,
axisColors,
hoveredColor,
opacity,
scale,
lineWidth,
fixed,
depthTest,
userData,
annotations,
annotationsClass
}), [onDragStart, onDrag, onDragEnd, translation, translationLimits, rotationLimits, scaleLimits, depthTest, scale, lineWidth, fixed, ...axisColors, hoveredColor, opacity, userData, autoTransform, annotations, annotationsClass]);
const vec = new THREE.Vector3();
useFrame(state => {
if (fixed) {
const sf = calculateScaleFactor(gizmoRef.current.getWorldPosition(vec), scale, state.camera, state.size);
cameraScale.current.setScalar(sf);
}
if (matrix && matrix instanceof THREE.Matrix4) {
ref.current.matrix = matrix;
}
// Update gizmo scale in accordance with matrix changes
// Without this, there might be noticable turbulences if scaling happens fast enough
ref.current.updateWorldMatrix(true, true);
mG.makeRotationFromEuler(gizmoRef.current.rotation).setPosition(gizmoRef.current.position).premultiply(ref.current.matrixWorld);
gizmoScale.current.setFromMatrixScale(mG);
vScale.copy(cameraScale.current).divide(gizmoScale.current);
if (Math.abs(gizmoRef.current.scale.x - vScale.x) > 1e-4 || Math.abs(gizmoRef.current.scale.y - vScale.y) > 1e-4 || Math.abs(gizmoRef.current.scale.z - vScale.z) > 1e-4) {
gizmoRef.current.scale.copy(vScale);
state.invalidate();
}
});
React.useImperativeHandle(fRef, () => ref.current, []);
return /*#__PURE__*/React.createElement(context.Provider, {
value: config
}, /*#__PURE__*/React.createElement("group", {
ref: parentRef
}, /*#__PURE__*/React.createElement("group", _extends({
ref: ref,
matrix: matrix,
matrixAutoUpdate: false
}, props), /*#__PURE__*/React.createElement("group", {
visible: visible,
ref: gizmoRef,
position: offset,
rotation: rotation
}, enabled && /*#__PURE__*/React.createElement(React.Fragment, null, !disableAxes && activeAxes[0] && /*#__PURE__*/React.createElement(AxisArrow, {
axis: 0,
direction: xDir
}), !disableAxes && activeAxes[1] && /*#__PURE__*/React.createElement(AxisArrow, {
axis: 1,
direction: yDir
}), !disableAxes && activeAxes[2] && /*#__PURE__*/React.createElement(AxisArrow, {
axis: 2,
direction: zDir
}), !disableSliders && activeAxes[0] && activeAxes[1] && /*#__PURE__*/React.createElement(PlaneSlider, {
axis: 2,
dir1: xDir,
dir2: yDir
}), !disableSliders && activeAxes[0] && activeAxes[2] && /*#__PURE__*/React.createElement(PlaneSlider, {
axis: 1,
dir1: zDir,
dir2: xDir
}), !disableSliders && activeAxes[2] && activeAxes[1] && /*#__PURE__*/React.createElement(PlaneSlider, {
axis: 0,
dir1: yDir,
dir2: zDir
}), !disableRotations && activeAxes[0] && activeAxes[1] && /*#__PURE__*/React.createElement(AxisRotator, {
axis: 2,
dir1: xDir,
dir2: yDir
}), !disableRotations && activeAxes[0] && activeAxes[2] && /*#__PURE__*/React.createElement(AxisRotator, {
axis: 1,
dir1: zDir,
dir2: xDir
}), !disableRotations && activeAxes[2] && activeAxes[1] && /*#__PURE__*/React.createElement(AxisRotator, {
axis: 0,
dir1: yDir,
dir2: zDir
}), !disableScaling && activeAxes[0] && /*#__PURE__*/React.createElement(ScalingSphere, {
axis: 0,
direction: xDir
}), !disableScaling && activeAxes[1] && /*#__PURE__*/React.createElement(ScalingSphere, {
axis: 1,
direction: yDir
}), !disableScaling && activeAxes[2] && /*#__PURE__*/React.createElement(ScalingSphere, {
axis: 2,
direction: zDir
}))), /*#__PURE__*/React.createElement("group", {
ref: childrenRef
}, children))));
});
export { PivotControls };