Skip to content

Commit

Permalink
Close #571 VR support
Browse files Browse the repository at this point in the history
  • Loading branch information
mistic100 committed Mar 26, 2022
1 parent 0530342 commit 221f0d1
Show file tree
Hide file tree
Showing 7 changed files with 255 additions and 0 deletions.
1 change: 1 addition & 0 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ <h5 class="card-title">Plugins</h5>
<a href="equirectangular-video.html" class="list-group-item list-group-item-action">Video (equirectangular)</a>
<a href="plugin-virtual-tour.html" class="list-group-item list-group-item-action">Virtual Tour</a>
<a href="plugin-visible-range.html" class="list-group-item list-group-item-action">Visible Range</a>
<a href="plugin-vr.html" class="list-group-item list-group-item-action">VR Headset</a>
</div>
</div>
</div>
Expand Down
34 changes: 34 additions & 0 deletions example/plugin-vr.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PhotoSphereViewer - VR demo</title>

<link rel="stylesheet" href="../dist/photo-sphere-viewer.css">
<link rel="stylesheet" href="style.css">
</head>
<body>

<div id="photosphere"></div>

<script src="../node_modules/three/build/three.js"></script>
<script src="../node_modules/uevent/browser.js"></script>
<script src="../dist/photo-sphere-viewer.js"></script>
<script src="../dist/plugins/vr.js"></script>

This comment has been minimized.

Copy link
@dhanil-vd123

dhanil-vd123 Jun 29, 2022

I think this file is missing in the folder


<script>
const viewer = new PhotoSphereViewer.Viewer({
container : 'photosphere',
panorama : 'sphere.jpg',
caption : 'Parc national du Mercantour <b>&copy; Damien Sorel</b>',
loadingImg: 'assets/photosphere-logo.gif',
plugins : [
[PhotoSphereViewer.VrPlugin, {

}],
],
});
</script>
</body>
</html>
72 changes: 72 additions & 0 deletions src/plugins/vr/VrButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { AbstractButton } from '../..';
import { EVENTS } from './constants';
import vr from './vr.svg';

/**
* @summary Navigation bar vr button class
* @extends PSV.buttons.AbstractButton
* @memberof PSV.buttons
*/
export class VrButton extends AbstractButton {

static id = 'vr';
static icon = vr;

/**
* @param {PSV.components.Navbar} navbar
*/
constructor(navbar) {
super(navbar, 'psv-button--hover-scale psv-vr-button', true);

/**
* @type {PSV.plugins.VrPlugin}
* @private
* @readonly
*/
this.plugin = this.psv.getPlugin('vr');

if (this.plugin) {
this.plugin.on(EVENTS.VR_UPDATED, this);
}
}

/**
* @override
*/
destroy() {
if (this.plugin) {
this.plugin.off(EVENTS.VR_UPDATED, this);
}

delete this.plugin;

super.destroy();
}

/**
* @override
*/
isSupported() {
return !this.plugin ? false : { initial: false, promise: this.plugin.prop.isSupported };
}

/**
* @summary Handles events
* @param {Event} e
* @private
*/
handleEvent(e) {
if (e.type === EVENTS.VR_UPDATED) {
this.toggleActive(e.args[0]);
}
}

/**
* @override
* @description Toggles vr control
*/
onClick() {
this.plugin.__toggle();
}

}
15 changes: 15 additions & 0 deletions src/plugins/vr/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @summary Available events
* @enum {string}
* @memberof PSV.plugins.VRPlugin
* @constant
*/
export const EVENTS = {
/**
* @event vr-updated
* @memberof PSV.plugins.VRPlugin
* @summary Triggered when the VR view is enabled/disabled
* @param {boolean} enabled
*/
VR_UPDATED: 'vr-updated',
};
109 changes: 109 additions & 0 deletions src/plugins/vr/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { AbstractPlugin, CONSTANTS, DEFAULTS, registerButton } from '../..';
import { EVENTS } from './constants';
import { VrButton } from './VrButton';


// add vr button
DEFAULTS.lang[VrButton.id] = 'Enter VR';
registerButton(VrButton, 'caption:right');


export { EVENTS } from './constants';


/**
* @summary Adds VR view on WebXR devices
* @extends PSV.plugins.AbstractPlugin
* @memberof PSV.plugins
*/
export class VrPlugin extends AbstractPlugin {

static id = 'vr';

/**
* @param {PSV.Viewer} psv
*/
constructor(psv) {
super(psv);

this.prop = {
isSupported: this.__checkSupport(),
session : null,
};

this.psv.renderer.renderer.xr.enabled = true;

this.psv.on(CONSTANTS.EVENTS.BEFORE_RENDER, this);
}

/**
* @package
*/
destroy() {
this.psv.off(CONSTANTS.EVENTS.BEFORE_RENDER, this);

this.prop.session?.end();

super.destroy();
}

/**
* @private
*/
handleEvent(e) {
switch (e.type) {
case CONSTANTS.EVENTS.BEFORE_RENDER:
if (this.prop.session) {
this.psv.needsUpdate();
}
break;
default:
break;
}
}

/**
* @summary Checks if the VR view is enabled
* @returns {boolean}
*/
isEnabled() {
return !!this.prop.session;
}

/**
* @private
*/
__toggle() {
if (!this.prop.session) {
const sessionInit = { optionalFeatures: ['local-floor', 'bounded-floor', 'hand-tracking', 'layers'] };
navigator.xr.requestSession('immersive-vr', sessionInit)
.then((session) => {
this.prop.session = session;
session.addEventListener('end', () => {
this.prop.session = null;
this.trigger(EVENTS.VR_UPDATED, false);
});
this.psv.renderer.renderer.xr.setSession(session);
this.trigger(EVENTS.VR_UPDATED, true);
});
}
else {
this.prop.session.end();
}
}

/**
* @summary Detects if the XR API is supported
* @returns {Promise<boolean>}
* @private
*/
__checkSupport() {
if ('xr' in navigator) {
return navigator.xr.isSessionSupported('immersive-vr');
}
else {
return Promise.resolve(false);
}
}

}
1 change: 1 addition & 0 deletions src/plugins/vr/vr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions types/plugins/vr/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Event } from 'uevent';
import { AbstractPlugin } from '../AbstractPlugin';

export const EVENTS: {
VR_UPDATED: 'vr-updated',
};

/**
* @summary Adds VR view on WebXR devices
*/
export class VRPlugin extends AbstractPlugin {

/**
* @summary Checks if the VR view is enabled
*/
isEnabled(): boolean;

/**
* @summary Triggered when the VR view is enabled/disabled
*/
on(e: 'vr-updated', cb: (e: Event, enabled: boolean) => void): this;

}

0 comments on commit 221f0d1

Please sign in to comment.