@shapediver/viewer.rendering-engine.camera-engine 3.16.8 → 3.16.10

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 (60) hide show
  1. package/dist/implementation/CameraEngine.d.ts +42 -42
  2. package/dist/implementation/CameraEngine.js +607 -607
  3. package/dist/implementation/CameraEngine.js.map +1 -1
  4. package/dist/implementation/camera/AbstractCamera.d.ts +90 -90
  5. package/dist/implementation/camera/AbstractCamera.js +354 -354
  6. package/dist/implementation/camera/AbstractCamera.js.map +1 -1
  7. package/dist/implementation/camera/OrthographicCamera.d.ts +37 -37
  8. package/dist/implementation/camera/OrthographicCamera.js +268 -268
  9. package/dist/implementation/camera/OrthographicCamera.js.map +1 -1
  10. package/dist/implementation/camera/PerspectiveCamera.d.ts +28 -28
  11. package/dist/implementation/camera/PerspectiveCamera.js +250 -250
  12. package/dist/implementation/camera/PerspectiveCamera.js.map +1 -1
  13. package/dist/implementation/controls/AbstractCameraControls.d.ts +217 -217
  14. package/dist/implementation/controls/AbstractCameraControls.js +635 -635
  15. package/dist/implementation/controls/AbstractCameraControls.js.map +1 -1
  16. package/dist/implementation/controls/CameraControlsEventDistribution.d.ts +39 -39
  17. package/dist/implementation/controls/CameraControlsEventDistribution.d.ts.map +1 -1
  18. package/dist/implementation/controls/CameraControlsEventDistribution.js +287 -287
  19. package/dist/implementation/controls/CameraControlsEventDistribution.js.map +1 -1
  20. package/dist/implementation/controls/CameraControlsLogic.d.ts +36 -36
  21. package/dist/implementation/controls/CameraControlsLogic.js +530 -530
  22. package/dist/implementation/controls/CameraControlsLogic.js.map +1 -1
  23. package/dist/implementation/controls/OrthographicCameraControls.d.ts +7 -7
  24. package/dist/implementation/controls/OrthographicCameraControls.js +34 -34
  25. package/dist/implementation/controls/PerspectiveCameraControls.d.ts +7 -7
  26. package/dist/implementation/controls/PerspectiveCameraControls.js +34 -34
  27. package/dist/implementation/interpolation/CameraInterpolationManager.d.ts +22 -22
  28. package/dist/implementation/interpolation/CameraInterpolationManager.js +165 -155
  29. package/dist/implementation/interpolation/CameraInterpolationManager.js.map +1 -1
  30. package/dist/implementation/interpolation/interpolationMethods/CameraCylindricalInterpolation.d.ts +36 -36
  31. package/dist/implementation/interpolation/interpolationMethods/CameraCylindricalInterpolation.js +57 -57
  32. package/dist/implementation/interpolation/interpolationMethods/CameraLinearInterpolation.d.ts +26 -26
  33. package/dist/implementation/interpolation/interpolationMethods/CameraLinearInterpolation.js +31 -31
  34. package/dist/implementation/interpolation/interpolationMethods/CameraMultipleInterpolation.d.ts +35 -35
  35. package/dist/implementation/interpolation/interpolationMethods/CameraMultipleInterpolation.js +45 -45
  36. package/dist/implementation/interpolation/interpolationMethods/CameraMultipleInterpolation.js.map +1 -1
  37. package/dist/implementation/interpolation/interpolationMethods/CameraOrthographicInterpolation.d.ts +26 -26
  38. package/dist/implementation/interpolation/interpolationMethods/CameraOrthographicInterpolation.js +31 -31
  39. package/dist/implementation/interpolation/interpolationMethods/CameraSphericalInterpolation.d.ts +32 -32
  40. package/dist/implementation/interpolation/interpolationMethods/CameraSphericalInterpolation.js +42 -42
  41. package/dist/index.d.ts +16 -16
  42. package/dist/index.js +18 -18
  43. package/dist/interfaces/ICameraEngine.d.ts +12 -12
  44. package/dist/interfaces/ICameraEngine.js +3 -3
  45. package/dist/interfaces/camera/ICamera.d.ts +47 -47
  46. package/dist/interfaces/camera/ICamera.js +2 -2
  47. package/dist/interfaces/camera/IOrthographicCamera.d.ts +8 -8
  48. package/dist/interfaces/camera/IOrthographicCamera.js +3 -3
  49. package/dist/interfaces/camera/IPerspectiveCamera.d.ts +7 -7
  50. package/dist/interfaces/camera/IPerspectiveCamera.js +2 -2
  51. package/dist/interfaces/controls/ICameraControls.d.ts +105 -105
  52. package/dist/interfaces/controls/ICameraControls.d.ts.map +1 -1
  53. package/dist/interfaces/controls/ICameraControls.js +3 -3
  54. package/dist/interfaces/controls/ICameraControlsEventDistribution.d.ts +6 -6
  55. package/dist/interfaces/controls/ICameraControlsEventDistribution.js +2 -2
  56. package/dist/interfaces/controls/ICameraControlsLogic.d.ts +14 -14
  57. package/dist/interfaces/controls/ICameraControlsLogic.js +2 -2
  58. package/dist/interfaces/interpolation/ICameraInterpolation.d.ts +11 -11
  59. package/dist/interfaces/interpolation/ICameraInterpolation.js +2 -2
  60. package/package.json +8 -8
@@ -1,531 +1,531 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CameraControlsLogic = void 0;
4
- const viewer_shared_math_1 = require("@shapediver/viewer.shared.math");
5
- const viewer_shared_types_1 = require("@shapediver/viewer.shared.types");
6
- const gl_matrix_1 = require("gl-matrix");
7
- const OrthographicCamera_1 = require("../camera/OrthographicCamera");
8
- class CameraControlsLogic {
9
- // #endregion Properties (13)
10
- // #region Constructors (1)
11
- constructor(_controls, _settingsAdjustments, _touchAdjustments) {
12
- this._controls = _controls;
13
- this._settingsAdjustments = _settingsAdjustments;
14
- this._touchAdjustments = _touchAdjustments;
15
- // #region Properties (13)
16
- this._adjustedSettings = {
17
- autoRotationSpeed: () => this._controls.autoRotationSpeed *
18
- this._settingsAdjustments.autoRotationSpeed,
19
- damping: () => this._controls.damping * this._settingsAdjustments.damping,
20
- movementSmoothness: () => this._controls.movementSmoothness *
21
- this._settingsAdjustments.movementSmoothness,
22
- panSpeed: () => this._controls.panSpeed * this._settingsAdjustments.panSpeed,
23
- rotationSpeed: () => this._controls.rotationSpeed *
24
- this._settingsAdjustments.rotationSpeed,
25
- zoomSpeed: () => this._controls.zoomSpeed * this._settingsAdjustments.zoomSpeed,
26
- };
27
- this._damping = {
28
- rotation: {
29
- time: 0,
30
- duration: 0,
31
- theta: 0,
32
- phi: 0,
33
- },
34
- zoom: {
35
- time: 0,
36
- duration: 0,
37
- delta: 0,
38
- },
39
- pan: {
40
- time: 0,
41
- duration: 0,
42
- offset: gl_matrix_1.vec3.create(),
43
- },
44
- };
45
- this._dollyDelta = 0;
46
- this._dollyEnd = 0;
47
- this._dollyStart = 0;
48
- this._panDelta = gl_matrix_1.vec2.create();
49
- this._panEnd = gl_matrix_1.vec2.create();
50
- this._panStart = gl_matrix_1.vec2.create();
51
- this._rotateDelta = gl_matrix_1.vec2.create();
52
- this._rotateEnd = gl_matrix_1.vec2.create();
53
- this._rotateStart = gl_matrix_1.vec2.create();
54
- this._quat = gl_matrix_1.quat.fromValues(-Math.sin(Math.PI / 4), 0, 0, Math.sin(Math.PI / 4));
55
- this._quatInverse = gl_matrix_1.quat.fromValues(Math.sin(Math.PI / 4), 0, 0, Math.sin(Math.PI / 4));
56
- }
57
- // #endregion Constructors (1)
58
- // #region Public Methods (7)
59
- isWithinRestrictions(position, target) {
60
- const pBox = new viewer_shared_math_1.Box(this._controls.cubePositionRestriction.min, this._controls.cubePositionRestriction.max), pSphere = new viewer_shared_math_1.Sphere(this._controls.spherePositionRestriction.center, this._controls.spherePositionRestriction.radius), tBox = new viewer_shared_math_1.Box(this._controls.cubeTargetRestriction.min, this._controls.cubeTargetRestriction.max), tSphere = new viewer_shared_math_1.Sphere(this._controls.sphereTargetRestriction.center, this._controls.sphereTargetRestriction.radius);
61
- if (!(pBox.containsPoint(position) && pSphere.containsPoint(position)))
62
- return false;
63
- if (!(tBox.containsPoint(target) && tSphere.containsPoint(target)))
64
- return false;
65
- const currentDistance = gl_matrix_1.vec3.distance(position, target);
66
- if (currentDistance > this._controls.zoomRestriction.maxDistance ||
67
- currentDistance < this._controls.zoomRestriction.minDistance)
68
- return false;
69
- const minPolarAngle = this._controls.rotationRestriction.minPolarAngle *
70
- (Math.PI / 180), maxPolarAngle = this._controls.rotationRestriction.maxPolarAngle *
71
- (Math.PI / 180), minAzimuthAngle = this._controls.rotationRestriction.minAzimuthAngle *
72
- (Math.PI / 180), maxAzimuthAngle = this._controls.rotationRestriction.maxAzimuthAngle *
73
- (Math.PI / 180);
74
- if (minAzimuthAngle !== -Infinity ||
75
- maxAzimuthAngle !== Infinity ||
76
- minPolarAngle !== 0 ||
77
- maxPolarAngle !== 180) {
78
- const offset = gl_matrix_1.vec3.sub(gl_matrix_1.vec3.create(), position, target);
79
- gl_matrix_1.vec3.transformQuat(offset, offset, this._quat);
80
- const spherical = new viewer_shared_math_1.Spherical().fromVec3(offset);
81
- if (spherical.theta < minAzimuthAngle ||
82
- spherical.theta > maxAzimuthAngle ||
83
- spherical.phi < minPolarAngle ||
84
- spherical.phi > maxPolarAngle) {
85
- return false;
86
- }
87
- }
88
- return true;
89
- }
90
- pan(x, y, active, touch) {
91
- if (!active) {
92
- this._panStart = gl_matrix_1.vec2.fromValues(x, y);
93
- }
94
- else {
95
- this._panEnd = gl_matrix_1.vec2.fromValues(x, y);
96
- gl_matrix_1.vec2.sub(this._panDelta, this._panEnd, this._panStart);
97
- if (this._panDelta[0] === 0 && this._panDelta[1] === 0)
98
- return;
99
- gl_matrix_1.vec2.copy(this._panStart, this._panEnd);
100
- const adjustedPanSpeed = this._adjustedSettings.panSpeed() *
101
- (touch ? this._touchAdjustments.panSpeed : 1.0);
102
- const offset = this.panDeltaToOffset(gl_matrix_1.vec2.mul(gl_matrix_1.vec2.create(), this._panDelta, gl_matrix_1.vec2.fromValues(adjustedPanSpeed, adjustedPanSpeed)));
103
- if (this._damping.pan.duration > 0) {
104
- if (offset[0] < 0) {
105
- offset[0] = Math.min(offset[0], this._adjustedSettings.movementSmoothness() *
106
- this._damping.pan.offset[0]);
107
- }
108
- else {
109
- offset[0] = Math.max(offset[0], this._adjustedSettings.movementSmoothness() *
110
- this._damping.pan.offset[0]);
111
- }
112
- if (offset[1] < 0) {
113
- offset[1] = Math.min(offset[1], this._adjustedSettings.movementSmoothness() *
114
- this._damping.pan.offset[1]);
115
- }
116
- else {
117
- offset[1] = Math.max(offset[1], this._adjustedSettings.movementSmoothness() *
118
- this._damping.pan.offset[1]);
119
- }
120
- if (offset[2] < 0) {
121
- offset[2] = Math.min(offset[2], this._adjustedSettings.movementSmoothness() *
122
- this._damping.pan.offset[2]);
123
- }
124
- else {
125
- offset[2] = Math.max(offset[2], this._adjustedSettings.movementSmoothness() *
126
- this._damping.pan.offset[2]);
127
- }
128
- }
129
- const damping = 1 -
130
- Math.max(0.01, Math.min(0.99, this._adjustedSettings.damping()));
131
- const framesOffsetX = (Math.log(1 / Math.abs(offset[0])) - 5 * Math.log(10)) /
132
- Math.log(damping);
133
- const framesOffsetY = (Math.log(1 / Math.abs(offset[1])) - 5 * Math.log(10)) /
134
- Math.log(damping);
135
- const framesOffsetZ = (Math.log(1 / Math.abs(offset[2])) - 5 * Math.log(10)) /
136
- Math.log(damping);
137
- this._damping.pan.time = 0;
138
- this._damping.pan.duration =
139
- Math.max(framesOffsetX, Math.max(framesOffsetY, framesOffsetZ)) * 16.6666;
140
- this._damping.pan.offset = gl_matrix_1.vec3.clone(offset);
141
- this._damping.rotation.duration = 0;
142
- this._damping.zoom.duration = 0;
143
- this._controls.applyTargetVector(offset, true);
144
- this._controls.applyPositionVector(offset, true);
145
- }
146
- }
147
- reset() {
148
- this._damping = {
149
- rotation: {
150
- time: 0,
151
- duration: 0,
152
- theta: 0,
153
- phi: 0,
154
- },
155
- zoom: {
156
- time: 0,
157
- duration: 0,
158
- delta: 0,
159
- },
160
- pan: {
161
- time: 0,
162
- duration: 0,
163
- offset: gl_matrix_1.vec3.create(),
164
- },
165
- };
166
- this._dollyDelta = 0;
167
- this._dollyEnd = 0;
168
- this._dollyStart = 0;
169
- this._panDelta = gl_matrix_1.vec2.create();
170
- this._panEnd = gl_matrix_1.vec2.create();
171
- this._panStart = gl_matrix_1.vec2.create();
172
- this._rotateDelta = gl_matrix_1.vec2.create();
173
- this._rotateEnd = gl_matrix_1.vec2.create();
174
- this._rotateStart = gl_matrix_1.vec2.create();
175
- }
176
- restrict(position, target, sceneRotation) {
177
- const pBox = new viewer_shared_math_1.Box(this._controls.cubePositionRestriction.min, this._controls.cubePositionRestriction.max), pSphere = new viewer_shared_math_1.Sphere(this._controls.spherePositionRestriction.center, this._controls.spherePositionRestriction.radius), tBox = new viewer_shared_math_1.Box(this._controls.cubeTargetRestriction.min, this._controls.cubeTargetRestriction.max), tSphere = new viewer_shared_math_1.Sphere(this._controls.sphereTargetRestriction.center, this._controls.sphereTargetRestriction.radius);
178
- if (!pBox.containsPoint(position))
179
- position = pBox.clampPoint(position);
180
- if (!pSphere.containsPoint(position))
181
- position = pSphere.clampPoint(position);
182
- if (!tBox.containsPoint(target))
183
- target = tBox.clampPoint(target);
184
- if (!tSphere.containsPoint(target))
185
- target = tSphere.clampPoint(target);
186
- // zoom restrictions
187
- const currentDistance = gl_matrix_1.vec3.distance(position, target);
188
- if (currentDistance > this._controls.zoomRestriction.maxDistance ||
189
- currentDistance < this._controls.zoomRestriction.minDistance) {
190
- const direction = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), position, target));
191
- const distance = Math.max(this._controls.zoomRestriction.minDistance, Math.min(this._controls.zoomRestriction.maxDistance, currentDistance));
192
- gl_matrix_1.vec3.add(position, gl_matrix_1.vec3.multiply(position, direction, gl_matrix_1.vec3.fromValues(distance, distance, distance)), target);
193
- }
194
- // angle restrictions
195
- const minPolarAngle = this._controls.rotationRestriction.minPolarAngle *
196
- (Math.PI / 180), maxPolarAngle = this._controls.rotationRestriction.maxPolarAngle *
197
- (Math.PI / 180), minAzimuthAngle = this._controls.rotationRestriction.minAzimuthAngle *
198
- (Math.PI / 180), maxAzimuthAngle = this._controls.rotationRestriction.maxAzimuthAngle *
199
- (Math.PI / 180);
200
- if (minAzimuthAngle !== -Infinity ||
201
- maxAzimuthAngle !== Infinity ||
202
- minPolarAngle !== 0 ||
203
- maxPolarAngle !== 180 ||
204
- this._controls.enableAzimuthRotation === false ||
205
- this._controls.enablePolarRotation === false ||
206
- this._controls.enableObjectControls === true) {
207
- let offset = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), position, target);
208
- gl_matrix_1.vec3.transformQuat(offset, offset, this._quat);
209
- const spherical = new viewer_shared_math_1.Spherical().fromVec3(offset);
210
- if (spherical.theta < minAzimuthAngle ||
211
- spherical.theta > maxAzimuthAngle ||
212
- spherical.phi < minPolarAngle ||
213
- spherical.phi > maxPolarAngle ||
214
- this._controls.enableAzimuthRotation === false ||
215
- this._controls.enablePolarRotation === false ||
216
- this._controls.enableObjectControls === true) {
217
- spherical.theta = Math.max(minAzimuthAngle, Math.min(maxAzimuthAngle, spherical.theta));
218
- spherical.phi = Math.max(minPolarAngle, Math.min(maxPolarAngle, spherical.phi));
219
- if (this._controls.enableAzimuthRotation === false ||
220
- this._controls.enablePolarRotation === false ||
221
- this._controls.enableObjectControls === true) {
222
- const defaultOffset = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), this._controls.camera.defaultPosition, this._controls.camera.defaultTarget);
223
- gl_matrix_1.vec3.transformQuat(defaultOffset, defaultOffset, this._quat);
224
- const defaultSpherical = new viewer_shared_math_1.Spherical().fromVec3(defaultOffset);
225
- if (this._controls.enableAzimuthRotation === false)
226
- spherical.theta = defaultSpherical.theta;
227
- if (this._controls.enablePolarRotation === false)
228
- spherical.phi = defaultSpherical.phi;
229
- if (this._controls.enableObjectControls) {
230
- spherical.theta = defaultSpherical.theta;
231
- spherical.phi = defaultSpherical.phi;
232
- }
233
- }
234
- spherical.makeSafe();
235
- offset = spherical.toVec3();
236
- gl_matrix_1.vec3.transformQuat(offset, offset, this._quatInverse);
237
- gl_matrix_1.vec3.add(position, offset, target);
238
- }
239
- if ((sceneRotation[1] < minAzimuthAngle ||
240
- sceneRotation[1] > maxAzimuthAngle ||
241
- sceneRotation[0] < minPolarAngle ||
242
- sceneRotation[0] > maxPolarAngle ||
243
- this._controls.enableAzimuthRotation === false ||
244
- this._controls.enablePolarRotation === false) &&
245
- this._controls.enableObjectControls === false) {
246
- sceneRotation[1] =
247
- this._controls.enableAzimuthRotation === false
248
- ? 0
249
- : Math.max(minAzimuthAngle, Math.min(maxAzimuthAngle, sceneRotation[1]));
250
- sceneRotation[0] =
251
- this._controls.enablePolarRotation === false
252
- ? 0
253
- : Math.max(minPolarAngle, Math.min(maxPolarAngle, sceneRotation[0]));
254
- }
255
- }
256
- return { position, target, sceneRotation };
257
- }
258
- rotate(x, y, active, touch) {
259
- if (this._controls.camera.type === viewer_shared_types_1.CAMERA_TYPE.ORTHOGRAPHIC &&
260
- this._controls.camera.direction !==
261
- viewer_shared_types_1.ORTHOGRAPHIC_CAMERA_DIRECTION.CUSTOM)
262
- return;
263
- if (!active) {
264
- this._rotateStart = gl_matrix_1.vec2.fromValues(x, y);
265
- }
266
- else {
267
- this._rotateEnd = gl_matrix_1.vec2.fromValues(x, y);
268
- gl_matrix_1.vec2.subtract(this._rotateDelta, this._rotateEnd, this._rotateStart);
269
- gl_matrix_1.vec2.copy(this._rotateStart, this._rotateEnd);
270
- if (!this._controls.canvas)
271
- return;
272
- if (this._controls.canvas.clientWidth == 0 ||
273
- this._controls.canvas.clientHeight == 0)
274
- return;
275
- const spherical = new viewer_shared_math_1.Spherical();
276
- const rotationSpeed = this._adjustedSettings.rotationSpeed() *
277
- (touch ? this._touchAdjustments.rotationSpeed : 1.0);
278
- spherical.theta -=
279
- (rotationSpeed * this._rotateDelta[0]) /
280
- this._controls.canvas.clientHeight;
281
- spherical.phi -=
282
- (rotationSpeed * this._rotateDelta[1]) /
283
- this._controls.canvas.clientHeight;
284
- if (this._damping.rotation.duration > 0) {
285
- const thetaDelta = this._damping.rotation.theta - spherical.theta;
286
- spherical.theta +=
287
- thetaDelta * this._adjustedSettings.movementSmoothness();
288
- const phiDelta = this._damping.rotation.phi - spherical.phi;
289
- spherical.phi +=
290
- phiDelta * this._adjustedSettings.movementSmoothness();
291
- }
292
- let sphericalForOffset = spherical;
293
- if (this._controls.enableTurntableControls)
294
- sphericalForOffset = new viewer_shared_math_1.Spherical(1.0, spherical.phi, 0);
295
- const offset = this.rotationSphericalToOffset(sphericalForOffset);
296
- const damping = 1 -
297
- Math.max(0.01, Math.min(1, this._adjustedSettings.damping()));
298
- const framesTheta = (Math.log(1 / Math.abs(spherical.theta)) - 5 * Math.log(10)) /
299
- Math.log(damping);
300
- const framesPhi = (Math.log(1 / Math.abs(spherical.phi)) - 5 * Math.log(10)) /
301
- Math.log(damping);
302
- this._damping.rotation.time = 0;
303
- this._damping.rotation.duration =
304
- Math.max(framesTheta, framesPhi) * 16.6666;
305
- this._damping.rotation.theta = spherical.theta;
306
- this._damping.rotation.phi = spherical.phi;
307
- this._damping.pan.duration = 0;
308
- this._damping.zoom.duration = 0;
309
- this._controls.applyPositionVector(offset, true);
310
- if (this._controls.enableTurntableControls)
311
- this._controls.applyRotation([0, spherical.theta], true);
312
- if (this._controls.enableObjectControls)
313
- this._controls.applyRotation([spherical.phi, spherical.theta], true);
314
- }
315
- }
316
- update(time, manualInteraction) {
317
- if (manualInteraction === true) {
318
- this._damping.zoom.duration = 0;
319
- this._damping.pan.duration = 0;
320
- this._damping.rotation.duration = 0;
321
- }
322
- const damping = 1 - Math.max(0.01, Math.min(1, this._adjustedSettings.damping()));
323
- if (this._damping.pan.duration > 0) {
324
- if (this._damping.pan.time + time > this._damping.pan.duration) {
325
- this._damping.pan.time = this._damping.pan.duration;
326
- this._damping.pan.duration = 0;
327
- }
328
- else {
329
- this._damping.pan.time += time;
330
- const frameSinceStart = this._damping.pan.time / 16.6666;
331
- const dampingFrames = Math.pow(damping, frameSinceStart);
332
- const offset = gl_matrix_1.vec3.multiply(gl_matrix_1.vec3.create(), this._damping.pan.offset, gl_matrix_1.vec3.fromValues(dampingFrames, dampingFrames, dampingFrames));
333
- this._controls.applyTargetVector(offset);
334
- this._controls.applyPositionVector(offset);
335
- }
336
- }
337
- else {
338
- this._damping.pan.time = 0;
339
- }
340
- if (this._damping.rotation.duration > 0) {
341
- if (this._damping.rotation.time + time >
342
- this._damping.rotation.duration) {
343
- this._damping.rotation.time = this._damping.rotation.duration;
344
- this._damping.rotation.duration = 0;
345
- }
346
- else {
347
- this._damping.rotation.time += time;
348
- const frameSinceStart = this._damping.rotation.time / 16.6666;
349
- const spherical = new viewer_shared_math_1.Spherical();
350
- spherical.theta =
351
- this._damping.rotation.theta *
352
- Math.pow(damping, frameSinceStart);
353
- spherical.phi =
354
- this._damping.rotation.phi *
355
- Math.pow(damping, frameSinceStart);
356
- let sphericalForOffset = spherical;
357
- if (this._controls.enableTurntableControls)
358
- sphericalForOffset = new viewer_shared_math_1.Spherical(1.0, spherical.phi, 0);
359
- const offset = this.rotationSphericalToOffset(sphericalForOffset);
360
- this._controls.applyPositionVector(offset);
361
- if (this._controls.enableTurntableControls)
362
- this._controls.applyRotation([0, spherical.theta]);
363
- if (this._controls.enableObjectControls)
364
- this._controls.applyRotation([
365
- spherical.phi,
366
- spherical.theta,
367
- ]);
368
- }
369
- }
370
- else {
371
- this._damping.rotation.time = 0;
372
- }
373
- if (this._damping.zoom.duration > 0) {
374
- if (this._damping.zoom.time + time > this._damping.zoom.duration) {
375
- this._damping.zoom.time = this._damping.zoom.duration;
376
- this._damping.zoom.duration = 0;
377
- }
378
- else {
379
- this._damping.zoom.time += time;
380
- const frameSinceStart = this._damping.zoom.time / 16.6666;
381
- const delta = this._damping.zoom.delta *
382
- Math.pow(damping, frameSinceStart);
383
- const offset = this.zoomDistanceToOffset(delta);
384
- this._controls.applyPositionVector(offset);
385
- }
386
- }
387
- else {
388
- this._damping.zoom.time = 0;
389
- }
390
- if (this._controls.enableAutoRotation) {
391
- const spherical = new viewer_shared_math_1.Spherical(1.0, 0.0, -this._adjustedSettings.autoRotationSpeed());
392
- let sphericalForOffset = spherical;
393
- if (this._controls.enableTurntableControls)
394
- sphericalForOffset = new viewer_shared_math_1.Spherical(1.0, spherical.phi, 0);
395
- const offset = this.rotationSphericalToOffset(sphericalForOffset);
396
- this._controls.applyPositionVector(offset);
397
- if (this._controls.enableTurntableControls)
398
- this._controls.applyRotation([0, spherical.theta]);
399
- if (this._controls.enableObjectControls)
400
- this._controls.applyRotation([spherical.phi, spherical.theta]);
401
- }
402
- }
403
- zoom(x, y, active, touch) {
404
- const distance = Math.sqrt(x * x + y * y);
405
- if (!active) {
406
- this._dollyStart = distance;
407
- }
408
- else {
409
- this._dollyEnd = distance;
410
- this._dollyDelta = this._dollyEnd - this._dollyStart;
411
- this._dollyStart = this._dollyEnd;
412
- if (this._damping.zoom.duration > 0) {
413
- if (this._dollyDelta < 0) {
414
- this._dollyDelta = Math.min(this._dollyDelta, this._adjustedSettings.movementSmoothness() *
415
- this._damping.zoom.delta);
416
- }
417
- else {
418
- this._dollyDelta = Math.max(this._dollyDelta, this._adjustedSettings.movementSmoothness() *
419
- this._damping.zoom.delta);
420
- }
421
- }
422
- const delta = -this._dollyDelta *
423
- this._adjustedSettings.zoomSpeed() *
424
- (touch ? this._touchAdjustments.zoomSpeed : 1.0);
425
- const damping = 1 -
426
- Math.max(0.01, Math.min(1, this._adjustedSettings.damping()));
427
- const framesDelta = (Math.log(1 / Math.abs(this._dollyDelta)) - 5 * Math.log(10)) /
428
- Math.log(damping);
429
- this._damping.zoom.time = 0;
430
- this._damping.zoom.duration = framesDelta * 16.6666;
431
- this._damping.zoom.delta = delta;
432
- this._damping.rotation.duration = 0;
433
- this._damping.pan.duration = 0;
434
- const offset = this.zoomDistanceToOffset(delta);
435
- this._controls.applyPositionVector(offset, true);
436
- }
437
- }
438
- // #endregion Public Methods (7)
439
- // #region Private Methods (3)
440
- panDeltaToOffset(panDelta) {
441
- var _a, _b, _c, _d;
442
- const offset = gl_matrix_1.vec3.create();
443
- const panOffset = gl_matrix_1.vec3.create();
444
- if (!this._controls.canvas)
445
- return offset;
446
- if (this._controls.canvas.clientWidth == 0 ||
447
- this._controls.canvas.clientHeight == 0)
448
- return offset;
449
- // perspective
450
- gl_matrix_1.vec3.subtract(offset, this._controls.getPositionWithManualUpdates(), this._controls.getTargetWithManualUpdates());
451
- if (this._controls.camera instanceof OrthographicCamera_1.OrthographicCamera) {
452
- const orthographicCamera = (this._controls.camera);
453
- const mat = gl_matrix_1.mat4.targetTo(gl_matrix_1.mat4.create(), orthographicCamera.position, orthographicCamera.target, orthographicCamera.up);
454
- // // we use only clientHeight here so aspect ratio does not distort speed
455
- // // left
456
- const v1 = gl_matrix_1.vec3.fromValues(mat[0], mat[1], mat[2]);
457
- const scalar1 = -(((panDelta[0] *
458
- (orthographicCamera.right - orthographicCamera.left) *
459
- 0.5) /
460
- ((_a = this._controls.canvas) === null || _a === void 0 ? void 0 : _a.clientHeight)) /** orthographicCamera.zoom */);
461
- gl_matrix_1.vec3.multiply(v1, v1, gl_matrix_1.vec3.fromValues(scalar1, scalar1, scalar1));
462
- gl_matrix_1.vec3.add(panOffset, panOffset, v1);
463
- // // up
464
- const v2 = gl_matrix_1.vec3.fromValues(mat[4], mat[5], mat[6]);
465
- const scalar2 = (panDelta[1] *
466
- (orthographicCamera.right - orthographicCamera.left) *
467
- 0.5) /
468
- ((_b = this._controls.canvas) === null || _b === void 0 ? void 0 : _b.clientHeight); /** orthographicCamera.zoom */
469
- gl_matrix_1.vec3.multiply(v2, v2, gl_matrix_1.vec3.fromValues(scalar2, scalar2, scalar2));
470
- gl_matrix_1.vec3.add(panOffset, panOffset, v2);
471
- }
472
- else {
473
- let targetDistance = gl_matrix_1.vec3.length(offset);
474
- // half of the fov is center to top of screen
475
- targetDistance *= Math.tan(((this._controls.camera.fov / 2) *
476
- Math.PI) /
477
- 180.0);
478
- // we use only clientHeight here so aspect ratio does not distort speed
479
- // left
480
- const mat = gl_matrix_1.mat4.targetTo(gl_matrix_1.mat4.create(), this._controls.camera.position, this._controls.camera.target, gl_matrix_1.vec3.fromValues(0, 0, 1));
481
- const v1 = gl_matrix_1.vec3.fromValues(mat[0], mat[1], mat[2]);
482
- const scalar1 = -((2 * panDelta[0] * targetDistance) /
483
- ((_c = this._controls.canvas) === null || _c === void 0 ? void 0 : _c.clientHeight));
484
- gl_matrix_1.vec3.multiply(v1, v1, gl_matrix_1.vec3.fromValues(scalar1, scalar1, scalar1));
485
- gl_matrix_1.vec3.add(panOffset, panOffset, v1);
486
- // // up
487
- const v2 = gl_matrix_1.vec3.fromValues(mat[4], mat[5], mat[6]);
488
- const scalar2 = (2 * panDelta[1] * targetDistance) /
489
- ((_d = this._controls.canvas) === null || _d === void 0 ? void 0 : _d.clientHeight);
490
- gl_matrix_1.vec3.multiply(v2, v2, gl_matrix_1.vec3.fromValues(scalar2, scalar2, scalar2));
491
- gl_matrix_1.vec3.add(panOffset, panOffset, v2);
492
- }
493
- return gl_matrix_1.vec3.clone(panOffset);
494
- }
495
- rotationSphericalToOffset(s) {
496
- let offset = gl_matrix_1.vec3.create();
497
- gl_matrix_1.vec3.subtract(offset, this._controls.getPositionWithManualUpdates(), this._controls.getTargetWithManualUpdates());
498
- gl_matrix_1.vec3.transformQuat(offset, offset, this._quat);
499
- const spherical = new viewer_shared_math_1.Spherical().fromVec3(offset);
500
- spherical.theta += s.theta;
501
- spherical.phi += s.phi;
502
- const minAzimuthAngle = this._controls.rotationRestriction.minAzimuthAngle *
503
- (Math.PI / 180), maxAzimuthAngle = this._controls.rotationRestriction.maxAzimuthAngle *
504
- (Math.PI / 180);
505
- if (spherical.theta > Math.PI) {
506
- spherical.theta -= 2 * Math.PI;
507
- if (minAzimuthAngle > spherical.theta) {
508
- spherical.theta += 2 * Math.PI;
509
- }
510
- }
511
- else if (spherical.theta < -Math.PI) {
512
- spherical.theta += 2 * Math.PI;
513
- if (maxAzimuthAngle < spherical.theta) {
514
- spherical.theta -= 2 * Math.PI;
515
- }
516
- }
517
- spherical.makeSafe();
518
- offset = spherical.toVec3();
519
- offset = gl_matrix_1.vec3.transformQuat(gl_matrix_1.vec3.create(), offset, this._quatInverse);
520
- offset = gl_matrix_1.vec3.add(gl_matrix_1.vec3.create(), offset, this._controls.getTargetWithManualUpdates());
521
- offset = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), offset, this._controls.getPositionWithManualUpdates());
522
- return gl_matrix_1.vec3.clone(offset);
523
- }
524
- zoomDistanceToOffset(distance) {
525
- const offset = gl_matrix_1.vec3.create();
526
- gl_matrix_1.vec3.subtract(offset, this._controls.getPositionWithManualUpdates(), this._controls.getTargetWithManualUpdates());
527
- return gl_matrix_1.vec3.multiply(gl_matrix_1.vec3.create(), offset, gl_matrix_1.vec3.fromValues(distance, distance, distance));
528
- }
529
- }
530
- exports.CameraControlsLogic = CameraControlsLogic;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CameraControlsLogic = void 0;
4
+ const viewer_shared_math_1 = require("@shapediver/viewer.shared.math");
5
+ const viewer_shared_types_1 = require("@shapediver/viewer.shared.types");
6
+ const gl_matrix_1 = require("gl-matrix");
7
+ const OrthographicCamera_1 = require("../camera/OrthographicCamera");
8
+ class CameraControlsLogic {
9
+ // #endregion Properties (13)
10
+ // #region Constructors (1)
11
+ constructor(_controls, _settingsAdjustments, _touchAdjustments) {
12
+ this._controls = _controls;
13
+ this._settingsAdjustments = _settingsAdjustments;
14
+ this._touchAdjustments = _touchAdjustments;
15
+ // #region Properties (13)
16
+ this._adjustedSettings = {
17
+ autoRotationSpeed: () => this._controls.autoRotationSpeed *
18
+ this._settingsAdjustments.autoRotationSpeed,
19
+ damping: () => this._controls.damping * this._settingsAdjustments.damping,
20
+ movementSmoothness: () => this._controls.movementSmoothness *
21
+ this._settingsAdjustments.movementSmoothness,
22
+ panSpeed: () => this._controls.panSpeed * this._settingsAdjustments.panSpeed,
23
+ rotationSpeed: () => this._controls.rotationSpeed *
24
+ this._settingsAdjustments.rotationSpeed,
25
+ zoomSpeed: () => this._controls.zoomSpeed * this._settingsAdjustments.zoomSpeed,
26
+ };
27
+ this._damping = {
28
+ rotation: {
29
+ time: 0,
30
+ duration: 0,
31
+ theta: 0,
32
+ phi: 0,
33
+ },
34
+ zoom: {
35
+ time: 0,
36
+ duration: 0,
37
+ delta: 0,
38
+ },
39
+ pan: {
40
+ time: 0,
41
+ duration: 0,
42
+ offset: gl_matrix_1.vec3.create(),
43
+ },
44
+ };
45
+ this._dollyDelta = 0;
46
+ this._dollyEnd = 0;
47
+ this._dollyStart = 0;
48
+ this._panDelta = gl_matrix_1.vec2.create();
49
+ this._panEnd = gl_matrix_1.vec2.create();
50
+ this._panStart = gl_matrix_1.vec2.create();
51
+ this._rotateDelta = gl_matrix_1.vec2.create();
52
+ this._rotateEnd = gl_matrix_1.vec2.create();
53
+ this._rotateStart = gl_matrix_1.vec2.create();
54
+ this._quat = gl_matrix_1.quat.fromValues(-Math.sin(Math.PI / 4), 0, 0, Math.sin(Math.PI / 4));
55
+ this._quatInverse = gl_matrix_1.quat.fromValues(Math.sin(Math.PI / 4), 0, 0, Math.sin(Math.PI / 4));
56
+ }
57
+ // #endregion Constructors (1)
58
+ // #region Public Methods (7)
59
+ isWithinRestrictions(position, target) {
60
+ const pBox = new viewer_shared_math_1.Box(this._controls.cubePositionRestriction.min, this._controls.cubePositionRestriction.max), pSphere = new viewer_shared_math_1.Sphere(this._controls.spherePositionRestriction.center, this._controls.spherePositionRestriction.radius), tBox = new viewer_shared_math_1.Box(this._controls.cubeTargetRestriction.min, this._controls.cubeTargetRestriction.max), tSphere = new viewer_shared_math_1.Sphere(this._controls.sphereTargetRestriction.center, this._controls.sphereTargetRestriction.radius);
61
+ if (!(pBox.containsPoint(position) && pSphere.containsPoint(position)))
62
+ return false;
63
+ if (!(tBox.containsPoint(target) && tSphere.containsPoint(target)))
64
+ return false;
65
+ const currentDistance = gl_matrix_1.vec3.distance(position, target);
66
+ if (currentDistance > this._controls.zoomRestriction.maxDistance ||
67
+ currentDistance < this._controls.zoomRestriction.minDistance)
68
+ return false;
69
+ const minPolarAngle = this._controls.rotationRestriction.minPolarAngle *
70
+ (Math.PI / 180), maxPolarAngle = this._controls.rotationRestriction.maxPolarAngle *
71
+ (Math.PI / 180), minAzimuthAngle = this._controls.rotationRestriction.minAzimuthAngle *
72
+ (Math.PI / 180), maxAzimuthAngle = this._controls.rotationRestriction.maxAzimuthAngle *
73
+ (Math.PI / 180);
74
+ if (minAzimuthAngle !== -Infinity ||
75
+ maxAzimuthAngle !== Infinity ||
76
+ minPolarAngle !== 0 ||
77
+ maxPolarAngle !== 180) {
78
+ const offset = gl_matrix_1.vec3.sub(gl_matrix_1.vec3.create(), position, target);
79
+ gl_matrix_1.vec3.transformQuat(offset, offset, this._quat);
80
+ const spherical = new viewer_shared_math_1.Spherical().fromVec3(offset);
81
+ if (spherical.theta < minAzimuthAngle ||
82
+ spherical.theta > maxAzimuthAngle ||
83
+ spherical.phi < minPolarAngle ||
84
+ spherical.phi > maxPolarAngle) {
85
+ return false;
86
+ }
87
+ }
88
+ return true;
89
+ }
90
+ pan(x, y, active, touch) {
91
+ if (!active) {
92
+ this._panStart = gl_matrix_1.vec2.fromValues(x, y);
93
+ }
94
+ else {
95
+ this._panEnd = gl_matrix_1.vec2.fromValues(x, y);
96
+ gl_matrix_1.vec2.sub(this._panDelta, this._panEnd, this._panStart);
97
+ if (this._panDelta[0] === 0 && this._panDelta[1] === 0)
98
+ return;
99
+ gl_matrix_1.vec2.copy(this._panStart, this._panEnd);
100
+ const adjustedPanSpeed = this._adjustedSettings.panSpeed() *
101
+ (touch ? this._touchAdjustments.panSpeed : 1.0);
102
+ const offset = this.panDeltaToOffset(gl_matrix_1.vec2.mul(gl_matrix_1.vec2.create(), this._panDelta, gl_matrix_1.vec2.fromValues(adjustedPanSpeed, adjustedPanSpeed)));
103
+ if (this._damping.pan.duration > 0) {
104
+ if (offset[0] < 0) {
105
+ offset[0] = Math.min(offset[0], this._adjustedSettings.movementSmoothness() *
106
+ this._damping.pan.offset[0]);
107
+ }
108
+ else {
109
+ offset[0] = Math.max(offset[0], this._adjustedSettings.movementSmoothness() *
110
+ this._damping.pan.offset[0]);
111
+ }
112
+ if (offset[1] < 0) {
113
+ offset[1] = Math.min(offset[1], this._adjustedSettings.movementSmoothness() *
114
+ this._damping.pan.offset[1]);
115
+ }
116
+ else {
117
+ offset[1] = Math.max(offset[1], this._adjustedSettings.movementSmoothness() *
118
+ this._damping.pan.offset[1]);
119
+ }
120
+ if (offset[2] < 0) {
121
+ offset[2] = Math.min(offset[2], this._adjustedSettings.movementSmoothness() *
122
+ this._damping.pan.offset[2]);
123
+ }
124
+ else {
125
+ offset[2] = Math.max(offset[2], this._adjustedSettings.movementSmoothness() *
126
+ this._damping.pan.offset[2]);
127
+ }
128
+ }
129
+ const damping = 1 -
130
+ Math.max(0.01, Math.min(0.99, this._adjustedSettings.damping()));
131
+ const framesOffsetX = (Math.log(1 / Math.abs(offset[0])) - 5 * Math.log(10)) /
132
+ Math.log(damping);
133
+ const framesOffsetY = (Math.log(1 / Math.abs(offset[1])) - 5 * Math.log(10)) /
134
+ Math.log(damping);
135
+ const framesOffsetZ = (Math.log(1 / Math.abs(offset[2])) - 5 * Math.log(10)) /
136
+ Math.log(damping);
137
+ this._damping.pan.time = 0;
138
+ this._damping.pan.duration =
139
+ Math.max(framesOffsetX, Math.max(framesOffsetY, framesOffsetZ)) * 16.6666;
140
+ this._damping.pan.offset = gl_matrix_1.vec3.clone(offset);
141
+ this._damping.rotation.duration = 0;
142
+ this._damping.zoom.duration = 0;
143
+ this._controls.applyTargetVector(offset, true);
144
+ this._controls.applyPositionVector(offset, true);
145
+ }
146
+ }
147
+ reset() {
148
+ this._damping = {
149
+ rotation: {
150
+ time: 0,
151
+ duration: 0,
152
+ theta: 0,
153
+ phi: 0,
154
+ },
155
+ zoom: {
156
+ time: 0,
157
+ duration: 0,
158
+ delta: 0,
159
+ },
160
+ pan: {
161
+ time: 0,
162
+ duration: 0,
163
+ offset: gl_matrix_1.vec3.create(),
164
+ },
165
+ };
166
+ this._dollyDelta = 0;
167
+ this._dollyEnd = 0;
168
+ this._dollyStart = 0;
169
+ this._panDelta = gl_matrix_1.vec2.create();
170
+ this._panEnd = gl_matrix_1.vec2.create();
171
+ this._panStart = gl_matrix_1.vec2.create();
172
+ this._rotateDelta = gl_matrix_1.vec2.create();
173
+ this._rotateEnd = gl_matrix_1.vec2.create();
174
+ this._rotateStart = gl_matrix_1.vec2.create();
175
+ }
176
+ restrict(position, target, sceneRotation) {
177
+ const pBox = new viewer_shared_math_1.Box(this._controls.cubePositionRestriction.min, this._controls.cubePositionRestriction.max), pSphere = new viewer_shared_math_1.Sphere(this._controls.spherePositionRestriction.center, this._controls.spherePositionRestriction.radius), tBox = new viewer_shared_math_1.Box(this._controls.cubeTargetRestriction.min, this._controls.cubeTargetRestriction.max), tSphere = new viewer_shared_math_1.Sphere(this._controls.sphereTargetRestriction.center, this._controls.sphereTargetRestriction.radius);
178
+ if (!pBox.containsPoint(position))
179
+ position = pBox.clampPoint(position);
180
+ if (!pSphere.containsPoint(position))
181
+ position = pSphere.clampPoint(position);
182
+ if (!tBox.containsPoint(target))
183
+ target = tBox.clampPoint(target);
184
+ if (!tSphere.containsPoint(target))
185
+ target = tSphere.clampPoint(target);
186
+ // zoom restrictions
187
+ const currentDistance = gl_matrix_1.vec3.distance(position, target);
188
+ if (currentDistance > this._controls.zoomRestriction.maxDistance ||
189
+ currentDistance < this._controls.zoomRestriction.minDistance) {
190
+ const direction = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), position, target));
191
+ const distance = Math.max(this._controls.zoomRestriction.minDistance, Math.min(this._controls.zoomRestriction.maxDistance, currentDistance));
192
+ gl_matrix_1.vec3.add(position, gl_matrix_1.vec3.multiply(position, direction, gl_matrix_1.vec3.fromValues(distance, distance, distance)), target);
193
+ }
194
+ // angle restrictions
195
+ const minPolarAngle = this._controls.rotationRestriction.minPolarAngle *
196
+ (Math.PI / 180), maxPolarAngle = this._controls.rotationRestriction.maxPolarAngle *
197
+ (Math.PI / 180), minAzimuthAngle = this._controls.rotationRestriction.minAzimuthAngle *
198
+ (Math.PI / 180), maxAzimuthAngle = this._controls.rotationRestriction.maxAzimuthAngle *
199
+ (Math.PI / 180);
200
+ if (minAzimuthAngle !== -Infinity ||
201
+ maxAzimuthAngle !== Infinity ||
202
+ minPolarAngle !== 0 ||
203
+ maxPolarAngle !== 180 ||
204
+ this._controls.enableAzimuthRotation === false ||
205
+ this._controls.enablePolarRotation === false ||
206
+ this._controls.enableObjectControls === true) {
207
+ let offset = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), position, target);
208
+ gl_matrix_1.vec3.transformQuat(offset, offset, this._quat);
209
+ const spherical = new viewer_shared_math_1.Spherical().fromVec3(offset);
210
+ if (spherical.theta < minAzimuthAngle ||
211
+ spherical.theta > maxAzimuthAngle ||
212
+ spherical.phi < minPolarAngle ||
213
+ spherical.phi > maxPolarAngle ||
214
+ this._controls.enableAzimuthRotation === false ||
215
+ this._controls.enablePolarRotation === false ||
216
+ this._controls.enableObjectControls === true) {
217
+ spherical.theta = Math.max(minAzimuthAngle, Math.min(maxAzimuthAngle, spherical.theta));
218
+ spherical.phi = Math.max(minPolarAngle, Math.min(maxPolarAngle, spherical.phi));
219
+ if (this._controls.enableAzimuthRotation === false ||
220
+ this._controls.enablePolarRotation === false ||
221
+ this._controls.enableObjectControls === true) {
222
+ const defaultOffset = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), this._controls.camera.defaultPosition, this._controls.camera.defaultTarget);
223
+ gl_matrix_1.vec3.transformQuat(defaultOffset, defaultOffset, this._quat);
224
+ const defaultSpherical = new viewer_shared_math_1.Spherical().fromVec3(defaultOffset);
225
+ if (this._controls.enableAzimuthRotation === false)
226
+ spherical.theta = defaultSpherical.theta;
227
+ if (this._controls.enablePolarRotation === false)
228
+ spherical.phi = defaultSpherical.phi;
229
+ if (this._controls.enableObjectControls) {
230
+ spherical.theta = defaultSpherical.theta;
231
+ spherical.phi = defaultSpherical.phi;
232
+ }
233
+ }
234
+ spherical.makeSafe();
235
+ offset = spherical.toVec3();
236
+ gl_matrix_1.vec3.transformQuat(offset, offset, this._quatInverse);
237
+ gl_matrix_1.vec3.add(position, offset, target);
238
+ }
239
+ if ((sceneRotation[1] < minAzimuthAngle ||
240
+ sceneRotation[1] > maxAzimuthAngle ||
241
+ sceneRotation[0] < minPolarAngle ||
242
+ sceneRotation[0] > maxPolarAngle ||
243
+ this._controls.enableAzimuthRotation === false ||
244
+ this._controls.enablePolarRotation === false) &&
245
+ this._controls.enableObjectControls === false) {
246
+ sceneRotation[1] =
247
+ this._controls.enableAzimuthRotation === false
248
+ ? 0
249
+ : Math.max(minAzimuthAngle, Math.min(maxAzimuthAngle, sceneRotation[1]));
250
+ sceneRotation[0] =
251
+ this._controls.enablePolarRotation === false
252
+ ? 0
253
+ : Math.max(minPolarAngle, Math.min(maxPolarAngle, sceneRotation[0]));
254
+ }
255
+ }
256
+ return { position, target, sceneRotation };
257
+ }
258
+ rotate(x, y, active, touch) {
259
+ if (this._controls.camera.type === viewer_shared_types_1.CAMERA_TYPE.ORTHOGRAPHIC &&
260
+ this._controls.camera.direction !==
261
+ viewer_shared_types_1.ORTHOGRAPHIC_CAMERA_DIRECTION.CUSTOM)
262
+ return;
263
+ if (!active) {
264
+ this._rotateStart = gl_matrix_1.vec2.fromValues(x, y);
265
+ }
266
+ else {
267
+ this._rotateEnd = gl_matrix_1.vec2.fromValues(x, y);
268
+ gl_matrix_1.vec2.subtract(this._rotateDelta, this._rotateEnd, this._rotateStart);
269
+ gl_matrix_1.vec2.copy(this._rotateStart, this._rotateEnd);
270
+ if (!this._controls.canvas)
271
+ return;
272
+ if (this._controls.canvas.clientWidth == 0 ||
273
+ this._controls.canvas.clientHeight == 0)
274
+ return;
275
+ const spherical = new viewer_shared_math_1.Spherical();
276
+ const rotationSpeed = this._adjustedSettings.rotationSpeed() *
277
+ (touch ? this._touchAdjustments.rotationSpeed : 1.0);
278
+ spherical.theta -=
279
+ (rotationSpeed * this._rotateDelta[0]) /
280
+ this._controls.canvas.clientHeight;
281
+ spherical.phi -=
282
+ (rotationSpeed * this._rotateDelta[1]) /
283
+ this._controls.canvas.clientHeight;
284
+ if (this._damping.rotation.duration > 0) {
285
+ const thetaDelta = this._damping.rotation.theta - spherical.theta;
286
+ spherical.theta +=
287
+ thetaDelta * this._adjustedSettings.movementSmoothness();
288
+ const phiDelta = this._damping.rotation.phi - spherical.phi;
289
+ spherical.phi +=
290
+ phiDelta * this._adjustedSettings.movementSmoothness();
291
+ }
292
+ let sphericalForOffset = spherical;
293
+ if (this._controls.enableTurntableControls)
294
+ sphericalForOffset = new viewer_shared_math_1.Spherical(1.0, spherical.phi, 0);
295
+ const offset = this.rotationSphericalToOffset(sphericalForOffset);
296
+ const damping = 1 -
297
+ Math.max(0.01, Math.min(1, this._adjustedSettings.damping()));
298
+ const framesTheta = (Math.log(1 / Math.abs(spherical.theta)) - 5 * Math.log(10)) /
299
+ Math.log(damping);
300
+ const framesPhi = (Math.log(1 / Math.abs(spherical.phi)) - 5 * Math.log(10)) /
301
+ Math.log(damping);
302
+ this._damping.rotation.time = 0;
303
+ this._damping.rotation.duration =
304
+ Math.max(framesTheta, framesPhi) * 16.6666;
305
+ this._damping.rotation.theta = spherical.theta;
306
+ this._damping.rotation.phi = spherical.phi;
307
+ this._damping.pan.duration = 0;
308
+ this._damping.zoom.duration = 0;
309
+ this._controls.applyPositionVector(offset, true);
310
+ if (this._controls.enableTurntableControls)
311
+ this._controls.applyRotation([0, spherical.theta], true);
312
+ if (this._controls.enableObjectControls)
313
+ this._controls.applyRotation([spherical.phi, spherical.theta], true);
314
+ }
315
+ }
316
+ update(time, manualInteraction) {
317
+ if (manualInteraction === true) {
318
+ this._damping.zoom.duration = 0;
319
+ this._damping.pan.duration = 0;
320
+ this._damping.rotation.duration = 0;
321
+ }
322
+ const damping = 1 - Math.max(0.01, Math.min(1, this._adjustedSettings.damping()));
323
+ if (this._damping.pan.duration > 0) {
324
+ if (this._damping.pan.time + time > this._damping.pan.duration) {
325
+ this._damping.pan.time = this._damping.pan.duration;
326
+ this._damping.pan.duration = 0;
327
+ }
328
+ else {
329
+ this._damping.pan.time += time;
330
+ const frameSinceStart = this._damping.pan.time / 16.6666;
331
+ const dampingFrames = Math.pow(damping, frameSinceStart);
332
+ const offset = gl_matrix_1.vec3.multiply(gl_matrix_1.vec3.create(), this._damping.pan.offset, gl_matrix_1.vec3.fromValues(dampingFrames, dampingFrames, dampingFrames));
333
+ this._controls.applyTargetVector(offset);
334
+ this._controls.applyPositionVector(offset);
335
+ }
336
+ }
337
+ else {
338
+ this._damping.pan.time = 0;
339
+ }
340
+ if (this._damping.rotation.duration > 0) {
341
+ if (this._damping.rotation.time + time >
342
+ this._damping.rotation.duration) {
343
+ this._damping.rotation.time = this._damping.rotation.duration;
344
+ this._damping.rotation.duration = 0;
345
+ }
346
+ else {
347
+ this._damping.rotation.time += time;
348
+ const frameSinceStart = this._damping.rotation.time / 16.6666;
349
+ const spherical = new viewer_shared_math_1.Spherical();
350
+ spherical.theta =
351
+ this._damping.rotation.theta *
352
+ Math.pow(damping, frameSinceStart);
353
+ spherical.phi =
354
+ this._damping.rotation.phi *
355
+ Math.pow(damping, frameSinceStart);
356
+ let sphericalForOffset = spherical;
357
+ if (this._controls.enableTurntableControls)
358
+ sphericalForOffset = new viewer_shared_math_1.Spherical(1.0, spherical.phi, 0);
359
+ const offset = this.rotationSphericalToOffset(sphericalForOffset);
360
+ this._controls.applyPositionVector(offset);
361
+ if (this._controls.enableTurntableControls)
362
+ this._controls.applyRotation([0, spherical.theta]);
363
+ if (this._controls.enableObjectControls)
364
+ this._controls.applyRotation([
365
+ spherical.phi,
366
+ spherical.theta,
367
+ ]);
368
+ }
369
+ }
370
+ else {
371
+ this._damping.rotation.time = 0;
372
+ }
373
+ if (this._damping.zoom.duration > 0) {
374
+ if (this._damping.zoom.time + time > this._damping.zoom.duration) {
375
+ this._damping.zoom.time = this._damping.zoom.duration;
376
+ this._damping.zoom.duration = 0;
377
+ }
378
+ else {
379
+ this._damping.zoom.time += time;
380
+ const frameSinceStart = this._damping.zoom.time / 16.6666;
381
+ const delta = this._damping.zoom.delta *
382
+ Math.pow(damping, frameSinceStart);
383
+ const offset = this.zoomDistanceToOffset(delta);
384
+ this._controls.applyPositionVector(offset);
385
+ }
386
+ }
387
+ else {
388
+ this._damping.zoom.time = 0;
389
+ }
390
+ if (this._controls.enableAutoRotation) {
391
+ const spherical = new viewer_shared_math_1.Spherical(1.0, 0.0, -this._adjustedSettings.autoRotationSpeed());
392
+ let sphericalForOffset = spherical;
393
+ if (this._controls.enableTurntableControls)
394
+ sphericalForOffset = new viewer_shared_math_1.Spherical(1.0, spherical.phi, 0);
395
+ const offset = this.rotationSphericalToOffset(sphericalForOffset);
396
+ this._controls.applyPositionVector(offset);
397
+ if (this._controls.enableTurntableControls)
398
+ this._controls.applyRotation([0, spherical.theta]);
399
+ if (this._controls.enableObjectControls)
400
+ this._controls.applyRotation([spherical.phi, spherical.theta]);
401
+ }
402
+ }
403
+ zoom(x, y, active, touch) {
404
+ const distance = Math.sqrt(x * x + y * y);
405
+ if (!active) {
406
+ this._dollyStart = distance;
407
+ }
408
+ else {
409
+ this._dollyEnd = distance;
410
+ this._dollyDelta = this._dollyEnd - this._dollyStart;
411
+ this._dollyStart = this._dollyEnd;
412
+ if (this._damping.zoom.duration > 0) {
413
+ if (this._dollyDelta < 0) {
414
+ this._dollyDelta = Math.min(this._dollyDelta, this._adjustedSettings.movementSmoothness() *
415
+ this._damping.zoom.delta);
416
+ }
417
+ else {
418
+ this._dollyDelta = Math.max(this._dollyDelta, this._adjustedSettings.movementSmoothness() *
419
+ this._damping.zoom.delta);
420
+ }
421
+ }
422
+ const delta = -this._dollyDelta *
423
+ this._adjustedSettings.zoomSpeed() *
424
+ (touch ? this._touchAdjustments.zoomSpeed : 1.0);
425
+ const damping = 1 -
426
+ Math.max(0.01, Math.min(1, this._adjustedSettings.damping()));
427
+ const framesDelta = (Math.log(1 / Math.abs(this._dollyDelta)) - 5 * Math.log(10)) /
428
+ Math.log(damping);
429
+ this._damping.zoom.time = 0;
430
+ this._damping.zoom.duration = framesDelta * 16.6666;
431
+ this._damping.zoom.delta = delta;
432
+ this._damping.rotation.duration = 0;
433
+ this._damping.pan.duration = 0;
434
+ const offset = this.zoomDistanceToOffset(delta);
435
+ this._controls.applyPositionVector(offset, true);
436
+ }
437
+ }
438
+ // #endregion Public Methods (7)
439
+ // #region Private Methods (3)
440
+ panDeltaToOffset(panDelta) {
441
+ var _a, _b, _c, _d;
442
+ const offset = gl_matrix_1.vec3.create();
443
+ const panOffset = gl_matrix_1.vec3.create();
444
+ if (!this._controls.canvas)
445
+ return offset;
446
+ if (this._controls.canvas.clientWidth == 0 ||
447
+ this._controls.canvas.clientHeight == 0)
448
+ return offset;
449
+ // perspective
450
+ gl_matrix_1.vec3.subtract(offset, this._controls.getPositionWithManualUpdates(), this._controls.getTargetWithManualUpdates());
451
+ if (this._controls.camera instanceof OrthographicCamera_1.OrthographicCamera) {
452
+ const orthographicCamera = (this._controls.camera);
453
+ const mat = gl_matrix_1.mat4.targetTo(gl_matrix_1.mat4.create(), orthographicCamera.position, orthographicCamera.target, orthographicCamera.up);
454
+ // // we use only clientHeight here so aspect ratio does not distort speed
455
+ // // left
456
+ const v1 = gl_matrix_1.vec3.fromValues(mat[0], mat[1], mat[2]);
457
+ const scalar1 = -(((panDelta[0] *
458
+ (orthographicCamera.right - orthographicCamera.left) *
459
+ 0.5) /
460
+ ((_a = this._controls.canvas) === null || _a === void 0 ? void 0 : _a.clientHeight)) /** orthographicCamera.zoom */);
461
+ gl_matrix_1.vec3.multiply(v1, v1, gl_matrix_1.vec3.fromValues(scalar1, scalar1, scalar1));
462
+ gl_matrix_1.vec3.add(panOffset, panOffset, v1);
463
+ // // up
464
+ const v2 = gl_matrix_1.vec3.fromValues(mat[4], mat[5], mat[6]);
465
+ const scalar2 = (panDelta[1] *
466
+ (orthographicCamera.right - orthographicCamera.left) *
467
+ 0.5) /
468
+ ((_b = this._controls.canvas) === null || _b === void 0 ? void 0 : _b.clientHeight); /** orthographicCamera.zoom */
469
+ gl_matrix_1.vec3.multiply(v2, v2, gl_matrix_1.vec3.fromValues(scalar2, scalar2, scalar2));
470
+ gl_matrix_1.vec3.add(panOffset, panOffset, v2);
471
+ }
472
+ else {
473
+ let targetDistance = gl_matrix_1.vec3.length(offset);
474
+ // half of the fov is center to top of screen
475
+ targetDistance *= Math.tan(((this._controls.camera.fov / 2) *
476
+ Math.PI) /
477
+ 180.0);
478
+ // we use only clientHeight here so aspect ratio does not distort speed
479
+ // left
480
+ const mat = gl_matrix_1.mat4.targetTo(gl_matrix_1.mat4.create(), this._controls.camera.position, this._controls.camera.target, gl_matrix_1.vec3.fromValues(0, 0, 1));
481
+ const v1 = gl_matrix_1.vec3.fromValues(mat[0], mat[1], mat[2]);
482
+ const scalar1 = -((2 * panDelta[0] * targetDistance) /
483
+ ((_c = this._controls.canvas) === null || _c === void 0 ? void 0 : _c.clientHeight));
484
+ gl_matrix_1.vec3.multiply(v1, v1, gl_matrix_1.vec3.fromValues(scalar1, scalar1, scalar1));
485
+ gl_matrix_1.vec3.add(panOffset, panOffset, v1);
486
+ // // up
487
+ const v2 = gl_matrix_1.vec3.fromValues(mat[4], mat[5], mat[6]);
488
+ const scalar2 = (2 * panDelta[1] * targetDistance) /
489
+ ((_d = this._controls.canvas) === null || _d === void 0 ? void 0 : _d.clientHeight);
490
+ gl_matrix_1.vec3.multiply(v2, v2, gl_matrix_1.vec3.fromValues(scalar2, scalar2, scalar2));
491
+ gl_matrix_1.vec3.add(panOffset, panOffset, v2);
492
+ }
493
+ return gl_matrix_1.vec3.clone(panOffset);
494
+ }
495
+ rotationSphericalToOffset(s) {
496
+ let offset = gl_matrix_1.vec3.create();
497
+ gl_matrix_1.vec3.subtract(offset, this._controls.getPositionWithManualUpdates(), this._controls.getTargetWithManualUpdates());
498
+ gl_matrix_1.vec3.transformQuat(offset, offset, this._quat);
499
+ const spherical = new viewer_shared_math_1.Spherical().fromVec3(offset);
500
+ spherical.theta += s.theta;
501
+ spherical.phi += s.phi;
502
+ const minAzimuthAngle = this._controls.rotationRestriction.minAzimuthAngle *
503
+ (Math.PI / 180), maxAzimuthAngle = this._controls.rotationRestriction.maxAzimuthAngle *
504
+ (Math.PI / 180);
505
+ if (spherical.theta > Math.PI) {
506
+ spherical.theta -= 2 * Math.PI;
507
+ if (minAzimuthAngle > spherical.theta) {
508
+ spherical.theta += 2 * Math.PI;
509
+ }
510
+ }
511
+ else if (spherical.theta < -Math.PI) {
512
+ spherical.theta += 2 * Math.PI;
513
+ if (maxAzimuthAngle < spherical.theta) {
514
+ spherical.theta -= 2 * Math.PI;
515
+ }
516
+ }
517
+ spherical.makeSafe();
518
+ offset = spherical.toVec3();
519
+ offset = gl_matrix_1.vec3.transformQuat(gl_matrix_1.vec3.create(), offset, this._quatInverse);
520
+ offset = gl_matrix_1.vec3.add(gl_matrix_1.vec3.create(), offset, this._controls.getTargetWithManualUpdates());
521
+ offset = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), offset, this._controls.getPositionWithManualUpdates());
522
+ return gl_matrix_1.vec3.clone(offset);
523
+ }
524
+ zoomDistanceToOffset(distance) {
525
+ const offset = gl_matrix_1.vec3.create();
526
+ gl_matrix_1.vec3.subtract(offset, this._controls.getPositionWithManualUpdates(), this._controls.getTargetWithManualUpdates());
527
+ return gl_matrix_1.vec3.multiply(gl_matrix_1.vec3.create(), offset, gl_matrix_1.vec3.fromValues(distance, distance, distance));
528
+ }
529
+ }
530
+ exports.CameraControlsLogic = CameraControlsLogic;
531
531
  //# sourceMappingURL=CameraControlsLogic.js.map