瀏覽代碼

Merge pull request #5311 from TrevorDev/xrCamera

WebXr camera
David Catuhe 6 年之前
父節點
當前提交
05f03bb2b3

+ 2 - 1
Tools/Gulp/config.json

@@ -1297,7 +1297,8 @@
                 "../../src/Cameras/VR/babylon.vrDeviceOrientationFreeCamera.js",
                 "../../src/Cameras/VR/babylon.vrDeviceOrientationArcRotateCamera.js",
                 "../../src/Cameras/VR/babylon.vrDeviceOrientationGamepadCamera.js",
-                "../../src/Cameras/VR/babylon.vrExperienceHelper.js"
+                "../../src/Cameras/VR/babylon.vrExperienceHelper.js",
+                "../../src/Cameras/XR/babylon.webXRCamera.js"
             ],
             "dependUpon": [
                 "core",

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

@@ -7,6 +7,8 @@
 - Added Object Based Motion Blur post-process ([julien-moreau](https://github.com/julien-moreau))
 - WebXR ([TrevorDev](https://github.com/TrevorDev))
   - Add customAnimationFrameRequester to allow sessions to hook into engine's render loop ([TrevorDev](https://github.com/TrevorDev))
+  - camera customDefaultRenderTarget to allow cameras to render to a custom render target (eg. xr framebuffer) instead of the canvas ([TrevorDev](https://github.com/TrevorDev))
+  - webXR camera which can be updated by a webXRSession ([TrevorDev](https://github.com/TrevorDev))
 
 ## Updates
 

+ 49 - 0
src/Cameras/XR/babylon.webXRCamera.ts

@@ -0,0 +1,49 @@
+module BABYLON {
+    /**
+     * WebXR Camera which holds the views for the xrSession
+     * @see https://doc.babylonjs.com/how_to/webxr
+     */
+    export class WebXRCamera extends FreeCamera {
+        /**
+         * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
+         * @param name the name of the camera
+         * @param scene the scene to add the camera to
+         */
+        constructor(name: string, scene: BABYLON.Scene) {
+            super(name, BABYLON.Vector3.Zero(), scene);
+
+            // Initial camera configuration
+            this.minZ = 0;
+            this.rotationQuaternion = new BABYLON.Quaternion();
+            this.cameraRigMode = BABYLON.Camera.RIG_MODE_CUSTOM;
+            this._updateNumberOfRigCameras(1);
+        }
+
+        private _updateNumberOfRigCameras(viewCount = 1) {
+            while (this.rigCameras.length < viewCount) {
+                var newCamera = new BABYLON.TargetCamera("view: " + this.rigCameras.length, BABYLON.Vector3.Zero(), this.getScene());
+                newCamera.minZ = 0;
+                newCamera.parent = this;
+                this.rigCameras.push(newCamera);
+            }
+            while (this.rigCameras.length > viewCount) {
+                var removedCamera = this.rigCameras.pop();
+                if (removedCamera) {
+                    removedCamera.dispose();
+                }
+            }
+        }
+
+        /** @hidden */
+        public _updateForDualEyeDebugging(pupilDistance = 0.01) {
+            // Create initial camera rigs
+            this._updateNumberOfRigCameras(2);
+            this.rigCameras[0].viewport = new BABYLON.Viewport(0, 0, 0.5, 1.0);
+            this.rigCameras[0].position.x = -pupilDistance / 2;
+            this.rigCameras[0].customDefaultRenderTarget = null;
+            this.rigCameras[1].viewport = new BABYLON.Viewport(0.5, 0, 0.5, 1.0);
+            this.rigCameras[1].position.x = pupilDistance / 2;
+            this.rigCameras[1].customDefaultRenderTarget = null;
+        }
+    }
+}

+ 9 - 1
src/Cameras/babylon.camera.ts

@@ -56,6 +56,10 @@ module BABYLON {
          * Defines that both eyes of the camera should be renderered in a VR mode (webVR).
          */
         public static readonly RIG_MODE_WEBVR = 21;
+        /**
+         * Custom rig mode allowing rig cameras to be populated manually with any number of cameras
+         */
+        public static readonly RIG_MODE_CUSTOM = 22;
 
         /**
          * Defines if by default attaching controls should prevent the default javascript event to continue.
@@ -200,6 +204,10 @@ module BABYLON {
          * else in the scene.
          */
         public customRenderTargets = new Array<RenderTargetTexture>();
+        /**
+         * When set, the camera will render to this render target instead of the default canvas
+         */
+        public customDefaultRenderTarget: Nullable<RenderTargetTexture> = null;
 
         /**
          * Observable triggered when the camera view matrix has changed.
@@ -415,7 +423,7 @@ module BABYLON {
         /** @hidden */
         public _isSynchronizedViewMatrix(): boolean {
             if (!super._isSynchronized()) {
-                return false;
+                return false;
             }
 
             return this._cache.position.equals(this.position)

+ 10 - 1
src/babylon.scene.ts

@@ -4344,7 +4344,16 @@ module BABYLON {
 
                 this._intermediateRendering = false;
 
-                engine.restoreDefaultFramebuffer(); // Restore back buffer if needed
+                if (this.activeCamera.customDefaultRenderTarget) {
+                    var internalTexture = this.activeCamera.customDefaultRenderTarget.getInternalTexture();
+                    if (internalTexture) {
+                        engine.bindFramebuffer(internalTexture);
+                    }else {
+                        Tools.Error("Camera contains invalid customDefaultRenderTarget");
+                    }
+                }else {
+                    engine.restoreDefaultFramebuffer(); // Restore back buffer if needed
+                }
             }
 
             this.onAfterRenderTargetsRenderObservable.notifyObservers(this);

二進制
tests/validation/ReferenceImages/cameraRig.png


+ 1 - 1
tests/validation/config.json

@@ -14,7 +14,7 @@
     },
     {
       "title": "Camera rig",
-      "playgroundId": "#ATL1CS#6",
+      "playgroundId": "#ATL1CS#9",
       "referenceImage": "cameraRig.png"
     },
     {