20
20
* }
21
21
*/
22
22
23
+ // TODO: onWindowResize();
24
+
23
25
THREE . TrackballCamera = function ( parameters ) {
24
26
25
27
THREE . Camera . call ( this , parameters . fov , parameters . aspect , parameters . near , parameters . far , parameters . target ) ;
@@ -50,10 +52,11 @@ THREE.TrackballCamera = function ( parameters ) {
50
52
51
53
this . useTarget = true ;
52
54
53
- this . mouseDragOn = false ;
54
-
55
+ this . state = this . STATE . NONE ;
55
56
this . screen = this . getScreenDimensions ( ) ;
56
57
58
+ this . mouse = new THREE . Vector2 ( ) ;
59
+
57
60
this . start = new THREE . Vector3 ( ) ;
58
61
this . end = new THREE . Vector3 ( ) ;
59
62
@@ -67,6 +70,8 @@ THREE.TrackballCamera = function ( parameters ) {
67
70
68
71
} ;
69
72
73
+ this . domElement . addEventListener ( 'contextmenu' , function ( event ) { event . preventDefault ( ) ; } , false ) ;
74
+
70
75
this . domElement . addEventListener ( 'mousemove' , bind ( this , this . mousemove ) , false ) ;
71
76
this . domElement . addEventListener ( 'mousedown' , bind ( this , this . mousedown ) , false ) ;
72
77
this . domElement . addEventListener ( 'mouseup' , bind ( this , this . mouseup ) , false ) ;
@@ -80,6 +85,13 @@ THREE.TrackballCamera.prototype = new THREE.Camera();
80
85
THREE . TrackballCamera . prototype . constructor = THREE . TrackballCamera ;
81
86
THREE . TrackballCamera . prototype . supr = THREE . Camera . prototype ;
82
87
88
+ THREE . TrackballCamera . prototype . STATE = {
89
+ NONE : - 1 ,
90
+ ROTATE : 0 ,
91
+ ZOOM : 1 ,
92
+ PAN : 2
93
+ } ;
94
+
83
95
THREE . TrackballCamera . prototype . handleEvent = function ( event ) {
84
96
85
97
if ( typeof this [ event . type ] == 'function' ) {
@@ -106,32 +118,42 @@ THREE.TrackballCamera.prototype.mousedown = function(event) {
106
118
107
119
event . preventDefault ( ) ;
108
120
event . stopPropagation ( ) ;
109
-
110
- this . mouseDragOn = true ;
111
121
112
- this . start = this . getMouseProjectionOnBall ( event . clientX , event . clientY ) ;
122
+ if ( this . state === this . STATE . NONE ) {
123
+
124
+ this . state = event . button ;
125
+
126
+ if ( this . state === this . STATE . ROTATE ) {
127
+
128
+ this . start = this . getMouseProjectionOnBall ( event . clientX , event . clientY ) ;
129
+
130
+ } else {
131
+
132
+ this . mouse = this . getMouseOnScreen ( event . clientX , event . clientY ) ;
133
+
134
+ }
135
+
136
+ }
113
137
114
138
} ;
115
139
116
140
THREE . TrackballCamera . prototype . mousemove = function ( event ) {
117
141
118
- if ( this . mouseDragOn ) {
142
+ if ( this . state === this . STATE . NONE ) {
119
143
120
- this . end = this . getMouseProjectionOnBall ( event . clientX , event . clientY ) ;
144
+ return ;
121
145
122
- var angle = Math . acos ( this . start . dot ( this . end ) / this . start . length ( ) / this . end . length ( ) ) ;
146
+ } else if ( this . state === this . STATE . ROTATE ) {
123
147
124
- if ( angle ) {
148
+ this . rotateCamera ( event . clientX , event . clientY ) ;
125
149
126
- var axis = ( new THREE . Vector3 ( ) ) . cross ( this . end , this . start ) . normalize ( ) ,
127
- quaternion = new THREE . Quaternion ( ) ;
150
+ } else if ( this . state === this . STATE . ZOOM && ! this . noZoom ) {
128
151
129
- quaternion . setFromAxisAngle ( axis , angle ) ;
152
+ this . zoomCamera ( event . clientX , event . clientY ) ;
130
153
131
- quaternion . multiplyVector3 ( this . position ) ;
132
- quaternion . multiplyVector3 ( this . up ) ;
154
+ } else if ( this . state === this . STATE . PAN && ! this . noPan ) {
133
155
134
- }
156
+ this . panCamera ( event . clientX , event . clientY ) ;
135
157
136
158
}
137
159
@@ -142,7 +164,7 @@ THREE.TrackballCamera.prototype.mouseup = function( event ) {
142
164
event . preventDefault ( ) ;
143
165
event . stopPropagation ( ) ;
144
166
145
- this . mouseDragOn = false ;
167
+ this . state = this . STATE . NONE ;
146
168
147
169
} ;
148
170
@@ -170,30 +192,92 @@ THREE.TrackballCamera.prototype.getScreenDimensions = function() {
170
192
171
193
} ;
172
194
195
+ THREE . TrackballCamera . prototype . getMouseOnScreen = function ( clientX , clientY ) {
196
+
197
+ return new THREE . Vector2 (
198
+ ( clientX - this . screen . offsetLeft ) / this . radius * 0.5 ,
199
+ ( clientY - this . screen . offsetTop ) / this . radius * 0.5
200
+ ) ;
201
+
202
+ } ;
203
+
173
204
THREE . TrackballCamera . prototype . getMouseProjectionOnBall = function ( clientX , clientY ) {
174
205
175
- var mouse = new THREE . Vector3 (
206
+ var mouseOnBall = new THREE . Vector3 (
176
207
( clientX - this . screen . width * 0.5 - this . screen . offsetLeft ) / this . radius ,
177
208
( this . screen . height * 0.5 + this . screen . offsetTop - clientY ) / this . radius ,
178
209
0.0
179
210
) ;
180
211
181
- var length = mouse . length ( ) ;
212
+ var length = mouseOnBall . length ( ) ;
182
213
183
214
if ( length > 1.0 ) {
184
215
185
- mouse . divideScalar ( length ) ;
216
+ mouseOnBall . normalize ( ) ;
186
217
187
218
} else {
188
219
189
- mouse . z = Math . sqrt ( 1.0 - length * length ) ;
220
+ mouseOnBall . z = Math . sqrt ( 1.0 - length * length ) ;
190
221
191
222
}
192
223
193
- var projection = this . up . clone ( ) . setLength ( mouse . y ) ;
194
- projection . addSelf ( this . up . clone ( ) . crossSelf ( this . position ) . setLength ( mouse . x ) ) ;
195
- projection . addSelf ( this . position . clone ( ) . setLength ( mouse . z ) ) ;
224
+ var projection = this . up . clone ( ) . setLength ( mouseOnBall . y ) ;
225
+ projection . addSelf ( this . up . clone ( ) . crossSelf ( this . position ) . setLength ( mouseOnBall . x ) ) ;
226
+ projection . addSelf ( this . position . clone ( ) . setLength ( mouseOnBall . z ) ) ;
196
227
197
228
return projection ;
198
229
199
230
} ;
231
+
232
+ THREE . TrackballCamera . prototype . rotateCamera = function ( clientX , clientY ) {
233
+
234
+ this . end = this . getMouseProjectionOnBall ( clientX , clientY ) ;
235
+
236
+ var angle = Math . acos ( this . start . dot ( this . end ) / this . start . length ( ) / this . end . length ( ) ) ;
237
+
238
+ if ( angle ) {
239
+
240
+ var axis = ( new THREE . Vector3 ( ) ) . cross ( this . end , this . start ) . normalize ( ) ,
241
+ quaternion = new THREE . Quaternion ( ) ;
242
+
243
+ quaternion . setFromAxisAngle ( axis , angle ) ;
244
+
245
+ quaternion . multiplyVector3 ( this . position ) ;
246
+ quaternion . multiplyVector3 ( this . up ) ;
247
+
248
+ }
249
+
250
+ } ;
251
+
252
+ THREE . TrackballCamera . prototype . zoomCamera = function ( clientX , clientY ) {
253
+
254
+ var newMouse = this . getMouseOnScreen ( clientX , clientY ) ,
255
+ eye = this . position . clone ( ) . subSelf ( this . target . position ) ,
256
+ factor = 1.0 + ( newMouse . y - this . mouse . y ) * this . zoomSpeed ;
257
+
258
+ if ( factor > 0.0 ) {
259
+
260
+ this . position . add ( this . target . position , eye . multiplyScalar ( factor ) ) ;
261
+ this . mouse = newMouse ;
262
+
263
+ }
264
+
265
+ } ;
266
+
267
+ THREE . TrackballCamera . prototype . panCamera = function ( clientX , clientY ) {
268
+
269
+ var newMouse = this . getMouseOnScreen ( clientX , clientY ) ,
270
+ mouseChange = newMouse . clone ( ) . subSelf ( this . mouse ) ,
271
+ factor = this . position . distanceTo ( this . target . position ) * this . panSpeed ;
272
+
273
+ mouseChange . multiplyScalar ( factor ) ;
274
+
275
+ var pan = this . position . clone ( ) . crossSelf ( this . up ) . setLength ( mouseChange . x ) ;
276
+ pan . addSelf ( this . up . clone ( ) . setLength ( mouseChange . y ) ) ;
277
+
278
+ this . position . addSelf ( pan ) ;
279
+ this . target . position . addSelf ( pan ) ;
280
+
281
+ this . mouse = newMouse ;
282
+
283
+ } ;
0 commit comments