1
+ import ArBaseControls from "./threex-arbasecontrols" ;
2
+ import { setParameters } from "./functions/utils" ;
3
+
4
+ export default class ArSmoothedControls extends ArBaseControls {
5
+ constructor ( object3d , parameters ) {
6
+ super ( object3d ) ;
7
+
8
+ this . _lastLerpStepAt = null ;
9
+ this . _visibleStartedAt = null ;
10
+ this . _unvisibleStartedAt = null ;
11
+
12
+ // handle default parameters
13
+ parameters = parameters || { } ;
14
+ this . parameters = {
15
+ // lerp coeficient for the position - between [0,1] - default to 1
16
+ lerpPosition : 0.8 ,
17
+ // lerp coeficient for the quaternion - between [0,1] - default to 1
18
+ lerpQuaternion : 0.2 ,
19
+ // lerp coeficient for the scale - between [0,1] - default to 1
20
+ lerpScale : 0.7 ,
21
+ // delay for lerp fixed steps - in seconds - default to 1/120
22
+ lerpStepDelay : 1 / 60 ,
23
+ // minimum delay the sub-control must be visible before this controls become visible - default to 0 seconds
24
+ minVisibleDelay : 0.0 ,
25
+ // minimum delay the sub-control must be unvisible before this controls become unvisible - default to 0 seconds
26
+ minUnvisibleDelay : 0.2 ,
27
+ } ;
28
+
29
+ //////////////////////////////////////////////////////////////////////////////
30
+ // setParameters
31
+ //////////////////////////////////////////////////////////////////////////////
32
+ setParameters ( parameters , this ) ;
33
+ }
34
+
35
+ update ( targetObject3d ) {
36
+ const object3d = this . object3d ;
37
+ const parameters = this . parameters ;
38
+ const wasVisible = object3d . visible ;
39
+ const present = performance . now ( ) / 1000 ;
40
+
41
+ //////////////////////////////////////////////////////////////////////////////
42
+ // handle object3d.visible with minVisibleDelay/minUnvisibleDelay
43
+ //////////////////////////////////////////////////////////////////////////////
44
+ if ( targetObject3d . visible === false ) this . _visibleStartedAt = null ;
45
+ if ( targetObject3d . visible === true ) this . _unvisibleStartedAt = null ;
46
+
47
+ if ( targetObject3d . visible === true && this . _visibleStartedAt === null )
48
+ this . _visibleStartedAt = present ;
49
+ if ( targetObject3d . visible === false && this . _unvisibleStartedAt === null )
50
+ this . _unvisibleStartedAt = present ;
51
+
52
+ if ( wasVisible === false && targetObject3d . visible === true ) {
53
+ const visibleFor = present - this . _visibleStartedAt ;
54
+ if ( visibleFor >= this . parameters . minVisibleDelay ) {
55
+ object3d . visible = true ;
56
+ snapDirectlyToTarget ( ) ;
57
+ }
58
+ // console.log('visibleFor', visibleFor)
59
+ }
60
+
61
+ if ( wasVisible === true && targetObject3d . visible === false ) {
62
+ const unvisibleFor = present - this . _unvisibleStartedAt ;
63
+ if ( unvisibleFor >= this . parameters . minUnvisibleDelay ) {
64
+ object3d . visible = false ;
65
+ }
66
+ }
67
+
68
+ //////////////////////////////////////////////////////////////////////////////
69
+ // apply lerp on positon/quaternion/scale
70
+ //////////////////////////////////////////////////////////////////////////////
71
+
72
+ // apply lerp steps - require fix time steps to behave the same no matter the fps
73
+ if ( this . _lastLerpStepAt === null ) {
74
+ applyOneSlerpStep ( ) ;
75
+ this . _lastLerpStepAt = present ;
76
+ } else {
77
+ var nStepsToDo = Math . floor (
78
+ ( present - this . _lastLerpStepAt ) / this . parameters . lerpStepDelay
79
+ ) ;
80
+ for ( var i = 0 ; i < nStepsToDo ; i ++ ) {
81
+ applyOneSlerpStep ( ) ;
82
+ this . _lastLerpStepAt += this . parameters . lerpStepDelay ;
83
+ }
84
+ }
85
+
86
+ // disable the lerp by directly copying targetObject3d position/quaternion/scale
87
+ if ( false ) {
88
+ snapDirectlyToTarget ( ) ;
89
+ }
90
+
91
+ // update the matrix
92
+ this . object3d . updateMatrix ( ) ;
93
+
94
+ //////////////////////////////////////////////////////////////////////////////
95
+ // honor becameVisible/becameUnVisible event
96
+ //////////////////////////////////////////////////////////////////////////////
97
+ // honor becameVisible event
98
+ if ( wasVisible === false && object3d . visible === true ) {
99
+ this . dispatchEvent ( { type : "becameVisible" } ) ;
100
+ }
101
+ // honor becameUnVisible event
102
+ if ( wasVisible === true && object3d . visible === false ) {
103
+ this . dispatchEvent ( { type : "becameUnVisible" } ) ;
104
+ }
105
+ return ;
106
+
107
+ function snapDirectlyToTarget ( ) {
108
+ object3d . position . copy ( targetObject3d . position ) ;
109
+ object3d . quaternion . copy ( targetObject3d . quaternion ) ;
110
+ object3d . scale . copy ( targetObject3d . scale ) ;
111
+ }
112
+
113
+ function applyOneSlerpStep ( ) {
114
+ object3d . position . lerp ( targetObject3d . position , parameters . lerpPosition ) ;
115
+ object3d . quaternion . slerp (
116
+ targetObject3d . quaternion ,
117
+ parameters . lerpQuaternion
118
+ ) ;
119
+ object3d . scale . lerp ( targetObject3d . scale , parameters . lerpScale ) ;
120
+ }
121
+ } ;
122
+
123
+ name ( ) {
124
+ return "ArSmoothedControls" ;
125
+ }
126
+ }
0 commit comments