|
@@ -11,12 +11,170 @@ THREE.DeviceOrientationControls = function ( object ) {
|
|
|
this.degtorad = Math.PI / 180;
|
|
|
this.freeze = true;
|
|
|
|
|
|
- this.orientationData = {};
|
|
|
- this.eulerRotationOrder = "ZXY";
|
|
|
+ this.deviceOrientation = {};
|
|
|
+ this.screenOrientation = 0;
|
|
|
|
|
|
- this.registerOrientationData = function( data ) {
|
|
|
- this.freeze = false;
|
|
|
- this.orientationData = data;
|
|
|
+ this._rotationVector = new THREE.Vector4();
|
|
|
+ this._rotationMatrix = new THREE.Matrix4();
|
|
|
+
|
|
|
+ this.onDeviceOrientationChangeEvent = function( rawEvtData ) {
|
|
|
+ this.deviceOrientation = rawEvtData;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.onScreenOrientationChangeEvent = function() {
|
|
|
+ this.screenOrientation = window.orientation || 0;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.setRotationVectorFromDeviceOrientation = function( alpha, beta, gamma) {
|
|
|
+ this._rotationVector.set(
|
|
|
+ (beta || 0) * this.degtorad, // x
|
|
|
+ (gamma || 0) * this.degtorad, // y
|
|
|
+ (alpha || 0) * this.degtorad // z
|
|
|
+ );
|
|
|
+
|
|
|
+ return this._rotationVector;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.setRotationMatrixFromRotationVector = function( rotationVector ) {
|
|
|
+ var x = rotationVector.x || 0; // beta
|
|
|
+ var y = rotationVector.y || 0; // gamma
|
|
|
+ var z = rotationVector.z || 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;
|
|
|
+
|
|
|
+ this._rotationMatrix.set(
|
|
|
+ m11, m12, m13, 0,
|
|
|
+ m21, m22, m23, 0,
|
|
|
+ m31, m32, m33, 0,
|
|
|
+ 0, 0, 0, 1
|
|
|
+ );
|
|
|
+
|
|
|
+ return this._rotationMatrix;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.remapRotationMatrixByScreenOrientation = function( screenOrientation, rotationMatrix ) {
|
|
|
+ var transformedRotationMatrix = new THREE.Matrix4();
|
|
|
+ transformedRotationMatrix.copy( rotationMatrix );
|
|
|
+
|
|
|
+ switch( 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)
|
|
|
+ //
|
|
|
+
|
|
|
+ transformedRotationMatrix.elements[0] = -rotationMatrix.elements[4];
|
|
|
+ transformedRotationMatrix.elements[4] = rotationMatrix.elements[0];
|
|
|
+ transformedRotationMatrix.elements[8] = rotationMatrix.elements[8];
|
|
|
+
|
|
|
+ transformedRotationMatrix.elements[1] = -rotationMatrix.elements[5];
|
|
|
+ transformedRotationMatrix.elements[5] = rotationMatrix.elements[1];
|
|
|
+ transformedRotationMatrix.elements[9] = rotationMatrix.elements[9];
|
|
|
+
|
|
|
+ transformedRotationMatrix.elements[2] = -rotationMatrix.elements[6];
|
|
|
+ transformedRotationMatrix.elements[6] = rotationMatrix.elements[2];
|
|
|
+ transformedRotationMatrix.elements[10] = rotationMatrix.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)
|
|
|
+ //
|
|
|
+
|
|
|
+ transformedRotationMatrix.elements[0] = -rotationMatrix.elements[0];
|
|
|
+ transformedRotationMatrix.elements[4] = -rotationMatrix.elements[4];
|
|
|
+ transformedRotationMatrix.elements[8] = rotationMatrix.elements[8];
|
|
|
+
|
|
|
+ transformedRotationMatrix.elements[1] = -rotationMatrix.elements[1];
|
|
|
+ transformedRotationMatrix.elements[5] = -rotationMatrix.elements[5];
|
|
|
+ transformedRotationMatrix.elements[9] = rotationMatrix.elements[9];
|
|
|
+
|
|
|
+ transformedRotationMatrix.elements[2] = -rotationMatrix.elements[2];
|
|
|
+ transformedRotationMatrix.elements[6] = -rotationMatrix.elements[6];
|
|
|
+ transformedRotationMatrix.elements[10] = rotationMatrix.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)
|
|
|
+ //
|
|
|
+
|
|
|
+ transformedRotationMatrix.elements[0] = rotationMatrix.elements[4];
|
|
|
+ transformedRotationMatrix.elements[4] = -rotationMatrix.elements[0];
|
|
|
+ transformedRotationMatrix.elements[8] = rotationMatrix.elements[8];
|
|
|
+
|
|
|
+ transformedRotationMatrix.elements[1] = rotationMatrix.elements[5];
|
|
|
+ transformedRotationMatrix.elements[5] = -rotationMatrix.elements[1];
|
|
|
+ transformedRotationMatrix.elements[9] = rotationMatrix.elements[9];
|
|
|
+
|
|
|
+ transformedRotationMatrix.elements[2] = rotationMatrix.elements[6];
|
|
|
+ transformedRotationMatrix.elements[6] = -rotationMatrix.elements[2];
|
|
|
+ transformedRotationMatrix.elements[10] = rotationMatrix.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._rotationMatrix.copy( transformedRotationMatrix );
|
|
|
+
|
|
|
+ return this._rotationMatrix;
|
|
|
};
|
|
|
|
|
|
this.update = function( delta ) {
|
|
@@ -24,12 +182,19 @@ THREE.DeviceOrientationControls = function ( object ) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this.object.rotation.set(
|
|
|
- (this.orientationData['beta'] || 0) * this.degtorad,
|
|
|
- (this.orientationData['gamma'] || 0) * this.degtorad,
|
|
|
- (this.orientationData['alpha'] || 0) * this.degtorad,
|
|
|
- this.eulerRotationOrder
|
|
|
+ this.setRotationVectorFromDeviceOrientation(
|
|
|
+ this.deviceOrientation.alpha,
|
|
|
+ this.deviceOrientation.beta,
|
|
|
+ this.deviceOrientation.gamma
|
|
|
);
|
|
|
+
|
|
|
+ this.setRotationMatrixFromRotationVector( this._rotationVector );
|
|
|
+
|
|
|
+ this.remapRotationMatrixByScreenOrientation( this.screenOrientation, this._rotationMatrix);
|
|
|
+
|
|
|
+ this.object.quaternion.setFromRotationMatrix( this._rotationMatrix );
|
|
|
+
|
|
|
+ this.object.updateProjectionMatrix();
|
|
|
};
|
|
|
|
|
|
function bind( scope, fn ) {
|
|
@@ -39,11 +204,19 @@ THREE.DeviceOrientationControls = function ( object ) {
|
|
|
};
|
|
|
|
|
|
this.connect = function() {
|
|
|
- window.addEventListener('deviceorientation', bind(this, this.registerOrientationData), false);
|
|
|
+ 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() {
|
|
|
- window.removeEventListener('deviceorientation', bind(this, this.registerOrientationData), false);
|
|
|
this.freeze = true;
|
|
|
+
|
|
|
+ window.removeEventListener( 'orientationchange', bind( this, this.onScreenOrientationChangeEvent ), false );
|
|
|
+ window.removeEventListener( 'deviceorientation', bind( this, this.onDeviceOrientationChangeEvent ), false );
|
|
|
};
|
|
|
+
|
|
|
};
|