@react-three/drei 9.74.11 → 9.74.13

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.
Files changed (189) hide show
  1. package/core/CatmullRomLine.js +2 -0
  2. package/core/Cloud.js +3 -0
  3. package/core/CubeCamera.js +1 -0
  4. package/core/CubicBezierLine.js +2 -0
  5. package/core/Environment.js +1 -0
  6. package/core/Example.js +6 -0
  7. package/core/FaceControls.cjs.js +1 -1
  8. package/core/FaceControls.js +2 -0
  9. package/core/FaceLandmarker.cjs.js +1 -1
  10. package/core/FaceLandmarker.js +3 -2
  11. package/core/Facemesh.js +2 -0
  12. package/core/GizmoHelper.js +3 -0
  13. package/core/GizmoViewcube.js +4 -0
  14. package/core/GizmoViewport.js +4 -0
  15. package/core/Gltf.js +4 -0
  16. package/core/MeshDiscardMaterial.js +2 -0
  17. package/core/MeshDistortMaterial.js +2 -1
  18. package/core/MeshReflectorMaterial.js +1 -0
  19. package/core/MeshRefractionMaterial.js +2 -0
  20. package/core/MeshTransmissionMaterial.js +1 -0
  21. package/core/OrthographicCamera.js +1 -0
  22. package/core/PerspectiveCamera.js +1 -0
  23. package/core/QuadraticBezierLine.js +2 -0
  24. package/core/Reflector.js +1 -0
  25. package/core/SpotLight.js +2 -1
  26. package/core/Stage.js +7 -0
  27. package/core/Text3D.js +1 -0
  28. package/core/Wireframe.js +1 -0
  29. package/core/index.cjs.js +1 -1
  30. package/core/index.js +0 -1
  31. package/core/useKTX2.js +1 -0
  32. package/core/useMatcapTexture.js +2 -0
  33. package/core/useNormalTexture.js +1 -0
  34. package/index.cjs.js +1 -1
  35. package/materials/DiscardMaterial.js +1 -0
  36. package/materials/MeshRefractionMaterial.js +1 -1
  37. package/native/index.cjs.js +1 -1
  38. package/native/index.js +0 -1
  39. package/package.json +9 -9
  40. package/src/core/AccumulativeShadows.js +311 -0
  41. package/src/core/AdaptiveDpr.js +28 -0
  42. package/src/core/AdaptiveEvents.js +20 -0
  43. package/src/core/ArcballControls.js +67 -0
  44. package/src/core/AsciiRenderer.js +60 -0
  45. package/src/core/BBAnchor.js +37 -0
  46. package/src/core/Backdrop.js +36 -0
  47. package/src/core/BakeShadows.js +16 -0
  48. package/src/core/Billboard.js +41 -0
  49. package/src/core/Bounds.js +245 -0
  50. package/src/core/CameraControls.js +92 -0
  51. package/src/core/CameraShake.js +61 -0
  52. package/src/core/CatmullRomLine.js +44 -0
  53. package/src/core/Caustics.js +375 -0
  54. package/src/core/Center.js +66 -0
  55. package/src/core/Clone.js +102 -0
  56. package/src/core/Cloud.js +59 -0
  57. package/src/core/ComputedAttribute.js +34 -0
  58. package/src/core/ContactShadows.js +114 -0
  59. package/src/core/CubeCamera.js +43 -0
  60. package/src/core/CubicBezierLine.js +28 -0
  61. package/src/core/CurveModifier.js +34 -0
  62. package/src/core/Decal.js +92 -0
  63. package/src/core/Detailed.js +34 -0
  64. package/src/core/DeviceOrientationControls.js +51 -0
  65. package/src/core/Edges.js +36 -0
  66. package/src/core/Effects.js +93 -0
  67. package/src/core/Environment.js +132 -0
  68. package/src/core/Example.js +42 -0
  69. package/src/core/FaceControls.js +315 -0
  70. package/src/core/FaceLandmarker.js +43 -0
  71. package/src/core/Facemesh.js +4545 -0
  72. package/src/core/FirstPersonControls.js +38 -0
  73. package/src/core/Float.js +36 -0
  74. package/src/core/FlyControls.js +55 -0
  75. package/src/core/GizmoHelper.js +111 -0
  76. package/src/core/GizmoViewcube.js +152 -0
  77. package/src/core/GizmoViewport.js +152 -0
  78. package/src/core/Gltf.js +20 -0
  79. package/src/core/GradientTexture.js +33 -0
  80. package/src/core/Grid.js +112 -0
  81. package/src/core/Hud.js +58 -0
  82. package/src/core/Image.js +119 -0
  83. package/src/core/Instances.js +215 -0
  84. package/src/core/Lightformer.js +51 -0
  85. package/src/core/Line.js +68 -0
  86. package/src/core/MapControls.js +64 -0
  87. package/src/core/MarchingCubes.js +76 -0
  88. package/src/core/Mask.js +42 -0
  89. package/src/core/MeshDiscardMaterial.js +15 -0
  90. package/src/core/MeshDistortMaterial.js +79 -0
  91. package/src/core/MeshPortalMaterial.js +381 -0
  92. package/src/core/MeshReflectorMaterial.js +182 -0
  93. package/src/core/MeshRefractionMaterial.js +79 -0
  94. package/src/core/MeshTransmissionMaterial.js +395 -0
  95. package/src/core/MeshWobbleMaterial.js +65 -0
  96. package/src/core/OrbitControls.js +82 -0
  97. package/src/core/OrthographicCamera.js +77 -0
  98. package/src/core/PerformanceMonitor.js +121 -0
  99. package/src/core/PerspectiveCamera.js +73 -0
  100. package/src/core/PointMaterial.js +36 -0
  101. package/src/core/PointerLockControls.js +90 -0
  102. package/src/core/Points.js +227 -0
  103. package/src/core/PositionalAudio.js +51 -0
  104. package/src/core/Preload.js +45 -0
  105. package/src/core/QuadraticBezierLine.js +44 -0
  106. package/src/core/Reflector.js +182 -0
  107. package/src/core/RenderTexture.js +96 -0
  108. package/src/core/Resize.js +39 -0
  109. package/src/core/RoundedBox.js +52 -0
  110. package/src/core/Sampler.js +85 -0
  111. package/src/core/ScreenQuad.js +24 -0
  112. package/src/core/ScreenSpace.js +25 -0
  113. package/src/core/Segments.js +102 -0
  114. package/src/core/Shadow.js +42 -0
  115. package/src/core/Sky.js +39 -0
  116. package/src/core/Sparkles.js +139 -0
  117. package/src/core/SpotLight.js +231 -0
  118. package/src/core/SpriteAnimator.js +342 -0
  119. package/src/core/Stage.js +135 -0
  120. package/src/core/Stars.js +108 -0
  121. package/src/core/Stats.js +30 -0
  122. package/src/core/Svg.js +59 -0
  123. package/src/core/Text.js +58 -0
  124. package/src/core/Text3D.js +76 -0
  125. package/src/core/TrackballControls.js +72 -0
  126. package/src/core/Trail.js +161 -0
  127. package/src/core/TransformControls.js +106 -0
  128. package/src/core/Wireframe.js +185 -0
  129. package/src/core/meshBounds.js +38 -0
  130. package/src/core/shaderMaterial.js +39 -0
  131. package/src/core/shapes.js +68 -0
  132. package/src/core/softShadows.js +161 -0
  133. package/src/core/useAnimations.js +56 -0
  134. package/src/core/useAspect.js +10 -0
  135. package/src/core/useBVH.js +90 -0
  136. package/src/core/useBoxProjectedEnv.js +98 -0
  137. package/src/core/useCamera.js +27 -0
  138. package/src/core/useContextBridge.js +21 -0
  139. package/src/core/useCubeCamera.js +49 -0
  140. package/src/core/useCubeTexture.js +18 -0
  141. package/src/core/useDepthBuffer.js +38 -0
  142. package/src/core/useDetectGPU.js +6 -0
  143. package/src/core/useEnvironment.js +48 -0
  144. package/src/core/useFBO.js +53 -0
  145. package/src/core/useFBX.js +12 -0
  146. package/src/core/useFont.js +20 -0
  147. package/src/core/useGLTF.js +37 -0
  148. package/src/core/useHelper.js +31 -0
  149. package/src/core/useIntersect.js +39 -0
  150. package/src/core/useKTX2.js +38 -0
  151. package/src/core/useMatcapTexture.js +45 -0
  152. package/src/core/useNormalTexture.js +30 -0
  153. package/src/core/useProgress.js +50 -0
  154. package/src/core/useTexture.js +35 -0
  155. package/src/core/useTrailTexture.js +164 -0
  156. package/src/core/useVideoTexture.js +41 -0
  157. package/src/helpers/environment-assets.js +14 -0
  158. package/src/helpers/useEffectfulState.js +18 -0
  159. package/src/materials/BlurPass.js +75 -0
  160. package/src/materials/ConvolutionMaterial.js +99 -0
  161. package/src/materials/DiscardMaterial.js +5 -0
  162. package/src/materials/MeshReflectorMaterial.js +290 -0
  163. package/src/materials/MeshRefractionMaterial.js +171 -0
  164. package/src/materials/SpotLightMaterial.js +111 -0
  165. package/src/materials/WireframeMaterial.js +235 -0
  166. package/src/web/CycleRaycast.js +97 -0
  167. package/src/web/Html.js +417 -0
  168. package/src/web/KeyboardControls.js +101 -0
  169. package/src/web/Loader.js +98 -0
  170. package/src/web/PresentationControls.js +86 -0
  171. package/src/web/ScrollControls.js +246 -0
  172. package/src/web/Select.js +175 -0
  173. package/src/web/View.js +206 -0
  174. package/src/web/pivotControls/AxisArrow.js +202 -0
  175. package/src/web/pivotControls/AxisRotator.js +235 -0
  176. package/src/web/pivotControls/PlaneSlider.js +211 -0
  177. package/src/web/pivotControls/context.js +5 -0
  178. package/src/web/pivotControls/index.js +223 -0
  179. package/src/web/useCursor.js +12 -0
  180. package/web/Loader.js +2 -0
  181. package/web/index.cjs.js +1 -1
  182. package/web/index.js +0 -1
  183. package/web/pivotControls/AxisArrow.js +3 -0
  184. package/web/pivotControls/AxisRotator.js +3 -0
  185. package/web/pivotControls/PlaneSlider.js +3 -0
  186. package/web/pivotControls/index.js +5 -0
  187. /package/{helpers → src/helpers}/glsl/DefaultSpotlightShadowShadows.glsl.js +0 -0
  188. /package/{helpers → src/helpers}/glsl/distort.vert.glsl.js +0 -0
  189. /package/{index.js → src/index.js} +0 -0
@@ -0,0 +1,202 @@
1
+ import * as React from 'react';
2
+ import * as THREE from 'three';
3
+ import { useThree } from '@react-three/fiber';
4
+ import { Line } from '../../core/Line.js';
5
+ import { Html } from '../Html.js';
6
+ import { context } from './context.js';
7
+
8
+ const vec1 = new THREE.Vector3();
9
+ const vec2 = new THREE.Vector3();
10
+ const calculateOffset = (clickPoint, normal, rayStart, rayDir) => {
11
+ const e1 = normal.dot(normal);
12
+ const e2 = normal.dot(clickPoint) - normal.dot(rayStart);
13
+ const e3 = normal.dot(rayDir);
14
+
15
+ if (e3 === 0) {
16
+ return -e2 / e1;
17
+ }
18
+
19
+ vec1.copy(rayDir).multiplyScalar(e1 / e3).sub(normal);
20
+ vec2.copy(rayDir).multiplyScalar(e2 / e3).add(rayStart).sub(clickPoint);
21
+ const offset = -vec1.dot(vec2) / vec1.dot(vec1);
22
+ return offset;
23
+ };
24
+ const upV = new THREE.Vector3(0, 1, 0);
25
+ const offsetMatrix = new THREE.Matrix4();
26
+ const AxisArrow = ({
27
+ direction,
28
+ axis
29
+ }) => {
30
+ const {
31
+ translation,
32
+ translationLimits,
33
+ annotations,
34
+ annotationsClass,
35
+ depthTest,
36
+ scale,
37
+ lineWidth,
38
+ fixed,
39
+ axisColors,
40
+ hoveredColor,
41
+ opacity,
42
+ onDragStart,
43
+ onDrag,
44
+ onDragEnd,
45
+ userData
46
+ } = React.useContext(context); // @ts-expect-error new in @react-three/fiber@7.0.5
47
+
48
+ const camControls = useThree(state => state.controls);
49
+ const divRef = React.useRef(null);
50
+ const objRef = React.useRef(null);
51
+ const clickInfo = React.useRef(null);
52
+ const offset0 = React.useRef(0);
53
+ const [isHovered, setIsHovered] = React.useState(false);
54
+ const onPointerDown = React.useCallback(e => {
55
+ if (annotations) {
56
+ divRef.current.innerText = `${translation.current[axis].toFixed(2)}`;
57
+ divRef.current.style.display = 'block';
58
+ }
59
+
60
+ e.stopPropagation();
61
+ const rotation = new THREE.Matrix4().extractRotation(objRef.current.matrixWorld);
62
+ const clickPoint = e.point.clone();
63
+ const origin = new THREE.Vector3().setFromMatrixPosition(objRef.current.matrixWorld);
64
+ const dir = direction.clone().applyMatrix4(rotation).normalize();
65
+ clickInfo.current = {
66
+ clickPoint,
67
+ dir
68
+ };
69
+ offset0.current = translation.current[axis];
70
+ onDragStart({
71
+ component: 'Arrow',
72
+ axis,
73
+ origin,
74
+ directions: [dir]
75
+ });
76
+ camControls && (camControls.enabled = false); // @ts-ignore - setPointerCapture is not in the type definition
77
+
78
+ e.target.setPointerCapture(e.pointerId);
79
+ }, [annotations, direction, camControls, onDragStart, translation, axis]);
80
+ const onPointerMove = React.useCallback(e => {
81
+ e.stopPropagation();
82
+ if (!isHovered) setIsHovered(true);
83
+
84
+ if (clickInfo.current) {
85
+ const {
86
+ clickPoint,
87
+ dir
88
+ } = clickInfo.current;
89
+ const [min, max] = (translationLimits == null ? void 0 : translationLimits[axis]) || [undefined, undefined];
90
+ let offset = calculateOffset(clickPoint, dir, e.ray.origin, e.ray.direction);
91
+
92
+ if (min !== undefined) {
93
+ offset = Math.max(offset, min - offset0.current);
94
+ }
95
+
96
+ if (max !== undefined) {
97
+ offset = Math.min(offset, max - offset0.current);
98
+ }
99
+
100
+ translation.current[axis] = offset0.current + offset;
101
+
102
+ if (annotations) {
103
+ divRef.current.innerText = `${translation.current[axis].toFixed(2)}`;
104
+ }
105
+
106
+ offsetMatrix.makeTranslation(dir.x * offset, dir.y * offset, dir.z * offset);
107
+ onDrag(offsetMatrix);
108
+ }
109
+ }, [annotations, onDrag, isHovered, translation, translationLimits, axis]);
110
+ const onPointerUp = React.useCallback(e => {
111
+ if (annotations) {
112
+ divRef.current.style.display = 'none';
113
+ }
114
+
115
+ e.stopPropagation();
116
+ clickInfo.current = null;
117
+ onDragEnd();
118
+ camControls && (camControls.enabled = true); // @ts-ignore - releasePointerCapture & PointerEvent#pointerId is not in the type definition
119
+
120
+ e.target.releasePointerCapture(e.pointerId);
121
+ }, [annotations, camControls, onDragEnd]);
122
+ const onPointerOut = React.useCallback(e => {
123
+ e.stopPropagation();
124
+ setIsHovered(false);
125
+ }, []);
126
+ const {
127
+ cylinderLength,
128
+ coneWidth,
129
+ coneLength,
130
+ matrixL
131
+ } = React.useMemo(() => {
132
+ const coneWidth = fixed ? lineWidth / scale * 1.6 : scale / 20;
133
+ const coneLength = fixed ? 0.2 : scale / 5;
134
+ const cylinderLength = fixed ? 1 - coneLength : scale - coneLength;
135
+ const quaternion = new THREE.Quaternion().setFromUnitVectors(upV, direction.clone().normalize());
136
+ const matrixL = new THREE.Matrix4().makeRotationFromQuaternion(quaternion);
137
+ return {
138
+ cylinderLength,
139
+ coneWidth,
140
+ coneLength,
141
+ matrixL
142
+ };
143
+ }, [direction, scale, lineWidth, fixed]);
144
+ const color_ = isHovered ? hoveredColor : axisColors[axis];
145
+ return /*#__PURE__*/React.createElement("group", {
146
+ ref: objRef
147
+ }, /*#__PURE__*/React.createElement("group", {
148
+ matrix: matrixL,
149
+ matrixAutoUpdate: false,
150
+ onPointerDown: onPointerDown,
151
+ onPointerMove: onPointerMove,
152
+ onPointerUp: onPointerUp,
153
+ onPointerOut: onPointerOut
154
+ }, annotations && /*#__PURE__*/React.createElement(Html, {
155
+ position: [0, -coneLength, 0]
156
+ }, /*#__PURE__*/React.createElement("div", {
157
+ style: {
158
+ display: 'none',
159
+ background: '#151520',
160
+ color: 'white',
161
+ padding: '6px 8px',
162
+ borderRadius: 7,
163
+ whiteSpace: 'nowrap'
164
+ },
165
+ className: annotationsClass,
166
+ ref: divRef
167
+ })), /*#__PURE__*/React.createElement("mesh", {
168
+ visible: false,
169
+ position: [0, (cylinderLength + coneLength) / 2.0, 0],
170
+ userData: userData
171
+ }, /*#__PURE__*/React.createElement("cylinderGeometry", {
172
+ args: [coneWidth * 1.4, coneWidth * 1.4, cylinderLength + coneLength, 8, 1]
173
+ })), /*#__PURE__*/React.createElement(Line, {
174
+ transparent: true,
175
+ raycast: () => null,
176
+ depthTest: depthTest,
177
+ points: [0, 0, 0, 0, cylinderLength, 0],
178
+ lineWidth: lineWidth,
179
+ color: color_,
180
+ opacity: opacity,
181
+ polygonOffset: true,
182
+ renderOrder: 1,
183
+ polygonOffsetFactor: -10,
184
+ fog: false
185
+ }), /*#__PURE__*/React.createElement("mesh", {
186
+ raycast: () => null,
187
+ position: [0, cylinderLength + coneLength / 2.0, 0],
188
+ renderOrder: 500
189
+ }, /*#__PURE__*/React.createElement("coneGeometry", {
190
+ args: [coneWidth, coneLength, 24, 1]
191
+ }), /*#__PURE__*/React.createElement("meshBasicMaterial", {
192
+ transparent: true,
193
+ depthTest: depthTest,
194
+ color: color_,
195
+ opacity: opacity,
196
+ polygonOffset: true,
197
+ polygonOffsetFactor: -10,
198
+ fog: false
199
+ }))));
200
+ };
201
+
202
+ export { AxisArrow, calculateOffset };
@@ -0,0 +1,235 @@
1
+ import * as React from 'react';
2
+ import * as THREE from 'three';
3
+ import { useThree } from '@react-three/fiber';
4
+ import { Line } from '../../core/Line.js';
5
+ import { Html } from '../Html.js';
6
+ import clamp from 'lodash.clamp';
7
+ import { context } from './context.js';
8
+
9
+ const clickDir = new THREE.Vector3();
10
+ const intersectionDir = new THREE.Vector3();
11
+
12
+ const toDegrees = radians => radians * 180 / Math.PI;
13
+
14
+ const toRadians = degrees => degrees * Math.PI / 180;
15
+
16
+ const calculateAngle = (clickPoint, intersectionPoint, origin, e1, e2) => {
17
+ clickDir.copy(clickPoint).sub(origin);
18
+ intersectionDir.copy(intersectionPoint).sub(origin);
19
+ const dote1e1 = e1.dot(e1);
20
+ const dote2e2 = e2.dot(e2);
21
+ const uClick = clickDir.dot(e1) / dote1e1;
22
+ const vClick = clickDir.dot(e2) / dote2e2;
23
+ const uIntersection = intersectionDir.dot(e1) / dote1e1;
24
+ const vIntersection = intersectionDir.dot(e2) / dote2e2;
25
+ const angleClick = Math.atan2(vClick, uClick);
26
+ const angleIntersection = Math.atan2(vIntersection, uIntersection);
27
+ return angleIntersection - angleClick;
28
+ };
29
+
30
+ const fmod = (num, denom) => {
31
+ let k = Math.floor(num / denom);
32
+ k = k < 0 ? k + 1 : k;
33
+ return num - k * denom;
34
+ };
35
+
36
+ const minimizeAngle = angle => {
37
+ let result = fmod(angle, 2 * Math.PI);
38
+
39
+ if (Math.abs(result) < 1e-6) {
40
+ return 0.0;
41
+ }
42
+
43
+ if (result < 0.0) {
44
+ result += 2 * Math.PI;
45
+ }
46
+
47
+ return result;
48
+ };
49
+
50
+ const rotMatrix = new THREE.Matrix4();
51
+ const posNew = new THREE.Vector3();
52
+ const ray = new THREE.Ray();
53
+ const intersection = new THREE.Vector3();
54
+ const AxisRotator = ({
55
+ dir1,
56
+ dir2,
57
+ axis
58
+ }) => {
59
+ const {
60
+ rotationLimits,
61
+ annotations,
62
+ annotationsClass,
63
+ depthTest,
64
+ scale,
65
+ lineWidth,
66
+ fixed,
67
+ axisColors,
68
+ hoveredColor,
69
+ opacity,
70
+ onDragStart,
71
+ onDrag,
72
+ onDragEnd,
73
+ userData
74
+ } = React.useContext(context); // @ts-expect-error new in @react-three/fiber@7.0.5
75
+
76
+ const camControls = useThree(state => state.controls);
77
+ const divRef = React.useRef(null);
78
+ const objRef = React.useRef(null);
79
+ const angle0 = React.useRef(0);
80
+ const angle = React.useRef(0);
81
+ const clickInfo = React.useRef(null);
82
+ const [isHovered, setIsHovered] = React.useState(false);
83
+ const onPointerDown = React.useCallback(e => {
84
+ if (annotations) {
85
+ divRef.current.innerText = `${toDegrees(angle.current).toFixed(0)}º`;
86
+ divRef.current.style.display = 'block';
87
+ }
88
+
89
+ e.stopPropagation();
90
+ const clickPoint = e.point.clone();
91
+ const origin = new THREE.Vector3().setFromMatrixPosition(objRef.current.matrixWorld);
92
+ const e1 = new THREE.Vector3().setFromMatrixColumn(objRef.current.matrixWorld, 0).normalize();
93
+ const e2 = new THREE.Vector3().setFromMatrixColumn(objRef.current.matrixWorld, 1).normalize();
94
+ const normal = new THREE.Vector3().setFromMatrixColumn(objRef.current.matrixWorld, 2).normalize();
95
+ const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, origin);
96
+ clickInfo.current = {
97
+ clickPoint,
98
+ origin,
99
+ e1,
100
+ e2,
101
+ normal,
102
+ plane
103
+ };
104
+ onDragStart({
105
+ component: 'Rotator',
106
+ axis,
107
+ origin,
108
+ directions: [e1, e2, normal]
109
+ });
110
+ camControls && (camControls.enabled = false); // @ts-ignore
111
+
112
+ e.target.setPointerCapture(e.pointerId);
113
+ }, [annotations, camControls, onDragStart, axis]);
114
+ const onPointerMove = React.useCallback(e => {
115
+ e.stopPropagation();
116
+ if (!isHovered) setIsHovered(true);
117
+
118
+ if (clickInfo.current) {
119
+ const {
120
+ clickPoint,
121
+ origin,
122
+ e1,
123
+ e2,
124
+ normal,
125
+ plane
126
+ } = clickInfo.current;
127
+ const [min, max] = (rotationLimits == null ? void 0 : rotationLimits[axis]) || [undefined, undefined];
128
+ ray.copy(e.ray);
129
+ ray.intersectPlane(plane, intersection);
130
+ ray.direction.negate();
131
+ ray.intersectPlane(plane, intersection);
132
+ let deltaAngle = calculateAngle(clickPoint, intersection, origin, e1, e2);
133
+ let degrees = toDegrees(deltaAngle); // @ts-ignore
134
+
135
+ if (e.shiftKey) {
136
+ degrees = Math.round(degrees / 10) * 10;
137
+ deltaAngle = toRadians(degrees);
138
+ }
139
+
140
+ if (min !== undefined && max !== undefined && max - min < 2 * Math.PI) {
141
+ deltaAngle = minimizeAngle(deltaAngle);
142
+ deltaAngle = deltaAngle > Math.PI ? deltaAngle - 2 * Math.PI : deltaAngle;
143
+ deltaAngle = clamp(deltaAngle, min - angle0.current, max - angle0.current);
144
+ angle.current = angle0.current + deltaAngle;
145
+ } else {
146
+ angle.current = minimizeAngle(angle0.current + deltaAngle);
147
+ angle.current = angle.current > Math.PI ? angle.current - 2 * Math.PI : angle.current;
148
+ }
149
+
150
+ if (annotations) {
151
+ degrees = toDegrees(angle.current);
152
+ divRef.current.innerText = `${degrees.toFixed(0)}º`;
153
+ }
154
+
155
+ rotMatrix.makeRotationAxis(normal, deltaAngle);
156
+ posNew.copy(origin).applyMatrix4(rotMatrix).sub(origin).negate();
157
+ rotMatrix.setPosition(posNew);
158
+ onDrag(rotMatrix);
159
+ }
160
+ }, [annotations, onDrag, isHovered, rotationLimits, axis]);
161
+ const onPointerUp = React.useCallback(e => {
162
+ if (annotations) {
163
+ divRef.current.style.display = 'none';
164
+ }
165
+
166
+ e.stopPropagation();
167
+ angle0.current = angle.current;
168
+ clickInfo.current = null;
169
+ onDragEnd();
170
+ camControls && (camControls.enabled = true); // @ts-ignore
171
+
172
+ e.target.releasePointerCapture(e.pointerId);
173
+ }, [annotations, camControls, onDragEnd]);
174
+ const onPointerOut = React.useCallback(e => {
175
+ e.stopPropagation();
176
+ setIsHovered(false);
177
+ }, []);
178
+ const matrixL = React.useMemo(() => {
179
+ const dir1N = dir1.clone().normalize();
180
+ const dir2N = dir2.clone().normalize();
181
+ return new THREE.Matrix4().makeBasis(dir1N, dir2N, dir1N.clone().cross(dir2N));
182
+ }, [dir1, dir2]);
183
+ const r = fixed ? 0.65 : scale * 0.65;
184
+ const arc = React.useMemo(() => {
185
+ const segments = 32;
186
+ const points = [];
187
+
188
+ for (let j = 0; j <= segments; j++) {
189
+ const angle = j * (Math.PI / 2) / segments;
190
+ points.push(new THREE.Vector3(Math.cos(angle) * r, Math.sin(angle) * r, 0));
191
+ }
192
+
193
+ return points;
194
+ }, [r]);
195
+ return /*#__PURE__*/React.createElement("group", {
196
+ ref: objRef,
197
+ onPointerDown: onPointerDown,
198
+ onPointerMove: onPointerMove,
199
+ onPointerUp: onPointerUp,
200
+ onPointerOut: onPointerOut,
201
+ matrix: matrixL,
202
+ matrixAutoUpdate: false
203
+ }, annotations && /*#__PURE__*/React.createElement(Html, {
204
+ position: [r, r, 0]
205
+ }, /*#__PURE__*/React.createElement("div", {
206
+ style: {
207
+ display: 'none',
208
+ background: '#151520',
209
+ color: 'white',
210
+ padding: '6px 8px',
211
+ borderRadius: 7,
212
+ whiteSpace: 'nowrap'
213
+ },
214
+ className: annotationsClass,
215
+ ref: divRef
216
+ })), /*#__PURE__*/React.createElement(Line, {
217
+ points: arc,
218
+ lineWidth: lineWidth * 4,
219
+ visible: false,
220
+ userData: userData
221
+ }), /*#__PURE__*/React.createElement(Line, {
222
+ transparent: true,
223
+ raycast: () => null,
224
+ depthTest: depthTest,
225
+ points: arc,
226
+ lineWidth: lineWidth,
227
+ color: isHovered ? hoveredColor : axisColors[axis],
228
+ opacity: opacity,
229
+ polygonOffset: true,
230
+ polygonOffsetFactor: -10,
231
+ fog: false
232
+ }));
233
+ };
234
+
235
+ export { AxisRotator };
@@ -0,0 +1,211 @@
1
+ import * as React from 'react';
2
+ import * as THREE from 'three';
3
+ import { useThree } from '@react-three/fiber';
4
+ import { Line } from '../../core/Line.js';
5
+ import { Html } from '../Html.js';
6
+ import { context } from './context.js';
7
+
8
+ const decomposeIntoBasis = (e1, e2, offset) => {
9
+ const i1 = Math.abs(e1.x) >= Math.abs(e1.y) && Math.abs(e1.x) >= Math.abs(e1.z) ? 0 : Math.abs(e1.y) >= Math.abs(e1.x) && Math.abs(e1.y) >= Math.abs(e1.z) ? 1 : 2;
10
+ const e2DegrowthOrder = [0, 1, 2].sort((a, b) => Math.abs(e2.getComponent(b)) - Math.abs(e2.getComponent(a)));
11
+ const i2 = i1 === e2DegrowthOrder[0] ? e2DegrowthOrder[1] : e2DegrowthOrder[0];
12
+ const a1 = e1.getComponent(i1);
13
+ const a2 = e1.getComponent(i2);
14
+ const b1 = e2.getComponent(i1);
15
+ const b2 = e2.getComponent(i2);
16
+ const c1 = offset.getComponent(i1);
17
+ const c2 = offset.getComponent(i2);
18
+ const y = (c2 - c1 * (a2 / a1)) / (b2 - b1 * (a2 / a1));
19
+ const x = (c1 - y * b1) / a1;
20
+ return [x, y];
21
+ };
22
+
23
+ const ray = new THREE.Ray();
24
+ const intersection = new THREE.Vector3();
25
+ const offsetMatrix = new THREE.Matrix4();
26
+ const PlaneSlider = ({
27
+ dir1,
28
+ dir2,
29
+ axis
30
+ }) => {
31
+ const {
32
+ translation,
33
+ translationLimits,
34
+ annotations,
35
+ annotationsClass,
36
+ depthTest,
37
+ scale,
38
+ lineWidth,
39
+ fixed,
40
+ axisColors,
41
+ hoveredColor,
42
+ opacity,
43
+ onDragStart,
44
+ onDrag,
45
+ onDragEnd,
46
+ userData
47
+ } = React.useContext(context); // @ts-expect-error new in @react-three/fiber@7.0.5
48
+
49
+ const camControls = useThree(state => state.controls);
50
+ const divRef = React.useRef(null);
51
+ const objRef = React.useRef(null);
52
+ const clickInfo = React.useRef(null);
53
+ const offsetX0 = React.useRef(0);
54
+ const offsetY0 = React.useRef(0);
55
+ const [isHovered, setIsHovered] = React.useState(false);
56
+ const onPointerDown = React.useCallback(e => {
57
+ if (annotations) {
58
+ divRef.current.innerText = `${translation.current[(axis + 1) % 3].toFixed(2)}, ${translation.current[(axis + 2) % 3].toFixed(2)}`;
59
+ divRef.current.style.display = 'block';
60
+ }
61
+
62
+ e.stopPropagation();
63
+ const clickPoint = e.point.clone();
64
+ const origin = new THREE.Vector3().setFromMatrixPosition(objRef.current.matrixWorld);
65
+ const e1 = new THREE.Vector3().setFromMatrixColumn(objRef.current.matrixWorld, 0).normalize();
66
+ const e2 = new THREE.Vector3().setFromMatrixColumn(objRef.current.matrixWorld, 1).normalize();
67
+ const normal = new THREE.Vector3().setFromMatrixColumn(objRef.current.matrixWorld, 2).normalize();
68
+ const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, origin);
69
+ clickInfo.current = {
70
+ clickPoint,
71
+ e1,
72
+ e2,
73
+ plane
74
+ };
75
+ offsetX0.current = translation.current[(axis + 1) % 3];
76
+ offsetY0.current = translation.current[(axis + 2) % 3];
77
+ onDragStart({
78
+ component: 'Slider',
79
+ axis,
80
+ origin,
81
+ directions: [e1, e2, normal]
82
+ });
83
+ camControls && (camControls.enabled = false); // @ts-ignore
84
+
85
+ e.target.setPointerCapture(e.pointerId);
86
+ }, [annotations, camControls, onDragStart, axis]);
87
+ const onPointerMove = React.useCallback(e => {
88
+ e.stopPropagation();
89
+ if (!isHovered) setIsHovered(true);
90
+
91
+ if (clickInfo.current) {
92
+ const {
93
+ clickPoint,
94
+ e1,
95
+ e2,
96
+ plane
97
+ } = clickInfo.current;
98
+ const [minX, maxX] = (translationLimits == null ? void 0 : translationLimits[(axis + 1) % 3]) || [undefined, undefined];
99
+ const [minY, maxY] = (translationLimits == null ? void 0 : translationLimits[(axis + 2) % 3]) || [undefined, undefined];
100
+ ray.copy(e.ray);
101
+ ray.intersectPlane(plane, intersection);
102
+ ray.direction.negate();
103
+ ray.intersectPlane(plane, intersection);
104
+ intersection.sub(clickPoint);
105
+ let [offsetX, offsetY] = decomposeIntoBasis(e1, e2, intersection);
106
+ /* let offsetY = (intersection.y - (intersection.x * e1.y) / e1.x) / (e2.y - (e2.x * e1.y) / e1.x)
107
+ let offsetX = (intersection.x - offsetY * e2.x) / e1.x */
108
+
109
+ if (minX !== undefined) {
110
+ offsetX = Math.max(offsetX, minX - offsetX0.current);
111
+ }
112
+
113
+ if (maxX !== undefined) {
114
+ offsetX = Math.min(offsetX, maxX - offsetX0.current);
115
+ }
116
+
117
+ if (minY !== undefined) {
118
+ offsetY = Math.max(offsetY, minY - offsetY0.current);
119
+ }
120
+
121
+ if (maxY !== undefined) {
122
+ offsetY = Math.min(offsetY, maxY - offsetY0.current);
123
+ }
124
+
125
+ translation.current[(axis + 1) % 3] = offsetX0.current + offsetX;
126
+ translation.current[(axis + 2) % 3] = offsetY0.current + offsetY;
127
+
128
+ if (annotations) {
129
+ divRef.current.innerText = `${translation.current[(axis + 1) % 3].toFixed(2)}, ${translation.current[(axis + 2) % 3].toFixed(2)}`;
130
+ }
131
+
132
+ offsetMatrix.makeTranslation(offsetX * e1.x + offsetY * e2.x, offsetX * e1.y + offsetY * e2.y, offsetX * e1.z + offsetY * e2.z);
133
+ onDrag(offsetMatrix);
134
+ }
135
+ }, [annotations, onDrag, isHovered, translation, translationLimits, axis]);
136
+ const onPointerUp = React.useCallback(e => {
137
+ if (annotations) {
138
+ divRef.current.style.display = 'none';
139
+ }
140
+
141
+ e.stopPropagation();
142
+ clickInfo.current = null;
143
+ onDragEnd();
144
+ camControls && (camControls.enabled = true); // @ts-ignore
145
+
146
+ e.target.releasePointerCapture(e.pointerId);
147
+ }, [annotations, camControls, onDragEnd]);
148
+ const onPointerOut = React.useCallback(e => {
149
+ e.stopPropagation();
150
+ setIsHovered(false);
151
+ }, []);
152
+ const matrixL = React.useMemo(() => {
153
+ const dir1N = dir1.clone().normalize();
154
+ const dir2N = dir2.clone().normalize();
155
+ return new THREE.Matrix4().makeBasis(dir1N, dir2N, dir1N.clone().cross(dir2N));
156
+ }, [dir1, dir2]);
157
+ const pos1 = fixed ? 1 / 7 : scale / 7;
158
+ const length = fixed ? 0.225 : scale * 0.225;
159
+ const color = isHovered ? hoveredColor : axisColors[axis];
160
+ const points = React.useMemo(() => [new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, length, 0), new THREE.Vector3(length, length, 0), new THREE.Vector3(length, 0, 0), new THREE.Vector3(0, 0, 0)], [length]);
161
+ return /*#__PURE__*/React.createElement("group", {
162
+ ref: objRef,
163
+ matrix: matrixL,
164
+ matrixAutoUpdate: false
165
+ }, annotations && /*#__PURE__*/React.createElement(Html, {
166
+ position: [0, 0, 0]
167
+ }, /*#__PURE__*/React.createElement("div", {
168
+ style: {
169
+ display: 'none',
170
+ background: '#151520',
171
+ color: 'white',
172
+ padding: '6px 8px',
173
+ borderRadius: 7,
174
+ whiteSpace: 'nowrap'
175
+ },
176
+ className: annotationsClass,
177
+ ref: divRef
178
+ })), /*#__PURE__*/React.createElement("group", {
179
+ position: [pos1 * 1.7, pos1 * 1.7, 0]
180
+ }, /*#__PURE__*/React.createElement("mesh", {
181
+ visible: true,
182
+ onPointerDown: onPointerDown,
183
+ onPointerMove: onPointerMove,
184
+ onPointerUp: onPointerUp,
185
+ onPointerOut: onPointerOut,
186
+ scale: length,
187
+ userData: userData
188
+ }, /*#__PURE__*/React.createElement("planeGeometry", null), /*#__PURE__*/React.createElement("meshBasicMaterial", {
189
+ transparent: true,
190
+ depthTest: depthTest,
191
+ color: color,
192
+ polygonOffset: true,
193
+ polygonOffsetFactor: -10,
194
+ side: THREE.DoubleSide,
195
+ fog: false
196
+ })), /*#__PURE__*/React.createElement(Line, {
197
+ position: [-length / 2, -length / 2, 0],
198
+ transparent: true,
199
+ depthTest: depthTest,
200
+ points: points,
201
+ lineWidth: lineWidth,
202
+ color: color,
203
+ opacity: opacity,
204
+ polygonOffset: true,
205
+ polygonOffsetFactor: -10,
206
+ userData: userData,
207
+ fog: false
208
+ })));
209
+ };
210
+
211
+ export { PlaneSlider };
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+
3
+ const context = /*#__PURE__*/React.createContext(null);
4
+
5
+ export { context };