In OrbitControls.js, I have added code for Device Orientation controls.I have added two functions,device orientation and screen orientation events and a piece of code in the update function just above the orbit controls update function code .
var 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
//beta=beta-180;
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
}
}();
function Quat2Angle(x, y, z, w) {
var pitch, roll, yaw;
var test = x * y + z * w;
if (test > 0.499) { // singularity at north pole
yaw = 2 * Math.atan2(x, w);
pitch = Math.PI / 2;
roll = 0;
var euler = new THREE.Vector3(pitch, roll, yaw);
return euler;
}
if (test < -0.499) { // singularity at south pole
yaw = -2 * Math.atan2(x, w);
pitch = -Math.PI / 2;
roll = 0;
var euler = new THREE.Vector3(pitch, roll, yaw);
return euler;
}
var sqx = x * x;
var sqy = y * y;
var sqz = z * z;
yaw = Math.atan2(2 * y * w - 2 * x * z, 1 - 2 * sqy - 2 * sqz);
pitch = Math.asin(2 * test);
roll = Math.atan2(2 * x * w - 2 * y * z, 1 - 2 * sqx - 2 * sqz);
var euler = new THREE.Vector3(pitch, roll, yaw);
return euler;
}
function onDeviceOrientationChangeEvent(event) {
scope.deviceOrientation = event;
}
window.addEventListener('deviceorientation', onDeviceOrientationChangeEvent, false);
function onScreenOrientationChangeEvent(event) {
scope.screenOrientation = window.orientation || 0;
}
window.addEventListener('orientationchange', onScreenOrientationChangeEvent, false);
// this method is exposed, but perhaps it would be better if we can make it private...
this.update = function () {
var offset = new THREE.Vector3();
var lastGamma = 0,
lastBeta = 0;
// so camera.up is the orbit axis
var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
var quatInverse = quat.clone().inverse();
var lastPosition = new THREE.Vector3();
var lastQuaternion = new THREE.Quaternion();
return function update() {
var position = scope.object.position;
offset.copy( position ).sub( scope.target );
// rotate offset to "y-axis-is-up" space
offset.applyQuaternion( quat );
// angle from z-axis around y-axis
spherical.setFromVector3( offset );
var alpha = scope.deviceOrientation.alpha ? THREE.Math.degToRad(scope.deviceOrientation.alpha) : 0; // Z
var beta = scope.deviceOrientation.beta ? THREE.Math.degToRad(scope.deviceOrientation.beta) : 0; // X'
var gamma = scope.deviceOrientation.gamma ? THREE.Math.degToRad(scope.deviceOrientation.gamma) : 0; // Y''
var orient = scope.screenOrientation ? THREE.Math.degToRad(scope.screenOrientation) : 0; // O
setObjectQuaternion(scope.object.quaternion, alpha, beta, gamma, orient);
var currentQ = new THREE.Quaternion().copy(scope.object.quaternion);
setObjectQuaternion(currentQ, alpha, beta, gamma, orient);
var currentAngle = Quat2Angle(currentQ.x, currentQ.y, currentQ.z, currentQ.w);
var radDeg = 180 / Math.PI;
// currentAngle.z = Left-right
// currentAngle.y = Up-down
rotateLeft((lastGamma - currentAngle.z));
lastGamma = currentAngle.z;
rotateUp(lastBeta - currentAngle.y);
lastBeta = currentAngle.y;
this.alpha = alpha;
Here,the orbit controls work properly with the device orientation controls except when the device is held in landscape while the device is set to portrait mode. When only device orientation controls is used,the video orientation adjusts to the orientation in which the mobile device is held regardless of the orientation that the device is set to. But, when i try to combine the orbit controls(touch) and device orientation controls and the mobile is held in landscape orientation when it is set to portrait mode, the video orientation doesn’t adjust and the video cannot be panned around properly using device orientation, especially in the up-down direction.