UNPKG

playcanvas

Version:

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

175 lines (174 loc) 5.85 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); class XrBridge { /** * @param {GraphicsDevice} device - The graphics device. * @param {EventHandler} eventHandler - Target for firing XR-related errors. */ constructor(device, eventHandler) { /** * @type {GraphicsDevice} */ __publicField(this, "device"); /** * Receives XR presentation-related events (for example {@link EventHandler#fire} with name `"error"`). * * @type {EventHandler} */ __publicField(this, "eventHandler"); /** * @type {object} */ __publicField(this, "impl"); /** * @type {EventHandle|null} * @private */ __publicField(this, "_evtDeviceLost", null); /** * @type {EventHandle|null} * @private */ __publicField(this, "_evtDeviceRestored", null); /** * Active XR session for presentation (shared across graphics backends). * * @type {XRSession|null} * @private */ __publicField(this, "_session", null); /** * Resolved framebuffer scale from the last {@link XrBridge#attachPresentation}. * * @type {number} * @private */ __publicField(this, "_framebufferScaleFactor", 1); /** * Callback when backend GPU binding construction fails. * * @type {Function|undefined} * @private */ __publicField(this, "_onBindingError"); this.device = device; this.eventHandler = eventHandler; this.impl = device.createXrBridgeImpl(this); this._evtDeviceLost = device.on("devicelost", this._onDeviceLost, this); this._evtDeviceRestored = device.on("devicerestored", this._onDeviceRestored, this); } destroy() { const device = this.device; if (device) { this._evtDeviceLost?.off(); this._evtDeviceLost = null; this._evtDeviceRestored?.off(); this._evtDeviceRestored = null; this.impl.endFrame(); this.impl.destroy(device); this.impl = null; this._session = null; this._framebufferScaleFactor = 1; this._onBindingError = void 0; this.device = null; this.eventHandler = null; } } /** @private */ _onDeviceLost() { this.impl.onGraphicsDeviceLost(); } /** @private */ _onDeviceRestored() { this.impl.onGraphicsDeviceRestored(); } /** * @param {XRSession} session - XR session. * @param {object} options - Presentation options (backend-specific; includes framebufferScaleFactor, depthNear, depthFar). */ attachPresentation(session, options) { this._session = session; this._framebufferScaleFactor = options.framebufferScaleFactor; this._onBindingError = options.onBindingError; this.impl.attachPresentation(session, options); } releasePresentation() { this.impl.releasePresentation(); } /** * Called once per XR frame before rendering to set the backend render target for this frame. * * @param {XRFrame} frame - Current XR frame. * @param {XRReferenceSpace|null} referenceSpace - Active XR reference space (WebGPU path uses * it for subimages). */ beginFrame(frame, referenceSpace) { this.impl.beginFrame(frame, referenceSpace); } /** * Resets the backend render target after the XR session ends. */ endFrame() { this.impl.endFrame(); } /** * Writes immersive framebuffer size in pixels for this frame (backend-specific source) * into {@link Vec2#x} (width) and {@link Vec2#y} (height). * * @param {XRFrame} frame - Current XR frame. * @param {Vec2} out - Receives width and height; reused by the caller to avoid per-frame allocation. */ getFramebufferSize(frame, out) { this.impl.getFramebufferSize(frame, out); } /** * Viewport rectangle for an XR view within the immersive framebuffer (or per-view texture). * * @param {XRFrame} frame - Current XR frame. * @param {XRView} xrView - WebXR view. * @returns {XRViewport} Viewport for this view. */ getViewport(frame, xrView) { return this.impl.getViewport(frame, xrView); } /** * Copies the XR passthrough camera image for the given `XRCamera` into a PlayCanvas * {@link Texture}. Delegates to the backend implementation; no-ops if not supported. * * @param {any} xrCamera - The XR camera whose image should be copied (XRCamera from WebXR API). * @param {Texture} texture - Destination engine texture. */ syncCameraColorTexture(xrCamera, texture) { this.impl?.syncCameraColorTexture?.(xrCamera, texture); } /** * Binds XR GPU depth information to the engine depth texture on backends that support it * (WebGL). No-ops on WebGPU until a binding API exists. * * @param {any} depthInfo - Depth information from WebXR (`getDepthInformation`). * @param {Texture} texture - Destination engine texture. * @param {number} depthPixelFormat - Resolved depth pixel format constant (`PIXELFORMAT_*`). */ syncCameraDepthTexture(depthInfo, texture, depthPixelFormat) { this.impl?.syncCameraDepthTexture?.(depthInfo, texture, depthPixelFormat); } /** * @returns {XRLayer|null} Backend output layer (e.g. XRWebGLLayer), if any. */ get presentationLayer() { return this.impl.presentationLayer ?? null; } /** * Backend graphics binding for camera/depth when available (for example WebGL * {@link XRWebGLBinding} or WebGPU `XRGPUBinding` when exposed by the user agent). * * @returns {Object|null} The binding object, or null. */ get graphicsBinding() { return this.impl.graphicsBinding ?? null; } } export { XrBridge };