From 181376fc1cd01aea622ef45604b36e17e286e4ed Mon Sep 17 00:00:00 2001 From: Kevin Staunton-Lambert Date: Mon, 29 Jul 2024 18:18:52 +1000 Subject: [PATCH] Reviving DeviceOrientationControls for iPhone --- src/plugin.js | 2 + vendor/three/DeviceOrientationControls.js | 168 +++++++++++----------- 2 files changed, 89 insertions(+), 81 deletions(-) diff --git a/src/plugin.js b/src/plugin.js index 605d534..389eb9c 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -10,6 +10,7 @@ import OrbitOrientationContols from './orbit-orientation-controls.js'; import * as utils from './utils'; import CanvasPlayerControls from './canvas-player-controls'; import OmnitoneController from './omnitone-controller'; +import DeviceOrientationControls from '../vendor/three/DeviceOrientationControls'; // WebXR related imports import WebXRPolyfill from 'webxr-polyfill'; @@ -836,6 +837,7 @@ void main() { } this.controls3d = new OrbitOrientationContols(options); + this.device = new DeviceOrientationControls(this.camera); this.canvasPlayerControls = new CanvasPlayerControls(this.player_, this.renderedCanvas, this.options_); this.animationFrameId_ = this.requestAnimationFrame(this.animate_); } else if (window.navigator.getVRDevices) { diff --git a/vendor/three/DeviceOrientationControls.js b/vendor/three/DeviceOrientationControls.js index 1d5183a..85df514 100644 --- a/vendor/three/DeviceOrientationControls.js +++ b/vendor/three/DeviceOrientationControls.js @@ -1,147 +1,153 @@ -( function () { +import { + Euler, + EventDispatcher, + MathUtils, + Quaternion, + Vector3 +} from '../../../build/three.module.js'; - const _zee = new THREE.Vector3( 0, 0, 1 ); +const _zee = new Vector3( 0, 0, 1 ); +const _euler = new Euler(); +const _q0 = new Quaternion(); +const _q1 = new Quaternion( - Math.sqrt( 0.5 ), 0, 0, Math.sqrt( 0.5 ) ); // - PI/2 around the x-axis - const _euler = new THREE.Euler(); +const _changeEvent = { type: 'change' }; - const _q0 = new THREE.Quaternion(); +class DeviceOrientationControls extends EventDispatcher { - const _q1 = new THREE.Quaternion( - Math.sqrt( 0.5 ), 0, 0, Math.sqrt( 0.5 ) ); // - PI/2 around the x-axis + constructor( object ) { + super(); - const _changeEvent = { - type: 'change' - }; + if ( window.isSecureContext === false ) { - class DeviceOrientationControls extends THREE.EventDispatcher { + console.error( 'THREE.DeviceOrientationControls: DeviceOrientationEvent is only available in secure contexts (https)' ); - constructor( object ) { + } - super(); + const scope = this; - if ( window.isSecureContext === false ) { + const EPS = 0.000001; + const lastQuaternion = new Quaternion(); - console.error( 'THREE.DeviceOrientationControls: DeviceOrientationEvent is only available in secure contexts (https)' ); + this.object = object; + this.object.rotation.reorder( 'YXZ' ); - } + this.enabled = true; - const scope = this; - const EPS = 0.000001; - const lastQuaternion = new THREE.Quaternion(); - this.object = object; - this.object.rotation.reorder( 'YXZ' ); - this.enabled = true; - this.deviceOrientation = {}; - this.screenOrientation = 0; - this.alphaOffset = 0; // radians + this.deviceOrientation = {}; + this.screenOrientation = 0; - const onDeviceOrientationChangeEvent = function ( event ) { + this.alphaOffset = 0; // radians - scope.deviceOrientation = event; + const onDeviceOrientationChangeEvent = function ( event ) { - }; + scope.deviceOrientation = event; - const onScreenOrientationChangeEvent = function () { + }; - scope.screenOrientation = window.orientation || 0; + const onScreenOrientationChangeEvent = function () { - }; // The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y'' + scope.screenOrientation = window.orientation || 0; + }; - const setObjectQuaternion = function ( quaternion, alpha, beta, gamma, orient ) { + // The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y'' - _euler.set( beta, alpha, - gamma, 'YXZ' ); // 'ZXY' for the device, but 'YXZ' for us + const setObjectQuaternion = 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.setFromEuler( _euler ); // orient the device - quaternion.multiply( _q1 ); // camera looks out the back of the device, not the top + quaternion.multiply( _q1 ); // camera looks out the back of the device, not the top - quaternion.multiply( _q0.setFromAxisAngle( _zee, - orient ) ); // adjust for screen orientation + quaternion.multiply( _q0.setFromAxisAngle( _zee, - orient ) ); // adjust for screen orientation - }; + }; - this.connect = function () { + this.connect = function () { - onScreenOrientationChangeEvent(); // run once on load - // iOS 13+ + onScreenOrientationChangeEvent(); // run once on load - if ( window.DeviceOrientationEvent !== undefined && typeof window.DeviceOrientationEvent.requestPermission === 'function' ) { + // iOS 13+ - window.DeviceOrientationEvent.requestPermission().then( function ( response ) { + if ( window.DeviceOrientationEvent !== undefined && typeof window.DeviceOrientationEvent.requestPermission === 'function' ) { - if ( response == 'granted' ) { + window.DeviceOrientationEvent.requestPermission().then( function ( response ) { - window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent ); - window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent ); + if ( response == 'granted' ) { - } + window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent ); + window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent ); - } ).catch( function ( error ) { + } - console.error( 'THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:', error ); + } ).catch( function ( error ) { - } ); + console.error( 'THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:', error ); - } else { + } ); - window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent ); - window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent ); + } else { - } + window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent ); + window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent ); - scope.enabled = true; + } - }; + scope.enabled = true; - this.disconnect = function () { + }; - window.removeEventListener( 'orientationchange', onScreenOrientationChangeEvent ); - window.removeEventListener( 'deviceorientation', onDeviceOrientationChangeEvent ); - scope.enabled = false; + this.disconnect = function () { - }; + window.removeEventListener( 'orientationchange', onScreenOrientationChangeEvent ); + window.removeEventListener( 'deviceorientation', onDeviceOrientationChangeEvent ); - this.update = function () { + scope.enabled = false; - if ( scope.enabled === false ) return; - const device = scope.deviceOrientation; + }; - if ( device ) { + this.update = function () { - const alpha = device.alpha ? THREE.MathUtils.degToRad( device.alpha ) + scope.alphaOffset : 0; // Z + if ( scope.enabled === false ) return; - const beta = device.beta ? THREE.MathUtils.degToRad( device.beta ) : 0; // X' + const device = scope.deviceOrientation; - const gamma = device.gamma ? THREE.MathUtils.degToRad( device.gamma ) : 0; // Y'' + if ( device ) { - const orient = scope.screenOrientation ? THREE.MathUtils.degToRad( scope.screenOrientation ) : 0; // O + const alpha = device.alpha ? MathUtils.degToRad( device.alpha ) + scope.alphaOffset : 0; // Z - setObjectQuaternion( scope.object.quaternion, alpha, beta, gamma, orient ); + const beta = device.beta ? MathUtils.degToRad( device.beta ) : 0; // X' - if ( 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { + const gamma = device.gamma ? MathUtils.degToRad( device.gamma ) : 0; // Y'' - lastQuaternion.copy( scope.object.quaternion ); - scope.dispatchEvent( _changeEvent ); + const orient = scope.screenOrientation ? MathUtils.degToRad( scope.screenOrientation ) : 0; // O - } + setObjectQuaternion( scope.object.quaternion, alpha, beta, gamma, orient ); - } + if ( 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { - }; + lastQuaternion.copy( scope.object.quaternion ); + scope.dispatchEvent( _changeEvent ); - this.dispose = function () { + } - scope.disconnect(); + } - }; + }; - this.connect(); + this.dispose = function () { - } + scope.disconnect(); - } + }; - THREE.DeviceOrientationControls = DeviceOrientationControls; + this.connect(); -} )(); \ No newline at end of file + } + +} + +export { DeviceOrientationControls };