UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 10.2 kB
import{EventHandler as e}from"../../core/event-handler.js";import{platform as t}from"../../core/platform.js";import{Mat4 as i}from"../../core/math/mat4.js";import{Quat as s}from"../../core/math/quat.js";import{Vec3 as a}from"../../core/math/vec3.js";import{XRTYPE_INLINE as r,XRTYPE_VR as n,XRTYPE_AR as o,XRDEPTHSENSINGUSAGE_CPU as h,XRDEPTHSENSINGFORMAT_L8A8 as p}from"./constants.js";import{DEVICETYPE_WEBGL1 as l,DEVICETYPE_WEBGL2 as c}from"../../platform/graphics/constants.js";import{XrDepthSensing as d}from"./xr-depth-sensing.js";import{XrDomOverlay as u}from"./xr-dom-overlay.js";import{XrHitTest as m}from"./xr-hit-test.js";import{XrImageTracking as _}from"./xr-image-tracking.js";import{XrInput as f}from"./xr-input.js";import{XrLightEstimation as v}from"./xr-light-estimation.js";import{XrPlaneDetection as g}from"./xr-plane-detection.js";import{XrAnchors as y}from"./xr-anchors.js";import{XrMeshDetection as b}from"./xr-mesh-detection.js";import{XrViews as F}from"./xr-views.js";class w extends e{constructor(e){super(),this.app=void 0,this._supported=t.browser&&!!navigator.xr,this._available={},this._type=null,this._spaceType=null,this._session=null,this._baseLayer=null,this.webglBinding=null,this._referenceSpace=null,this.depthSensing=void 0,this.domOverlay=void 0,this.hitTest=void 0,this.imageTracking=void 0,this.planeDetection=void 0,this.meshDetection=void 0,this.input=void 0,this.lightEstimation=void 0,this.views=void 0,this.anchors=void 0,this._camera=null,this._localPosition=new a,this._localRotation=new s,this._depthNear=.1,this._depthFar=1e3,this._supportedFrameRates=null,this._width=0,this._height=0,this._framebufferScaleFactor=1,this.app=e,this._available[r]=!1,this._available[n]=!1,this._available[o]=!1,this.views=new F(this),this.depthSensing=new d(this),this.domOverlay=new u(this),this.hitTest=new m(this),this.imageTracking=new _(this),this.planeDetection=new g(this),this.meshDetection=new b(this),this.input=new f(this),this.lightEstimation=new v(this),this.anchors=new y(this),this.views=new F(this),this._supported&&(navigator.xr.addEventListener("devicechange",(()=>{this._deviceAvailabilityCheck()})),this._deviceAvailabilityCheck(),this.app.graphicsDevice.on("devicelost",this._onDeviceLost,this),this.app.graphicsDevice.on("devicerestored",this._onDeviceRestored,this))}destroy(){}start(e,t,i,s){var a,r,n;let l=s;if("object"==typeof s&&(l=s.callback),!this._available[t])return void(l&&l(new Error("XR is not available")));if(this._session)return void(l&&l(new Error("XR session is already started")));this._camera=e,this._camera.camera.xr=this,this._type=t,this._spaceType=i,this._framebufferScaleFactor=null!=(a=null==s?void 0:s.framebufferScaleFactor)?a:1,this._setClipPlanes(e.nearClip,e.farClip);const c={requiredFeatures:[i],optionalFeatures:[]},d=(null==(r=this.app.graphicsDevice)?void 0:r.isWebGL1)||(null==(n=this.app.graphicsDevice)?void 0:n.isWebGL2);if(t===o){if(c.optionalFeatures.push("light-estimation"),c.optionalFeatures.push("hit-test"),s&&(s.imageTracking&&this.imageTracking.supported&&c.optionalFeatures.push("image-tracking"),s.planeDetection&&c.optionalFeatures.push("plane-detection"),s.meshDetection&&c.optionalFeatures.push("mesh-detection")),this.domOverlay.supported&&this.domOverlay.root&&(c.optionalFeatures.push("dom-overlay"),c.domOverlay={root:this.domOverlay.root}),s&&s.anchors&&this.anchors.supported&&c.optionalFeatures.push("anchors"),s&&s.depthSensing&&this.depthSensing.supported){c.optionalFeatures.push("depth-sensing");const e=[],t=[];if(!navigator.userAgent.includes("OculusBrowser")){if(e.push(h),t.push(p),s.depthSensing.usagePreference){const t=e.indexOf(s.depthSensing.usagePreference);-1!==t&&e.splice(t,1),e.unshift(s.depthSensing.usagePreference)}if(s.depthSensing.dataFormatPreference){const e=t.indexOf(s.depthSensing.dataFormatPreference);-1!==e&&t.splice(e,1),t.unshift(s.depthSensing.dataFormatPreference)}}c.depthSensing={usagePreference:e,dataFormatPreference:t}}d&&s&&s.cameraColor&&this.views.supportedColor&&c.optionalFeatures.push("camera-access")}c.optionalFeatures.push("hand-tracking"),s&&s.optionalFeatures&&(c.optionalFeatures=c.optionalFeatures.concat(s.optionalFeatures)),this.imageTracking.supported&&this.imageTracking.images.length?this.imageTracking.prepareImages(((e,s)=>{if(e)return l&&l(e),void this.fire("error",e);null!==s&&(c.trackedImages=s),this._onStartOptionsReady(t,i,c,l)})):this._onStartOptionsReady(t,i,c,l)}_onStartOptionsReady(e,t,i,s){navigator.xr.requestSession(e,i).then((e=>{this._onSessionStart(e,t,s)})).catch((e=>{this._camera.camera.xr=null,this._camera=null,this._type=null,this._spaceType=null,s&&s(e),this.fire("error",e)}))}end(e){this._session?(this.webglBinding=null,e&&this.once("end",e),this._session.end()):e&&e(new Error("XR Session is not initialized"))}isAvailable(e){return this._available[e]}_deviceAvailabilityCheck(){for(const e in this._available)this._sessionSupportCheck(e)}initiateRoomCapture(e){this._session?this._session.initiateRoomCapture?this._session.initiateRoomCapture().then((()=>{e&&e(null)})).catch((t=>{e&&e(t)})):e(new Error("Session does not support manual room capture")):e(new Error("Session is not active"))}updateTargetFrameRate(e,t){var i;null!=(i=this._session)&&i.updateTargetFrameRate?this._session.updateTargetFrameRate(e).then((()=>{null==t||t()})).catch((e=>{null==t||t(e)})):null==t||t(new Error("unable to update frameRate"))}_sessionSupportCheck(e){navigator.xr.isSessionSupported(e).then((t=>{this._available[e]!==t&&(this._available[e]=t,this.fire("available",e,t),this.fire(`available:${e}`,t))})).catch((e=>{this.fire("error",e)}))}_onSessionStart(e,t,i){let s=!1;this._session=e;const a=()=>{this.fire("visibility:change",e.visibilityState)},r=()=>{this._setClipPlanes(this._camera.nearClip,this._camera.farClip)},n=()=>{this._camera&&(this._camera.off("set_nearClip",r),this._camera.off("set_farClip",r),this._camera.camera.xr=null,this._camera=null),e.removeEventListener("end",n),e.removeEventListener("visibilitychange",a),s||this.fire("end"),this._session=null,this._referenceSpace=null,this._width=0,this._height=0,this._type=null,this._spaceType=null,this.app.systems&&this.app.tick()};e.addEventListener("end",n),e.addEventListener("visibilitychange",a),this._camera.on("set_nearClip",r),this._camera.on("set_farClip",r),this._createBaseLayer(),this.session.supportedFrameRates?this._supportedFrameRates=Array.from(this.session.supportedFrameRates):this._supportedFrameRates=null,this._session.addEventListener("frameratechange",(()=>{var e;this.fire("frameratechange",null==(e=this._session)?void 0:e.frameRate)})),e.requestReferenceSpace(t).then((e=>{this._referenceSpace=e,this.app.tick(),i&&i(null),this.fire("start")})).catch((t=>{s=!0,e.end(),i&&i(t),this.fire("error",t)}))}_setClipPlanes(e,t){this._depthNear===e&&this._depthFar===t||(this._depthNear=e,this._depthFar=t,this._session&&this._session.updateRenderState({depthNear:this._depthNear,depthFar:this._depthFar}))}_createBaseLayer(){const e=this.app.graphicsDevice,t=e.maxPixelRatio/window.devicePixelRatio*this._framebufferScaleFactor;this._baseLayer=new XRWebGLLayer(this._session,e.gl,{alpha:!0,depth:!0,stencil:!0,framebufferScaleFactor:t,antialias:!1});const i=e.deviceType;if((i===l||i===c)&&window.XRWebGLBinding)try{this.webglBinding=new XRWebGLBinding(this._session,e.gl)}catch(e){this.fire("error",e)}this._session.updateRenderState({baseLayer:this._baseLayer,depthNear:this._depthNear,depthFar:this._depthFar})}_onDeviceLost(){this._session&&(this.webglBinding&&(this.webglBinding=null),this._baseLayer=null,this._session.updateRenderState({baseLayer:this._baseLayer,depthNear:this._depthNear,depthFar:this._depthFar}))}_onDeviceRestored(){this._session&&setTimeout((()=>{this.app.graphicsDevice.gl.makeXRCompatible().then((()=>{this._createBaseLayer()})).catch((e=>{this.fire("error",e)}))}),0)}update(e){if(!this._session)return!1;const t=e.session.renderState.baseLayer.framebufferWidth,s=e.session.renderState.baseLayer.framebufferHeight;this._width===t&&this._height===s||(this._width=t,this._height=s,this.app.graphicsDevice.setResolution(t,s));const a=e.getViewerPose(this._referenceSpace);if(!a)return!1;const r=this.views.list.length;this.views.update(e,a.views);const n=a.transform.position,h=a.transform.orientation;if(this._localPosition.set(n.x,n.y,n.z),this._localRotation.set(h.x,h.y,h.z,h.w),0===r&&this.views.list.length>0){const e=new i,t=this.views.list[0];e.copy(t.projMat);const s=e.data,a=2*Math.atan(1/s[5])*180/Math.PI,r=s[5]/s[0],n=s[14]/(s[10]+1),o=s[14]/(s[10]-1),h=!1;this._camera.camera.setXrProperties({aspectRatio:r,farClip:n,fov:a,horizontalFov:h,nearClip:o})}return this._camera.camera._node.setLocalPosition(this._localPosition),this._camera.camera._node.setLocalRotation(this._localRotation),this.input.update(e),this._type===o&&(this.hitTest.supported&&this.hitTest.update(e),this.lightEstimation.supported&&this.lightEstimation.update(e),this.imageTracking.supported&&this.imageTracking.update(e),this.anchors.supported&&this.anchors.update(e),this.planeDetection.supported&&this.planeDetection.update(e),this.depthSensing.supported&&this.depthSensing.update(),this.meshDetection.supported&&this.meshDetection.update(e)),this.fire("update",e),!0}get supported(){return this._supported}get active(){return!!this._session}get type(){return this._type}get spaceType(){return this._spaceType}get session(){return this._session}get frameRate(){var e,t;return null!=(e=null==(t=this._session)?void 0:t.frameRate)?e:null}get supportedFrameRates(){return this._supportedFrameRates}get framebufferScaleFactor(){return this._framebufferScaleFactor}set fixedFoveation(e){var t,i;null!==(null!=(t=null==(i=this._baseLayer)?void 0:i.fixedFoveation)?t:null)&&(this.app.graphicsDevice.samples,this._baseLayer.fixedFoveation=e)}get fixedFoveation(){var e,t;return null!=(e=null==(t=this._baseLayer)?void 0:t.fixedFoveation)?e:null}get camera(){return this._camera?this._camera.entity:null}get visibilityState(){return this._session?this._session.visibilityState:null}}w.EVENT_AVAILABLE="available",w.EVENT_START="start",w.EVENT_END="end",w.EVENT_UPDATE="update",w.EVENT_ERROR="error";export{w as XrManager};