@react-three/drei 11.0.0-alpha.1 → 11.0.0-alpha.3

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 (119) hide show
  1. package/core/index.d.mts +1858 -0
  2. package/core/index.d.ts +1858 -0
  3. package/core/index.mjs +8559 -0
  4. package/experimental/index.d.mts +222 -0
  5. package/experimental/index.d.ts +222 -0
  6. package/experimental/index.mjs +353 -0
  7. package/external/index.d.mts +464 -0
  8. package/external/index.d.ts +464 -0
  9. package/external/index.mjs +5079 -0
  10. package/index.d.mts +1746 -2147
  11. package/index.d.ts +2166 -0
  12. package/index.mjs +12940 -19766
  13. package/legacy/index.d.mts +2350 -0
  14. package/legacy/index.d.ts +2350 -0
  15. package/legacy/index.mjs +12326 -0
  16. package/native/index.d.mts +2515 -0
  17. package/native/index.d.ts +2515 -0
  18. package/native/index.mjs +12383 -0
  19. package/package.json +18 -15
  20. package/webgpu/index.d.mts +2514 -0
  21. package/webgpu/index.d.ts +2514 -0
  22. package/webgpu/index.mjs +12547 -0
  23. package/_chunks/hls.mjs +0 -3
  24. package/_chunks/libs/@mediapipe/tasks-vision.mjs +0 -4781
  25. package/_chunks/libs/@monogrid/gainmap-js.mjs +0 -1137
  26. package/_chunks/libs/@use-gesture/core.mjs +0 -1650
  27. package/_chunks/libs/@use-gesture/react.mjs +0 -207
  28. package/_chunks/libs/camera-controls.mjs +0 -2207
  29. package/_chunks/libs/detect-gpu.mjs +0 -515
  30. package/_chunks/libs/hls.js.mjs +0 -21925
  31. package/_chunks/libs/maath.mjs +0 -5200
  32. package/_chunks/libs/stats-gl.mjs +0 -301
  33. package/_chunks/libs/stats.js.mjs +0 -90
  34. package/_chunks/libs/suspend-react.mjs +0 -60
  35. package/_chunks/libs/three.mjs +0 -23169
  36. package/_chunks/libs/tunnel-rat.mjs +0 -458
  37. package/_chunks/libs/zustand.mjs +0 -104
  38. package/_chunks/rolldown-runtime.mjs +0 -47
  39. package/_chunks/vision_bundle.mjs +0 -3
  40. package/core/_chunks/hls.mjs +0 -3
  41. package/core/_chunks/libs/@monogrid/gainmap-js.mjs +0 -1137
  42. package/core/_chunks/libs/@use-gesture/core.mjs +0 -1650
  43. package/core/_chunks/libs/@use-gesture/react.mjs +0 -207
  44. package/core/_chunks/libs/detect-gpu.mjs +0 -515
  45. package/core/_chunks/libs/hls.js.mjs +0 -21925
  46. package/core/_chunks/libs/maath.mjs +0 -5200
  47. package/core/_chunks/libs/stats-gl.mjs +0 -301
  48. package/core/_chunks/libs/stats.js.mjs +0 -90
  49. package/core/_chunks/libs/suspend-react.mjs +0 -60
  50. package/core/_chunks/libs/three.mjs +0 -22457
  51. package/core/_chunks/libs/tunnel-rat.mjs +0 -458
  52. package/core/_chunks/libs/zustand.mjs +0 -104
  53. package/core/_chunks/rolldown-runtime.mjs +0 -47
  54. package/core/core/index.d.mts +0 -2232
  55. package/core/core/index.mjs +0 -11082
  56. package/experimental/_chunks/libs/three.mjs +0 -15386
  57. package/experimental/experimental/index.d.mts +0 -253
  58. package/experimental/experimental/index.mjs +0 -434
  59. package/external/_chunks/hls.mjs +0 -3
  60. package/external/_chunks/libs/@mediapipe/tasks-vision.mjs +0 -4781
  61. package/external/_chunks/libs/camera-controls.mjs +0 -2207
  62. package/external/_chunks/libs/hls.js.mjs +0 -21925
  63. package/external/_chunks/libs/maath.mjs +0 -5200
  64. package/external/_chunks/libs/suspend-react.mjs +0 -58
  65. package/external/_chunks/libs/three.mjs +0 -15387
  66. package/external/_chunks/rolldown-runtime.mjs +0 -32
  67. package/external/_chunks/vision_bundle.mjs +0 -3
  68. package/external/external/index.d.mts +0 -499
  69. package/external/external/index.mjs +0 -9422
  70. package/legacy/_chunks/hls.mjs +0 -3
  71. package/legacy/_chunks/libs/@monogrid/gainmap-js.mjs +0 -1137
  72. package/legacy/_chunks/libs/@use-gesture/core.mjs +0 -1650
  73. package/legacy/_chunks/libs/@use-gesture/react.mjs +0 -207
  74. package/legacy/_chunks/libs/bidi-js.mjs +0 -675
  75. package/legacy/_chunks/libs/detect-gpu.mjs +0 -515
  76. package/legacy/_chunks/libs/hls.js.mjs +0 -21925
  77. package/legacy/_chunks/libs/maath.mjs +0 -5200
  78. package/legacy/_chunks/libs/stats-gl.mjs +0 -301
  79. package/legacy/_chunks/libs/stats.js.mjs +0 -90
  80. package/legacy/_chunks/libs/suspend-react.mjs +0 -60
  81. package/legacy/_chunks/libs/three.mjs +0 -26062
  82. package/legacy/_chunks/libs/troika-three-text.mjs +0 -6494
  83. package/legacy/_chunks/libs/tunnel-rat.mjs +0 -458
  84. package/legacy/_chunks/libs/zustand.mjs +0 -104
  85. package/legacy/_chunks/rolldown-runtime.mjs +0 -47
  86. package/legacy/legacy/index.d.mts +0 -2788
  87. package/legacy/legacy/index.mjs +0 -14984
  88. package/native/_chunks/hls.mjs +0 -3
  89. package/native/_chunks/libs/@monogrid/gainmap-js.mjs +0 -1137
  90. package/native/_chunks/libs/@use-gesture/core.mjs +0 -1650
  91. package/native/_chunks/libs/@use-gesture/react.mjs +0 -207
  92. package/native/_chunks/libs/detect-gpu.mjs +0 -515
  93. package/native/_chunks/libs/hls.js.mjs +0 -21925
  94. package/native/_chunks/libs/maath.mjs +0 -5200
  95. package/native/_chunks/libs/stats-gl.mjs +0 -301
  96. package/native/_chunks/libs/stats.js.mjs +0 -90
  97. package/native/_chunks/libs/suspend-react.mjs +0 -60
  98. package/native/_chunks/libs/three.mjs +0 -22592
  99. package/native/_chunks/libs/tunnel-rat.mjs +0 -458
  100. package/native/_chunks/libs/zustand.mjs +0 -104
  101. package/native/_chunks/rolldown-runtime.mjs +0 -47
  102. package/native/native/index.d.mts +0 -3168
  103. package/native/native/index.mjs +0 -14863
  104. package/webgpu/_chunks/hls.mjs +0 -3
  105. package/webgpu/_chunks/libs/@monogrid/gainmap-js.mjs +0 -1137
  106. package/webgpu/_chunks/libs/@use-gesture/core.mjs +0 -1650
  107. package/webgpu/_chunks/libs/@use-gesture/react.mjs +0 -207
  108. package/webgpu/_chunks/libs/detect-gpu.mjs +0 -515
  109. package/webgpu/_chunks/libs/hls.js.mjs +0 -21925
  110. package/webgpu/_chunks/libs/maath.mjs +0 -5200
  111. package/webgpu/_chunks/libs/stats-gl.mjs +0 -301
  112. package/webgpu/_chunks/libs/stats.js.mjs +0 -90
  113. package/webgpu/_chunks/libs/suspend-react.mjs +0 -60
  114. package/webgpu/_chunks/libs/three.mjs +0 -22592
  115. package/webgpu/_chunks/libs/tunnel-rat.mjs +0 -458
  116. package/webgpu/_chunks/libs/zustand.mjs +0 -104
  117. package/webgpu/_chunks/rolldown-runtime.mjs +0 -47
  118. package/webgpu/webgpu/index.d.mts +0 -3166
  119. package/webgpu/webgpu/index.mjs +0 -15015
@@ -1,2207 +0,0 @@
1
- import { t as __commonJSMin } from "../rolldown-runtime.mjs";
2
-
3
- //#region node_modules/camera-controls/dist/camera-controls.cjs
4
- /*!
5
- * camera-controls
6
- * https://github.com/yomotsu/camera-controls
7
- * (c) 2017 @yomotsu
8
- * Released under the MIT License.
9
- */
10
- var require_camera_controls = /* @__PURE__ */ __commonJSMin(((exports) => {
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const MOUSE_BUTTON = {
13
- LEFT: 1,
14
- RIGHT: 2,
15
- MIDDLE: 4
16
- };
17
- const ACTION = Object.freeze({
18
- NONE: 0,
19
- ROTATE: 1,
20
- TRUCK: 2,
21
- SCREEN_PAN: 4,
22
- OFFSET: 8,
23
- DOLLY: 16,
24
- ZOOM: 32,
25
- TOUCH_ROTATE: 64,
26
- TOUCH_TRUCK: 128,
27
- TOUCH_SCREEN_PAN: 256,
28
- TOUCH_OFFSET: 512,
29
- TOUCH_DOLLY: 1024,
30
- TOUCH_ZOOM: 2048,
31
- TOUCH_DOLLY_TRUCK: 4096,
32
- TOUCH_DOLLY_SCREEN_PAN: 8192,
33
- TOUCH_DOLLY_OFFSET: 16384,
34
- TOUCH_DOLLY_ROTATE: 32768,
35
- TOUCH_ZOOM_TRUCK: 65536,
36
- TOUCH_ZOOM_OFFSET: 131072,
37
- TOUCH_ZOOM_SCREEN_PAN: 262144,
38
- TOUCH_ZOOM_ROTATE: 524288
39
- });
40
- const DOLLY_DIRECTION = {
41
- NONE: 0,
42
- IN: 1,
43
- OUT: -1
44
- };
45
- function isPerspectiveCamera(camera) {
46
- return camera.isPerspectiveCamera;
47
- }
48
- function isOrthographicCamera(camera) {
49
- return camera.isOrthographicCamera;
50
- }
51
- const PI_2 = Math.PI * 2;
52
- const PI_HALF = Math.PI / 2;
53
- const EPSILON = 1e-5;
54
- const DEG2RAD = Math.PI / 180;
55
- function clamp(value, min, max) {
56
- return Math.max(min, Math.min(max, value));
57
- }
58
- function approxZero(number, error = EPSILON) {
59
- return Math.abs(number) < error;
60
- }
61
- function approxEquals(a, b, error = EPSILON) {
62
- return approxZero(a - b, error);
63
- }
64
- function roundToStep(value, step) {
65
- return Math.round(value / step) * step;
66
- }
67
- function infinityToMaxNumber(value) {
68
- if (isFinite(value)) return value;
69
- if (value < 0) return -Number.MAX_VALUE;
70
- return Number.MAX_VALUE;
71
- }
72
- function maxNumberToInfinity(value) {
73
- if (Math.abs(value) < Number.MAX_VALUE) return value;
74
- return value * Infinity;
75
- }
76
- function smoothDamp(current, target, currentVelocityRef, smoothTime, maxSpeed = Infinity, deltaTime) {
77
- smoothTime = Math.max(1e-4, smoothTime);
78
- const omega = 2 / smoothTime;
79
- const x = omega * deltaTime;
80
- const exp = 1 / (1 + x + .48 * x * x + .235 * x * x * x);
81
- let change = current - target;
82
- const originalTo = target;
83
- const maxChange = maxSpeed * smoothTime;
84
- change = clamp(change, -maxChange, maxChange);
85
- target = current - change;
86
- const temp = (currentVelocityRef.value + omega * change) * deltaTime;
87
- currentVelocityRef.value = (currentVelocityRef.value - omega * temp) * exp;
88
- let output = target + (change + temp) * exp;
89
- if (originalTo - current > 0 === output > originalTo) {
90
- output = originalTo;
91
- currentVelocityRef.value = (output - originalTo) / deltaTime;
92
- }
93
- return output;
94
- }
95
- function smoothDampVec3(current, target, currentVelocityRef, smoothTime, maxSpeed = Infinity, deltaTime, out) {
96
- smoothTime = Math.max(1e-4, smoothTime);
97
- const omega = 2 / smoothTime;
98
- const x = omega * deltaTime;
99
- const exp = 1 / (1 + x + .48 * x * x + .235 * x * x * x);
100
- let targetX = target.x;
101
- let targetY = target.y;
102
- let targetZ = target.z;
103
- let changeX = current.x - targetX;
104
- let changeY = current.y - targetY;
105
- let changeZ = current.z - targetZ;
106
- const originalToX = targetX;
107
- const originalToY = targetY;
108
- const originalToZ = targetZ;
109
- const maxChange = maxSpeed * smoothTime;
110
- const maxChangeSq = maxChange * maxChange;
111
- const magnitudeSq = changeX * changeX + changeY * changeY + changeZ * changeZ;
112
- if (magnitudeSq > maxChangeSq) {
113
- const magnitude = Math.sqrt(magnitudeSq);
114
- changeX = changeX / magnitude * maxChange;
115
- changeY = changeY / magnitude * maxChange;
116
- changeZ = changeZ / magnitude * maxChange;
117
- }
118
- targetX = current.x - changeX;
119
- targetY = current.y - changeY;
120
- targetZ = current.z - changeZ;
121
- const tempX = (currentVelocityRef.x + omega * changeX) * deltaTime;
122
- const tempY = (currentVelocityRef.y + omega * changeY) * deltaTime;
123
- const tempZ = (currentVelocityRef.z + omega * changeZ) * deltaTime;
124
- currentVelocityRef.x = (currentVelocityRef.x - omega * tempX) * exp;
125
- currentVelocityRef.y = (currentVelocityRef.y - omega * tempY) * exp;
126
- currentVelocityRef.z = (currentVelocityRef.z - omega * tempZ) * exp;
127
- out.x = targetX + (changeX + tempX) * exp;
128
- out.y = targetY + (changeY + tempY) * exp;
129
- out.z = targetZ + (changeZ + tempZ) * exp;
130
- const origMinusCurrentX = originalToX - current.x;
131
- const origMinusCurrentY = originalToY - current.y;
132
- const origMinusCurrentZ = originalToZ - current.z;
133
- const outMinusOrigX = out.x - originalToX;
134
- const outMinusOrigY = out.y - originalToY;
135
- const outMinusOrigZ = out.z - originalToZ;
136
- if (origMinusCurrentX * outMinusOrigX + origMinusCurrentY * outMinusOrigY + origMinusCurrentZ * outMinusOrigZ > 0) {
137
- out.x = originalToX;
138
- out.y = originalToY;
139
- out.z = originalToZ;
140
- currentVelocityRef.x = (out.x - originalToX) / deltaTime;
141
- currentVelocityRef.y = (out.y - originalToY) / deltaTime;
142
- currentVelocityRef.z = (out.z - originalToZ) / deltaTime;
143
- }
144
- return out;
145
- }
146
- function extractClientCoordFromEvent(pointers, out) {
147
- out.set(0, 0);
148
- pointers.forEach((pointer) => {
149
- out.x += pointer.clientX;
150
- out.y += pointer.clientY;
151
- });
152
- out.x /= pointers.length;
153
- out.y /= pointers.length;
154
- }
155
- function notSupportedInOrthographicCamera(camera, message) {
156
- if (isOrthographicCamera(camera)) {
157
- console.warn(`${message} is not supported in OrthographicCamera`);
158
- return true;
159
- }
160
- return false;
161
- }
162
- var EventDispatcher = class {
163
- constructor() {
164
- this._listeners = {};
165
- }
166
- /**
167
- * Adds the specified event listener.
168
- * @param type event name
169
- * @param listener handler function
170
- * @category Methods
171
- */
172
- addEventListener(type, listener) {
173
- const listeners = this._listeners;
174
- if (listeners[type] === void 0) listeners[type] = [];
175
- if (listeners[type].indexOf(listener) === -1) listeners[type].push(listener);
176
- }
177
- /**
178
- * Presence of the specified event listener.
179
- * @param type event name
180
- * @param listener handler function
181
- * @category Methods
182
- */
183
- hasEventListener(type, listener) {
184
- const listeners = this._listeners;
185
- return listeners[type] !== void 0 && listeners[type].indexOf(listener) !== -1;
186
- }
187
- /**
188
- * Removes the specified event listener
189
- * @param type event name
190
- * @param listener handler function
191
- * @category Methods
192
- */
193
- removeEventListener(type, listener) {
194
- const listenerArray = this._listeners[type];
195
- if (listenerArray !== void 0) {
196
- const index = listenerArray.indexOf(listener);
197
- if (index !== -1) listenerArray.splice(index, 1);
198
- }
199
- }
200
- /**
201
- * Removes all event listeners
202
- * @param type event name
203
- * @category Methods
204
- */
205
- removeAllEventListeners(type) {
206
- if (!type) {
207
- this._listeners = {};
208
- return;
209
- }
210
- if (Array.isArray(this._listeners[type])) this._listeners[type].length = 0;
211
- }
212
- /**
213
- * Fire an event type.
214
- * @param event DispatcherEvent
215
- * @category Methods
216
- */
217
- dispatchEvent(event) {
218
- const listenerArray = this._listeners[event.type];
219
- if (listenerArray !== void 0) {
220
- event.target = this;
221
- const array = listenerArray.slice(0);
222
- for (let i = 0, l = array.length; i < l; i++) array[i].call(this, event);
223
- }
224
- }
225
- };
226
- var _a;
227
- const VERSION = "3.1.0";
228
- const TOUCH_DOLLY_FACTOR = 1 / 8;
229
- const isMac = /Mac/.test((_a = globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator) === null || _a === void 0 ? void 0 : _a.platform);
230
- let THREE;
231
- let _ORIGIN;
232
- let _AXIS_Y;
233
- let _AXIS_Z;
234
- let _v2;
235
- let _v3A;
236
- let _v3B;
237
- let _v3C;
238
- let _cameraDirection;
239
- let _xColumn;
240
- let _yColumn;
241
- let _zColumn;
242
- let _deltaTarget;
243
- let _deltaOffset;
244
- let _sphericalA;
245
- let _sphericalB;
246
- let _box3A;
247
- let _box3B;
248
- let _sphere;
249
- let _quaternionA;
250
- let _quaternionB;
251
- let _rotationMatrix;
252
- let _raycaster;
253
- var CameraControls = class CameraControls extends EventDispatcher {
254
- /**
255
- * Injects THREE as the dependency. You can then proceed to use CameraControls.
256
- *
257
- * e.g
258
- * ```javascript
259
- * CameraControls.install( { THREE: THREE } );
260
- * ```
261
- *
262
- * Note: If you do not wish to use enter three.js to reduce file size(tree-shaking for example), make a subset to install.
263
- *
264
- * ```js
265
- * import {
266
- * Vector2,
267
- * Vector3,
268
- * Vector4,
269
- * Quaternion,
270
- * Matrix4,
271
- * Spherical,
272
- * Box3,
273
- * Sphere,
274
- * Raycaster,
275
- * MathUtils,
276
- * } from 'three';
277
- *
278
- * const subsetOfTHREE = {
279
- * Vector2 : Vector2,
280
- * Vector3 : Vector3,
281
- * Vector4 : Vector4,
282
- * Quaternion: Quaternion,
283
- * Matrix4 : Matrix4,
284
- * Spherical : Spherical,
285
- * Box3 : Box3,
286
- * Sphere : Sphere,
287
- * Raycaster : Raycaster,
288
- * };
289
-
290
- * CameraControls.install( { THREE: subsetOfTHREE } );
291
- * ```
292
- * @category Statics
293
- */
294
- static install(libs) {
295
- THREE = libs.THREE;
296
- _ORIGIN = Object.freeze(new THREE.Vector3(0, 0, 0));
297
- _AXIS_Y = Object.freeze(new THREE.Vector3(0, 1, 0));
298
- _AXIS_Z = Object.freeze(new THREE.Vector3(0, 0, 1));
299
- _v2 = new THREE.Vector2();
300
- _v3A = new THREE.Vector3();
301
- _v3B = new THREE.Vector3();
302
- _v3C = new THREE.Vector3();
303
- _cameraDirection = new THREE.Vector3();
304
- _xColumn = new THREE.Vector3();
305
- _yColumn = new THREE.Vector3();
306
- _zColumn = new THREE.Vector3();
307
- _deltaTarget = new THREE.Vector3();
308
- _deltaOffset = new THREE.Vector3();
309
- _sphericalA = new THREE.Spherical();
310
- _sphericalB = new THREE.Spherical();
311
- _box3A = new THREE.Box3();
312
- _box3B = new THREE.Box3();
313
- _sphere = new THREE.Sphere();
314
- _quaternionA = new THREE.Quaternion();
315
- _quaternionB = new THREE.Quaternion();
316
- _rotationMatrix = new THREE.Matrix4();
317
- _raycaster = new THREE.Raycaster();
318
- }
319
- /**
320
- * list all ACTIONs
321
- * @category Statics
322
- */
323
- static get ACTION() {
324
- return ACTION;
325
- }
326
- /**
327
- * @deprecated Use `cameraControls.mouseButtons.left = CameraControls.ACTION.SCREEN_PAN` instead.
328
- */
329
- set verticalDragToForward(_) {
330
- console.warn("camera-controls: `verticalDragToForward` was removed. Use `mouseButtons.left = CameraControls.ACTION.SCREEN_PAN` instead.");
331
- }
332
- /**
333
- * Creates a `CameraControls` instance.
334
- *
335
- * Note:
336
- * You **must install** three.js before using camera-controls. see [#install](#install)
337
- * Not doing so will lead to runtime errors (`undefined` references to THREE).
338
- *
339
- * e.g.
340
- * ```
341
- * CameraControls.install( { THREE } );
342
- * const cameraControls = new CameraControls( camera, domElement );
343
- * ```
344
- *
345
- * @param camera A `THREE.PerspectiveCamera` or `THREE.OrthographicCamera` to be controlled.
346
- * @param domElement A `HTMLElement` for the draggable area, usually `renderer.domElement`.
347
- * @category Constructor
348
- */
349
- constructor(camera, domElement) {
350
- super();
351
- /**
352
- * Minimum vertical angle in radians.
353
- * The angle has to be between `0` and `.maxPolarAngle` inclusive.
354
- * The default value is `0`.
355
- *
356
- * e.g.
357
- * ```
358
- * cameraControls.maxPolarAngle = 0;
359
- * ```
360
- * @category Properties
361
- */
362
- this.minPolarAngle = 0;
363
- /**
364
- * Maximum vertical angle in radians.
365
- * The angle has to be between `.maxPolarAngle` and `Math.PI` inclusive.
366
- * The default value is `Math.PI`.
367
- *
368
- * e.g.
369
- * ```
370
- * cameraControls.maxPolarAngle = Math.PI;
371
- * ```
372
- * @category Properties
373
- */
374
- this.maxPolarAngle = Math.PI;
375
- /**
376
- * Minimum horizontal angle in radians.
377
- * The angle has to be less than `.maxAzimuthAngle`.
378
- * The default value is `- Infinity`.
379
- *
380
- * e.g.
381
- * ```
382
- * cameraControls.minAzimuthAngle = - Infinity;
383
- * ```
384
- * @category Properties
385
- */
386
- this.minAzimuthAngle = -Infinity;
387
- /**
388
- * Maximum horizontal angle in radians.
389
- * The angle has to be greater than `.minAzimuthAngle`.
390
- * The default value is `Infinity`.
391
- *
392
- * e.g.
393
- * ```
394
- * cameraControls.maxAzimuthAngle = Infinity;
395
- * ```
396
- * @category Properties
397
- */
398
- this.maxAzimuthAngle = Infinity;
399
- /**
400
- * Minimum distance for dolly. The value must be higher than `0`. Default is `Number.EPSILON`.
401
- * PerspectiveCamera only.
402
- * @category Properties
403
- */
404
- this.minDistance = Number.EPSILON;
405
- /**
406
- * Maximum distance for dolly. The value must be higher than `minDistance`. Default is `Infinity`.
407
- * PerspectiveCamera only.
408
- * @category Properties
409
- */
410
- this.maxDistance = Infinity;
411
- /**
412
- * `true` to enable Infinity Dolly for wheel and pinch. Use this with `minDistance` and `maxDistance`
413
- * If the Dolly distance is less (or over) than the `minDistance` (or `maxDistance`), `infinityDolly` will keep the distance and pushes the target position instead.
414
- * @category Properties
415
- */
416
- this.infinityDolly = false;
417
- /**
418
- * Minimum camera zoom.
419
- * @category Properties
420
- */
421
- this.minZoom = .01;
422
- /**
423
- * Maximum camera zoom.
424
- * @category Properties
425
- */
426
- this.maxZoom = Infinity;
427
- /**
428
- * Approximate time in seconds to reach the target. A smaller value will reach the target faster.
429
- * @category Properties
430
- */
431
- this.smoothTime = .25;
432
- /**
433
- * the smoothTime while dragging
434
- * @category Properties
435
- */
436
- this.draggingSmoothTime = .125;
437
- /**
438
- * Max transition speed in unit-per-seconds
439
- * @category Properties
440
- */
441
- this.maxSpeed = Infinity;
442
- /**
443
- * Speed of azimuth (horizontal) rotation.
444
- * @category Properties
445
- */
446
- this.azimuthRotateSpeed = 1;
447
- /**
448
- * Speed of polar (vertical) rotation.
449
- * @category Properties
450
- */
451
- this.polarRotateSpeed = 1;
452
- /**
453
- * Speed of mouse-wheel dollying.
454
- * @category Properties
455
- */
456
- this.dollySpeed = 1;
457
- /**
458
- * `true` to invert direction when dollying or zooming via drag
459
- * @category Properties
460
- */
461
- this.dollyDragInverted = false;
462
- /**
463
- * Speed of drag for truck and pedestal.
464
- * @category Properties
465
- */
466
- this.truckSpeed = 2;
467
- /**
468
- * `true` to enable Dolly-in to the mouse cursor coords.
469
- * @category Properties
470
- */
471
- this.dollyToCursor = false;
472
- /**
473
- * @category Properties
474
- */
475
- this.dragToOffset = false;
476
- /**
477
- * Friction ratio of the boundary.
478
- * @category Properties
479
- */
480
- this.boundaryFriction = 0;
481
- /**
482
- * Controls how soon the `rest` event fires as the camera slows.
483
- * @category Properties
484
- */
485
- this.restThreshold = .01;
486
- /**
487
- * An array of Meshes to collide with camera.
488
- * Be aware colliderMeshes may decrease performance. The collision test uses 4 raycasters from the camera since the near plane has 4 corners.
489
- * @category Properties
490
- */
491
- this.colliderMeshes = [];
492
- /**
493
- * Force cancel user dragging.
494
- * @category Methods
495
- */
496
- this.cancel = () => {};
497
- this._enabled = true;
498
- this._state = ACTION.NONE;
499
- this._viewport = null;
500
- this._changedDolly = 0;
501
- this._changedZoom = 0;
502
- this._hasRested = true;
503
- this._boundaryEnclosesCamera = false;
504
- this._needsUpdate = true;
505
- this._updatedLastTime = false;
506
- this._elementRect = new DOMRect();
507
- this._isDragging = false;
508
- this._dragNeedsUpdate = true;
509
- this._activePointers = [];
510
- this._lockedPointer = null;
511
- this._interactiveArea = new DOMRect(0, 0, 1, 1);
512
- this._isUserControllingRotate = false;
513
- this._isUserControllingDolly = false;
514
- this._isUserControllingTruck = false;
515
- this._isUserControllingOffset = false;
516
- this._isUserControllingZoom = false;
517
- this._lastDollyDirection = DOLLY_DIRECTION.NONE;
518
- this._thetaVelocity = { value: 0 };
519
- this._phiVelocity = { value: 0 };
520
- this._radiusVelocity = { value: 0 };
521
- this._targetVelocity = new THREE.Vector3();
522
- this._focalOffsetVelocity = new THREE.Vector3();
523
- this._zoomVelocity = { value: 0 };
524
- this._truckInternal = (deltaX, deltaY, dragToOffset, screenSpacePanning) => {
525
- let truckX;
526
- let pedestalY;
527
- if (isPerspectiveCamera(this._camera)) {
528
- const offset = _v3A.copy(this._camera.position).sub(this._target);
529
- const fov = this._camera.getEffectiveFOV() * DEG2RAD;
530
- const targetDistance = offset.length() * Math.tan(fov * .5);
531
- truckX = this.truckSpeed * deltaX * targetDistance / this._elementRect.height;
532
- pedestalY = this.truckSpeed * deltaY * targetDistance / this._elementRect.height;
533
- } else if (isOrthographicCamera(this._camera)) {
534
- const camera$1 = this._camera;
535
- truckX = this.truckSpeed * deltaX * (camera$1.right - camera$1.left) / camera$1.zoom / this._elementRect.width;
536
- pedestalY = this.truckSpeed * deltaY * (camera$1.top - camera$1.bottom) / camera$1.zoom / this._elementRect.height;
537
- } else return;
538
- if (screenSpacePanning) {
539
- dragToOffset ? this.setFocalOffset(this._focalOffsetEnd.x + truckX, this._focalOffsetEnd.y, this._focalOffsetEnd.z, true) : this.truck(truckX, 0, true);
540
- this.forward(-pedestalY, true);
541
- } else dragToOffset ? this.setFocalOffset(this._focalOffsetEnd.x + truckX, this._focalOffsetEnd.y + pedestalY, this._focalOffsetEnd.z, true) : this.truck(truckX, pedestalY, true);
542
- };
543
- this._rotateInternal = (deltaX, deltaY) => {
544
- const theta = PI_2 * this.azimuthRotateSpeed * deltaX / this._elementRect.height;
545
- const phi = PI_2 * this.polarRotateSpeed * deltaY / this._elementRect.height;
546
- this.rotate(theta, phi, true);
547
- };
548
- this._dollyInternal = (delta, x, y) => {
549
- const dollyScale = Math.pow(.95, -delta * this.dollySpeed);
550
- const lastDistance = this._sphericalEnd.radius;
551
- const distance = this._sphericalEnd.radius * dollyScale;
552
- const clampedDistance = clamp(distance, this.minDistance, this.maxDistance);
553
- const overflowedDistance = clampedDistance - distance;
554
- if (this.infinityDolly && this.dollyToCursor) this._dollyToNoClamp(distance, true);
555
- else if (this.infinityDolly && !this.dollyToCursor) {
556
- this.dollyInFixed(overflowedDistance, true);
557
- this._dollyToNoClamp(clampedDistance, true);
558
- } else this._dollyToNoClamp(clampedDistance, true);
559
- if (this.dollyToCursor) {
560
- this._changedDolly += (this.infinityDolly ? distance : clampedDistance) - lastDistance;
561
- this._dollyControlCoord.set(x, y);
562
- }
563
- this._lastDollyDirection = Math.sign(-delta);
564
- };
565
- this._zoomInternal = (delta, x, y) => {
566
- const zoomScale = Math.pow(.95, delta * this.dollySpeed);
567
- const lastZoom = this._zoom;
568
- const zoom = this._zoom * zoomScale;
569
- this.zoomTo(zoom, true);
570
- if (this.dollyToCursor) {
571
- this._changedZoom += zoom - lastZoom;
572
- this._dollyControlCoord.set(x, y);
573
- }
574
- };
575
- if (typeof THREE === "undefined") console.error("camera-controls: `THREE` is undefined. You must first run `CameraControls.install( { THREE: THREE } )`. Check the docs for further information.");
576
- this._camera = camera;
577
- this._yAxisUpSpace = new THREE.Quaternion().setFromUnitVectors(this._camera.up, _AXIS_Y);
578
- this._yAxisUpSpaceInverse = this._yAxisUpSpace.clone().invert();
579
- this._state = ACTION.NONE;
580
- this._target = new THREE.Vector3();
581
- this._targetEnd = this._target.clone();
582
- this._focalOffset = new THREE.Vector3();
583
- this._focalOffsetEnd = this._focalOffset.clone();
584
- this._spherical = new THREE.Spherical().setFromVector3(_v3A.copy(this._camera.position).applyQuaternion(this._yAxisUpSpace));
585
- this._sphericalEnd = this._spherical.clone();
586
- this._lastDistance = this._spherical.radius;
587
- this._zoom = this._camera.zoom;
588
- this._zoomEnd = this._zoom;
589
- this._lastZoom = this._zoom;
590
- this._nearPlaneCorners = [
591
- new THREE.Vector3(),
592
- new THREE.Vector3(),
593
- new THREE.Vector3(),
594
- new THREE.Vector3()
595
- ];
596
- this._updateNearPlaneCorners();
597
- this._boundary = new THREE.Box3(new THREE.Vector3(-Infinity, -Infinity, -Infinity), new THREE.Vector3(Infinity, Infinity, Infinity));
598
- this._cameraUp0 = this._camera.up.clone();
599
- this._target0 = this._target.clone();
600
- this._position0 = this._camera.position.clone();
601
- this._zoom0 = this._zoom;
602
- this._focalOffset0 = this._focalOffset.clone();
603
- this._dollyControlCoord = new THREE.Vector2();
604
- this.mouseButtons = {
605
- left: ACTION.ROTATE,
606
- middle: ACTION.DOLLY,
607
- right: ACTION.TRUCK,
608
- wheel: isPerspectiveCamera(this._camera) ? ACTION.DOLLY : isOrthographicCamera(this._camera) ? ACTION.ZOOM : ACTION.NONE
609
- };
610
- this.touches = {
611
- one: ACTION.TOUCH_ROTATE,
612
- two: isPerspectiveCamera(this._camera) ? ACTION.TOUCH_DOLLY_TRUCK : isOrthographicCamera(this._camera) ? ACTION.TOUCH_ZOOM_TRUCK : ACTION.NONE,
613
- three: ACTION.TOUCH_TRUCK
614
- };
615
- const dragStartPosition = new THREE.Vector2();
616
- const lastDragPosition = new THREE.Vector2();
617
- const dollyStart = new THREE.Vector2();
618
- const onPointerDown = (event) => {
619
- if (!this._enabled || !this._domElement) return;
620
- if (this._interactiveArea.left !== 0 || this._interactiveArea.top !== 0 || this._interactiveArea.width !== 1 || this._interactiveArea.height !== 1) {
621
- const elRect = this._domElement.getBoundingClientRect();
622
- const left = event.clientX / elRect.width;
623
- const top = event.clientY / elRect.height;
624
- if (left < this._interactiveArea.left || left > this._interactiveArea.right || top < this._interactiveArea.top || top > this._interactiveArea.bottom) return;
625
- }
626
- const mouseButton = event.pointerType !== "mouse" ? null : (event.buttons & MOUSE_BUTTON.LEFT) === MOUSE_BUTTON.LEFT ? MOUSE_BUTTON.LEFT : (event.buttons & MOUSE_BUTTON.MIDDLE) === MOUSE_BUTTON.MIDDLE ? MOUSE_BUTTON.MIDDLE : (event.buttons & MOUSE_BUTTON.RIGHT) === MOUSE_BUTTON.RIGHT ? MOUSE_BUTTON.RIGHT : null;
627
- if (mouseButton !== null) {
628
- const zombiePointer = this._findPointerByMouseButton(mouseButton);
629
- zombiePointer && this._disposePointer(zombiePointer);
630
- }
631
- if ((event.buttons & MOUSE_BUTTON.LEFT) === MOUSE_BUTTON.LEFT && this._lockedPointer) return;
632
- const pointer = {
633
- pointerId: event.pointerId,
634
- clientX: event.clientX,
635
- clientY: event.clientY,
636
- deltaX: 0,
637
- deltaY: 0,
638
- mouseButton
639
- };
640
- this._activePointers.push(pointer);
641
- this._domElement.ownerDocument.removeEventListener("pointermove", onPointerMove, { passive: false });
642
- this._domElement.ownerDocument.removeEventListener("pointerup", onPointerUp);
643
- this._domElement.ownerDocument.addEventListener("pointermove", onPointerMove, { passive: false });
644
- this._domElement.ownerDocument.addEventListener("pointerup", onPointerUp);
645
- this._isDragging = true;
646
- startDragging(event);
647
- };
648
- const onPointerMove = (event) => {
649
- if (event.cancelable) event.preventDefault();
650
- const pointerId = event.pointerId;
651
- const pointer = this._lockedPointer || this._findPointerById(pointerId);
652
- if (!pointer) return;
653
- pointer.clientX = event.clientX;
654
- pointer.clientY = event.clientY;
655
- pointer.deltaX = event.movementX;
656
- pointer.deltaY = event.movementY;
657
- this._state = 0;
658
- if (event.pointerType === "touch") switch (this._activePointers.length) {
659
- case 1:
660
- this._state = this.touches.one;
661
- break;
662
- case 2:
663
- this._state = this.touches.two;
664
- break;
665
- case 3:
666
- this._state = this.touches.three;
667
- break;
668
- }
669
- else {
670
- if (!this._isDragging && this._lockedPointer || this._isDragging && (event.buttons & MOUSE_BUTTON.LEFT) === MOUSE_BUTTON.LEFT) this._state = this._state | this.mouseButtons.left;
671
- if (this._isDragging && (event.buttons & MOUSE_BUTTON.MIDDLE) === MOUSE_BUTTON.MIDDLE) this._state = this._state | this.mouseButtons.middle;
672
- if (this._isDragging && (event.buttons & MOUSE_BUTTON.RIGHT) === MOUSE_BUTTON.RIGHT) this._state = this._state | this.mouseButtons.right;
673
- }
674
- dragging();
675
- };
676
- const onPointerUp = (event) => {
677
- const pointer = this._findPointerById(event.pointerId);
678
- if (pointer && pointer === this._lockedPointer) return;
679
- pointer && this._disposePointer(pointer);
680
- if (event.pointerType === "touch") switch (this._activePointers.length) {
681
- case 0:
682
- this._state = ACTION.NONE;
683
- break;
684
- case 1:
685
- this._state = this.touches.one;
686
- break;
687
- case 2:
688
- this._state = this.touches.two;
689
- break;
690
- case 3:
691
- this._state = this.touches.three;
692
- break;
693
- }
694
- else this._state = ACTION.NONE;
695
- endDragging();
696
- };
697
- let lastScrollTimeStamp = -1;
698
- const onMouseWheel = (event) => {
699
- if (!this._domElement) return;
700
- if (!this._enabled || this.mouseButtons.wheel === ACTION.NONE) return;
701
- if (this._interactiveArea.left !== 0 || this._interactiveArea.top !== 0 || this._interactiveArea.width !== 1 || this._interactiveArea.height !== 1) {
702
- const elRect = this._domElement.getBoundingClientRect();
703
- const left = event.clientX / elRect.width;
704
- const top = event.clientY / elRect.height;
705
- if (left < this._interactiveArea.left || left > this._interactiveArea.right || top < this._interactiveArea.top || top > this._interactiveArea.bottom) return;
706
- }
707
- event.preventDefault();
708
- if (this.dollyToCursor || this.mouseButtons.wheel === ACTION.ROTATE || this.mouseButtons.wheel === ACTION.TRUCK) {
709
- const now = performance.now();
710
- if (lastScrollTimeStamp - now < 1e3) this._getClientRect(this._elementRect);
711
- lastScrollTimeStamp = now;
712
- }
713
- const deltaYFactor = isMac ? -1 : -3;
714
- const delta = event.deltaMode === 1 || event.ctrlKey ? event.deltaY / deltaYFactor : event.deltaY / (deltaYFactor * 10);
715
- const x = this.dollyToCursor ? (event.clientX - this._elementRect.x) / this._elementRect.width * 2 - 1 : 0;
716
- const y = this.dollyToCursor ? (event.clientY - this._elementRect.y) / this._elementRect.height * -2 + 1 : 0;
717
- switch (this.mouseButtons.wheel) {
718
- case ACTION.ROTATE:
719
- this._rotateInternal(event.deltaX, event.deltaY);
720
- this._isUserControllingRotate = true;
721
- break;
722
- case ACTION.TRUCK:
723
- this._truckInternal(event.deltaX, event.deltaY, false, false);
724
- this._isUserControllingTruck = true;
725
- break;
726
- case ACTION.SCREEN_PAN:
727
- this._truckInternal(event.deltaX, event.deltaY, false, true);
728
- this._isUserControllingTruck = true;
729
- break;
730
- case ACTION.OFFSET:
731
- this._truckInternal(event.deltaX, event.deltaY, true, false);
732
- this._isUserControllingOffset = true;
733
- break;
734
- case ACTION.DOLLY:
735
- this._dollyInternal(-delta, x, y);
736
- this._isUserControllingDolly = true;
737
- break;
738
- case ACTION.ZOOM:
739
- this._zoomInternal(-delta, x, y);
740
- this._isUserControllingZoom = true;
741
- break;
742
- }
743
- this.dispatchEvent({ type: "control" });
744
- };
745
- const onContextMenu = (event) => {
746
- if (!this._domElement || !this._enabled) return;
747
- if (this.mouseButtons.right === CameraControls.ACTION.NONE) {
748
- const pointerId = event instanceof PointerEvent ? event.pointerId : 0;
749
- const pointer = this._findPointerById(pointerId);
750
- pointer && this._disposePointer(pointer);
751
- this._domElement.ownerDocument.removeEventListener("pointermove", onPointerMove, { passive: false });
752
- this._domElement.ownerDocument.removeEventListener("pointerup", onPointerUp);
753
- return;
754
- }
755
- event.preventDefault();
756
- };
757
- const startDragging = (event) => {
758
- if (!this._enabled) return;
759
- extractClientCoordFromEvent(this._activePointers, _v2);
760
- this._getClientRect(this._elementRect);
761
- dragStartPosition.copy(_v2);
762
- lastDragPosition.copy(_v2);
763
- if (this._activePointers.length >= 2) {
764
- const dx = _v2.x - this._activePointers[1].clientX;
765
- const dy = _v2.y - this._activePointers[1].clientY;
766
- const distance = Math.sqrt(dx * dx + dy * dy);
767
- dollyStart.set(0, distance);
768
- const x = (this._activePointers[0].clientX + this._activePointers[1].clientX) * .5;
769
- const y = (this._activePointers[0].clientY + this._activePointers[1].clientY) * .5;
770
- lastDragPosition.set(x, y);
771
- }
772
- this._state = 0;
773
- if (!event) {
774
- if (this._lockedPointer) this._state = this._state | this.mouseButtons.left;
775
- } else if ("pointerType" in event && event.pointerType === "touch") switch (this._activePointers.length) {
776
- case 1:
777
- this._state = this.touches.one;
778
- break;
779
- case 2:
780
- this._state = this.touches.two;
781
- break;
782
- case 3:
783
- this._state = this.touches.three;
784
- break;
785
- }
786
- else {
787
- if (!this._lockedPointer && (event.buttons & MOUSE_BUTTON.LEFT) === MOUSE_BUTTON.LEFT) this._state = this._state | this.mouseButtons.left;
788
- if ((event.buttons & MOUSE_BUTTON.MIDDLE) === MOUSE_BUTTON.MIDDLE) this._state = this._state | this.mouseButtons.middle;
789
- if ((event.buttons & MOUSE_BUTTON.RIGHT) === MOUSE_BUTTON.RIGHT) this._state = this._state | this.mouseButtons.right;
790
- }
791
- if ((this._state & ACTION.ROTATE) === ACTION.ROTATE || (this._state & ACTION.TOUCH_ROTATE) === ACTION.TOUCH_ROTATE || (this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE || (this._state & ACTION.TOUCH_ZOOM_ROTATE) === ACTION.TOUCH_ZOOM_ROTATE) {
792
- this._sphericalEnd.theta = this._spherical.theta;
793
- this._sphericalEnd.phi = this._spherical.phi;
794
- this._thetaVelocity.value = 0;
795
- this._phiVelocity.value = 0;
796
- }
797
- if ((this._state & ACTION.TRUCK) === ACTION.TRUCK || (this._state & ACTION.SCREEN_PAN) === ACTION.SCREEN_PAN || (this._state & ACTION.TOUCH_TRUCK) === ACTION.TOUCH_TRUCK || (this._state & ACTION.TOUCH_SCREEN_PAN) === ACTION.TOUCH_SCREEN_PAN || (this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (this._state & ACTION.TOUCH_DOLLY_SCREEN_PAN) === ACTION.TOUCH_DOLLY_SCREEN_PAN || (this._state & ACTION.TOUCH_ZOOM_TRUCK) === ACTION.TOUCH_ZOOM_TRUCK || (this._state & ACTION.TOUCH_ZOOM_SCREEN_PAN) === ACTION.TOUCH_DOLLY_SCREEN_PAN) {
798
- this._targetEnd.copy(this._target);
799
- this._targetVelocity.set(0, 0, 0);
800
- }
801
- if ((this._state & ACTION.DOLLY) === ACTION.DOLLY || (this._state & ACTION.TOUCH_DOLLY) === ACTION.TOUCH_DOLLY || (this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (this._state & ACTION.TOUCH_DOLLY_SCREEN_PAN) === ACTION.TOUCH_DOLLY_SCREEN_PAN || (this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET || (this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE) {
802
- this._sphericalEnd.radius = this._spherical.radius;
803
- this._radiusVelocity.value = 0;
804
- }
805
- if ((this._state & ACTION.ZOOM) === ACTION.ZOOM || (this._state & ACTION.TOUCH_ZOOM) === ACTION.TOUCH_ZOOM || (this._state & ACTION.TOUCH_ZOOM_TRUCK) === ACTION.TOUCH_ZOOM_TRUCK || (this._state & ACTION.TOUCH_ZOOM_SCREEN_PAN) === ACTION.TOUCH_ZOOM_SCREEN_PAN || (this._state & ACTION.TOUCH_ZOOM_OFFSET) === ACTION.TOUCH_ZOOM_OFFSET || (this._state & ACTION.TOUCH_ZOOM_ROTATE) === ACTION.TOUCH_ZOOM_ROTATE) {
806
- this._zoomEnd = this._zoom;
807
- this._zoomVelocity.value = 0;
808
- }
809
- if ((this._state & ACTION.OFFSET) === ACTION.OFFSET || (this._state & ACTION.TOUCH_OFFSET) === ACTION.TOUCH_OFFSET || (this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET || (this._state & ACTION.TOUCH_ZOOM_OFFSET) === ACTION.TOUCH_ZOOM_OFFSET) {
810
- this._focalOffsetEnd.copy(this._focalOffset);
811
- this._focalOffsetVelocity.set(0, 0, 0);
812
- }
813
- this.dispatchEvent({ type: "controlstart" });
814
- };
815
- const dragging = () => {
816
- if (!this._enabled || !this._dragNeedsUpdate) return;
817
- this._dragNeedsUpdate = false;
818
- extractClientCoordFromEvent(this._activePointers, _v2);
819
- const lockedPointer = this._domElement && this._domElement.ownerDocument.pointerLockElement === this._domElement ? this._lockedPointer || this._activePointers[0] : null;
820
- const deltaX = lockedPointer ? -lockedPointer.deltaX : lastDragPosition.x - _v2.x;
821
- const deltaY = lockedPointer ? -lockedPointer.deltaY : lastDragPosition.y - _v2.y;
822
- lastDragPosition.copy(_v2);
823
- if ((this._state & ACTION.ROTATE) === ACTION.ROTATE || (this._state & ACTION.TOUCH_ROTATE) === ACTION.TOUCH_ROTATE || (this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE || (this._state & ACTION.TOUCH_ZOOM_ROTATE) === ACTION.TOUCH_ZOOM_ROTATE) {
824
- this._rotateInternal(deltaX, deltaY);
825
- this._isUserControllingRotate = true;
826
- }
827
- if ((this._state & ACTION.DOLLY) === ACTION.DOLLY || (this._state & ACTION.ZOOM) === ACTION.ZOOM) {
828
- const dollyX = this.dollyToCursor ? (dragStartPosition.x - this._elementRect.x) / this._elementRect.width * 2 - 1 : 0;
829
- const dollyY = this.dollyToCursor ? (dragStartPosition.y - this._elementRect.y) / this._elementRect.height * -2 + 1 : 0;
830
- const dollyDirection = this.dollyDragInverted ? -1 : 1;
831
- if ((this._state & ACTION.DOLLY) === ACTION.DOLLY) {
832
- this._dollyInternal(dollyDirection * deltaY * TOUCH_DOLLY_FACTOR, dollyX, dollyY);
833
- this._isUserControllingDolly = true;
834
- } else {
835
- this._zoomInternal(dollyDirection * deltaY * TOUCH_DOLLY_FACTOR, dollyX, dollyY);
836
- this._isUserControllingZoom = true;
837
- }
838
- }
839
- if ((this._state & ACTION.TOUCH_DOLLY) === ACTION.TOUCH_DOLLY || (this._state & ACTION.TOUCH_ZOOM) === ACTION.TOUCH_ZOOM || (this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (this._state & ACTION.TOUCH_ZOOM_TRUCK) === ACTION.TOUCH_ZOOM_TRUCK || (this._state & ACTION.TOUCH_DOLLY_SCREEN_PAN) === ACTION.TOUCH_DOLLY_SCREEN_PAN || (this._state & ACTION.TOUCH_ZOOM_SCREEN_PAN) === ACTION.TOUCH_ZOOM_SCREEN_PAN || (this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET || (this._state & ACTION.TOUCH_ZOOM_OFFSET) === ACTION.TOUCH_ZOOM_OFFSET || (this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE || (this._state & ACTION.TOUCH_ZOOM_ROTATE) === ACTION.TOUCH_ZOOM_ROTATE) {
840
- const dx = _v2.x - this._activePointers[1].clientX;
841
- const dy = _v2.y - this._activePointers[1].clientY;
842
- const distance = Math.sqrt(dx * dx + dy * dy);
843
- const dollyDelta = dollyStart.y - distance;
844
- dollyStart.set(0, distance);
845
- const dollyX = this.dollyToCursor ? (lastDragPosition.x - this._elementRect.x) / this._elementRect.width * 2 - 1 : 0;
846
- const dollyY = this.dollyToCursor ? (lastDragPosition.y - this._elementRect.y) / this._elementRect.height * -2 + 1 : 0;
847
- if ((this._state & ACTION.TOUCH_DOLLY) === ACTION.TOUCH_DOLLY || (this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE || (this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (this._state & ACTION.TOUCH_DOLLY_SCREEN_PAN) === ACTION.TOUCH_DOLLY_SCREEN_PAN || (this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET) {
848
- this._dollyInternal(dollyDelta * TOUCH_DOLLY_FACTOR, dollyX, dollyY);
849
- this._isUserControllingDolly = true;
850
- } else {
851
- this._zoomInternal(dollyDelta * TOUCH_DOLLY_FACTOR, dollyX, dollyY);
852
- this._isUserControllingZoom = true;
853
- }
854
- }
855
- if ((this._state & ACTION.TRUCK) === ACTION.TRUCK || (this._state & ACTION.TOUCH_TRUCK) === ACTION.TOUCH_TRUCK || (this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (this._state & ACTION.TOUCH_ZOOM_TRUCK) === ACTION.TOUCH_ZOOM_TRUCK) {
856
- this._truckInternal(deltaX, deltaY, false, false);
857
- this._isUserControllingTruck = true;
858
- }
859
- if ((this._state & ACTION.SCREEN_PAN) === ACTION.SCREEN_PAN || (this._state & ACTION.TOUCH_SCREEN_PAN) === ACTION.TOUCH_SCREEN_PAN || (this._state & ACTION.TOUCH_DOLLY_SCREEN_PAN) === ACTION.TOUCH_DOLLY_SCREEN_PAN || (this._state & ACTION.TOUCH_ZOOM_SCREEN_PAN) === ACTION.TOUCH_ZOOM_SCREEN_PAN) {
860
- this._truckInternal(deltaX, deltaY, false, true);
861
- this._isUserControllingTruck = true;
862
- }
863
- if ((this._state & ACTION.OFFSET) === ACTION.OFFSET || (this._state & ACTION.TOUCH_OFFSET) === ACTION.TOUCH_OFFSET || (this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET || (this._state & ACTION.TOUCH_ZOOM_OFFSET) === ACTION.TOUCH_ZOOM_OFFSET) {
864
- this._truckInternal(deltaX, deltaY, true, false);
865
- this._isUserControllingOffset = true;
866
- }
867
- this.dispatchEvent({ type: "control" });
868
- };
869
- const endDragging = () => {
870
- extractClientCoordFromEvent(this._activePointers, _v2);
871
- lastDragPosition.copy(_v2);
872
- this._dragNeedsUpdate = false;
873
- if (this._activePointers.length === 0 || this._activePointers.length === 1 && this._activePointers[0] === this._lockedPointer) this._isDragging = false;
874
- if (this._activePointers.length === 0 && this._domElement) {
875
- this._domElement.ownerDocument.removeEventListener("pointermove", onPointerMove, { passive: false });
876
- this._domElement.ownerDocument.removeEventListener("pointerup", onPointerUp);
877
- this.dispatchEvent({ type: "controlend" });
878
- }
879
- };
880
- this.lockPointer = () => {
881
- if (!this._enabled || !this._domElement) return;
882
- this.cancel();
883
- this._lockedPointer = {
884
- pointerId: -1,
885
- clientX: 0,
886
- clientY: 0,
887
- deltaX: 0,
888
- deltaY: 0,
889
- mouseButton: null
890
- };
891
- this._activePointers.push(this._lockedPointer);
892
- this._domElement.ownerDocument.removeEventListener("pointermove", onPointerMove, { passive: false });
893
- this._domElement.ownerDocument.removeEventListener("pointerup", onPointerUp);
894
- this._domElement.requestPointerLock();
895
- this._domElement.ownerDocument.addEventListener("pointerlockchange", onPointerLockChange);
896
- this._domElement.ownerDocument.addEventListener("pointerlockerror", onPointerLockError);
897
- this._domElement.ownerDocument.addEventListener("pointermove", onPointerMove, { passive: false });
898
- this._domElement.ownerDocument.addEventListener("pointerup", onPointerUp);
899
- startDragging();
900
- };
901
- this.unlockPointer = () => {
902
- var _a, _b, _c;
903
- if (this._lockedPointer !== null) {
904
- this._disposePointer(this._lockedPointer);
905
- this._lockedPointer = null;
906
- }
907
- (_a = this._domElement) === null || _a === void 0 || _a.ownerDocument.exitPointerLock();
908
- (_b = this._domElement) === null || _b === void 0 || _b.ownerDocument.removeEventListener("pointerlockchange", onPointerLockChange);
909
- (_c = this._domElement) === null || _c === void 0 || _c.ownerDocument.removeEventListener("pointerlockerror", onPointerLockError);
910
- this.cancel();
911
- };
912
- const onPointerLockChange = () => {
913
- if (!(this._domElement && this._domElement.ownerDocument.pointerLockElement === this._domElement)) this.unlockPointer();
914
- };
915
- const onPointerLockError = () => {
916
- this.unlockPointer();
917
- };
918
- this._addAllEventListeners = (domElement$1) => {
919
- this._domElement = domElement$1;
920
- this._domElement.style.touchAction = "none";
921
- this._domElement.style.userSelect = "none";
922
- this._domElement.style.webkitUserSelect = "none";
923
- this._domElement.addEventListener("pointerdown", onPointerDown);
924
- this._domElement.addEventListener("pointercancel", onPointerUp);
925
- this._domElement.addEventListener("wheel", onMouseWheel, { passive: false });
926
- this._domElement.addEventListener("contextmenu", onContextMenu);
927
- };
928
- this._removeAllEventListeners = () => {
929
- if (!this._domElement) return;
930
- this._domElement.style.touchAction = "";
931
- this._domElement.style.userSelect = "";
932
- this._domElement.style.webkitUserSelect = "";
933
- this._domElement.removeEventListener("pointerdown", onPointerDown);
934
- this._domElement.removeEventListener("pointercancel", onPointerUp);
935
- this._domElement.removeEventListener("wheel", onMouseWheel, { passive: false });
936
- this._domElement.removeEventListener("contextmenu", onContextMenu);
937
- this._domElement.ownerDocument.removeEventListener("pointermove", onPointerMove, { passive: false });
938
- this._domElement.ownerDocument.removeEventListener("pointerup", onPointerUp);
939
- this._domElement.ownerDocument.removeEventListener("pointerlockchange", onPointerLockChange);
940
- this._domElement.ownerDocument.removeEventListener("pointerlockerror", onPointerLockError);
941
- };
942
- this.cancel = () => {
943
- if (this._state === ACTION.NONE) return;
944
- this._state = ACTION.NONE;
945
- this._activePointers.length = 0;
946
- endDragging();
947
- };
948
- if (domElement) this.connect(domElement);
949
- this.update(0);
950
- }
951
- /**
952
- * The camera to be controlled
953
- * @category Properties
954
- */
955
- get camera() {
956
- return this._camera;
957
- }
958
- set camera(camera) {
959
- this._camera = camera;
960
- this.updateCameraUp();
961
- this._camera.updateProjectionMatrix();
962
- this._updateNearPlaneCorners();
963
- this._needsUpdate = true;
964
- }
965
- /**
966
- * Whether or not the controls are enabled.
967
- * `false` to disable user dragging/touch-move, but all methods works.
968
- * @category Properties
969
- */
970
- get enabled() {
971
- return this._enabled;
972
- }
973
- set enabled(enabled) {
974
- this._enabled = enabled;
975
- if (!this._domElement) return;
976
- if (enabled) {
977
- this._domElement.style.touchAction = "none";
978
- this._domElement.style.userSelect = "none";
979
- this._domElement.style.webkitUserSelect = "none";
980
- } else {
981
- this.cancel();
982
- this._domElement.style.touchAction = "";
983
- this._domElement.style.userSelect = "";
984
- this._domElement.style.webkitUserSelect = "";
985
- }
986
- }
987
- /**
988
- * Returns `true` if the controls are active updating.
989
- * readonly value.
990
- * @category Properties
991
- */
992
- get active() {
993
- return !this._hasRested;
994
- }
995
- /**
996
- * Getter for the current `ACTION`.
997
- * readonly value.
998
- * @category Properties
999
- */
1000
- get currentAction() {
1001
- return this._state;
1002
- }
1003
- /**
1004
- * get/set Current distance.
1005
- * @category Properties
1006
- */
1007
- get distance() {
1008
- return this._spherical.radius;
1009
- }
1010
- set distance(distance) {
1011
- if (this._spherical.radius === distance && this._sphericalEnd.radius === distance) return;
1012
- this._spherical.radius = distance;
1013
- this._sphericalEnd.radius = distance;
1014
- this._needsUpdate = true;
1015
- }
1016
- /**
1017
- * get/set the azimuth angle (horizontal) in radians.
1018
- * Every 360 degrees turn is added to `.azimuthAngle` value, which is accumulative.
1019
- * @category Properties
1020
- */
1021
- get azimuthAngle() {
1022
- return this._spherical.theta;
1023
- }
1024
- set azimuthAngle(azimuthAngle) {
1025
- if (this._spherical.theta === azimuthAngle && this._sphericalEnd.theta === azimuthAngle) return;
1026
- this._spherical.theta = azimuthAngle;
1027
- this._sphericalEnd.theta = azimuthAngle;
1028
- this._needsUpdate = true;
1029
- }
1030
- /**
1031
- * get/set the polar angle (vertical) in radians.
1032
- * @category Properties
1033
- */
1034
- get polarAngle() {
1035
- return this._spherical.phi;
1036
- }
1037
- set polarAngle(polarAngle) {
1038
- if (this._spherical.phi === polarAngle && this._sphericalEnd.phi === polarAngle) return;
1039
- this._spherical.phi = polarAngle;
1040
- this._sphericalEnd.phi = polarAngle;
1041
- this._needsUpdate = true;
1042
- }
1043
- /**
1044
- * Whether camera position should be enclosed in the boundary or not.
1045
- * @category Properties
1046
- */
1047
- get boundaryEnclosesCamera() {
1048
- return this._boundaryEnclosesCamera;
1049
- }
1050
- set boundaryEnclosesCamera(boundaryEnclosesCamera) {
1051
- this._boundaryEnclosesCamera = boundaryEnclosesCamera;
1052
- this._needsUpdate = true;
1053
- }
1054
- /**
1055
- * Set drag-start, touches and wheel enable area in the domElement.
1056
- * each values are between `0` and `1` inclusive, where `0` is left/top and `1` is right/bottom of the screen.
1057
- * e.g. `{ x: 0, y: 0, width: 1, height: 1 }` for entire area.
1058
- * @category Properties
1059
- */
1060
- set interactiveArea(interactiveArea) {
1061
- this._interactiveArea.width = clamp(interactiveArea.width, 0, 1);
1062
- this._interactiveArea.height = clamp(interactiveArea.height, 0, 1);
1063
- this._interactiveArea.x = clamp(interactiveArea.x, 0, 1 - this._interactiveArea.width);
1064
- this._interactiveArea.y = clamp(interactiveArea.y, 0, 1 - this._interactiveArea.height);
1065
- }
1066
- /**
1067
- * Adds the specified event listener.
1068
- * Applicable event types (which is `K`) are:
1069
- * | Event name | Timing |
1070
- * | ------------------- | ------ |
1071
- * | `'controlstart'` | When the user starts to control the camera via mouse / touches. ¹ |
1072
- * | `'control'` | When the user controls the camera (dragging). |
1073
- * | `'controlend'` | When the user ends to control the camera. ¹ |
1074
- * | `'transitionstart'` | When any kind of transition starts, either user control or using a method with `enableTransition = true` |
1075
- * | `'update'` | When the camera position is updated. |
1076
- * | `'wake'` | When the camera starts moving. |
1077
- * | `'rest'` | When the camera movement is below `.restThreshold` ². |
1078
- * | `'sleep'` | When the camera end moving. |
1079
- *
1080
- * 1. `mouseButtons.wheel` (Mouse wheel control) does not emit `'controlstart'` and `'controlend'`. `mouseButtons.wheel` uses scroll-event internally, and scroll-event happens intermittently. That means "start" and "end" cannot be detected.
1081
- * 2. Due to damping, `sleep` will usually fire a few seconds after the camera _appears_ to have stopped moving. If you want to do something (e.g. enable UI, perform another transition) at the point when the camera has stopped, you probably want the `rest` event. This can be fine tuned using the `.restThreshold` parameter. See the [Rest and Sleep Example](https://yomotsu.github.io/camera-controls/examples/rest-and-sleep.html).
1082
- *
1083
- * e.g.
1084
- * ```
1085
- * cameraControl.addEventListener( 'controlstart', myCallbackFunction );
1086
- * ```
1087
- * @param type event name
1088
- * @param listener handler function
1089
- * @category Methods
1090
- */
1091
- addEventListener(type, listener) {
1092
- super.addEventListener(type, listener);
1093
- }
1094
- /**
1095
- * Removes the specified event listener
1096
- * e.g.
1097
- * ```
1098
- * cameraControl.addEventListener( 'controlstart', myCallbackFunction );
1099
- * ```
1100
- * @param type event name
1101
- * @param listener handler function
1102
- * @category Methods
1103
- */
1104
- removeEventListener(type, listener) {
1105
- super.removeEventListener(type, listener);
1106
- }
1107
- /**
1108
- * Rotate azimuthal angle(horizontal) and polar angle(vertical).
1109
- * Every value is added to the current value.
1110
- * @param azimuthAngle Azimuth rotate angle. In radian.
1111
- * @param polarAngle Polar rotate angle. In radian.
1112
- * @param enableTransition Whether to move smoothly or immediately
1113
- * @category Methods
1114
- */
1115
- rotate(azimuthAngle, polarAngle, enableTransition = false) {
1116
- return this.rotateTo(this._sphericalEnd.theta + azimuthAngle, this._sphericalEnd.phi + polarAngle, enableTransition);
1117
- }
1118
- /**
1119
- * Rotate azimuthal angle(horizontal) to the given angle and keep the same polar angle(vertical) target.
1120
- *
1121
- * e.g.
1122
- * ```
1123
- * cameraControls.rotateAzimuthTo( 30 * THREE.MathUtils.DEG2RAD, true );
1124
- * ```
1125
- * @param azimuthAngle Azimuth rotate angle. In radian.
1126
- * @param enableTransition Whether to move smoothly or immediately
1127
- * @category Methods
1128
- */
1129
- rotateAzimuthTo(azimuthAngle, enableTransition = false) {
1130
- return this.rotateTo(azimuthAngle, this._sphericalEnd.phi, enableTransition);
1131
- }
1132
- /**
1133
- * Rotate polar angle(vertical) to the given angle and keep the same azimuthal angle(horizontal) target.
1134
- *
1135
- * e.g.
1136
- * ```
1137
- * cameraControls.rotatePolarTo( 30 * THREE.MathUtils.DEG2RAD, true );
1138
- * ```
1139
- * @param polarAngle Polar rotate angle. In radian.
1140
- * @param enableTransition Whether to move smoothly or immediately
1141
- * @category Methods
1142
- */
1143
- rotatePolarTo(polarAngle, enableTransition = false) {
1144
- return this.rotateTo(this._sphericalEnd.theta, polarAngle, enableTransition);
1145
- }
1146
- /**
1147
- * Rotate azimuthal angle(horizontal) and polar angle(vertical) to the given angle.
1148
- * Camera view will rotate over the orbit pivot absolutely:
1149
- *
1150
- * azimuthAngle
1151
- * ```
1152
- * 0º
1153
- * \
1154
- * 90º -----+----- -90º
1155
- * \
1156
- * 180º
1157
- * ```
1158
- * | direction | angle |
1159
- * | --------- | ---------------------- |
1160
- * | front | 0º |
1161
- * | left | 90º (`Math.PI / 2`) |
1162
- * | right | -90º (`- Math.PI / 2`) |
1163
- * | back | 180º (`Math.PI`) |
1164
- *
1165
- * polarAngle
1166
- * ```
1167
- * 180º
1168
- * |
1169
- * 90º
1170
- * |
1171
- * 0º
1172
- * ```
1173
- * | direction | angle |
1174
- * | -------------------- | ---------------------- |
1175
- * | top/sky | 180º (`Math.PI`) |
1176
- * | horizontal from view | 90º (`Math.PI / 2`) |
1177
- * | bottom/floor | 0º |
1178
- *
1179
- * @param azimuthAngle Azimuth rotate angle to. In radian.
1180
- * @param polarAngle Polar rotate angle to. In radian.
1181
- * @param enableTransition Whether to move smoothly or immediately
1182
- * @category Methods
1183
- */
1184
- rotateTo(azimuthAngle, polarAngle, enableTransition = false) {
1185
- this._isUserControllingRotate = false;
1186
- const theta = clamp(azimuthAngle, this.minAzimuthAngle, this.maxAzimuthAngle);
1187
- const phi = clamp(polarAngle, this.minPolarAngle, this.maxPolarAngle);
1188
- this._sphericalEnd.theta = theta;
1189
- this._sphericalEnd.phi = phi;
1190
- this._sphericalEnd.makeSafe();
1191
- this._needsUpdate = true;
1192
- if (!enableTransition) {
1193
- this._spherical.theta = this._sphericalEnd.theta;
1194
- this._spherical.phi = this._sphericalEnd.phi;
1195
- }
1196
- const resolveImmediately = !enableTransition || approxEquals(this._spherical.theta, this._sphericalEnd.theta, this.restThreshold) && approxEquals(this._spherical.phi, this._sphericalEnd.phi, this.restThreshold);
1197
- return this._createOnRestPromise(resolveImmediately);
1198
- }
1199
- /**
1200
- * Dolly in/out camera position.
1201
- * @param distance Distance of dollyIn. Negative number for dollyOut.
1202
- * @param enableTransition Whether to move smoothly or immediately.
1203
- * @category Methods
1204
- */
1205
- dolly(distance, enableTransition = false) {
1206
- return this.dollyTo(this._sphericalEnd.radius - distance, enableTransition);
1207
- }
1208
- /**
1209
- * Dolly in/out camera position to given distance.
1210
- * @param distance Distance of dolly.
1211
- * @param enableTransition Whether to move smoothly or immediately.
1212
- * @category Methods
1213
- */
1214
- dollyTo(distance, enableTransition = false) {
1215
- this._isUserControllingDolly = false;
1216
- this._lastDollyDirection = DOLLY_DIRECTION.NONE;
1217
- this._changedDolly = 0;
1218
- return this._dollyToNoClamp(clamp(distance, this.minDistance, this.maxDistance), enableTransition);
1219
- }
1220
- _dollyToNoClamp(distance, enableTransition = false) {
1221
- const lastRadius = this._sphericalEnd.radius;
1222
- if (this.colliderMeshes.length >= 1) {
1223
- const maxDistanceByCollisionTest = this._collisionTest();
1224
- const isCollided = approxEquals(maxDistanceByCollisionTest, this._spherical.radius);
1225
- if (!(lastRadius > distance) && isCollided) return Promise.resolve();
1226
- this._sphericalEnd.radius = Math.min(distance, maxDistanceByCollisionTest);
1227
- } else this._sphericalEnd.radius = distance;
1228
- this._needsUpdate = true;
1229
- if (!enableTransition) this._spherical.radius = this._sphericalEnd.radius;
1230
- const resolveImmediately = !enableTransition || approxEquals(this._spherical.radius, this._sphericalEnd.radius, this.restThreshold);
1231
- return this._createOnRestPromise(resolveImmediately);
1232
- }
1233
- /**
1234
- * Dolly in, but does not change the distance between the target and the camera, and moves the target position instead.
1235
- * Specify a negative value for dolly out.
1236
- * @param distance Distance of dolly.
1237
- * @param enableTransition Whether to move smoothly or immediately.
1238
- * @category Methods
1239
- */
1240
- dollyInFixed(distance, enableTransition = false) {
1241
- this._targetEnd.add(this._getCameraDirection(_cameraDirection).multiplyScalar(distance));
1242
- if (!enableTransition) this._target.copy(this._targetEnd);
1243
- const resolveImmediately = !enableTransition || approxEquals(this._target.x, this._targetEnd.x, this.restThreshold) && approxEquals(this._target.y, this._targetEnd.y, this.restThreshold) && approxEquals(this._target.z, this._targetEnd.z, this.restThreshold);
1244
- return this._createOnRestPromise(resolveImmediately);
1245
- }
1246
- /**
1247
- * Zoom in/out camera. The value is added to camera zoom.
1248
- * Limits set with `.minZoom` and `.maxZoom`
1249
- * @param zoomStep zoom scale
1250
- * @param enableTransition Whether to move smoothly or immediately
1251
- * @category Methods
1252
- */
1253
- zoom(zoomStep, enableTransition = false) {
1254
- return this.zoomTo(this._zoomEnd + zoomStep, enableTransition);
1255
- }
1256
- /**
1257
- * Zoom in/out camera to given scale. The value overwrites camera zoom.
1258
- * Limits set with .minZoom and .maxZoom
1259
- * @param zoom
1260
- * @param enableTransition
1261
- * @category Methods
1262
- */
1263
- zoomTo(zoom, enableTransition = false) {
1264
- this._isUserControllingZoom = false;
1265
- this._zoomEnd = clamp(zoom, this.minZoom, this.maxZoom);
1266
- this._needsUpdate = true;
1267
- if (!enableTransition) this._zoom = this._zoomEnd;
1268
- const resolveImmediately = !enableTransition || approxEquals(this._zoom, this._zoomEnd, this.restThreshold);
1269
- this._changedZoom = 0;
1270
- return this._createOnRestPromise(resolveImmediately);
1271
- }
1272
- /**
1273
- * @deprecated `pan()` has been renamed to `truck()`
1274
- * @category Methods
1275
- */
1276
- pan(x, y, enableTransition = false) {
1277
- console.warn("`pan` has been renamed to `truck`");
1278
- return this.truck(x, y, enableTransition);
1279
- }
1280
- /**
1281
- * Truck and pedestal camera using current azimuthal angle
1282
- * @param x Horizontal translate amount
1283
- * @param y Vertical translate amount
1284
- * @param enableTransition Whether to move smoothly or immediately
1285
- * @category Methods
1286
- */
1287
- truck(x, y, enableTransition = false) {
1288
- this._camera.updateMatrix();
1289
- _xColumn.setFromMatrixColumn(this._camera.matrix, 0);
1290
- _yColumn.setFromMatrixColumn(this._camera.matrix, 1);
1291
- _xColumn.multiplyScalar(x);
1292
- _yColumn.multiplyScalar(-y);
1293
- const offset = _v3A.copy(_xColumn).add(_yColumn);
1294
- const to = _v3B.copy(this._targetEnd).add(offset);
1295
- return this.moveTo(to.x, to.y, to.z, enableTransition);
1296
- }
1297
- /**
1298
- * Move forward / backward.
1299
- * @param distance Amount to move forward / backward. Negative value to move backward
1300
- * @param enableTransition Whether to move smoothly or immediately
1301
- * @category Methods
1302
- */
1303
- forward(distance, enableTransition = false) {
1304
- _v3A.setFromMatrixColumn(this._camera.matrix, 0);
1305
- _v3A.crossVectors(this._camera.up, _v3A);
1306
- _v3A.multiplyScalar(distance);
1307
- const to = _v3B.copy(this._targetEnd).add(_v3A);
1308
- return this.moveTo(to.x, to.y, to.z, enableTransition);
1309
- }
1310
- /**
1311
- * Move up / down.
1312
- * @param height Amount to move up / down. Negative value to move down
1313
- * @param enableTransition Whether to move smoothly or immediately
1314
- * @category Methods
1315
- */
1316
- elevate(height, enableTransition = false) {
1317
- _v3A.copy(this._camera.up).multiplyScalar(height);
1318
- return this.moveTo(this._targetEnd.x + _v3A.x, this._targetEnd.y + _v3A.y, this._targetEnd.z + _v3A.z, enableTransition);
1319
- }
1320
- /**
1321
- * Move target position to given point.
1322
- * @param x x coord to move center position
1323
- * @param y y coord to move center position
1324
- * @param z z coord to move center position
1325
- * @param enableTransition Whether to move smoothly or immediately
1326
- * @category Methods
1327
- */
1328
- moveTo(x, y, z, enableTransition = false) {
1329
- this._isUserControllingTruck = false;
1330
- const offset = _v3A.set(x, y, z).sub(this._targetEnd);
1331
- this._encloseToBoundary(this._targetEnd, offset, this.boundaryFriction);
1332
- this._needsUpdate = true;
1333
- if (!enableTransition) this._target.copy(this._targetEnd);
1334
- const resolveImmediately = !enableTransition || approxEquals(this._target.x, this._targetEnd.x, this.restThreshold) && approxEquals(this._target.y, this._targetEnd.y, this.restThreshold) && approxEquals(this._target.z, this._targetEnd.z, this.restThreshold);
1335
- return this._createOnRestPromise(resolveImmediately);
1336
- }
1337
- /**
1338
- * Look in the given point direction.
1339
- * @param x point x.
1340
- * @param y point y.
1341
- * @param z point z.
1342
- * @param enableTransition Whether to move smoothly or immediately.
1343
- * @returns Transition end promise
1344
- * @category Methods
1345
- */
1346
- lookInDirectionOf(x, y, z, enableTransition = false) {
1347
- const position = _v3A.set(x, y, z).sub(this._targetEnd).normalize().multiplyScalar(-this._sphericalEnd.radius).add(this._targetEnd);
1348
- return this.setPosition(position.x, position.y, position.z, enableTransition);
1349
- }
1350
- /**
1351
- * Fit the viewport to the box or the bounding box of the object, using the nearest axis. paddings are in unit.
1352
- * set `cover: true` to fill enter screen.
1353
- * e.g.
1354
- * ```
1355
- * cameraControls.fitToBox( myMesh );
1356
- * ```
1357
- * @param box3OrObject Axis aligned bounding box to fit the view.
1358
- * @param enableTransition Whether to move smoothly or immediately.
1359
- * @param options | `<object>` { cover: boolean, paddingTop: number, paddingLeft: number, paddingBottom: number, paddingRight: number }
1360
- * @returns Transition end promise
1361
- * @category Methods
1362
- */
1363
- fitToBox(box3OrObject, enableTransition, { cover = false, paddingLeft = 0, paddingRight = 0, paddingBottom = 0, paddingTop = 0 } = {}) {
1364
- const promises = [];
1365
- const aabb = box3OrObject.isBox3 ? _box3A.copy(box3OrObject) : _box3A.setFromObject(box3OrObject);
1366
- if (aabb.isEmpty()) {
1367
- console.warn("camera-controls: fitTo() cannot be used with an empty box. Aborting");
1368
- Promise.resolve();
1369
- }
1370
- const theta = roundToStep(this._sphericalEnd.theta, PI_HALF);
1371
- const phi = roundToStep(this._sphericalEnd.phi, PI_HALF);
1372
- promises.push(this.rotateTo(theta, phi, enableTransition));
1373
- const normal = _v3A.setFromSpherical(this._sphericalEnd).normalize();
1374
- const rotation = _quaternionA.setFromUnitVectors(normal, _AXIS_Z);
1375
- const viewFromPolar = approxEquals(Math.abs(normal.y), 1);
1376
- if (viewFromPolar) rotation.multiply(_quaternionB.setFromAxisAngle(_AXIS_Y, theta));
1377
- rotation.multiply(this._yAxisUpSpaceInverse);
1378
- const bb = _box3B.makeEmpty();
1379
- _v3B.copy(aabb.min).applyQuaternion(rotation);
1380
- bb.expandByPoint(_v3B);
1381
- _v3B.copy(aabb.min).setX(aabb.max.x).applyQuaternion(rotation);
1382
- bb.expandByPoint(_v3B);
1383
- _v3B.copy(aabb.min).setY(aabb.max.y).applyQuaternion(rotation);
1384
- bb.expandByPoint(_v3B);
1385
- _v3B.copy(aabb.max).setZ(aabb.min.z).applyQuaternion(rotation);
1386
- bb.expandByPoint(_v3B);
1387
- _v3B.copy(aabb.min).setZ(aabb.max.z).applyQuaternion(rotation);
1388
- bb.expandByPoint(_v3B);
1389
- _v3B.copy(aabb.max).setY(aabb.min.y).applyQuaternion(rotation);
1390
- bb.expandByPoint(_v3B);
1391
- _v3B.copy(aabb.max).setX(aabb.min.x).applyQuaternion(rotation);
1392
- bb.expandByPoint(_v3B);
1393
- _v3B.copy(aabb.max).applyQuaternion(rotation);
1394
- bb.expandByPoint(_v3B);
1395
- bb.min.x -= paddingLeft;
1396
- bb.min.y -= paddingBottom;
1397
- bb.max.x += paddingRight;
1398
- bb.max.y += paddingTop;
1399
- rotation.setFromUnitVectors(_AXIS_Z, normal);
1400
- if (viewFromPolar) rotation.premultiply(_quaternionB.invert());
1401
- rotation.premultiply(this._yAxisUpSpace);
1402
- const bbSize = bb.getSize(_v3A);
1403
- const center = bb.getCenter(_v3B).applyQuaternion(rotation);
1404
- if (isPerspectiveCamera(this._camera)) {
1405
- const distance = this.getDistanceToFitBox(bbSize.x, bbSize.y, bbSize.z, cover);
1406
- promises.push(this.moveTo(center.x, center.y, center.z, enableTransition));
1407
- promises.push(this.dollyTo(distance, enableTransition));
1408
- promises.push(this.setFocalOffset(0, 0, 0, enableTransition));
1409
- } else if (isOrthographicCamera(this._camera)) {
1410
- const camera = this._camera;
1411
- const width = camera.right - camera.left;
1412
- const height = camera.top - camera.bottom;
1413
- const zoom = cover ? Math.max(width / bbSize.x, height / bbSize.y) : Math.min(width / bbSize.x, height / bbSize.y);
1414
- promises.push(this.moveTo(center.x, center.y, center.z, enableTransition));
1415
- promises.push(this.zoomTo(zoom, enableTransition));
1416
- promises.push(this.setFocalOffset(0, 0, 0, enableTransition));
1417
- }
1418
- return Promise.all(promises);
1419
- }
1420
- /**
1421
- * Fit the viewport to the sphere or the bounding sphere of the object.
1422
- * @param sphereOrMesh
1423
- * @param enableTransition
1424
- * @category Methods
1425
- */
1426
- fitToSphere(sphereOrMesh, enableTransition) {
1427
- const promises = [];
1428
- const boundingSphere = "isObject3D" in sphereOrMesh ? CameraControls.createBoundingSphere(sphereOrMesh, _sphere) : _sphere.copy(sphereOrMesh);
1429
- promises.push(this.moveTo(boundingSphere.center.x, boundingSphere.center.y, boundingSphere.center.z, enableTransition));
1430
- if (isPerspectiveCamera(this._camera)) {
1431
- const distanceToFit = this.getDistanceToFitSphere(boundingSphere.radius);
1432
- promises.push(this.dollyTo(distanceToFit, enableTransition));
1433
- } else if (isOrthographicCamera(this._camera)) {
1434
- const width = this._camera.right - this._camera.left;
1435
- const height = this._camera.top - this._camera.bottom;
1436
- const diameter = 2 * boundingSphere.radius;
1437
- const zoom = Math.min(width / diameter, height / diameter);
1438
- promises.push(this.zoomTo(zoom, enableTransition));
1439
- }
1440
- promises.push(this.setFocalOffset(0, 0, 0, enableTransition));
1441
- return Promise.all(promises);
1442
- }
1443
- /**
1444
- * Look at the `target` from the `position`.
1445
- * @param positionX
1446
- * @param positionY
1447
- * @param positionZ
1448
- * @param targetX
1449
- * @param targetY
1450
- * @param targetZ
1451
- * @param enableTransition
1452
- * @category Methods
1453
- */
1454
- setLookAt(positionX, positionY, positionZ, targetX, targetY, targetZ, enableTransition = false) {
1455
- this._isUserControllingRotate = false;
1456
- this._isUserControllingDolly = false;
1457
- this._isUserControllingTruck = false;
1458
- this._lastDollyDirection = DOLLY_DIRECTION.NONE;
1459
- this._changedDolly = 0;
1460
- const target = _v3B.set(targetX, targetY, targetZ);
1461
- const position = _v3A.set(positionX, positionY, positionZ);
1462
- this._targetEnd.copy(target);
1463
- this._sphericalEnd.setFromVector3(position.sub(target).applyQuaternion(this._yAxisUpSpace));
1464
- this._needsUpdate = true;
1465
- if (!enableTransition) {
1466
- this._target.copy(this._targetEnd);
1467
- this._spherical.copy(this._sphericalEnd);
1468
- }
1469
- const resolveImmediately = !enableTransition || approxEquals(this._target.x, this._targetEnd.x, this.restThreshold) && approxEquals(this._target.y, this._targetEnd.y, this.restThreshold) && approxEquals(this._target.z, this._targetEnd.z, this.restThreshold) && approxEquals(this._spherical.theta, this._sphericalEnd.theta, this.restThreshold) && approxEquals(this._spherical.phi, this._sphericalEnd.phi, this.restThreshold) && approxEquals(this._spherical.radius, this._sphericalEnd.radius, this.restThreshold);
1470
- return this._createOnRestPromise(resolveImmediately);
1471
- }
1472
- /**
1473
- * Interpolates between two states.
1474
- * @param stateA
1475
- * @param stateB
1476
- * @param t
1477
- * @param enableTransition
1478
- * @category Methods
1479
- */
1480
- lerp(stateA, stateB, t, enableTransition = false) {
1481
- this._isUserControllingRotate = false;
1482
- this._isUserControllingDolly = false;
1483
- this._isUserControllingTruck = false;
1484
- this._lastDollyDirection = DOLLY_DIRECTION.NONE;
1485
- this._changedDolly = 0;
1486
- const targetA = _v3A.set(...stateA.target);
1487
- if ("spherical" in stateA) _sphericalA.set(...stateA.spherical);
1488
- else {
1489
- const positionA = _v3B.set(...stateA.position);
1490
- _sphericalA.setFromVector3(positionA.sub(targetA).applyQuaternion(this._yAxisUpSpace));
1491
- }
1492
- const targetB = _v3C.set(...stateB.target);
1493
- if ("spherical" in stateB) _sphericalB.set(...stateB.spherical);
1494
- else {
1495
- const positionB = _v3B.set(...stateB.position);
1496
- _sphericalB.setFromVector3(positionB.sub(targetB).applyQuaternion(this._yAxisUpSpace));
1497
- }
1498
- this._targetEnd.copy(targetA.lerp(targetB, t));
1499
- const deltaTheta = _sphericalB.theta - _sphericalA.theta;
1500
- const deltaPhi = _sphericalB.phi - _sphericalA.phi;
1501
- const deltaRadius = _sphericalB.radius - _sphericalA.radius;
1502
- this._sphericalEnd.set(_sphericalA.radius + deltaRadius * t, _sphericalA.phi + deltaPhi * t, _sphericalA.theta + deltaTheta * t);
1503
- this._needsUpdate = true;
1504
- if (!enableTransition) {
1505
- this._target.copy(this._targetEnd);
1506
- this._spherical.copy(this._sphericalEnd);
1507
- }
1508
- const resolveImmediately = !enableTransition || approxEquals(this._target.x, this._targetEnd.x, this.restThreshold) && approxEquals(this._target.y, this._targetEnd.y, this.restThreshold) && approxEquals(this._target.z, this._targetEnd.z, this.restThreshold) && approxEquals(this._spherical.theta, this._sphericalEnd.theta, this.restThreshold) && approxEquals(this._spherical.phi, this._sphericalEnd.phi, this.restThreshold) && approxEquals(this._spherical.radius, this._sphericalEnd.radius, this.restThreshold);
1509
- return this._createOnRestPromise(resolveImmediately);
1510
- }
1511
- /**
1512
- * Similar to setLookAt, but it interpolates between two states.
1513
- * @param positionAX
1514
- * @param positionAY
1515
- * @param positionAZ
1516
- * @param targetAX
1517
- * @param targetAY
1518
- * @param targetAZ
1519
- * @param positionBX
1520
- * @param positionBY
1521
- * @param positionBZ
1522
- * @param targetBX
1523
- * @param targetBY
1524
- * @param targetBZ
1525
- * @param t
1526
- * @param enableTransition
1527
- * @category Methods
1528
- */
1529
- lerpLookAt(positionAX, positionAY, positionAZ, targetAX, targetAY, targetAZ, positionBX, positionBY, positionBZ, targetBX, targetBY, targetBZ, t, enableTransition = false) {
1530
- return this.lerp({
1531
- position: [
1532
- positionAX,
1533
- positionAY,
1534
- positionAZ
1535
- ],
1536
- target: [
1537
- targetAX,
1538
- targetAY,
1539
- targetAZ
1540
- ]
1541
- }, {
1542
- position: [
1543
- positionBX,
1544
- positionBY,
1545
- positionBZ
1546
- ],
1547
- target: [
1548
- targetBX,
1549
- targetBY,
1550
- targetBZ
1551
- ]
1552
- }, t, enableTransition);
1553
- }
1554
- /**
1555
- * Set angle and distance by given position.
1556
- * An alias of `setLookAt()`, without target change. Thus keep gazing at the current target
1557
- * @param positionX
1558
- * @param positionY
1559
- * @param positionZ
1560
- * @param enableTransition
1561
- * @category Methods
1562
- */
1563
- setPosition(positionX, positionY, positionZ, enableTransition = false) {
1564
- return this.setLookAt(positionX, positionY, positionZ, this._targetEnd.x, this._targetEnd.y, this._targetEnd.z, enableTransition);
1565
- }
1566
- /**
1567
- * Set the target position where gaze at.
1568
- * An alias of `setLookAt()`, without position change. Thus keep the same position.
1569
- * @param targetX
1570
- * @param targetY
1571
- * @param targetZ
1572
- * @param enableTransition
1573
- * @category Methods
1574
- */
1575
- setTarget(targetX, targetY, targetZ, enableTransition = false) {
1576
- const pos = this.getPosition(_v3A);
1577
- const promise = this.setLookAt(pos.x, pos.y, pos.z, targetX, targetY, targetZ, enableTransition);
1578
- this._sphericalEnd.phi = clamp(this._sphericalEnd.phi, this.minPolarAngle, this.maxPolarAngle);
1579
- return promise;
1580
- }
1581
- /**
1582
- * Set focal offset using the screen parallel coordinates. z doesn't affect in Orthographic as with Dolly.
1583
- * @param x
1584
- * @param y
1585
- * @param z
1586
- * @param enableTransition
1587
- * @category Methods
1588
- */
1589
- setFocalOffset(x, y, z, enableTransition = false) {
1590
- this._isUserControllingOffset = false;
1591
- this._focalOffsetEnd.set(x, y, z);
1592
- this._needsUpdate = true;
1593
- if (!enableTransition) this._focalOffset.copy(this._focalOffsetEnd);
1594
- const resolveImmediately = !enableTransition || approxEquals(this._focalOffset.x, this._focalOffsetEnd.x, this.restThreshold) && approxEquals(this._focalOffset.y, this._focalOffsetEnd.y, this.restThreshold) && approxEquals(this._focalOffset.z, this._focalOffsetEnd.z, this.restThreshold);
1595
- return this._createOnRestPromise(resolveImmediately);
1596
- }
1597
- /**
1598
- * Set orbit point without moving the camera.
1599
- * SHOULD NOT RUN DURING ANIMATIONS. `setOrbitPoint()` will immediately fix the positions.
1600
- * @param targetX
1601
- * @param targetY
1602
- * @param targetZ
1603
- * @category Methods
1604
- */
1605
- setOrbitPoint(targetX, targetY, targetZ) {
1606
- this._camera.updateMatrixWorld();
1607
- _xColumn.setFromMatrixColumn(this._camera.matrixWorldInverse, 0);
1608
- _yColumn.setFromMatrixColumn(this._camera.matrixWorldInverse, 1);
1609
- _zColumn.setFromMatrixColumn(this._camera.matrixWorldInverse, 2);
1610
- const position = _v3A.set(targetX, targetY, targetZ);
1611
- const distance = position.distanceTo(this._camera.position);
1612
- const cameraToPoint = position.sub(this._camera.position);
1613
- _xColumn.multiplyScalar(cameraToPoint.x);
1614
- _yColumn.multiplyScalar(cameraToPoint.y);
1615
- _zColumn.multiplyScalar(cameraToPoint.z);
1616
- _v3A.copy(_xColumn).add(_yColumn).add(_zColumn);
1617
- _v3A.z = _v3A.z + distance;
1618
- this.dollyTo(distance, false);
1619
- this.setFocalOffset(-_v3A.x, _v3A.y, -_v3A.z, false);
1620
- this.moveTo(targetX, targetY, targetZ, false);
1621
- }
1622
- /**
1623
- * Set the boundary box that encloses the target of the camera. box3 is in THREE.Box3
1624
- * @param box3
1625
- * @category Methods
1626
- */
1627
- setBoundary(box3) {
1628
- if (!box3) {
1629
- this._boundary.min.set(-Infinity, -Infinity, -Infinity);
1630
- this._boundary.max.set(Infinity, Infinity, Infinity);
1631
- this._needsUpdate = true;
1632
- return;
1633
- }
1634
- this._boundary.copy(box3);
1635
- this._boundary.clampPoint(this._targetEnd, this._targetEnd);
1636
- this._needsUpdate = true;
1637
- }
1638
- /**
1639
- * Set (or unset) the current viewport.
1640
- * Set this when you want to use renderer viewport and .dollyToCursor feature at the same time.
1641
- * @param viewportOrX
1642
- * @param y
1643
- * @param width
1644
- * @param height
1645
- * @category Methods
1646
- */
1647
- setViewport(viewportOrX, y, width, height) {
1648
- if (viewportOrX === null) {
1649
- this._viewport = null;
1650
- return;
1651
- }
1652
- this._viewport = this._viewport || new THREE.Vector4();
1653
- if (typeof viewportOrX === "number") this._viewport.set(viewportOrX, y, width, height);
1654
- else this._viewport.copy(viewportOrX);
1655
- }
1656
- /**
1657
- * Calculate the distance to fit the box.
1658
- * @param width box width
1659
- * @param height box height
1660
- * @param depth box depth
1661
- * @returns distance
1662
- * @category Methods
1663
- */
1664
- getDistanceToFitBox(width, height, depth, cover = false) {
1665
- if (notSupportedInOrthographicCamera(this._camera, "getDistanceToFitBox")) return this._spherical.radius;
1666
- const boundingRectAspect = width / height;
1667
- const fov = this._camera.getEffectiveFOV() * DEG2RAD;
1668
- const aspect = this._camera.aspect;
1669
- return ((cover ? boundingRectAspect > aspect : boundingRectAspect < aspect) ? height : width / aspect) * .5 / Math.tan(fov * .5) + depth * .5;
1670
- }
1671
- /**
1672
- * Calculate the distance to fit the sphere.
1673
- * @param radius sphere radius
1674
- * @returns distance
1675
- * @category Methods
1676
- */
1677
- getDistanceToFitSphere(radius) {
1678
- if (notSupportedInOrthographicCamera(this._camera, "getDistanceToFitSphere")) return this._spherical.radius;
1679
- const vFOV = this._camera.getEffectiveFOV() * DEG2RAD;
1680
- const hFOV = Math.atan(Math.tan(vFOV * .5) * this._camera.aspect) * 2;
1681
- const fov = 1 < this._camera.aspect ? vFOV : hFOV;
1682
- return radius / Math.sin(fov * .5);
1683
- }
1684
- /**
1685
- * Returns the orbit center position, where the camera looking at.
1686
- * @param out The receiving Vector3 instance to copy the result
1687
- * @param receiveEndValue Whether receive the transition end coords or current. default is `true`
1688
- * @category Methods
1689
- */
1690
- getTarget(out, receiveEndValue = true) {
1691
- return (!!out && out.isVector3 ? out : new THREE.Vector3()).copy(receiveEndValue ? this._targetEnd : this._target);
1692
- }
1693
- /**
1694
- * Returns the camera position.
1695
- * @param out The receiving Vector3 instance to copy the result
1696
- * @param receiveEndValue Whether receive the transition end coords or current. default is `true`
1697
- * @category Methods
1698
- */
1699
- getPosition(out, receiveEndValue = true) {
1700
- return (!!out && out.isVector3 ? out : new THREE.Vector3()).setFromSpherical(receiveEndValue ? this._sphericalEnd : this._spherical).applyQuaternion(this._yAxisUpSpaceInverse).add(receiveEndValue ? this._targetEnd : this._target);
1701
- }
1702
- /**
1703
- * Returns the spherical coordinates of the orbit.
1704
- * @param out The receiving Spherical instance to copy the result
1705
- * @param receiveEndValue Whether receive the transition end coords or current. default is `true`
1706
- * @category Methods
1707
- */
1708
- getSpherical(out, receiveEndValue = true) {
1709
- return (out || new THREE.Spherical()).copy(receiveEndValue ? this._sphericalEnd : this._spherical);
1710
- }
1711
- /**
1712
- * Returns the focal offset, which is how much the camera appears to be translated in screen parallel coordinates.
1713
- * @param out The receiving Vector3 instance to copy the result
1714
- * @param receiveEndValue Whether receive the transition end coords or current. default is `true`
1715
- * @category Methods
1716
- */
1717
- getFocalOffset(out, receiveEndValue = true) {
1718
- return (!!out && out.isVector3 ? out : new THREE.Vector3()).copy(receiveEndValue ? this._focalOffsetEnd : this._focalOffset);
1719
- }
1720
- /**
1721
- * Normalize camera azimuth angle (horizontal rotation) between -180 and 180 degrees.
1722
- * @returns This CameraControls instance.
1723
- * @category Methods
1724
- */
1725
- normalizeRotations() {
1726
- this._sphericalEnd.theta = (this._sphericalEnd.theta % PI_2 + PI_2) % PI_2;
1727
- if (this._sphericalEnd.theta > Math.PI) this._sphericalEnd.theta -= PI_2;
1728
- this._spherical.theta += PI_2 * Math.round((this._sphericalEnd.theta - this._spherical.theta) / PI_2);
1729
- return this;
1730
- }
1731
- /**
1732
- * stop all transitions.
1733
- */
1734
- stop() {
1735
- this._focalOffset.copy(this._focalOffsetEnd);
1736
- this._target.copy(this._targetEnd);
1737
- this._spherical.copy(this._sphericalEnd);
1738
- this._zoom = this._zoomEnd;
1739
- }
1740
- /**
1741
- * Reset all rotation and position to defaults.
1742
- * @param enableTransition
1743
- * @category Methods
1744
- */
1745
- reset(enableTransition = false) {
1746
- if (!approxEquals(this._camera.up.x, this._cameraUp0.x) || !approxEquals(this._camera.up.y, this._cameraUp0.y) || !approxEquals(this._camera.up.z, this._cameraUp0.z)) {
1747
- this._camera.up.copy(this._cameraUp0);
1748
- const position = this.getPosition(_v3A);
1749
- this.updateCameraUp();
1750
- this.setPosition(position.x, position.y, position.z);
1751
- }
1752
- const promises = [
1753
- this.setLookAt(this._position0.x, this._position0.y, this._position0.z, this._target0.x, this._target0.y, this._target0.z, enableTransition),
1754
- this.setFocalOffset(this._focalOffset0.x, this._focalOffset0.y, this._focalOffset0.z, enableTransition),
1755
- this.zoomTo(this._zoom0, enableTransition)
1756
- ];
1757
- return Promise.all(promises);
1758
- }
1759
- /**
1760
- * Set current camera position as the default position.
1761
- * @category Methods
1762
- */
1763
- saveState() {
1764
- this._cameraUp0.copy(this._camera.up);
1765
- this.getTarget(this._target0);
1766
- this.getPosition(this._position0);
1767
- this._zoom0 = this._zoom;
1768
- this._focalOffset0.copy(this._focalOffset);
1769
- }
1770
- /**
1771
- * Sync camera-up direction.
1772
- * When camera-up vector is changed, `.updateCameraUp()` must be called.
1773
- * @category Methods
1774
- */
1775
- updateCameraUp() {
1776
- this._yAxisUpSpace.setFromUnitVectors(this._camera.up, _AXIS_Y);
1777
- this._yAxisUpSpaceInverse.copy(this._yAxisUpSpace).invert();
1778
- }
1779
- /**
1780
- * Apply current camera-up direction to the camera.
1781
- * The orbit system will be re-initialized with the current position.
1782
- * @category Methods
1783
- */
1784
- applyCameraUp() {
1785
- const cameraDirection = _v3A.subVectors(this._target, this._camera.position).normalize();
1786
- const side = _v3B.crossVectors(cameraDirection, this._camera.up);
1787
- this._camera.up.crossVectors(side, cameraDirection).normalize();
1788
- this._camera.updateMatrixWorld();
1789
- const position = this.getPosition(_v3A);
1790
- this.updateCameraUp();
1791
- this.setPosition(position.x, position.y, position.z);
1792
- }
1793
- /**
1794
- * Update camera position and directions.
1795
- * This should be called in your tick loop every time, and returns true if re-rendering is needed.
1796
- * @param delta
1797
- * @returns updated
1798
- * @category Methods
1799
- */
1800
- update(delta) {
1801
- const deltaTheta = this._sphericalEnd.theta - this._spherical.theta;
1802
- const deltaPhi = this._sphericalEnd.phi - this._spherical.phi;
1803
- const deltaRadius = this._sphericalEnd.radius - this._spherical.radius;
1804
- const deltaTarget = _deltaTarget.subVectors(this._targetEnd, this._target);
1805
- const deltaOffset = _deltaOffset.subVectors(this._focalOffsetEnd, this._focalOffset);
1806
- const deltaZoom = this._zoomEnd - this._zoom;
1807
- if (approxZero(deltaTheta)) {
1808
- this._thetaVelocity.value = 0;
1809
- this._spherical.theta = this._sphericalEnd.theta;
1810
- } else {
1811
- const smoothTime = this._isUserControllingRotate ? this.draggingSmoothTime : this.smoothTime;
1812
- this._spherical.theta = smoothDamp(this._spherical.theta, this._sphericalEnd.theta, this._thetaVelocity, smoothTime, Infinity, delta);
1813
- this._needsUpdate = true;
1814
- }
1815
- if (approxZero(deltaPhi)) {
1816
- this._phiVelocity.value = 0;
1817
- this._spherical.phi = this._sphericalEnd.phi;
1818
- } else {
1819
- const smoothTime = this._isUserControllingRotate ? this.draggingSmoothTime : this.smoothTime;
1820
- this._spherical.phi = smoothDamp(this._spherical.phi, this._sphericalEnd.phi, this._phiVelocity, smoothTime, Infinity, delta);
1821
- this._needsUpdate = true;
1822
- }
1823
- if (approxZero(deltaRadius)) {
1824
- this._radiusVelocity.value = 0;
1825
- this._spherical.radius = this._sphericalEnd.radius;
1826
- } else {
1827
- const smoothTime = this._isUserControllingDolly ? this.draggingSmoothTime : this.smoothTime;
1828
- this._spherical.radius = smoothDamp(this._spherical.radius, this._sphericalEnd.radius, this._radiusVelocity, smoothTime, this.maxSpeed, delta);
1829
- this._needsUpdate = true;
1830
- }
1831
- if (approxZero(deltaTarget.x) && approxZero(deltaTarget.y) && approxZero(deltaTarget.z)) {
1832
- this._targetVelocity.set(0, 0, 0);
1833
- this._target.copy(this._targetEnd);
1834
- } else {
1835
- const smoothTime = this._isUserControllingTruck ? this.draggingSmoothTime : this.smoothTime;
1836
- smoothDampVec3(this._target, this._targetEnd, this._targetVelocity, smoothTime, this.maxSpeed, delta, this._target);
1837
- this._needsUpdate = true;
1838
- }
1839
- if (approxZero(deltaOffset.x) && approxZero(deltaOffset.y) && approxZero(deltaOffset.z)) {
1840
- this._focalOffsetVelocity.set(0, 0, 0);
1841
- this._focalOffset.copy(this._focalOffsetEnd);
1842
- } else {
1843
- const smoothTime = this._isUserControllingOffset ? this.draggingSmoothTime : this.smoothTime;
1844
- smoothDampVec3(this._focalOffset, this._focalOffsetEnd, this._focalOffsetVelocity, smoothTime, this.maxSpeed, delta, this._focalOffset);
1845
- this._needsUpdate = true;
1846
- }
1847
- if (approxZero(deltaZoom)) {
1848
- this._zoomVelocity.value = 0;
1849
- this._zoom = this._zoomEnd;
1850
- } else {
1851
- const smoothTime = this._isUserControllingZoom ? this.draggingSmoothTime : this.smoothTime;
1852
- this._zoom = smoothDamp(this._zoom, this._zoomEnd, this._zoomVelocity, smoothTime, Infinity, delta);
1853
- }
1854
- if (this.dollyToCursor) {
1855
- if (isPerspectiveCamera(this._camera) && this._changedDolly !== 0) {
1856
- const dollyControlAmount = this._spherical.radius - this._lastDistance;
1857
- const camera = this._camera;
1858
- const cameraDirection = this._getCameraDirection(_cameraDirection);
1859
- const planeX = _v3A.copy(cameraDirection).cross(camera.up).normalize();
1860
- if (planeX.lengthSq() === 0) planeX.x = 1;
1861
- const planeY = _v3B.crossVectors(planeX, cameraDirection);
1862
- const worldToScreen = this._sphericalEnd.radius * Math.tan(camera.getEffectiveFOV() * DEG2RAD * .5);
1863
- const lerpRatio = (this._sphericalEnd.radius - dollyControlAmount - this._sphericalEnd.radius) / this._sphericalEnd.radius;
1864
- const cursor = _v3C.copy(this._targetEnd).add(planeX.multiplyScalar(this._dollyControlCoord.x * worldToScreen * camera.aspect)).add(planeY.multiplyScalar(this._dollyControlCoord.y * worldToScreen));
1865
- const newTargetEnd = _v3A.copy(this._targetEnd).lerp(cursor, lerpRatio);
1866
- const isMin = this._lastDollyDirection === DOLLY_DIRECTION.IN && this._spherical.radius <= this.minDistance;
1867
- const isMax = this._lastDollyDirection === DOLLY_DIRECTION.OUT && this.maxDistance <= this._spherical.radius;
1868
- if (this.infinityDolly && (isMin || isMax)) {
1869
- this._sphericalEnd.radius -= dollyControlAmount;
1870
- this._spherical.radius -= dollyControlAmount;
1871
- const dollyAmount = _v3B.copy(cameraDirection).multiplyScalar(-dollyControlAmount);
1872
- newTargetEnd.add(dollyAmount);
1873
- }
1874
- this._boundary.clampPoint(newTargetEnd, newTargetEnd);
1875
- const targetEndDiff = _v3B.subVectors(newTargetEnd, this._targetEnd);
1876
- this._targetEnd.copy(newTargetEnd);
1877
- this._target.add(targetEndDiff);
1878
- this._changedDolly -= dollyControlAmount;
1879
- if (approxZero(this._changedDolly)) this._changedDolly = 0;
1880
- } else if (isOrthographicCamera(this._camera) && this._changedZoom !== 0) {
1881
- const dollyControlAmount = this._zoom - this._lastZoom;
1882
- const camera = this._camera;
1883
- const worldCursorPosition = _v3A.set(this._dollyControlCoord.x, this._dollyControlCoord.y, (camera.near + camera.far) / (camera.near - camera.far)).unproject(camera);
1884
- const quaternion = _v3B.set(0, 0, -1).applyQuaternion(camera.quaternion);
1885
- const cursor = _v3C.copy(worldCursorPosition).add(quaternion.multiplyScalar(-worldCursorPosition.dot(camera.up)));
1886
- const lerpRatio = -(this._zoom - dollyControlAmount - this._zoom) / this._zoom;
1887
- const cameraDirection = this._getCameraDirection(_cameraDirection);
1888
- const prevPlaneConstant = this._targetEnd.dot(cameraDirection);
1889
- const newTargetEnd = _v3A.copy(this._targetEnd).lerp(cursor, lerpRatio);
1890
- const newPlaneConstant = newTargetEnd.dot(cameraDirection);
1891
- const pullBack = cameraDirection.multiplyScalar(newPlaneConstant - prevPlaneConstant);
1892
- newTargetEnd.sub(pullBack);
1893
- this._boundary.clampPoint(newTargetEnd, newTargetEnd);
1894
- const targetEndDiff = _v3B.subVectors(newTargetEnd, this._targetEnd);
1895
- this._targetEnd.copy(newTargetEnd);
1896
- this._target.add(targetEndDiff);
1897
- this._changedZoom -= dollyControlAmount;
1898
- if (approxZero(this._changedZoom)) this._changedZoom = 0;
1899
- }
1900
- }
1901
- if (this._camera.zoom !== this._zoom) {
1902
- this._camera.zoom = this._zoom;
1903
- this._camera.updateProjectionMatrix();
1904
- this._updateNearPlaneCorners();
1905
- this._needsUpdate = true;
1906
- }
1907
- this._dragNeedsUpdate = true;
1908
- const maxDistance = this._collisionTest();
1909
- this._spherical.radius = Math.min(this._spherical.radius, maxDistance);
1910
- this._spherical.makeSafe();
1911
- this._camera.position.setFromSpherical(this._spherical).applyQuaternion(this._yAxisUpSpaceInverse).add(this._target);
1912
- this._camera.lookAt(this._target);
1913
- if (!approxZero(this._focalOffset.x) || !approxZero(this._focalOffset.y) || !approxZero(this._focalOffset.z)) {
1914
- _xColumn.setFromMatrixColumn(this._camera.matrix, 0);
1915
- _yColumn.setFromMatrixColumn(this._camera.matrix, 1);
1916
- _zColumn.setFromMatrixColumn(this._camera.matrix, 2);
1917
- _xColumn.multiplyScalar(this._focalOffset.x);
1918
- _yColumn.multiplyScalar(-this._focalOffset.y);
1919
- _zColumn.multiplyScalar(this._focalOffset.z);
1920
- _v3A.copy(_xColumn).add(_yColumn).add(_zColumn);
1921
- this._camera.position.add(_v3A);
1922
- this._camera.updateMatrixWorld();
1923
- }
1924
- if (this._boundaryEnclosesCamera) this._encloseToBoundary(this._camera.position.copy(this._target), _v3A.setFromSpherical(this._spherical).applyQuaternion(this._yAxisUpSpaceInverse), 1);
1925
- const updated = this._needsUpdate;
1926
- if (updated && !this._updatedLastTime) {
1927
- this._hasRested = false;
1928
- this.dispatchEvent({ type: "wake" });
1929
- this.dispatchEvent({ type: "update" });
1930
- } else if (updated) {
1931
- this.dispatchEvent({ type: "update" });
1932
- if (approxZero(deltaTheta, this.restThreshold) && approxZero(deltaPhi, this.restThreshold) && approxZero(deltaRadius, this.restThreshold) && approxZero(deltaTarget.x, this.restThreshold) && approxZero(deltaTarget.y, this.restThreshold) && approxZero(deltaTarget.z, this.restThreshold) && approxZero(deltaOffset.x, this.restThreshold) && approxZero(deltaOffset.y, this.restThreshold) && approxZero(deltaOffset.z, this.restThreshold) && approxZero(deltaZoom, this.restThreshold) && !this._hasRested) {
1933
- this._hasRested = true;
1934
- this.dispatchEvent({ type: "rest" });
1935
- }
1936
- } else if (!updated && this._updatedLastTime) this.dispatchEvent({ type: "sleep" });
1937
- this._lastDistance = this._spherical.radius;
1938
- this._lastZoom = this._zoom;
1939
- this._updatedLastTime = updated;
1940
- this._needsUpdate = false;
1941
- return updated;
1942
- }
1943
- /**
1944
- * Get all state in JSON string
1945
- * @category Methods
1946
- */
1947
- toJSON() {
1948
- return JSON.stringify({
1949
- enabled: this._enabled,
1950
- minDistance: this.minDistance,
1951
- maxDistance: infinityToMaxNumber(this.maxDistance),
1952
- minZoom: this.minZoom,
1953
- maxZoom: infinityToMaxNumber(this.maxZoom),
1954
- minPolarAngle: this.minPolarAngle,
1955
- maxPolarAngle: infinityToMaxNumber(this.maxPolarAngle),
1956
- minAzimuthAngle: infinityToMaxNumber(this.minAzimuthAngle),
1957
- maxAzimuthAngle: infinityToMaxNumber(this.maxAzimuthAngle),
1958
- smoothTime: this.smoothTime,
1959
- draggingSmoothTime: this.draggingSmoothTime,
1960
- dollySpeed: this.dollySpeed,
1961
- truckSpeed: this.truckSpeed,
1962
- dollyToCursor: this.dollyToCursor,
1963
- target: this._targetEnd.toArray(),
1964
- position: _v3A.setFromSpherical(this._sphericalEnd).add(this._targetEnd).toArray(),
1965
- zoom: this._zoomEnd,
1966
- focalOffset: this._focalOffsetEnd.toArray(),
1967
- target0: this._target0.toArray(),
1968
- position0: this._position0.toArray(),
1969
- zoom0: this._zoom0,
1970
- focalOffset0: this._focalOffset0.toArray()
1971
- });
1972
- }
1973
- /**
1974
- * Reproduce the control state with JSON. enableTransition is where anim or not in a boolean.
1975
- * @param json
1976
- * @param enableTransition
1977
- * @category Methods
1978
- */
1979
- fromJSON(json, enableTransition = false) {
1980
- const obj = JSON.parse(json);
1981
- this.enabled = obj.enabled;
1982
- this.minDistance = obj.minDistance;
1983
- this.maxDistance = maxNumberToInfinity(obj.maxDistance);
1984
- this.minZoom = obj.minZoom;
1985
- this.maxZoom = maxNumberToInfinity(obj.maxZoom);
1986
- this.minPolarAngle = obj.minPolarAngle;
1987
- this.maxPolarAngle = maxNumberToInfinity(obj.maxPolarAngle);
1988
- this.minAzimuthAngle = maxNumberToInfinity(obj.minAzimuthAngle);
1989
- this.maxAzimuthAngle = maxNumberToInfinity(obj.maxAzimuthAngle);
1990
- this.smoothTime = obj.smoothTime;
1991
- this.draggingSmoothTime = obj.draggingSmoothTime;
1992
- this.dollySpeed = obj.dollySpeed;
1993
- this.truckSpeed = obj.truckSpeed;
1994
- this.dollyToCursor = obj.dollyToCursor;
1995
- this._target0.fromArray(obj.target0);
1996
- this._position0.fromArray(obj.position0);
1997
- this._zoom0 = obj.zoom0;
1998
- this._focalOffset0.fromArray(obj.focalOffset0);
1999
- this.moveTo(obj.target[0], obj.target[1], obj.target[2], enableTransition);
2000
- _sphericalA.setFromVector3(_v3A.fromArray(obj.position).sub(this._targetEnd).applyQuaternion(this._yAxisUpSpace));
2001
- this.rotateTo(_sphericalA.theta, _sphericalA.phi, enableTransition);
2002
- this.dollyTo(_sphericalA.radius, enableTransition);
2003
- this.zoomTo(obj.zoom, enableTransition);
2004
- this.setFocalOffset(obj.focalOffset[0], obj.focalOffset[1], obj.focalOffset[2], enableTransition);
2005
- this._needsUpdate = true;
2006
- }
2007
- /**
2008
- * Attach all internal event handlers to enable drag control.
2009
- * @category Methods
2010
- */
2011
- connect(domElement) {
2012
- if (this._domElement) {
2013
- console.warn("camera-controls is already connected.");
2014
- return;
2015
- }
2016
- domElement.setAttribute("data-camera-controls-version", VERSION);
2017
- this._addAllEventListeners(domElement);
2018
- this._getClientRect(this._elementRect);
2019
- }
2020
- /**
2021
- * Detach all internal event handlers to disable drag control.
2022
- */
2023
- disconnect() {
2024
- this.cancel();
2025
- this._removeAllEventListeners();
2026
- if (this._domElement) {
2027
- this._domElement.removeAttribute("data-camera-controls-version");
2028
- this._domElement = void 0;
2029
- }
2030
- }
2031
- /**
2032
- * Dispose the cameraControls instance itself, remove all eventListeners.
2033
- * @category Methods
2034
- */
2035
- dispose() {
2036
- this.removeAllEventListeners();
2037
- this.disconnect();
2038
- }
2039
- _getTargetDirection(out) {
2040
- return out.setFromSpherical(this._spherical).divideScalar(this._spherical.radius).applyQuaternion(this._yAxisUpSpaceInverse);
2041
- }
2042
- _getCameraDirection(out) {
2043
- return this._getTargetDirection(out).negate();
2044
- }
2045
- _findPointerById(pointerId) {
2046
- return this._activePointers.find((activePointer) => activePointer.pointerId === pointerId);
2047
- }
2048
- _findPointerByMouseButton(mouseButton) {
2049
- return this._activePointers.find((activePointer) => activePointer.mouseButton === mouseButton);
2050
- }
2051
- _disposePointer(pointer) {
2052
- this._activePointers.splice(this._activePointers.indexOf(pointer), 1);
2053
- }
2054
- _encloseToBoundary(position, offset, friction) {
2055
- const offsetLength2 = offset.lengthSq();
2056
- if (offsetLength2 === 0) return position;
2057
- const newTarget = _v3B.copy(offset).add(position);
2058
- const deltaClampedTarget = this._boundary.clampPoint(newTarget, _v3C).sub(newTarget);
2059
- const deltaClampedTargetLength2 = deltaClampedTarget.lengthSq();
2060
- if (deltaClampedTargetLength2 === 0) return position.add(offset);
2061
- else if (deltaClampedTargetLength2 === offsetLength2) return position;
2062
- else if (friction === 0) return position.add(offset).add(deltaClampedTarget);
2063
- else {
2064
- const offsetFactor = 1 + friction * deltaClampedTargetLength2 / offset.dot(deltaClampedTarget);
2065
- return position.add(_v3B.copy(offset).multiplyScalar(offsetFactor)).add(deltaClampedTarget.multiplyScalar(1 - friction));
2066
- }
2067
- }
2068
- _updateNearPlaneCorners() {
2069
- if (isPerspectiveCamera(this._camera)) {
2070
- const camera = this._camera;
2071
- const near = camera.near;
2072
- const fov = camera.getEffectiveFOV() * DEG2RAD;
2073
- const heightHalf = Math.tan(fov * .5) * near;
2074
- const widthHalf = heightHalf * camera.aspect;
2075
- this._nearPlaneCorners[0].set(-widthHalf, -heightHalf, 0);
2076
- this._nearPlaneCorners[1].set(widthHalf, -heightHalf, 0);
2077
- this._nearPlaneCorners[2].set(widthHalf, heightHalf, 0);
2078
- this._nearPlaneCorners[3].set(-widthHalf, heightHalf, 0);
2079
- } else if (isOrthographicCamera(this._camera)) {
2080
- const camera = this._camera;
2081
- const zoomInv = 1 / camera.zoom;
2082
- const left = camera.left * zoomInv;
2083
- const right = camera.right * zoomInv;
2084
- const top = camera.top * zoomInv;
2085
- const bottom = camera.bottom * zoomInv;
2086
- this._nearPlaneCorners[0].set(left, top, 0);
2087
- this._nearPlaneCorners[1].set(right, top, 0);
2088
- this._nearPlaneCorners[2].set(right, bottom, 0);
2089
- this._nearPlaneCorners[3].set(left, bottom, 0);
2090
- }
2091
- }
2092
- _collisionTest() {
2093
- let distance = Infinity;
2094
- if (!(this.colliderMeshes.length >= 1)) return distance;
2095
- if (notSupportedInOrthographicCamera(this._camera, "_collisionTest")) return distance;
2096
- const rayDirection = this._getTargetDirection(_cameraDirection);
2097
- _rotationMatrix.lookAt(_ORIGIN, rayDirection, this._camera.up);
2098
- for (let i = 0; i < 4; i++) {
2099
- const nearPlaneCorner = _v3B.copy(this._nearPlaneCorners[i]);
2100
- nearPlaneCorner.applyMatrix4(_rotationMatrix);
2101
- const origin = _v3C.addVectors(this._target, nearPlaneCorner);
2102
- _raycaster.set(origin, rayDirection);
2103
- _raycaster.far = this._spherical.radius + 1;
2104
- const intersects = _raycaster.intersectObjects(this.colliderMeshes);
2105
- if (intersects.length !== 0 && intersects[0].distance < distance) distance = intersects[0].distance;
2106
- }
2107
- return distance;
2108
- }
2109
- /**
2110
- * Get its client rect and package into given `DOMRect` .
2111
- */
2112
- _getClientRect(target) {
2113
- if (!this._domElement) return;
2114
- const rect = this._domElement.getBoundingClientRect();
2115
- target.x = rect.left;
2116
- target.y = rect.top;
2117
- if (this._viewport) {
2118
- target.x += this._viewport.x;
2119
- target.y += rect.height - this._viewport.w - this._viewport.y;
2120
- target.width = this._viewport.z;
2121
- target.height = this._viewport.w;
2122
- } else {
2123
- target.width = rect.width;
2124
- target.height = rect.height;
2125
- }
2126
- return target;
2127
- }
2128
- _createOnRestPromise(resolveImmediately) {
2129
- if (resolveImmediately) return Promise.resolve();
2130
- this._hasRested = false;
2131
- this.dispatchEvent({ type: "transitionstart" });
2132
- return new Promise((resolve) => {
2133
- const onResolve = () => {
2134
- this.removeEventListener("rest", onResolve);
2135
- resolve();
2136
- };
2137
- this.addEventListener("rest", onResolve);
2138
- });
2139
- }
2140
- _addAllEventListeners(_domElement) {}
2141
- _removeAllEventListeners() {}
2142
- /**
2143
- * backward compatible
2144
- * @deprecated use smoothTime (in seconds) instead
2145
- * @category Properties
2146
- */
2147
- get dampingFactor() {
2148
- console.warn(".dampingFactor has been deprecated. use smoothTime (in seconds) instead.");
2149
- return 0;
2150
- }
2151
- /**
2152
- * backward compatible
2153
- * @deprecated use smoothTime (in seconds) instead
2154
- * @category Properties
2155
- */
2156
- set dampingFactor(_) {
2157
- console.warn(".dampingFactor has been deprecated. use smoothTime (in seconds) instead.");
2158
- }
2159
- /**
2160
- * backward compatible
2161
- * @deprecated use draggingSmoothTime (in seconds) instead
2162
- * @category Properties
2163
- */
2164
- get draggingDampingFactor() {
2165
- console.warn(".draggingDampingFactor has been deprecated. use draggingSmoothTime (in seconds) instead.");
2166
- return 0;
2167
- }
2168
- /**
2169
- * backward compatible
2170
- * @deprecated use draggingSmoothTime (in seconds) instead
2171
- * @category Properties
2172
- */
2173
- set draggingDampingFactor(_) {
2174
- console.warn(".draggingDampingFactor has been deprecated. use draggingSmoothTime (in seconds) instead.");
2175
- }
2176
- static createBoundingSphere(object3d, out = new THREE.Sphere()) {
2177
- const boundingSphere = out;
2178
- const center = boundingSphere.center;
2179
- _box3A.makeEmpty();
2180
- object3d.traverseVisible((object) => {
2181
- if (!object.isMesh) return;
2182
- _box3A.expandByObject(object);
2183
- });
2184
- _box3A.getCenter(center);
2185
- let maxRadiusSq = 0;
2186
- object3d.traverseVisible((object) => {
2187
- if (!object.isMesh) return;
2188
- const mesh = object;
2189
- if (!mesh.geometry) return;
2190
- const geometry = mesh.geometry.clone();
2191
- geometry.applyMatrix4(mesh.matrixWorld);
2192
- const position = geometry.attributes.position;
2193
- for (let i = 0, l = position.count; i < l; i++) {
2194
- _v3A.fromBufferAttribute(position, i);
2195
- maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_v3A));
2196
- }
2197
- });
2198
- boundingSphere.radius = Math.sqrt(maxRadiusSq);
2199
- return boundingSphere;
2200
- }
2201
- };
2202
- exports.EventDispatcher = EventDispatcher;
2203
- exports.default = CameraControls;
2204
- }));
2205
-
2206
- //#endregion
2207
- export { require_camera_controls as t };