Browse Source

added dynamic moving to TrackballCamera

Eberhard Gräther 14 years ago
parent
commit
6d08b4980b
1 changed files with 104 additions and 46 deletions
  1. 104 46
      src/extras/cameras/TrackballCamera.js

+ 104 - 46
src/extras/cameras/TrackballCamera.js

@@ -17,6 +17,9 @@
  *	noZoom: <bool>,
  *	noPan: <bool>,
 
+ *	staticMoving: <bool>,
+ *	dynamicDampingFactor: <float>,
+
  *	keys: <Array>, // [ rotateKey, zoomKey, panKey ],
 
  *	domElement: <HTMLElement>,
@@ -36,12 +39,15 @@ THREE.TrackballCamera = function ( parameters ) {
 	this.screen = parameters.screen || { width : window.innerWidth, height : window.innerHeight, offsetLeft : 0, offsetTop : 0 };
 	this.radius = parameters.radius || ( this.screen.width + this.screen.height ) / 4;
 
-	this.zoomSpeed = parameters.zoomSpeed || 1.5;
+	this.zoomSpeed = parameters.zoomSpeed || 1.2;
 	this.panSpeed = parameters.panSpeed || 0.3;
 
 	this.noZoom = parameters.noZoom || false;
 	this.noPan = parameters.noPan || false;
 
+	this.staticMoving = parameters.staticMoving || false;
+	this.dynamicDampingFactor = parameters.dynamicDampingFactor || 0.2;
+
 	this.keys = parameters.keys || [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
 
 	this.useTarget = true;
@@ -50,13 +56,16 @@ THREE.TrackballCamera = function ( parameters ) {
 	//internals
 
 	var _keyPressed = false,
-	
 	_state = this.STATE.NONE,
-	
-	_mouse = new THREE.Vector2(),
-	
-	_start = new THREE.Vector3(),
-	_end = new THREE.Vector3();
+
+	_rotateStart = new THREE.Vector3(),
+	_rotateEnd = new THREE.Vector3(),
+
+	_zoomStart = new THREE.Vector2(),
+	_zoomEnd = new THREE.Vector2(),
+
+	_panStart = new THREE.Vector2(),
+	_panEnd = new THREE.Vector2();
 
 
 	// methods
@@ -108,69 +117,109 @@ THREE.TrackballCamera = function ( parameters ) {
 
 	};
 
-	this.rotateCamera = function( clientX, clientY ) {
-
-		_end = this.getMouseProjectionOnBall( clientX, clientY );
+	this.rotateCamera = function() {
 
-		var angle = Math.acos( _start.dot( _end ) / _start.length() / _end.length() );
+		var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
 
 		if ( angle ) {
 
-			var axis = (new THREE.Vector3()).cross( _end, _start ).normalize(),
+			var axis = (new THREE.Vector3()).cross( _rotateStart, _rotateEnd ).normalize(),
 			quaternion = new THREE.Quaternion();
 
-			quaternion.setFromAxisAngle( axis, angle );
+			quaternion.setFromAxisAngle( axis, -angle );
 
 			quaternion.multiplyVector3( this.position );
 			quaternion.multiplyVector3( this.up );
 
-			// quaternion.setFromAxisAngle( axis, angle * -0.1 );
-			// quaternion.multiplyVector3( _start );
+			if ( !this.staticMoving ) {
+
+				quaternion.multiplyVector3( _rotateEnd );
+
+				quaternion.setFromAxisAngle( axis, angle * ( this.dynamicDampingFactor - 1.0 ) );
+				quaternion.multiplyVector3( _rotateStart );
+
+			}
 
 		}
 
 	};
 
-	this.zoomCamera = function( clientX, clientY ) {
+	this.zoomCamera = function() {
 
-		var newMouse = this.getMouseOnScreen( clientX, clientY ),
-		eye = this.position.clone().subSelf( this.target.position ),
-		factor = 1.0 + ( newMouse.y - _mouse.y ) * this.zoomSpeed;
+		var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * this.zoomSpeed;
 
-		if ( factor > 0.0 ) {
+		if ( factor !== 1.0 && factor > 0.0 ) {
 
+			var eye = this.position.clone().subSelf( this.target.position );
 			this.position.add( this.target.position, eye.multiplyScalar( factor ) );
-			_mouse = newMouse;
+
+			if ( this.staticMoving ) {
+
+				_zoomStart = _zoomEnd;
+
+			} else {
+
+				_zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
+
+			}
 
 		}
 
 	};
 
-	this.panCamera = function( clientX, clientY ) {
+	this.panCamera = function() {
+
+		var mouseChange = _panEnd.clone().subSelf( _panStart );
+
+		if ( mouseChange.lengthSq() ) {
+
+			var factor = this.position.distanceTo( this.target.position ) * this.panSpeed;
+
+			mouseChange.multiplyScalar( factor );
+
+			var pan = this.position.clone().crossSelf( this.up ).setLength( mouseChange.x );
+			pan.addSelf( this.up.clone().setLength( mouseChange.y ) );
 
-		var newMouse = this.getMouseOnScreen( clientX, clientY ),
-		mouseChange = newMouse.clone().subSelf( _mouse ),
-		factor = this.position.distanceTo( this.target.position ) * this.panSpeed;
+			this.position.addSelf( pan );
+			this.target.position.addSelf( pan );
 
-		mouseChange.multiplyScalar( factor );
+			if ( this.staticMoving ) {
 
-		var pan = this.position.clone().crossSelf( this.up ).setLength( mouseChange.x );
-		pan.addSelf( this.up.clone().setLength( mouseChange.y ) );
+				_panStart = _panEnd;
 
-		this.position.addSelf( pan );
-		this.target.position.addSelf( pan );
+			} else {
+
+				_panStart.addSelf( mouseChange.sub( _panEnd, _panStart ).multiplyScalar( this.dynamicDampingFactor ) );
 
-		_mouse = newMouse;
+			}
+
+		}
 
 	};
 	
-	// this.update = function( parentMatrixWorld, forceUpdate, camera ) {
-	// 
-	// 	this.rotateCamera();
-	// 
-	// 	this.supr.update.call( this, parentMatrixWorld, forceUpdate, camera );
-	// 
-	// };
+	this.update = function( parentMatrixWorld, forceUpdate, camera ) {
+	
+		if ( !this.staticMoving ) {
+
+			this.rotateCamera();
+
+		}
+
+		if ( !this.noZoom ) {
+
+			this.zoomCamera();
+
+		}
+
+		if ( !this.noPan ) {
+
+			this.panCamera();
+
+		}
+	
+		this.supr.update.call( this, parentMatrixWorld, forceUpdate, camera );
+	
+	};
 
 	// listeners
 
@@ -220,11 +269,15 @@ THREE.TrackballCamera = function ( parameters ) {
 
 			if ( _state === this.STATE.ROTATE ) {
 
-				_start = this.getMouseProjectionOnBall( event.clientX, event.clientY );
+				_rotateStart = _rotateEnd = this.getMouseProjectionOnBall( event.clientX, event.clientY );
+
+			} else if ( _state === this.STATE.ZOOM ) {
+
+				_zoomStart = _zoomEnd = this.getMouseOnScreen( event.clientX, event.clientY );
 
 			} else {
 
-				_mouse = this.getMouseOnScreen( event.clientX, event.clientY );
+				_panStart = _panEnd = this.getMouseOnScreen( event.clientX, event.clientY );
 
 			}
 
@@ -236,8 +289,9 @@ THREE.TrackballCamera = function ( parameters ) {
 
 		if ( _keyPressed ) {
 
-			_start = this.getMouseProjectionOnBall( event.clientX, event.clientY );
-			_mouse = this.getMouseOnScreen( event.clientX, event.clientY );
+			_rotateStart = _rotateEnd = this.getMouseProjectionOnBall( event.clientX, event.clientY );
+			_zoomStart = _zoomEnd = this.getMouseOnScreen( event.clientX, event.clientY );
+			_panStart = _panEnd = this.getMouseOnScreen( event.clientX, event.clientY );
 
 			_keyPressed = false;
 
@@ -249,17 +303,21 @@ THREE.TrackballCamera = function ( parameters ) {
 
 		} else if ( _state === this.STATE.ROTATE ) {
 
-			// _end = this.getMouseProjectionOnBall( event.clientX, event.clientY );
+			_rotateEnd = this.getMouseProjectionOnBall( event.clientX, event.clientY );
 
-			this.rotateCamera( event.clientX, event.clientY );
+			if ( this.staticMoving ) {
+
+				this.rotateCamera();
+
+			}
 
 		} else if ( _state === this.STATE.ZOOM && !this.noZoom ) {
 
-			this.zoomCamera( event.clientX, event.clientY );
+			_zoomEnd = this.getMouseOnScreen( event.clientX, event.clientY );
 
 		} else if ( _state === this.STATE.PAN && !this.noPan ) {
 
-			this.panCamera( event.clientX, event.clientY );
+			_panEnd = this.getMouseOnScreen( event.clientX, event.clientY );
 
 		}