Browse Source

Simplified Device Orientation Controls

WestLangley 11 years ago
parent
commit
488a7aeea4

+ 0 - 1
examples/css3d_panorama_deviceorientation.html

@@ -87,7 +87,6 @@
 				];
 
 				var cube = new THREE.Object3D();
-				cube.rotation.x = 90 * ( Math.PI / 180 );
 				scene.add( cube );
 
 				for ( var i = 0; i < sides.length; i ++ ) {

+ 55 - 150
examples/js/controls/DeviceOrientationControls.js

@@ -1,202 +1,107 @@
 /**
  * @author richt / http://richt.me
+ * @author WestLangley / http://github.com/WestLangley
  *
- * W3C Device Orientation control (http://www.w3.org/TR/orientation-event/)
+ * W3C Device Orientation control (http://w3c.github.io/deviceorientation/spec-source-orientation.html)
  */
 
 THREE.DeviceOrientationControls = function ( object ) {
 
 	this.object = object;
 
+	this.object.rotation.reorder( "YXZ" );
+
 	this.freeze = true;
 
 	this.deviceOrientation = {};
-	this.screenOrientation = 0;
-
-	var degtorad = Math.PI / 180;
 
-	var objectRotationMatrix = new THREE.Matrix4();
-	var tmpRotationMatrix    = new THREE.Matrix4();
+	this.screenOrientation = 0;
 
 	this.onDeviceOrientationChangeEvent = function( rawEvtData ) {
+
 		this.deviceOrientation = rawEvtData;
+
 	};
 
 	this.onScreenOrientationChangeEvent = function() {
+
 		this.screenOrientation = window.orientation || 0;
-	};
 
-	this.setObjectRotationMatrixFromDeviceOrientation = function() {
-		var x = this.deviceOrientation.beta  ? this.deviceOrientation.beta  * degtorad : 0; // beta
-		var y = this.deviceOrientation.gamma ? this.deviceOrientation.gamma * degtorad : 0; // gamma
-		var z = this.deviceOrientation.alpha ? this.deviceOrientation.alpha * degtorad : 0; // alpha
-
-		var cX = Math.cos(x);
-		var cY = Math.cos(y);
-		var cZ = Math.cos(z);
-		var sX = Math.sin(x);
-		var sY = Math.sin(y);
-		var sZ = Math.sin(z);
-
-		//
-		// ZXY rotation matrix construction.
-		//
-		// (see: http://bit.ly/1fjIr6Y)
-		//
-
-		var m11 = cZ * cY - sZ * sX * sY;
-		var m12 = - cX * sZ;
-		var m13 = cY * sZ * sX + cZ * sY;
-
-		var m21 = cY * sZ + cZ * sX * sY;
-		var m22 = cZ * cX;
-		var m23 = sZ * sY - cZ * cY * sX;
-
-		var m31 = - cX * sY;
-		var m32 = sX;
-		var m33 = cX * cY;
-
-		objectRotationMatrix.set(
-			m11,    m12,    m13,    0,
-			m21,    m22,    m23,    0,
-			m31,    m32,    m33,    0,
-			0,      0,      0,      1
-		);
-
-		return objectRotationMatrix;
 	};
 
-	this.remapObjectRotationMatrixFromScreenOrientation = function() {
-                tmpRotationMatrix.copy( objectRotationMatrix );
-
-		switch( this.screenOrientation ) {
-			case 90:
-			case -270:
-				//
-				// 90 degrees counter-clockwise screen transformation matrix:
-				//
-				//      /  0 -1  0  0  \
-				//      |  1  0  0  0  |
-				//      |  0  0  1  0  |
-				//      \  0  0  0  1  /
-				//
-				// (see: http://bit.ly/1itCOq2)
-				//
-
-				objectRotationMatrix.elements[0]  = - tmpRotationMatrix.elements[4];
-				objectRotationMatrix.elements[4]  =   tmpRotationMatrix.elements[0];
-				objectRotationMatrix.elements[8]  =   tmpRotationMatrix.elements[8];
-
-				objectRotationMatrix.elements[1]  = - tmpRotationMatrix.elements[5];
-				objectRotationMatrix.elements[5]  =   tmpRotationMatrix.elements[1];
-				objectRotationMatrix.elements[9]  =   tmpRotationMatrix.elements[9];
-
-				objectRotationMatrix.elements[2]  = - tmpRotationMatrix.elements[6];
-				objectRotationMatrix.elements[6]  =   tmpRotationMatrix.elements[2];
-				objectRotationMatrix.elements[10] =   tmpRotationMatrix.elements[10];
-
-				break;
-			case 180:
-			case -180:
-				//
-				// 180 degrees counter-clockwise screen transformation matrix:
-				//
-				//      / -1  0  0  0  \
-				//      |  0 -1  0  0  |
-				//      |  0  0  1  0  |
-				//      \  0  0  0  1  /
-				//
-				// (see: http://bit.ly/1dIrx0I)
-				//
-
-				objectRotationMatrix.elements[0]  = - tmpRotationMatrix.elements[0];
-				objectRotationMatrix.elements[4]  = - tmpRotationMatrix.elements[4];
-				objectRotationMatrix.elements[8]  =   tmpRotationMatrix.elements[8];
-
-				objectRotationMatrix.elements[1]  = - tmpRotationMatrix.elements[1];
-				objectRotationMatrix.elements[5]  = - tmpRotationMatrix.elements[5];
-				objectRotationMatrix.elements[9]  =   tmpRotationMatrix.elements[9];
-
-				objectRotationMatrix.elements[2]  = - tmpRotationMatrix.elements[2];
-				objectRotationMatrix.elements[6]  = - tmpRotationMatrix.elements[6];
-				objectRotationMatrix.elements[10] =   tmpRotationMatrix.elements[10];
-
-				break;
-			case 270:
-			case -90:
-				//
-				// 270 degrees counter-clockwise screen transformation matrix:
-				//
-				//      /  0  1  0  0  \
-				//      | -1  0  0  0  |
-				//      |  0  0  1  0  |
-				//      \  0  0  0  1  /
-				//
-				// (see: http://bit.ly/1h73sQ0)
-				//
-
-				objectRotationMatrix.elements[0]  =   tmpRotationMatrix.elements[4];
-				objectRotationMatrix.elements[4]  = - tmpRotationMatrix.elements[0];
-				objectRotationMatrix.elements[8]  =   tmpRotationMatrix.elements[8];
-
-				objectRotationMatrix.elements[1]  =   tmpRotationMatrix.elements[5];
-				objectRotationMatrix.elements[5]  = - tmpRotationMatrix.elements[1];
-				objectRotationMatrix.elements[9]  =   tmpRotationMatrix.elements[9];
-
-				objectRotationMatrix.elements[2]  =   tmpRotationMatrix.elements[6];
-				objectRotationMatrix.elements[6]  = - tmpRotationMatrix.elements[2];
-				objectRotationMatrix.elements[10] =   tmpRotationMatrix.elements[10];
-
-				break;
-			default:
-				//
-				// 0 degrees screen transformation matrix:
-				//
-				//      /  1  0  0  0  \
-				//      |  0  1  0  0  |
-				//      |  0  0  1  0  |
-				//      \  0  0  0  1  /
-				//
-				// This transformation is the same as the identity matrix so we need do nothing
-
-				break;
-		}
+	this.update = function() {
 
-		return objectRotationMatrix;
-	};
+		var alpha, beta, gamma;
 
-	this.update = function( delta ) {
-		if ( this.freeze ) {
-			return;
-		}
+		return function () {
 
-		this.setObjectRotationMatrixFromDeviceOrientation();
+			if ( this.freeze ) return;
 
-		this.remapObjectRotationMatrixFromScreenOrientation();
+			alpha  = this.deviceOrientation.gamma ? THREE.Math.degToRad( this.deviceOrientation.alpha ) : 0; // Z
+			beta   = this.deviceOrientation.beta  ? THREE.Math.degToRad( this.deviceOrientation.beta  ) : 0; // X'
+			gamma  = this.deviceOrientation.gamma ? THREE.Math.degToRad( this.deviceOrientation.gamma ) : 0; // Y''
+			orient = this.screenOrientation       ? THREE.Math.degToRad( this.screenOrientation       ) : 0; // O
 
-		this.object.quaternion.setFromRotationMatrix( objectRotationMatrix );
-	};
+			setObjectQuaternion( this.object.quaternion, alpha, beta, gamma, orient );
+
+		}
+
+	}();
 
 	function bind( scope, fn ) {
+
 		return function () {
+
 			fn.apply( scope, arguments );
+
 		};
+
 	};
 
 	this.connect = function() {
+
 		this.onScreenOrientationChangeEvent(); // run once on load
 
 		window.addEventListener( 'orientationchange', bind( this, this.onScreenOrientationChangeEvent ), false );
 		window.addEventListener( 'deviceorientation', bind( this, this.onDeviceOrientationChangeEvent ), false );
 
 		this.freeze = false;
+
 	};
 
 	this.disconnect = function() {
+
 		this.freeze = true;
 
 		window.removeEventListener( 'orientationchange', bind( this, this.onScreenOrientationChangeEvent ), false );
 		window.removeEventListener( 'deviceorientation', bind( this, this.onDeviceOrientationChangeEvent ), false );
+
 	};
 
+	// The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''
+
+	setObjectQuaternion = function () {
+
+		var zee = new THREE.Vector3( 0, 0, 1 );
+
+		var euler = new THREE.Euler();
+
+		var q0 = new THREE.Quaternion();
+
+		var q1 = new THREE.Quaternion( - Math.sqrt( 0.5 ), 0, 0, Math.sqrt( 0.5 ) ); // - PI/2 around the x-axis
+
+		return function ( quaternion, alpha, beta, gamma, orient ) {
+
+			euler.set( beta, alpha, - gamma, 'YXZ' );						// 'ZXY' for the device, but 'YXZ' for us
+
+			quaternion.setFromEuler( euler );								// orient the device
+
+			quaternion.multiply( q1 );										// camera looks out the back of the device, not the top
+
+			quaternion.multiply( q0.setFromAxisAngle( zee, - orient ) );	// adjust for screen orientation
+
+		}
+
+	}();
+
 };

+ 4 - 4
examples/misc_controls_deviceorientation.html

@@ -71,18 +71,18 @@
 
 						scene = new THREE.Scene();
 
-						var geometry = new THREE.SphereGeometry( 500, 60, 40 );
+						var geometry = new THREE.SphereGeometry( 500, 16, 8 );
 						geometry.applyMatrix( new THREE.Matrix4().makeScale( -1, 1, 1 ) );
 
 						var material = new THREE.MeshBasicMaterial( {
-								map: THREE.ImageUtils.loadTexture( 'textures/2294472375_24a3b8ef46_o.jpg' )
+								//map: THREE.ImageUtils.loadTexture( 'textures/2294472375_24a3b8ef46_o.jpg' )
+								wireframe: true
 						} );
 
 						var mesh = new THREE.Mesh( geometry, material );
-						mesh.rotation.x = 90 * ( Math.PI / 180 );
 						scene.add(mesh);
 
-						renderer = hasWebGL ? new THREE.WebGLRenderer() : new THREE.CanvasRenderer();
+						renderer = hasWebGL ? new THREE.WebGLRenderer() : new THREE.CanvasRenderer( { devicePixelRatio: 1 } );
 						renderer.setSize(window.innerWidth, window.innerHeight);
 						renderer.domElement.style.position = 'absolute';
 						renderer.domElement.style.top = 0;