浏览代码

Add a touch of damping to OrbitControls

Inspired by damping in TrackballControls, adds a little bit of kinetic
friction to OrbitControls. This makes the rotation controls feel much
more physical.

Damping is disabled by default, preserving the existing behavior.

Damping is enabled explicitly in the example.
Leo Singer 11 年之前
父节点
当前提交
3a95051694
共有 2 个文件被更改,包括 39 次插入12 次删除
  1. 28 12
      examples/js/controls/OrbitControls.js
  2. 11 0
      examples/misc_controls_orbit.html

+ 28 - 12
examples/js/controls/OrbitControls.js

@@ -71,6 +71,14 @@ THREE.OrbitControls = function ( object, domElement ) {
 	// The four arrow keys
 	this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
 
+	// A little bit of damping, as if the mouse movement imparts momentum which
+	// is carried away by kinetic friction. On each update, a step is taken
+	// proportional to this factor times the requested angle change.
+	//   0.0: don't move at all
+	//   0.2: feels physically responsive at about 60 FPS
+	//   1.0: track mouse motion immediately
+	this.damping = 1.0;
+
 	////////////
 	// internals
 
@@ -229,6 +237,18 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 	};
 
+	this.getThetaPhi = function() {
+		// angle from z-axis around y-axis
+
+		var theta = Math.atan2( offset.x, offset.z );
+
+		// angle from y-axis
+
+		var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
+
+		return [theta, phi];
+	}
+
 	this.update = function () {
 
 		var position = this.object.position;
@@ -238,23 +258,21 @@ THREE.OrbitControls = function ( object, domElement ) {
 		// rotate offset to "y-axis-is-up" space
 		offset.applyQuaternion( quat );
 
-		// angle from z-axis around y-axis
+		var thetaPhi = this.getThetaPhi();
+		var theta = thetaPhi[0];
+		var phi = thetaPhi[1];
 
-		var theta = Math.atan2( offset.x, offset.z );
-
-		// angle from y-axis
-
-		var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
+		theta += this.damping * thetaDelta;
+		phi += this.damping * phiDelta;
+		thetaDelta *= (1 - this.damping);
+		phiDelta *= (1 - this.damping);
 
 		if ( this.autoRotate ) {
 
-			this.rotateLeft( getAutoRotationAngle() );
+			theta += getAutoRotationAngle();
 
 		}
 
-		theta += thetaDelta;
-		phi += phiDelta;
-
 		// restrict phi to be between desired limits
 		phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
 
@@ -280,8 +298,6 @@ THREE.OrbitControls = function ( object, domElement ) {
 
 		this.object.lookAt( this.target );
 
-		thetaDelta = 0;
-		phiDelta = 0;
 		scale = 1;
 		pan.set( 0, 0, 0 );
 

+ 11 - 0
examples/misc_controls_orbit.html

@@ -55,12 +55,20 @@
 			init();
 			render();
 
+			function animate() {
+
+				requestAnimationFrame(animate);
+				controls.update();
+
+			}
+
 			function init() {
 
 				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
 				camera.position.z = 500;
 
 				controls = new THREE.OrbitControls( camera );
+				controls.damping = 0.2;
 				controls.addEventListener( 'change', render );
 
 				scene = new THREE.Scene();
@@ -117,6 +125,9 @@
 
 				window.addEventListener( 'resize', onWindowResize, false );
 
+				controls.addEventListener('change', render);
+				animate();
+
 			}
 
 			function onWindowResize() {