@@ -18,8 +18,10 @@ const tmpQ1 = new Quat();
18
18
const tmpR1 = new Ray ( ) ;
19
19
const tmpP1 = new Plane ( ) ;
20
20
21
+ /** @type {AddEventListenerOptions & EventListenerOptions } */
21
22
const PASSIVE = { passive : false } ;
22
23
const ZOOM_SCALE_SCENE_MULT = 10 ;
24
+ const EPSILON = 0.0001 ;
23
25
24
26
/**
25
27
* Calculate the lerp rate.
@@ -55,7 +57,7 @@ class CameraControls extends Script {
55
57
56
58
/**
57
59
* @private
58
- * @type {CameraComponent }
60
+ * @type {CameraComponent | null }
59
61
*/
60
62
_camera = null ;
61
63
@@ -155,6 +157,12 @@ class CameraControls extends Script {
155
157
*/
156
158
_moving = false ;
157
159
160
+ /**
161
+ * @type {boolean }
162
+ * @private
163
+ */
164
+ _focusing = false ;
165
+
158
166
/**
159
167
* @type {Record<string, boolean> }
160
168
* @private
@@ -222,6 +230,15 @@ class CameraControls extends Script {
222
230
*/
223
231
enableFly = true ;
224
232
233
+ /**
234
+ * @attribute
235
+ * @title Focus Damping
236
+ * @description The damping applied when calling {@link CameraControls#focus}. A higher value means
237
+ * more damping. A value of 0 means no damping.
238
+ * @type {number }
239
+ */
240
+ focusDamping = 0.98 ;
241
+
225
242
/**
226
243
* @attribute
227
244
* @title Rotate Speed
@@ -236,7 +253,7 @@ class CameraControls extends Script {
236
253
* @description The rotation damping. A higher value means more damping. A value of 0 means no damping.
237
254
* @type {number }
238
255
*/
239
- rotateDamping = 0.97 ;
256
+ rotateDamping = 0.98 ;
240
257
241
258
/**
242
259
* @attribute
@@ -334,7 +351,9 @@ class CameraControls extends Script {
334
351
335
352
const camera = this . _camera ;
336
353
this . detach ( ) ;
337
- this . attach ( camera ) ;
354
+ if ( camera ) {
355
+ this . attach ( camera ) ;
356
+ }
338
357
}
339
358
340
359
get element ( ) {
@@ -547,6 +566,11 @@ class CameraControls extends Script {
547
566
const startFly = this . _isStartFly ( event ) ;
548
567
const startOrbit = this . _isStartOrbit ( event ) ;
549
568
569
+ if ( this . _focusing ) {
570
+ this . _cancelSmoothTransform ( ) ;
571
+ this . _focusing = false ;
572
+ }
573
+
550
574
if ( startTouchPan ) {
551
575
// start touch pan
552
576
this . _lastPinchDist = this . _getPinchDist ( ) ;
@@ -768,6 +792,11 @@ class CameraControls extends Script {
768
792
769
793
// clamp movement if locked
770
794
if ( this . _moving ) {
795
+ if ( this . _focusing ) {
796
+ this . _cancelSmoothTransform ( ) ;
797
+ this . _focusing = false ;
798
+ }
799
+
771
800
this . _clampPosition ( this . _origin ) ;
772
801
}
773
802
}
@@ -874,12 +903,34 @@ class CameraControls extends Script {
874
903
* @param {number } dt - The delta time.
875
904
*/
876
905
_smoothTransform ( dt ) {
877
- const ar = dt === - 1 ? 1 : lerpRate ( this . rotateDamping , dt ) ;
878
- const am = dt === - 1 ? 1 : lerpRate ( this . moveDamping , dt ) ;
906
+ const ar = dt === - 1 ? 1 : lerpRate ( this . _focusing ? this . focusDamping : this . rotateDamping , dt ) ;
907
+ const am = dt === - 1 ? 1 : lerpRate ( this . _focusing ? this . focusDamping : this . moveDamping , dt ) ;
879
908
this . _angles . x = math . lerp ( this . _angles . x , this . _dir . x , ar ) ;
880
909
this . _angles . y = math . lerp ( this . _angles . y , this . _dir . y , ar ) ;
881
910
this . _position . lerp ( this . _position , this . _origin , am ) ;
882
911
this . _baseTransform . setTRS ( this . _position , tmpQ1 . setFromEulerAngles ( this . _angles ) , Vec3 . ONE ) ;
912
+
913
+ const focusDelta = this . _position . distance ( this . _origin ) +
914
+ Math . abs ( this . _angles . x - this . _dir . x ) +
915
+ Math . abs ( this . _angles . y - this . _dir . y ) ;
916
+ if ( this . _focusing && focusDelta < EPSILON ) {
917
+ this . _focusing = false ;
918
+ }
919
+ }
920
+
921
+ /**
922
+ * @private
923
+ */
924
+ _cancelSmoothZoom ( ) {
925
+ this . _cameraDist = this . _zoomDist ;
926
+ }
927
+
928
+ /**
929
+ * @private
930
+ */
931
+ _cancelSmoothTransform ( ) {
932
+ this . _origin . copy ( this . _position ) ;
933
+ this . _dir . set ( this . _angles . x , this . _angles . y ) ;
883
934
}
884
935
885
936
/**
@@ -894,8 +945,8 @@ class CameraControls extends Script {
894
945
/**
895
946
* Focus the camera on a point.
896
947
*
897
- * @param {Vec3 } point - The point.
898
- * @param {Vec3 } [start] - The start.
948
+ * @param {Vec3 } point - The focus point.
949
+ * @param {Vec3 } [start] - The camera start position .
899
950
* @param {boolean } [smooth] - Whether to smooth the focus.
900
951
*/
901
952
focus ( point , start , smooth = true ) {
@@ -905,35 +956,39 @@ class CameraControls extends Script {
905
956
if ( this . _flying ) {
906
957
return ;
907
958
}
908
- if ( ! start ) {
909
- this . _origin . copy ( point ) ;
910
- if ( ! smooth ) {
911
- this . _position . copy ( point ) ;
912
- }
913
- return ;
914
- }
915
959
916
- tmpV1 . sub2 ( start , point ) ;
917
- const elev = Math . atan2 ( tmpV1 . y , Math . sqrt ( tmpV1 . x * tmpV1 . x + tmpV1 . z * tmpV1 . z ) ) * math . RAD_TO_DEG ;
918
- const azim = Math . atan2 ( tmpV1 . x , tmpV1 . z ) * math . RAD_TO_DEG ;
919
- this . _clampAngles ( this . _dir . set ( - elev , azim ) ) ;
960
+ if ( start ) {
961
+ tmpV1 . sub2 ( start , point ) ;
962
+ const elev = Math . atan2 ( tmpV1 . y , Math . sqrt ( tmpV1 . x * tmpV1 . x + tmpV1 . z * tmpV1 . z ) ) * math . RAD_TO_DEG ;
963
+ const azim = Math . atan2 ( tmpV1 . x , tmpV1 . z ) * math . RAD_TO_DEG ;
964
+ this . _clampAngles ( this . _dir . set ( - elev , azim ) ) ;
920
965
921
- this . _origin . copy ( point ) ;
966
+ this . _origin . copy ( point ) ;
922
967
923
- this . _cameraTransform . setTranslate ( 0 , 0 , 0 ) ;
968
+ this . _cameraTransform . setTranslate ( 0 , 0 , 0 ) ;
924
969
925
- const pos = this . entity . getPosition ( ) ;
926
- const rot = this . entity . getRotation ( ) ;
927
- this . _baseTransform . setTRS ( pos , rot , Vec3 . ONE ) ;
970
+ const pos = this . entity . getPosition ( ) ;
971
+ const rot = this . entity . getRotation ( ) ;
972
+ this . _baseTransform . setTRS ( pos , rot , Vec3 . ONE ) ;
928
973
929
- this . _zoomDist = this . _clampZoom ( tmpV1 . length ( ) ) ;
974
+ this . _zoomDist = this . _clampZoom ( tmpV1 . length ( ) ) ;
930
975
931
- if ( ! smooth ) {
932
- this . _smoothZoom ( - 1 ) ;
933
- this . _smoothTransform ( - 1 ) ;
976
+ if ( ! smooth ) {
977
+ this . _smoothZoom ( - 1 ) ;
978
+ this . _smoothTransform ( - 1 ) ;
979
+ }
980
+
981
+ this . _updateTransform ( ) ;
982
+ } else {
983
+ this . _origin . copy ( point ) ;
984
+ if ( ! smooth ) {
985
+ this . _position . copy ( point ) ;
986
+ }
934
987
}
935
988
936
- this . _updateTransform ( ) ;
989
+ if ( smooth ) {
990
+ this . _focusing = true ;
991
+ }
937
992
}
938
993
939
994
/**
@@ -957,7 +1012,7 @@ class CameraControls extends Script {
957
1012
* @param {number } [zoomDist] - The zoom distance.
958
1013
* @param {boolean } [smooth] - Whether to smooth the refocus.
959
1014
*/
960
- refocus ( point , start = null , zoomDist , smooth = true ) {
1015
+ refocus ( point , start , zoomDist , smooth = true ) {
961
1016
if ( typeof zoomDist === 'number' ) {
962
1017
this . resetZoom ( zoomDist , smooth ) ;
963
1018
}
@@ -1003,9 +1058,8 @@ class CameraControls extends Script {
1003
1058
1004
1059
this . _camera = null ;
1005
1060
1006
- this . _dir . x = this . _angles . x ;
1007
- this . _dir . y = this . _angles . y ;
1008
- this . _origin . copy ( this . _position ) ;
1061
+ this . _cancelSmoothZoom ( ) ;
1062
+ this . _cancelSmoothTransform ( ) ;
1009
1063
1010
1064
this . _pointerEvents . clear ( ) ;
1011
1065
this . _lastPinchDist = - 1 ;
0 commit comments