UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

138 lines (137 loc) 4.5 kB
import { EventHandler } from "../../core/event-handler.js"; import { platform } from "../../core/platform.js"; import { XrInputSource } from "./xr-input-source.js"; class XrInput extends EventHandler { static EVENT_ADD = "add"; static EVENT_REMOVE = "remove"; static EVENT_SELECT = "select"; static EVENT_SELECTSTART = "selectstart"; static EVENT_SELECTEND = "selectend"; static EVENT_SQUEEZE = "squeeze"; static EVENT_SQUEEZESTART = "squeezestart"; static EVENT_SQUEEZEEND = "squeezeend"; manager; _inputSources = []; _onInputSourcesChangeEvt; velocitiesSupported = false; constructor(manager) { super(); this.manager = manager; this.velocitiesSupported = !!(platform.browser && window.XRPose?.prototype?.hasOwnProperty("linearVelocity")); this._onInputSourcesChangeEvt = (evt) => { this._onInputSourcesChange(evt); }; this.manager.on("start", this._onSessionStart, this); this.manager.on("end", this._onSessionEnd, this); } _onSessionStart() { const session = this.manager.session; session.addEventListener("inputsourceschange", this._onInputSourcesChangeEvt); session.addEventListener("select", (evt) => { const inputSource = this._getByInputSource(evt.inputSource); inputSource.update(evt.frame); inputSource.fire("select", evt); this.fire("select", inputSource, evt); }); session.addEventListener("selectstart", (evt) => { const inputSource = this._getByInputSource(evt.inputSource); inputSource.update(evt.frame); inputSource._selecting = true; inputSource.fire("selectstart", evt); this.fire("selectstart", inputSource, evt); }); session.addEventListener("selectend", (evt) => { const inputSource = this._getByInputSource(evt.inputSource); inputSource.update(evt.frame); inputSource._selecting = false; inputSource.fire("selectend", evt); this.fire("selectend", inputSource, evt); }); session.addEventListener("squeeze", (evt) => { const inputSource = this._getByInputSource(evt.inputSource); inputSource.update(evt.frame); inputSource.fire("squeeze", evt); this.fire("squeeze", inputSource, evt); }); session.addEventListener("squeezestart", (evt) => { const inputSource = this._getByInputSource(evt.inputSource); inputSource.update(evt.frame); inputSource._squeezing = true; inputSource.fire("squeezestart", evt); this.fire("squeezestart", inputSource, evt); }); session.addEventListener("squeezeend", (evt) => { const inputSource = this._getByInputSource(evt.inputSource); inputSource.update(evt.frame); inputSource._squeezing = false; inputSource.fire("squeezeend", evt); this.fire("squeezeend", inputSource, evt); }); const inputSources = session.inputSources; for (let i = 0; i < inputSources.length; i++) { this._addInputSource(inputSources[i]); } } _onSessionEnd() { let i = this._inputSources.length; while (i--) { const inputSource = this._inputSources[i]; this._inputSources.splice(i, 1); inputSource.fire("remove"); this.fire("remove", inputSource); } const session = this.manager.session; session.removeEventListener("inputsourceschange", this._onInputSourcesChangeEvt); } _onInputSourcesChange(evt) { for (let i = 0; i < evt.removed.length; i++) { this._removeInputSource(evt.removed[i]); } for (let i = 0; i < evt.added.length; i++) { this._addInputSource(evt.added[i]); } } _getByInputSource(xrInputSource) { for (let i = 0; i < this._inputSources.length; i++) { if (this._inputSources[i].inputSource === xrInputSource) { return this._inputSources[i]; } } return null; } _addInputSource(xrInputSource) { if (this._getByInputSource(xrInputSource)) { return; } const inputSource = new XrInputSource(this.manager, xrInputSource); this._inputSources.push(inputSource); this.fire("add", inputSource); } _removeInputSource(xrInputSource) { for (let i = 0; i < this._inputSources.length; i++) { if (this._inputSources[i].inputSource !== xrInputSource) { continue; } const inputSource = this._inputSources[i]; this._inputSources.splice(i, 1); let h = inputSource.hitTestSources.length; while (h--) { inputSource.hitTestSources[h].remove(); } inputSource.fire("remove"); this.fire("remove", inputSource); return; } } update(frame) { for (let i = 0; i < this._inputSources.length; i++) { this._inputSources[i].update(frame); } } get inputSources() { return this._inputSources; } } export { XrInput };