Skip to content

Commit

Permalink
feat(event-display): create a common xr-manager
Browse files Browse the repository at this point in the history
  • Loading branch information
9inpachi committed Jun 20, 2021
1 parent a703bdd commit 2700aaf
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Camera, Group, WebGLRenderer, XRSessionInit } from 'three';

export enum XRSessionType {
VR = 'vr',
AR = 'ar',
}

/**
* XR manager for XR related operations.
*/
export class XRManager {
/** Whether the XR is currently active or not. */
private xrActive: boolean = false;
/** Renderer to set the XR session for. */
private renderer: WebGLRenderer;
/** Currently active XR session. */
private currentXRSession: any = null;
/** Callback to call when the XR session ends. */
private onSessionEnded: () => void;
/** Group containing the the camera for XR. */
public cameraGroup: Group;
/** The camera used by XR. */
public xrCamera: Camera;

/**
* Set and configure the XR session.
* @param sessionType Type of the session, either AR or VR.
* @param sessionInit Other options for the session like optional features.
* @param renderer Renderer to set the XR session for.
* @param onSessionStarted Callback to call when the XR session starts.
* @param onSessionEnded Callback to call when the XR session ends.
*/
public setXRSession(
sessionType: XRSessionType,
sessionInit: XRSessionInit,
renderer: WebGLRenderer,
onSessionStarted?: () => void,
onSessionEnded?: () => void
) {
this.renderer = renderer;
this.onSessionEnded = onSessionEnded;
const webXR = (navigator as any)?.xr;
const xrType = sessionType === XRSessionType.VR ? 'vr' : 'ar';

(webXR?.requestSession(`immersive-${xrType}`, sessionInit) as Promise<any>)
.then((session: any) => {
onSessionStarted?.();
this.onXRSessionStarted(session);
})
.catch((error: any) => {
console.error(`${xrType.toUpperCase()} Error:`, error);
});
}

/**
* Callback for when the XR session is started.
* @param session The XR session.
*/
private onXRSessionStarted = async (session: any) => {
this.xrActive = true;
session.addEventListener('end', this.onXRSessionEnded);
await this.renderer.xr.setSession(session);
this.currentXRSession = session;
};

/**
* Callback when the XR session ends.
*/
private onXRSessionEnded = () => {
this.xrActive = false;
this.currentXRSession.removeEventListener('end', this.onXRSessionEnded);
this.currentXRSession = null;
this.onSessionEnded?.();
};

/**
* End the current XR session.
*/
public endXRSession() {
this.currentXRSession?.end();
}

/**
* Get the group containing the camera for XR.
* XR camera works by adding a Group with Camera to the scene.
* @param camera Camera which is to be cloned for XR use.
* @returns The camera group used in XR mode.
*/
public getCameraGroup(camera?: Camera): Group {
// Set up the camera position in the XR - Adding a group with camera does it
if (!this.cameraGroup) {
this.cameraGroup = new Group();
}
if (camera && this.xrActive) {
this.xrCamera = this.renderer.xr
.getCamera(new Camera())
.copy(camera.clone() as Camera);
this.xrCamera.name = 'XR_CAMERA';

this.cameraGroup.position.copy(this.xrCamera.position);
this.cameraGroup.add(this.xrCamera);
}

return this.cameraGroup;
}
}
2 changes: 1 addition & 1 deletion packages/phoenix-ng/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
"start:ssl": "ng serve --ssl --host=0.0.0.0",
"start:ssl": "ng serve --ssl --host 0.0.0.0",
"start:single": "ng serve --configuration singleEvent",
"build": "ng build",
"build:prod": "ng build --configuration production",
Expand Down

0 comments on commit 2700aaf

Please sign in to comment.