Skip to content

Commit

Permalink
Fix #1300 gyroscope: better support of "absolutePosition" option
Browse files Browse the repository at this point in the history
  • Loading branch information
mistic100 committed May 18, 2024
1 parent 35e94cb commit eb2bdbe
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 12 deletions.
2 changes: 1 addition & 1 deletion docs/plugins/gyroscope.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Applies camera roll (rotation on Z axis).

- type: `boolean`
- default: `false`
- updatable: yes
- updatable: no

By default the camera will keep its current horizontal position when the gyroscope is enabled. Turn this option `true` to enable absolute positionning and only use the device orientation.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class DeviceOrientationControls {
screenOrientation: number;
alphaOffset: number;

constructor(object: Object3D);
constructor(object: Object3D, preferAbsolute: boolean);

connect();

Expand Down
23 changes: 22 additions & 1 deletion packages/gyroscope-plugin/src/DeviceOrientationControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const _q1 = new Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); // - PI/2 aro
* @internal
*/
export class DeviceOrientationControls {
constructor(object) {
constructor(object, preferAbsolute) {
if (window.isSecureContext === false) {
console.error(
'THREE.DeviceOrientationControls: DeviceOrientationEvent is only available in secure contexts (https)'
Expand All @@ -23,6 +23,8 @@ export class DeviceOrientationControls {
const EPS = 0.000001;
const lastQuaternion = new Quaternion();

let nonAbsoluteListener = false;

this.object = object;
this.object.rotation.reorder('YXZ');

Expand All @@ -37,6 +39,15 @@ export class DeviceOrientationControls {
scope.deviceOrientation = event;
};

const onDeviceOrientationAbsoluteChangeEvent = function (event) {
// if the 'deviceorientationabsolute' event is supported, automatically remove the 'deviceorientation' listener
if (nonAbsoluteListener) {
window.removeEventListener('deviceorientation', onDeviceOrientationChangeEvent);
nonAbsoluteListener = false;
}
scope.deviceOrientation = event;
};

const onScreenOrientationChangeEvent = function () {
scope.screenOrientation = window.orientation || 0;
};
Expand Down Expand Up @@ -67,6 +78,10 @@ export class DeviceOrientationControls {
if (response == 'granted') {
window.addEventListener('orientationchange', onScreenOrientationChangeEvent);
window.addEventListener('deviceorientation', onDeviceOrientationChangeEvent);
if (preferAbsolute) {
window.addEventListener('deviceorientationabsolute', onDeviceOrientationAbsoluteChangeEvent);
nonAbsoluteListener = true;
}
}
})
.catch(function (error) {
Expand All @@ -75,6 +90,10 @@ export class DeviceOrientationControls {
} else {
window.addEventListener('orientationchange', onScreenOrientationChangeEvent);
window.addEventListener('deviceorientation', onDeviceOrientationChangeEvent);
if (preferAbsolute) {
window.addEventListener('deviceorientationabsolute', onDeviceOrientationAbsoluteChangeEvent);
nonAbsoluteListener = true;
}
}

scope.enabled = true;
Expand All @@ -83,6 +102,8 @@ export class DeviceOrientationControls {
this.disconnect = function () {
window.removeEventListener('orientationchange', onScreenOrientationChangeEvent);
window.removeEventListener('deviceorientation', onDeviceOrientationChangeEvent);
window.removeEventListener('deviceorientationabsolute', onDeviceOrientationAbsoluteChangeEvent);
nonAbsoluteListener = false;

scope.enabled = false;
};
Expand Down
15 changes: 6 additions & 9 deletions packages/gyroscope-plugin/src/GyroscopePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AbstractConfigurablePlugin, events, utils } from '@photo-sphere-viewer/
import { Object3D, Vector3 } from 'three';
import { DeviceOrientationControls } from './DeviceOrientationControls';
import { GyroscopePluginEvents, GyroscopeUpdatedEvent } from './events';
import { GyroscopePluginConfig } from './model.js';
import { GyroscopePluginConfig, UpdatableGyroscopePluginConfig } from './model.js';

const getConfig = utils.getConfigParser<GyroscopePluginConfig>(
{
Expand Down Expand Up @@ -32,12 +32,13 @@ const direction = new Vector3();
export class GyroscopePlugin extends AbstractConfigurablePlugin<
GyroscopePluginConfig,
GyroscopePluginConfig,
GyroscopePluginConfig,
UpdatableGyroscopePluginConfig,
GyroscopePluginEvents
> {
static override readonly id = 'gyroscope';
static override readonly VERSION = PKG_VERSION;
static override readonly configParser = getConfig;
static override readonly readonlyOptions: Array<keyof GyroscopePluginConfig> = ['absolutePosition'];

private readonly state = {
isSupported: this.__checkSupport(),
Expand Down Expand Up @@ -74,6 +75,7 @@ export class GyroscopePlugin extends AbstractConfigurablePlugin<

this.stop();

this.controls?.disconnect();
delete this.controls;

super.destroy();
Expand Down Expand Up @@ -138,13 +140,10 @@ export class GyroscopePlugin extends AbstractConfigurablePlugin<

// enable gyro controls
if (!this.controls) {
this.controls = new DeviceOrientationControls(new Object3D());
} else {
this.controls.connect();
this.controls = new DeviceOrientationControls(new Object3D(), this.config.absolutePosition);
}

// force reset
this.controls.deviceOrientation = null;
// reset
this.controls.alphaOffset = 0;

this.state.alphaOffset = this.config.absolutePosition ? 0 : null;
Expand All @@ -159,8 +158,6 @@ export class GyroscopePlugin extends AbstractConfigurablePlugin<
*/
stop() {
if (this.isEnabled()) {
this.controls.disconnect();

this.state.enabled = false;
this.viewer.config.moveInertia = this.state.config_moveInertia;

Expand Down
2 changes: 2 additions & 0 deletions packages/gyroscope-plugin/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ export type GyroscopePluginConfig = {
*/
moveMode?: 'smooth' | 'fast';
};

export type UpdatableGyroscopePluginConfig = Omit<GyroscopePluginConfig, 'absolutePosition'>;

0 comments on commit eb2bdbe

Please sign in to comment.