@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
114 lines (113 loc) • 4.16 kB
JavaScript
"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);
}
}