UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

114 lines (113 loc) 4.16 kB
"use strict"; import { Matrix4 } from "three"; import { isBooleanTrue } from "../Type"; import { DEFAULT_WEBXR_REFERENCE_SPACE_TYPE } from "./Common"; import { CoreWebXRControllerContainer } from "./CoreWebXRControllerContainer"; const tempMatrix = new Matrix4(); const webXRButtonsContainerClass = "polygonjs-webxr-buttons-container"; export class BaseCoreWebXRController { constructor(scene, renderer, camera, canvas, options) { this.scene = scene; this.renderer = renderer; this.camera = camera; this.canvas = canvas; this.options = options; this.controllerContainers = []; this._onSessionStartBound = this._onSessionStart.bind(this); this._onSessionEndBound = this._onSessionEnd.bind(this); /** * * BUTTONS * */ this._buttonByCanvasId = /* @__PURE__ */ new Map(); renderer.xr.enabled = true; if (isBooleanTrue(options.overrideReferenceSpaceType) && options.referenceSpaceType) { renderer.xr.setReferenceSpaceType(options.referenceSpaceType); } else { renderer.xr.setReferenceSpaceType(DEFAULT_WEBXR_REFERENCE_SPACE_TYPE); } } getController(controllerIndex) { return this.controllerContainers[controllerIndex] || this._createController(controllerIndex); } mount() { this._mountButton(); } unmount() { this._removedStartEndEvents(); this._unmountButton(); } requestSession(sessionInit, callback) { this._addStartEndEvents(); } _addStartEndEvents() { this.renderer.xr.addEventListener("sessionstart", this._onSessionStartBound); this.renderer.xr.addEventListener("sessionend", this._onSessionEndBound); } _removedStartEndEvents() { this.renderer.xr.removeEventListener("sessionstart", this._onSessionStartBound); this.renderer.xr.removeEventListener("sessionend", this._onSessionEndBound); } _createController(controllerIndex) { const controllerContainer = new CoreWebXRControllerContainer(this.scene, this.renderer, controllerIndex); controllerContainer.initialize(this.camera); this.controllerContainers.push(controllerContainer); this._addControllerEvents(controllerContainer, controllerIndex); return controllerContainer; } _addControllerEvents(controllerContainer, controllerIndex) { } process(frame) { for (const controllerContainer of this.controllerContainers) { tempMatrix.identity().extractRotation(controllerContainer.controller.matrixWorld); controllerContainer.ray.origin.setFromMatrixPosition(controllerContainer.controller.matrixWorld); controllerContainer.ray.direction.set(0, 0, -1).applyMatrix4(tempMatrix); } } _onSessionStart() { for (const controllerContainer of this.controllerContainers) { controllerContainer.initialize(this.camera); } this.scene.play(); } _onSessionEnd() { this._removedStartEndEvents(); for (const controllerContainer of this.controllerContainers) { controllerContainer.initialize(null); } this.scene.pause(); } _mountButton() { if (!this.renderer.xr.enabled) { console.warn("renderer.xr is not enabled, not mounting webXR button"); return; } const parent = this.canvas.parentElement; if (parent) { let buttonsContainer = parent.querySelector(`.${webXRButtonsContainerClass}`); if (!buttonsContainer) { buttonsContainer = document.createElement("div"); buttonsContainer.classList.add(webXRButtonsContainerClass); parent.prepend(buttonsContainer); buttonsContainer.style.position = "absolute"; buttonsContainer.style.bottom = "20px"; buttonsContainer.style.textAlign = "center"; buttonsContainer.style.width = "100%"; } const button = this.createButton(); this.attachButton(buttonsContainer, button); this._buttonByCanvasId.set(this.canvas.id, button); } else { console.warn("canvas has no parent"); } } _unmountButton() { var _a; const button = this._buttonByCanvasId.get(this.canvas.id); if (!button) { return; } (_a = button.parentElement) == null ? void 0 : _a.removeChild(button); } }