فهرست منبع

Merge pull request #8458 from RaananW/canvasResizeXR

[XR] resize the canvas when entering (and leaving) XR
sebavan 5 سال پیش
والد
کامیت
209f9a8f1c
3فایلهای تغییر یافته به همراه45 افزوده شده و 3 حذف شده
  1. 1 0
      dist/preview release/what's new.md
  2. 43 1
      src/XR/webXRManagedOutputCanvas.ts
  3. 1 2
      src/XR/webXRSessionManager.ts

+ 1 - 0
dist/preview release/what's new.md

@@ -143,6 +143,7 @@
 - It is now possible to enable experimental (AR) features using the options of the default xr helper ([RaananW](https://github.com/RaananW))
 - Full support for right handed scenes ([#8132](https://github.com/BabylonJS/Babylon.js/issues/8132)) ([RaananW](https://github.com/RaananW))
 - WebXR anchors feature implemented ([#7917](https://github.com/BabylonJS/Babylon.js/issues/7917)) ([RaananW](https://github.com/RaananW))
+- Canvas is being resized when entering XR ([RaananW](https://github.com/RaananW))
 
 ### Collisions
 

+ 43 - 1
src/XR/webXRManagedOutputCanvas.ts

@@ -2,6 +2,7 @@ import { Nullable } from "../types";
 import { ThinEngine } from '../Engines/thinEngine';
 import { WebXRRenderTarget } from "./webXRTypes";
 import { WebXRSessionManager } from './webXRSessionManager';
+import { Observable } from '../Misc/observable';
 
 /**
  * COnfiguration object for WebXR output canvas
@@ -47,6 +48,10 @@ export class WebXRManagedOutputCanvasOptions {
 export class WebXRManagedOutputCanvas implements WebXRRenderTarget {
     private _canvas: Nullable<HTMLCanvasElement> = null;
     private _engine: ThinEngine;
+    private _originalCanvasSize: {
+        width: number,
+        height: number
+    };
 
     /**
      * Rendering context of the canvas which can be used to display/mirror xr content
@@ -58,6 +63,11 @@ export class WebXRManagedOutputCanvas implements WebXRRenderTarget {
     public xrLayer: Nullable<XRWebGLLayer> = null;
 
     /**
+     * Obseervers registered here will be triggered when the xr layer was initialized
+     */
+    public onXRLayerInitObservable: Observable<XRWebGLLayer> = new Observable();
+
+    /**
      * Initializes the canvas to be added/removed upon entering/exiting xr
      * @param _xrSessionManager The XR Session manager
      * @param _options optional configuration for this canvas output. defaults will be used if not provided
@@ -96,7 +106,9 @@ export class WebXRManagedOutputCanvas implements WebXRRenderTarget {
      */
     public initializeXRLayerAsync(xrSession: XRSession): Promise<XRWebGLLayer> {
         const createLayer = () => {
-            return new XRWebGLLayer(xrSession, this.canvasContext, this._options.canvasOptions);
+            const layer = new XRWebGLLayer(xrSession, this.canvasContext, this._options.canvasOptions);
+            this.onXRLayerInitObservable.notifyObservers(layer);
+            return layer;
         };
 
         // support canvases without makeXRCompatible
@@ -115,12 +127,38 @@ export class WebXRManagedOutputCanvas implements WebXRRenderTarget {
         if (this._canvas && this._canvas !== this._engine.getRenderingCanvas()) {
             document.body.appendChild(this._canvas);
         }
+        if (this.xrLayer) {
+            this._setCanvasSize(true);
+        } else {
+            this.onXRLayerInitObservable.addOnce((layer) => {
+                this._setCanvasSize(true, layer);
+            });
+        }
+
     }
 
     private _removeCanvas() {
         if (this._canvas && document.body.contains(this._canvas) && this._canvas !== this._engine.getRenderingCanvas()) {
             document.body.removeChild(this._canvas);
         }
+        this._setCanvasSize(false);
+    }
+
+    private _setCanvasSize(init: boolean = true, xrLayer = this.xrLayer) {
+        if (!this._canvas) {
+            return;
+        }
+        if (init) {
+            if (xrLayer) {
+                this._canvas.style.width = xrLayer.framebufferWidth + 'px';
+                this._canvas.style.height = xrLayer.framebufferHeight + 'px';
+            }
+        } else {
+            if (this._originalCanvasSize) {
+                this._canvas.style.width = this._originalCanvasSize.width + 'px';
+                this._canvas.style.height = this._originalCanvasSize.height + 'px';
+            }
+        }
     }
 
     private _setManagedOutputCanvas(canvas: Nullable<HTMLCanvasElement>) {
@@ -129,6 +167,10 @@ export class WebXRManagedOutputCanvas implements WebXRRenderTarget {
             this._canvas = null;
             (this.canvasContext as any) = null;
         } else {
+            this._originalCanvasSize = {
+                width: canvas.offsetWidth,
+                height: canvas.offsetHeight
+            };
             this._canvas = canvas;
             this.canvasContext = <any>this._canvas.getContext('webgl2');
             if (!this.canvasContext) {

+ 1 - 2
src/XR/webXRSessionManager.ts

@@ -223,9 +223,8 @@ export class WebXRSessionManager implements IDisposable {
                 this.currentFrame = xrFrame;
                 this.currentTimestamp = timestamp;
                 if (xrFrame) {
-                    this.onXRFrameObservable.notifyObservers(xrFrame);
-                    // only run the render loop if a frame exists
                     engine.framebufferDimensionsObject = this.baseLayer!;
+                    this.onXRFrameObservable.notifyObservers(xrFrame);
                     engine._renderLoop();
                     engine.framebufferDimensionsObject = null;
                 }