@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 2.94 kB
JavaScript
import{platform as e}from"../../core/platform.js";import{EventHandler as s}from"../../core/event-handler.js";import{XRSPACE_VIEWER as t}from"./constants.js";import{XrHitTestSource as i}from"./xr-hit-test-source.js";class r extends s{constructor(s){super(),this.manager=void 0,this._supported=e.browser&&!(!window.XRSession||!window.XRSession.prototype.requestHitTestSource),this._available=!1,this._checkingAvailability=!1,this.sources=[],this.manager=s,this._supported&&(this.manager.on("start",this._onSessionStart,this),this.manager.on("end",this._onSessionEnd,this))}_onSessionStart(){if(this.manager.session.enabledFeatures){const e=-1!==this.manager.session.enabledFeatures.indexOf("hit-test");if(!e)return;this._available=e,this.fire("available")}else this._checkingAvailability||(this._checkingAvailability=!0,this.manager.session.requestReferenceSpace(t).then((e=>{this.manager.session.requestHitTestSource({space:e}).then((e=>{e.cancel(),this.manager.active&&(this._available=!0,this.fire("available"))})).catch((()=>{}))})).catch((()=>{})))}_onSessionEnd(){if(this._available){this._available=!1;for(let e=0;e<this.sources.length;e++)this.sources[e].onStop();this.sources=[],this.fire("unavailable")}}start(e={}){if(!this._supported)return void(null==e.callback||e.callback(new Error("XR HitTest is not supported"),null));if(!this._available)return void(null==e.callback||e.callback(new Error("XR HitTest is not available"),null));let s;e.profile||e.spaceType||(e.spaceType=t);const i=e.offsetRay;if(i){const e=new DOMPoint(i.origin.x,i.origin.y,i.origin.z,1),t=new DOMPoint(i.direction.x,i.direction.y,i.direction.z,0);s=new XRRay(e,t)}const r=e.callback;e.spaceType?this.manager.session.requestReferenceSpace(e.spaceType).then((t=>{if(!this.manager.session){const e=new Error("XR Session is not started (2)");return r&&r(e),void this.fire("error",e)}this.manager.session.requestHitTestSource({space:t,entityTypes:e.entityTypes||void 0,offsetRay:s}).then((s=>{this._onHitTestSource(s,!1,e.inputSource,r)})).catch((e=>{r&&r(e),this.fire("error",e)}))})).catch((e=>{r&&r(e),this.fire("error",e)})):this.manager.session.requestHitTestSourceForTransientInput({profile:e.profile,entityTypes:e.entityTypes||void 0,offsetRay:s}).then((s=>{this._onHitTestSource(s,!0,e.inputSource,r)})).catch((e=>{r&&r(e),this.fire("error",e)}))}_onHitTestSource(e,s,t,r){if(!this.manager.session){e.cancel();const s=new Error("XR Session is not started (3)");return r&&r(s),void this.fire("error",s)}const a=new i(this.manager,e,s,null!=t?t:null);this.sources.push(a),r&&r(null,a),this.fire("add",a)}update(e){if(this._available)for(let s=0;s<this.sources.length;s++)this.sources[s].update(e)}get supported(){return this._supported}get available(){return this._available}}r.EVENT_AVAILABLE="available",r.EVENT_UNAVAILABLE="unavailable",r.EVENT_ADD="add",r.EVENT_REMOVE="remove",r.EVENT_RESULT="result",r.EVENT_ERROR="error";export{r as XrHitTest};