浏览代码

Merge branch 'master' into useControllerWhileMeshLoading

Trevor Baron 7 年之前
父节点
当前提交
a3b51b8873
共有 31 个文件被更改,包括 13022 次插入11199 次删除
  1. 4048 4058
      Playground/babylon.d.txt
  2. 二进制
      Playground/scenes/Alien/Alien.bin
  3. 1562 0
      Playground/scenes/Alien/Alien.gltf
  4. 二进制
      Playground/scenes/Alien/Alien_baseColor.png
  5. 二进制
      Playground/scenes/Alien/Alien_normal.png
  6. 二进制
      Playground/scenes/Alien/Alien_occlusionRoughnessMetallic.png
  7. 2 1
      Tools/Gulp/config.json
  8. 5902 5900
      dist/preview release/babylon.d.ts
  9. 37 37
      dist/preview release/babylon.js
  10. 50 12
      dist/preview release/babylon.max.js
  11. 37 37
      dist/preview release/babylon.worker.js
  12. 1017 1015
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  13. 34 34
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  14. 50 12
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  15. 50 12
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  16. 50 12
      dist/preview release/es6.js
  17. 2 7
      dist/preview release/typedocValidationBaseline.json
  18. 37 37
      dist/preview release/viewer/babylon.viewer.js
  19. 50 12
      dist/preview release/viewer/babylon.viewer.max.js
  20. 2 2
      dist/preview release/what's new.md
  21. 3 2
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  22. 50 0
      src/Gamepad/Controllers/babylon.daydreamController.ts
  23. 1 1
      src/Gamepad/Controllers/babylon.gearVRController.ts
  24. 1 1
      src/Gamepad/Controllers/babylon.genericController.ts
  25. 1 1
      src/Gamepad/Controllers/babylon.oculusTouchController.ts
  26. 8 1
      src/Gamepad/Controllers/babylon.poseEnabledController.ts
  27. 1 1
      src/Gamepad/Controllers/babylon.viveController.ts
  28. 2 2
      src/Gamepad/Controllers/babylon.webVRController.ts
  29. 1 1
      src/Gamepad/Controllers/babylon.windowsMotionController.ts
  30. 1 1
      src/Shaders/default.fragment.fx
  31. 23 0
      tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.ts

文件差异内容过多而无法显示
+ 4048 - 4058
Playground/babylon.d.txt


二进制
Playground/scenes/Alien/Alien.bin


文件差异内容过多而无法显示
+ 1562 - 0
Playground/scenes/Alien/Alien.gltf


二进制
Playground/scenes/Alien/Alien_baseColor.png


二进制
Playground/scenes/Alien/Alien_normal.png


二进制
Playground/scenes/Alien/Alien_occlusionRoughnessMetallic.png


+ 2 - 1
Tools/Gulp/config.json

@@ -660,7 +660,8 @@
                 "../../src/Gamepad/Controllers/babylon.viveController.js",
                 "../../src/Gamepad/Controllers/babylon.viveController.js",
                 "../../src/Gamepad/Controllers/babylon.genericController.js",
                 "../../src/Gamepad/Controllers/babylon.genericController.js",
                 "../../src/Gamepad/Controllers/babylon.windowsMotionController.js",
                 "../../src/Gamepad/Controllers/babylon.windowsMotionController.js",
-                "../../src/Gamepad/Controllers/babylon.gearVRController.js"
+                "../../src/Gamepad/Controllers/babylon.gearVRController.js",
+                "../../src/Gamepad/Controllers/babylon.daydreamController.js"
             ],
             ],
             "dependUpon": [
             "dependUpon": [
                 "core"
                 "core"

文件差异内容过多而无法显示
+ 5902 - 5900
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 37 - 37
dist/preview release/babylon.js


+ 50 - 12
dist/preview release/babylon.max.js

@@ -24059,7 +24059,6 @@ var BABYLON;
             // Camera
             // Camera
             this.resetCachedMaterial();
             this.resetCachedMaterial();
             this._renderId++;
             this._renderId++;
-            this.activeCamera.update();
             this.updateTransformMatrix();
             this.updateTransformMatrix();
             if (camera._alternateCamera) {
             if (camera._alternateCamera) {
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
@@ -24203,10 +24202,6 @@ var BABYLON;
                 this._renderForCamera(camera);
                 this._renderForCamera(camera);
                 return;
                 return;
             }
             }
-            // Update camera
-            if (this.activeCamera) {
-                this.activeCamera.update();
-            }
             // rig cameras
             // rig cameras
             for (var index = 0; index < camera._rigCameras.length; index++) {
             for (var index = 0; index < camera._rigCameras.length; index++) {
                 this._renderForCamera(camera._rigCameras[index], camera);
                 this._renderForCamera(camera._rigCameras[index], camera);
@@ -24319,6 +24314,28 @@ var BABYLON;
             }
             }
             // Before render
             // Before render
             this.onBeforeRenderObservable.notifyObservers(this);
             this.onBeforeRenderObservable.notifyObservers(this);
+            // Update Cameras
+            if (this.activeCameras.length > 0) {
+                for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
+                    var camera = this.activeCameras[cameraIndex];
+                    camera.update();
+                    if (camera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                        // rig cameras
+                        for (var index = 0; index < camera._rigCameras.length; index++) {
+                            camera._rigCameras[index].update();
+                        }
+                    }
+                }
+            }
+            else if (this.activeCamera) {
+                this.activeCamera.update();
+                if (this.activeCamera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                    // rig cameras
+                    for (var index = 0; index < this.activeCamera._rigCameras.length; index++) {
+                        this.activeCamera._rigCameras[index].update();
+                    }
+                }
+            }
             // Customs render targets
             // Customs render targets
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             var engine = this.getEngine();
             var engine = this.getEngine();
@@ -59805,6 +59822,11 @@ var BABYLON;
             var maxSize = engine.getCaps().maxTextureSize;
             var maxSize = engine.getCaps().maxTextureSize;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
+            // If rendering to a webvr camera's left or right eye only half the width should be used to avoid resize when rendered to screen
+            var webVRCamera = camera.parent;
+            if (webVRCamera && (webVRCamera.leftCamera == camera || webVRCamera.rightCamera == camera)) {
+                requiredWidth /= 2;
+            }
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredHeight = this._options.height || requiredHeight;
             var desiredHeight = this._options.height || requiredHeight;
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
@@ -66671,6 +66693,7 @@ var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var PostProcessRenderPipeline = /** @class */ (function () {
     var PostProcessRenderPipeline = /** @class */ (function () {
         function PostProcessRenderPipeline(engine, name) {
         function PostProcessRenderPipeline(engine, name) {
+            this.engine = engine;
             this._name = name;
             this._name = name;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
@@ -66770,6 +66793,18 @@ var BABYLON;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
         };
         };
+        PostProcessRenderPipeline.prototype._enableMSAAOnFirstPostProcess = function () {
+            // Set samples of the very first post process to 4 to enable native anti-aliasing in browsers that support webGL 2.0 (See: https://github.com/BabylonJS/Babylon.js/issues/3754)
+            var effectKeys = Object.keys(this._renderEffects);
+            if (this.engine.webGLVersion >= 2 && effectKeys.length > 0) {
+                var postProcesses = this._renderEffects[effectKeys[0]].getPostProcesses();
+                if (postProcesses) {
+                    postProcesses[0].samples = 4;
+                    return true;
+                }
+            }
+            return false;
+        };
         PostProcessRenderPipeline.prototype.dispose = function () {
         PostProcessRenderPipeline.prototype.dispose = function () {
             // Must be implemented by children 
             // Must be implemented by children 
         };
         };
@@ -69119,6 +69154,7 @@ var BABYLON;
             if (this._cameras !== null) {
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
             }
             }
+            this._enableMSAAOnFirstPostProcess();
         };
         };
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
             for (var i = 0; i < this._cameras.length; i++) {
             for (var i = 0; i < this._cameras.length; i++) {
@@ -80555,7 +80591,7 @@ var BABYLON;
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 this.controllers.forEach(function (controller) {
                 this.controllers.forEach(function (controller) {
-                    controller._deviceToWorld = _this._deviceToWorld;
+                    controller._deviceToWorld.copyFrom(_this._deviceToWorld);
                     controller.update();
                     controller.update();
                 });
                 });
             }
             }
@@ -80589,6 +80625,9 @@ var BABYLON;
          */
          */
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
             var _this = this;
             var _this = this;
+            // Update the parent camera prior to using a child camera to avoid desynchronization
+            var parentCamera = this._cameraRigParams["parentCamera"];
+            parentCamera._updateCache();
             //WebVR 1.1
             //WebVR 1.1
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
@@ -80602,7 +80641,6 @@ var BABYLON;
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             // Computing target and final matrix
             // Computing target and final matrix
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
-            var parentCamera = this._cameraRigParams["parentCamera"];
             // should the view matrix be updated with scale and position offset?
             // should the view matrix be updated with scale and position offset?
             if (parentCamera.deviceScaleFactor !== 1) {
             if (parentCamera.deviceScaleFactor !== 1) {
                 this._webvrViewMatrix.invert();
                 this._webvrViewMatrix.invert();
@@ -80649,7 +80687,7 @@ var BABYLON;
                         _this._rightController = null;
                         _this._rightController = null;
                     }
                     }
                     if (webVrController.hand === "left") {
                     if (webVrController.hand === "left") {
-                        _this._rightController = null;
+                        _this._leftController = null;
                     }
                     }
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     if (controllerIndex !== -1) {
                     if (controllerIndex !== -1) {
@@ -80660,7 +80698,7 @@ var BABYLON;
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                     var webVrController_1 = gamepad;
                     var webVrController_1 = gamepad;
-                    webVrController_1._deviceToWorld = _this._deviceToWorld;
+                    webVrController_1._deviceToWorld.copyFrom(_this._deviceToWorld);
                     if (_this.webVROptions.controllerMeshes) {
                     if (_this.webVROptions.controllerMeshes) {
                         if (webVrController_1.defaultModel) {
                         if (webVrController_1.defaultModel) {
                             webVrController_1.defaultModel.setEnabled(true);
                             webVrController_1.defaultModel.setEnabled(true);
@@ -87123,7 +87161,7 @@ var BABYLON;
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._target = BABYLON.Vector3.Zero();
             this._target = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
-            this.invertYAxis = false;
+            this._invertYAxis = false;
             this.position = BABYLON.Vector3.Zero();
             this.position = BABYLON.Vector3.Zero();
             this._scene = scene;
             this._scene = scene;
             this._scene.reflectionProbes.push(this);
             this._scene.reflectionProbes.push(this);
@@ -87137,10 +87175,10 @@ var BABYLON;
                         _this._add.copyFromFloats(-1, 0, 0);
                         _this._add.copyFromFloats(-1, 0, 0);
                         break;
                         break;
                     case 2:
                     case 2:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? 1 : -1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? 1 : -1, 0);
                         break;
                         break;
                     case 3:
                     case 3:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? -1 : 1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? -1 : 1, 0);
                         break;
                         break;
                     case 4:
                     case 4:
                         _this._add.copyFromFloats(0, 0, 1);
                         _this._add.copyFromFloats(0, 0, 1);

文件差异内容过多而无法显示
+ 37 - 37
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 1017 - 1015
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


文件差异内容过多而无法显示
+ 34 - 34
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 50 - 12
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -24059,7 +24059,6 @@ var BABYLON;
             // Camera
             // Camera
             this.resetCachedMaterial();
             this.resetCachedMaterial();
             this._renderId++;
             this._renderId++;
-            this.activeCamera.update();
             this.updateTransformMatrix();
             this.updateTransformMatrix();
             if (camera._alternateCamera) {
             if (camera._alternateCamera) {
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
@@ -24203,10 +24202,6 @@ var BABYLON;
                 this._renderForCamera(camera);
                 this._renderForCamera(camera);
                 return;
                 return;
             }
             }
-            // Update camera
-            if (this.activeCamera) {
-                this.activeCamera.update();
-            }
             // rig cameras
             // rig cameras
             for (var index = 0; index < camera._rigCameras.length; index++) {
             for (var index = 0; index < camera._rigCameras.length; index++) {
                 this._renderForCamera(camera._rigCameras[index], camera);
                 this._renderForCamera(camera._rigCameras[index], camera);
@@ -24319,6 +24314,28 @@ var BABYLON;
             }
             }
             // Before render
             // Before render
             this.onBeforeRenderObservable.notifyObservers(this);
             this.onBeforeRenderObservable.notifyObservers(this);
+            // Update Cameras
+            if (this.activeCameras.length > 0) {
+                for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
+                    var camera = this.activeCameras[cameraIndex];
+                    camera.update();
+                    if (camera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                        // rig cameras
+                        for (var index = 0; index < camera._rigCameras.length; index++) {
+                            camera._rigCameras[index].update();
+                        }
+                    }
+                }
+            }
+            else if (this.activeCamera) {
+                this.activeCamera.update();
+                if (this.activeCamera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                    // rig cameras
+                    for (var index = 0; index < this.activeCamera._rigCameras.length; index++) {
+                        this.activeCamera._rigCameras[index].update();
+                    }
+                }
+            }
             // Customs render targets
             // Customs render targets
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             var engine = this.getEngine();
             var engine = this.getEngine();
@@ -59116,6 +59133,11 @@ var BABYLON;
             var maxSize = engine.getCaps().maxTextureSize;
             var maxSize = engine.getCaps().maxTextureSize;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
+            // If rendering to a webvr camera's left or right eye only half the width should be used to avoid resize when rendered to screen
+            var webVRCamera = camera.parent;
+            if (webVRCamera && (webVRCamera.leftCamera == camera || webVRCamera.rightCamera == camera)) {
+                requiredWidth /= 2;
+            }
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredHeight = this._options.height || requiredHeight;
             var desiredHeight = this._options.height || requiredHeight;
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
@@ -65982,6 +66004,7 @@ var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var PostProcessRenderPipeline = /** @class */ (function () {
     var PostProcessRenderPipeline = /** @class */ (function () {
         function PostProcessRenderPipeline(engine, name) {
         function PostProcessRenderPipeline(engine, name) {
+            this.engine = engine;
             this._name = name;
             this._name = name;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
@@ -66081,6 +66104,18 @@ var BABYLON;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
         };
         };
+        PostProcessRenderPipeline.prototype._enableMSAAOnFirstPostProcess = function () {
+            // Set samples of the very first post process to 4 to enable native anti-aliasing in browsers that support webGL 2.0 (See: https://github.com/BabylonJS/Babylon.js/issues/3754)
+            var effectKeys = Object.keys(this._renderEffects);
+            if (this.engine.webGLVersion >= 2 && effectKeys.length > 0) {
+                var postProcesses = this._renderEffects[effectKeys[0]].getPostProcesses();
+                if (postProcesses) {
+                    postProcesses[0].samples = 4;
+                    return true;
+                }
+            }
+            return false;
+        };
         PostProcessRenderPipeline.prototype.dispose = function () {
         PostProcessRenderPipeline.prototype.dispose = function () {
             // Must be implemented by children 
             // Must be implemented by children 
         };
         };
@@ -68430,6 +68465,7 @@ var BABYLON;
             if (this._cameras !== null) {
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
             }
             }
+            this._enableMSAAOnFirstPostProcess();
         };
         };
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
             for (var i = 0; i < this._cameras.length; i++) {
             for (var i = 0; i < this._cameras.length; i++) {
@@ -79816,7 +79852,7 @@ var BABYLON;
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 this.controllers.forEach(function (controller) {
                 this.controllers.forEach(function (controller) {
-                    controller._deviceToWorld = _this._deviceToWorld;
+                    controller._deviceToWorld.copyFrom(_this._deviceToWorld);
                     controller.update();
                     controller.update();
                 });
                 });
             }
             }
@@ -79850,6 +79886,9 @@ var BABYLON;
          */
          */
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
             var _this = this;
             var _this = this;
+            // Update the parent camera prior to using a child camera to avoid desynchronization
+            var parentCamera = this._cameraRigParams["parentCamera"];
+            parentCamera._updateCache();
             //WebVR 1.1
             //WebVR 1.1
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
@@ -79863,7 +79902,6 @@ var BABYLON;
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             // Computing target and final matrix
             // Computing target and final matrix
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
-            var parentCamera = this._cameraRigParams["parentCamera"];
             // should the view matrix be updated with scale and position offset?
             // should the view matrix be updated with scale and position offset?
             if (parentCamera.deviceScaleFactor !== 1) {
             if (parentCamera.deviceScaleFactor !== 1) {
                 this._webvrViewMatrix.invert();
                 this._webvrViewMatrix.invert();
@@ -79910,7 +79948,7 @@ var BABYLON;
                         _this._rightController = null;
                         _this._rightController = null;
                     }
                     }
                     if (webVrController.hand === "left") {
                     if (webVrController.hand === "left") {
-                        _this._rightController = null;
+                        _this._leftController = null;
                     }
                     }
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     if (controllerIndex !== -1) {
                     if (controllerIndex !== -1) {
@@ -79921,7 +79959,7 @@ var BABYLON;
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                     var webVrController_1 = gamepad;
                     var webVrController_1 = gamepad;
-                    webVrController_1._deviceToWorld = _this._deviceToWorld;
+                    webVrController_1._deviceToWorld.copyFrom(_this._deviceToWorld);
                     if (_this.webVROptions.controllerMeshes) {
                     if (_this.webVROptions.controllerMeshes) {
                         if (webVrController_1.defaultModel) {
                         if (webVrController_1.defaultModel) {
                             webVrController_1.defaultModel.setEnabled(true);
                             webVrController_1.defaultModel.setEnabled(true);
@@ -86384,7 +86422,7 @@ var BABYLON;
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._target = BABYLON.Vector3.Zero();
             this._target = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
-            this.invertYAxis = false;
+            this._invertYAxis = false;
             this.position = BABYLON.Vector3.Zero();
             this.position = BABYLON.Vector3.Zero();
             this._scene = scene;
             this._scene = scene;
             this._scene.reflectionProbes.push(this);
             this._scene.reflectionProbes.push(this);
@@ -86398,10 +86436,10 @@ var BABYLON;
                         _this._add.copyFromFloats(-1, 0, 0);
                         _this._add.copyFromFloats(-1, 0, 0);
                         break;
                         break;
                     case 2:
                     case 2:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? 1 : -1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? 1 : -1, 0);
                         break;
                         break;
                     case 3:
                     case 3:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? -1 : 1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? -1 : 1, 0);
                         break;
                         break;
                     case 4:
                     case 4:
                         _this._add.copyFromFloats(0, 0, 1);
                         _this._add.copyFromFloats(0, 0, 1);

+ 50 - 12
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js

@@ -24045,7 +24045,6 @@ var BABYLON;
             // Camera
             // Camera
             this.resetCachedMaterial();
             this.resetCachedMaterial();
             this._renderId++;
             this._renderId++;
-            this.activeCamera.update();
             this.updateTransformMatrix();
             this.updateTransformMatrix();
             if (camera._alternateCamera) {
             if (camera._alternateCamera) {
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
@@ -24189,10 +24188,6 @@ var BABYLON;
                 this._renderForCamera(camera);
                 this._renderForCamera(camera);
                 return;
                 return;
             }
             }
-            // Update camera
-            if (this.activeCamera) {
-                this.activeCamera.update();
-            }
             // rig cameras
             // rig cameras
             for (var index = 0; index < camera._rigCameras.length; index++) {
             for (var index = 0; index < camera._rigCameras.length; index++) {
                 this._renderForCamera(camera._rigCameras[index], camera);
                 this._renderForCamera(camera._rigCameras[index], camera);
@@ -24305,6 +24300,28 @@ var BABYLON;
             }
             }
             // Before render
             // Before render
             this.onBeforeRenderObservable.notifyObservers(this);
             this.onBeforeRenderObservable.notifyObservers(this);
+            // Update Cameras
+            if (this.activeCameras.length > 0) {
+                for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
+                    var camera = this.activeCameras[cameraIndex];
+                    camera.update();
+                    if (camera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                        // rig cameras
+                        for (var index = 0; index < camera._rigCameras.length; index++) {
+                            camera._rigCameras[index].update();
+                        }
+                    }
+                }
+            }
+            else if (this.activeCamera) {
+                this.activeCamera.update();
+                if (this.activeCamera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                    // rig cameras
+                    for (var index = 0; index < this.activeCamera._rigCameras.length; index++) {
+                        this.activeCamera._rigCameras[index].update();
+                    }
+                }
+            }
             // Customs render targets
             // Customs render targets
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             var engine = this.getEngine();
             var engine = this.getEngine();
@@ -59102,6 +59119,11 @@ var BABYLON;
             var maxSize = engine.getCaps().maxTextureSize;
             var maxSize = engine.getCaps().maxTextureSize;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
+            // If rendering to a webvr camera's left or right eye only half the width should be used to avoid resize when rendered to screen
+            var webVRCamera = camera.parent;
+            if (webVRCamera && (webVRCamera.leftCamera == camera || webVRCamera.rightCamera == camera)) {
+                requiredWidth /= 2;
+            }
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredHeight = this._options.height || requiredHeight;
             var desiredHeight = this._options.height || requiredHeight;
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
@@ -65968,6 +65990,7 @@ var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var PostProcessRenderPipeline = /** @class */ (function () {
     var PostProcessRenderPipeline = /** @class */ (function () {
         function PostProcessRenderPipeline(engine, name) {
         function PostProcessRenderPipeline(engine, name) {
+            this.engine = engine;
             this._name = name;
             this._name = name;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
@@ -66067,6 +66090,18 @@ var BABYLON;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
         };
         };
+        PostProcessRenderPipeline.prototype._enableMSAAOnFirstPostProcess = function () {
+            // Set samples of the very first post process to 4 to enable native anti-aliasing in browsers that support webGL 2.0 (See: https://github.com/BabylonJS/Babylon.js/issues/3754)
+            var effectKeys = Object.keys(this._renderEffects);
+            if (this.engine.webGLVersion >= 2 && effectKeys.length > 0) {
+                var postProcesses = this._renderEffects[effectKeys[0]].getPostProcesses();
+                if (postProcesses) {
+                    postProcesses[0].samples = 4;
+                    return true;
+                }
+            }
+            return false;
+        };
         PostProcessRenderPipeline.prototype.dispose = function () {
         PostProcessRenderPipeline.prototype.dispose = function () {
             // Must be implemented by children 
             // Must be implemented by children 
         };
         };
@@ -68416,6 +68451,7 @@ var BABYLON;
             if (this._cameras !== null) {
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
             }
             }
+            this._enableMSAAOnFirstPostProcess();
         };
         };
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
             for (var i = 0; i < this._cameras.length; i++) {
             for (var i = 0; i < this._cameras.length; i++) {
@@ -79802,7 +79838,7 @@ var BABYLON;
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 this.controllers.forEach(function (controller) {
                 this.controllers.forEach(function (controller) {
-                    controller._deviceToWorld = _this._deviceToWorld;
+                    controller._deviceToWorld.copyFrom(_this._deviceToWorld);
                     controller.update();
                     controller.update();
                 });
                 });
             }
             }
@@ -79836,6 +79872,9 @@ var BABYLON;
          */
          */
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
             var _this = this;
             var _this = this;
+            // Update the parent camera prior to using a child camera to avoid desynchronization
+            var parentCamera = this._cameraRigParams["parentCamera"];
+            parentCamera._updateCache();
             //WebVR 1.1
             //WebVR 1.1
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
@@ -79849,7 +79888,6 @@ var BABYLON;
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             // Computing target and final matrix
             // Computing target and final matrix
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
-            var parentCamera = this._cameraRigParams["parentCamera"];
             // should the view matrix be updated with scale and position offset?
             // should the view matrix be updated with scale and position offset?
             if (parentCamera.deviceScaleFactor !== 1) {
             if (parentCamera.deviceScaleFactor !== 1) {
                 this._webvrViewMatrix.invert();
                 this._webvrViewMatrix.invert();
@@ -79896,7 +79934,7 @@ var BABYLON;
                         _this._rightController = null;
                         _this._rightController = null;
                     }
                     }
                     if (webVrController.hand === "left") {
                     if (webVrController.hand === "left") {
-                        _this._rightController = null;
+                        _this._leftController = null;
                     }
                     }
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     if (controllerIndex !== -1) {
                     if (controllerIndex !== -1) {
@@ -79907,7 +79945,7 @@ var BABYLON;
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                     var webVrController_1 = gamepad;
                     var webVrController_1 = gamepad;
-                    webVrController_1._deviceToWorld = _this._deviceToWorld;
+                    webVrController_1._deviceToWorld.copyFrom(_this._deviceToWorld);
                     if (_this.webVROptions.controllerMeshes) {
                     if (_this.webVROptions.controllerMeshes) {
                         if (webVrController_1.defaultModel) {
                         if (webVrController_1.defaultModel) {
                             webVrController_1.defaultModel.setEnabled(true);
                             webVrController_1.defaultModel.setEnabled(true);
@@ -86370,7 +86408,7 @@ var BABYLON;
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._target = BABYLON.Vector3.Zero();
             this._target = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
-            this.invertYAxis = false;
+            this._invertYAxis = false;
             this.position = BABYLON.Vector3.Zero();
             this.position = BABYLON.Vector3.Zero();
             this._scene = scene;
             this._scene = scene;
             this._scene.reflectionProbes.push(this);
             this._scene.reflectionProbes.push(this);
@@ -86384,10 +86422,10 @@ var BABYLON;
                         _this._add.copyFromFloats(-1, 0, 0);
                         _this._add.copyFromFloats(-1, 0, 0);
                         break;
                         break;
                     case 2:
                     case 2:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? 1 : -1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? 1 : -1, 0);
                         break;
                         break;
                     case 3:
                     case 3:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? -1 : 1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? -1 : 1, 0);
                         break;
                         break;
                     case 4:
                     case 4:
                         _this._add.copyFromFloats(0, 0, 1);
                         _this._add.copyFromFloats(0, 0, 1);

+ 50 - 12
dist/preview release/es6.js

@@ -24045,7 +24045,6 @@ var BABYLON;
             // Camera
             // Camera
             this.resetCachedMaterial();
             this.resetCachedMaterial();
             this._renderId++;
             this._renderId++;
-            this.activeCamera.update();
             this.updateTransformMatrix();
             this.updateTransformMatrix();
             if (camera._alternateCamera) {
             if (camera._alternateCamera) {
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
@@ -24189,10 +24188,6 @@ var BABYLON;
                 this._renderForCamera(camera);
                 this._renderForCamera(camera);
                 return;
                 return;
             }
             }
-            // Update camera
-            if (this.activeCamera) {
-                this.activeCamera.update();
-            }
             // rig cameras
             // rig cameras
             for (var index = 0; index < camera._rigCameras.length; index++) {
             for (var index = 0; index < camera._rigCameras.length; index++) {
                 this._renderForCamera(camera._rigCameras[index], camera);
                 this._renderForCamera(camera._rigCameras[index], camera);
@@ -24305,6 +24300,28 @@ var BABYLON;
             }
             }
             // Before render
             // Before render
             this.onBeforeRenderObservable.notifyObservers(this);
             this.onBeforeRenderObservable.notifyObservers(this);
+            // Update Cameras
+            if (this.activeCameras.length > 0) {
+                for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
+                    var camera = this.activeCameras[cameraIndex];
+                    camera.update();
+                    if (camera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                        // rig cameras
+                        for (var index = 0; index < camera._rigCameras.length; index++) {
+                            camera._rigCameras[index].update();
+                        }
+                    }
+                }
+            }
+            else if (this.activeCamera) {
+                this.activeCamera.update();
+                if (this.activeCamera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                    // rig cameras
+                    for (var index = 0; index < this.activeCamera._rigCameras.length; index++) {
+                        this.activeCamera._rigCameras[index].update();
+                    }
+                }
+            }
             // Customs render targets
             // Customs render targets
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             var engine = this.getEngine();
             var engine = this.getEngine();
@@ -59791,6 +59808,11 @@ var BABYLON;
             var maxSize = engine.getCaps().maxTextureSize;
             var maxSize = engine.getCaps().maxTextureSize;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
+            // If rendering to a webvr camera's left or right eye only half the width should be used to avoid resize when rendered to screen
+            var webVRCamera = camera.parent;
+            if (webVRCamera && (webVRCamera.leftCamera == camera || webVRCamera.rightCamera == camera)) {
+                requiredWidth /= 2;
+            }
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredHeight = this._options.height || requiredHeight;
             var desiredHeight = this._options.height || requiredHeight;
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
@@ -66657,6 +66679,7 @@ var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var PostProcessRenderPipeline = /** @class */ (function () {
     var PostProcessRenderPipeline = /** @class */ (function () {
         function PostProcessRenderPipeline(engine, name) {
         function PostProcessRenderPipeline(engine, name) {
+            this.engine = engine;
             this._name = name;
             this._name = name;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
@@ -66756,6 +66779,18 @@ var BABYLON;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
         };
         };
+        PostProcessRenderPipeline.prototype._enableMSAAOnFirstPostProcess = function () {
+            // Set samples of the very first post process to 4 to enable native anti-aliasing in browsers that support webGL 2.0 (See: https://github.com/BabylonJS/Babylon.js/issues/3754)
+            var effectKeys = Object.keys(this._renderEffects);
+            if (this.engine.webGLVersion >= 2 && effectKeys.length > 0) {
+                var postProcesses = this._renderEffects[effectKeys[0]].getPostProcesses();
+                if (postProcesses) {
+                    postProcesses[0].samples = 4;
+                    return true;
+                }
+            }
+            return false;
+        };
         PostProcessRenderPipeline.prototype.dispose = function () {
         PostProcessRenderPipeline.prototype.dispose = function () {
             // Must be implemented by children 
             // Must be implemented by children 
         };
         };
@@ -69105,6 +69140,7 @@ var BABYLON;
             if (this._cameras !== null) {
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
             }
             }
+            this._enableMSAAOnFirstPostProcess();
         };
         };
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
             for (var i = 0; i < this._cameras.length; i++) {
             for (var i = 0; i < this._cameras.length; i++) {
@@ -80541,7 +80577,7 @@ var BABYLON;
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 this.controllers.forEach(function (controller) {
                 this.controllers.forEach(function (controller) {
-                    controller._deviceToWorld = _this._deviceToWorld;
+                    controller._deviceToWorld.copyFrom(_this._deviceToWorld);
                     controller.update();
                     controller.update();
                 });
                 });
             }
             }
@@ -80575,6 +80611,9 @@ var BABYLON;
          */
          */
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
             var _this = this;
             var _this = this;
+            // Update the parent camera prior to using a child camera to avoid desynchronization
+            var parentCamera = this._cameraRigParams["parentCamera"];
+            parentCamera._updateCache();
             //WebVR 1.1
             //WebVR 1.1
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
@@ -80588,7 +80627,6 @@ var BABYLON;
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             // Computing target and final matrix
             // Computing target and final matrix
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
-            var parentCamera = this._cameraRigParams["parentCamera"];
             // should the view matrix be updated with scale and position offset?
             // should the view matrix be updated with scale and position offset?
             if (parentCamera.deviceScaleFactor !== 1) {
             if (parentCamera.deviceScaleFactor !== 1) {
                 this._webvrViewMatrix.invert();
                 this._webvrViewMatrix.invert();
@@ -80635,7 +80673,7 @@ var BABYLON;
                         _this._rightController = null;
                         _this._rightController = null;
                     }
                     }
                     if (webVrController.hand === "left") {
                     if (webVrController.hand === "left") {
-                        _this._rightController = null;
+                        _this._leftController = null;
                     }
                     }
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     if (controllerIndex !== -1) {
                     if (controllerIndex !== -1) {
@@ -80646,7 +80684,7 @@ var BABYLON;
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                     var webVrController_1 = gamepad;
                     var webVrController_1 = gamepad;
-                    webVrController_1._deviceToWorld = _this._deviceToWorld;
+                    webVrController_1._deviceToWorld.copyFrom(_this._deviceToWorld);
                     if (_this.webVROptions.controllerMeshes) {
                     if (_this.webVROptions.controllerMeshes) {
                         if (webVrController_1.defaultModel) {
                         if (webVrController_1.defaultModel) {
                             webVrController_1.defaultModel.setEnabled(true);
                             webVrController_1.defaultModel.setEnabled(true);
@@ -87109,7 +87147,7 @@ var BABYLON;
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._target = BABYLON.Vector3.Zero();
             this._target = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
-            this.invertYAxis = false;
+            this._invertYAxis = false;
             this.position = BABYLON.Vector3.Zero();
             this.position = BABYLON.Vector3.Zero();
             this._scene = scene;
             this._scene = scene;
             this._scene.reflectionProbes.push(this);
             this._scene.reflectionProbes.push(this);
@@ -87123,10 +87161,10 @@ var BABYLON;
                         _this._add.copyFromFloats(-1, 0, 0);
                         _this._add.copyFromFloats(-1, 0, 0);
                         break;
                         break;
                     case 2:
                     case 2:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? 1 : -1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? 1 : -1, 0);
                         break;
                         break;
                     case 3:
                     case 3:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? -1 : 1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? -1 : 1, 0);
                         break;
                         break;
                     case 4:
                     case 4:
                         _this._add.copyFromFloats(0, 0, 1);
                         _this._add.copyFromFloats(0, 0, 1);

+ 2 - 7
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
 {
-  "errors": 7232,
+  "errors": 7231,
   "babylon.typedoc.json": {
   "babylon.typedoc.json": {
-    "errors": 7232,
+    "errors": 7231,
     "AnimationKeyInterpolation": {
     "AnimationKeyInterpolation": {
       "Enumeration": {
       "Enumeration": {
         "Comments": {
         "Comments": {
@@ -25315,11 +25315,6 @@
             "MissingText": true
             "MissingText": true
           }
           }
         },
         },
-        "invertYAxis": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
         "name": {
         "name": {
           "Comments": {
           "Comments": {
             "MissingText": true
             "MissingText": true

文件差异内容过多而无法显示
+ 37 - 37
dist/preview release/viewer/babylon.viewer.js


+ 50 - 12
dist/preview release/viewer/babylon.viewer.max.js

@@ -24129,7 +24129,6 @@ var BABYLON;
             // Camera
             // Camera
             this.resetCachedMaterial();
             this.resetCachedMaterial();
             this._renderId++;
             this._renderId++;
-            this.activeCamera.update();
             this.updateTransformMatrix();
             this.updateTransformMatrix();
             if (camera._alternateCamera) {
             if (camera._alternateCamera) {
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
                 this.updateAlternateTransformMatrix(camera._alternateCamera);
@@ -24273,10 +24272,6 @@ var BABYLON;
                 this._renderForCamera(camera);
                 this._renderForCamera(camera);
                 return;
                 return;
             }
             }
-            // Update camera
-            if (this.activeCamera) {
-                this.activeCamera.update();
-            }
             // rig cameras
             // rig cameras
             for (var index = 0; index < camera._rigCameras.length; index++) {
             for (var index = 0; index < camera._rigCameras.length; index++) {
                 this._renderForCamera(camera._rigCameras[index], camera);
                 this._renderForCamera(camera._rigCameras[index], camera);
@@ -24389,6 +24384,28 @@ var BABYLON;
             }
             }
             // Before render
             // Before render
             this.onBeforeRenderObservable.notifyObservers(this);
             this.onBeforeRenderObservable.notifyObservers(this);
+            // Update Cameras
+            if (this.activeCameras.length > 0) {
+                for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
+                    var camera = this.activeCameras[cameraIndex];
+                    camera.update();
+                    if (camera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                        // rig cameras
+                        for (var index = 0; index < camera._rigCameras.length; index++) {
+                            camera._rigCameras[index].update();
+                        }
+                    }
+                }
+            }
+            else if (this.activeCamera) {
+                this.activeCamera.update();
+                if (this.activeCamera.cameraRigMode !== BABYLON.Camera.RIG_MODE_NONE) {
+                    // rig cameras
+                    for (var index = 0; index < this.activeCamera._rigCameras.length; index++) {
+                        this.activeCamera._rigCameras[index].update();
+                    }
+                }
+            }
             // Customs render targets
             // Customs render targets
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             this.OnBeforeRenderTargetsRenderObservable.notifyObservers(this);
             var engine = this.getEngine();
             var engine = this.getEngine();
@@ -59875,6 +59892,11 @@ var BABYLON;
             var maxSize = engine.getCaps().maxTextureSize;
             var maxSize = engine.getCaps().maxTextureSize;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
             var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
+            // If rendering to a webvr camera's left or right eye only half the width should be used to avoid resize when rendered to screen
+            var webVRCamera = camera.parent;
+            if (webVRCamera && (webVRCamera.leftCamera == camera || webVRCamera.rightCamera == camera)) {
+                requiredWidth /= 2;
+            }
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredWidth = (this._options.width || requiredWidth);
             var desiredHeight = this._options.height || requiredHeight;
             var desiredHeight = this._options.height || requiredHeight;
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
             if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
@@ -66741,6 +66763,7 @@ var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var PostProcessRenderPipeline = /** @class */ (function () {
     var PostProcessRenderPipeline = /** @class */ (function () {
         function PostProcessRenderPipeline(engine, name) {
         function PostProcessRenderPipeline(engine, name) {
+            this.engine = engine;
             this._name = name;
             this._name = name;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
@@ -66840,6 +66863,18 @@ var BABYLON;
             this._renderEffects = {};
             this._renderEffects = {};
             this._renderEffectsForIsolatedPass = new Array();
             this._renderEffectsForIsolatedPass = new Array();
         };
         };
+        PostProcessRenderPipeline.prototype._enableMSAAOnFirstPostProcess = function () {
+            // Set samples of the very first post process to 4 to enable native anti-aliasing in browsers that support webGL 2.0 (See: https://github.com/BabylonJS/Babylon.js/issues/3754)
+            var effectKeys = Object.keys(this._renderEffects);
+            if (this.engine.webGLVersion >= 2 && effectKeys.length > 0) {
+                var postProcesses = this._renderEffects[effectKeys[0]].getPostProcesses();
+                if (postProcesses) {
+                    postProcesses[0].samples = 4;
+                    return true;
+                }
+            }
+            return false;
+        };
         PostProcessRenderPipeline.prototype.dispose = function () {
         PostProcessRenderPipeline.prototype.dispose = function () {
             // Must be implemented by children 
             // Must be implemented by children 
         };
         };
@@ -69189,6 +69224,7 @@ var BABYLON;
             if (this._cameras !== null) {
             if (this._cameras !== null) {
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
                 this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
             }
             }
+            this._enableMSAAOnFirstPostProcess();
         };
         };
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
         DefaultRenderingPipeline.prototype._disposePostProcesses = function () {
             for (var i = 0; i < this._cameras.length; i++) {
             for (var i = 0; i < this._cameras.length; i++) {
@@ -80625,7 +80661,7 @@ var BABYLON;
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 this._deviceToWorld.invertToRef(this._worldToDevice);
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 // Update the gamepad to ensure the mesh is updated on the same frame as camera
                 this.controllers.forEach(function (controller) {
                 this.controllers.forEach(function (controller) {
-                    controller._deviceToWorld = _this._deviceToWorld;
+                    controller._deviceToWorld.copyFrom(_this._deviceToWorld);
                     controller.update();
                     controller.update();
                 });
                 });
             }
             }
@@ -80659,6 +80695,9 @@ var BABYLON;
          */
          */
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
         WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
             var _this = this;
             var _this = this;
+            // Update the parent camera prior to using a child camera to avoid desynchronization
+            var parentCamera = this._cameraRigParams["parentCamera"];
+            parentCamera._updateCache();
             //WebVR 1.1
             //WebVR 1.1
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
             BABYLON.Matrix.FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
@@ -80672,7 +80711,6 @@ var BABYLON;
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
             // Computing target and final matrix
             // Computing target and final matrix
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
             this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
-            var parentCamera = this._cameraRigParams["parentCamera"];
             // should the view matrix be updated with scale and position offset?
             // should the view matrix be updated with scale and position offset?
             if (parentCamera.deviceScaleFactor !== 1) {
             if (parentCamera.deviceScaleFactor !== 1) {
                 this._webvrViewMatrix.invert();
                 this._webvrViewMatrix.invert();
@@ -80719,7 +80757,7 @@ var BABYLON;
                         _this._rightController = null;
                         _this._rightController = null;
                     }
                     }
                     if (webVrController.hand === "left") {
                     if (webVrController.hand === "left") {
-                        _this._rightController = null;
+                        _this._leftController = null;
                     }
                     }
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     var controllerIndex = _this.controllers.indexOf(webVrController);
                     if (controllerIndex !== -1) {
                     if (controllerIndex !== -1) {
@@ -80730,7 +80768,7 @@ var BABYLON;
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                     var webVrController_1 = gamepad;
                     var webVrController_1 = gamepad;
-                    webVrController_1._deviceToWorld = _this._deviceToWorld;
+                    webVrController_1._deviceToWorld.copyFrom(_this._deviceToWorld);
                     if (_this.webVROptions.controllerMeshes) {
                     if (_this.webVROptions.controllerMeshes) {
                         if (webVrController_1.defaultModel) {
                         if (webVrController_1.defaultModel) {
                             webVrController_1.defaultModel.setEnabled(true);
                             webVrController_1.defaultModel.setEnabled(true);
@@ -87193,7 +87231,7 @@ var BABYLON;
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._viewMatrix = BABYLON.Matrix.Identity();
             this._target = BABYLON.Vector3.Zero();
             this._target = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
             this._add = BABYLON.Vector3.Zero();
-            this.invertYAxis = false;
+            this._invertYAxis = false;
             this.position = BABYLON.Vector3.Zero();
             this.position = BABYLON.Vector3.Zero();
             this._scene = scene;
             this._scene = scene;
             this._scene.reflectionProbes.push(this);
             this._scene.reflectionProbes.push(this);
@@ -87207,10 +87245,10 @@ var BABYLON;
                         _this._add.copyFromFloats(-1, 0, 0);
                         _this._add.copyFromFloats(-1, 0, 0);
                         break;
                         break;
                     case 2:
                     case 2:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? 1 : -1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? 1 : -1, 0);
                         break;
                         break;
                     case 3:
                     case 3:
-                        _this._add.copyFromFloats(0, _this.invertYAxis ? -1 : 1, 0);
+                        _this._add.copyFromFloats(0, _this._invertYAxis ? -1 : 1, 0);
                         break;
                         break;
                     case 4:
                     case 4:
                         _this._add.copyFromFloats(0, 0, 1);
                         _this._add.copyFromFloats(0, 0, 1);

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

@@ -6,7 +6,7 @@
 - Improved building process: We now run a full visual validation test for each pull request. Furthermore, code comments and what's new updates are now mandatory ([sebavan](https://github.com/sebavan))
 - Improved building process: We now run a full visual validation test for each pull request. Furthermore, code comments and what's new updates are now mandatory ([sebavan](https://github.com/sebavan))
 - Introduced texture binding atlas. This optimization allows the engine to reuse texture bindings instead of rebinding textures when they are not on constant sampler indexes ([deltakosh](https://github.com/deltakosh))
 - Introduced texture binding atlas. This optimization allows the engine to reuse texture bindings instead of rebinding textures when they are not on constant sampler indexes ([deltakosh](https://github.com/deltakosh))
 - New [AnimationGroup class](http://doc.babylonjs.com/how_to/group) to control simultaneously multiple animations with different targets ([deltakosh](https://github.com/deltakosh))
 - New [AnimationGroup class](http://doc.babylonjs.com/how_to/group) to control simultaneously multiple animations with different targets ([deltakosh](https://github.com/deltakosh))
-- `WebVRCamera` now supports GearVR ([brianzinn](https://github.com/brianzinn))
+- `WebVRCamera` add basic support for Daydream and Gear VR ([brianzinn](https://github.com/brianzinn))
 - New glTF [serializer](https://github.com/BabylonJS/Babylon.js/tree/master/serializers/src/glTF/2.0). You can now export glTF or glb files directly from a Babylon scene ([kcoley](https://github.com/kcoley))
 - New glTF [serializer](https://github.com/BabylonJS/Babylon.js/tree/master/serializers/src/glTF/2.0). You can now export glTF or glb files directly from a Babylon scene ([kcoley](https://github.com/kcoley))
 - Babylon.js now uses Promises in addition to callbacks. We created several `xxxAsync` functions all over the framework (`SceneLoader.AppendAsync` for instance, which returns a Promise). A polyfill is also integrated to support older browsers ([deltakosh](https://github.com/deltakosh))
 - Babylon.js now uses Promises in addition to callbacks. We created several `xxxAsync` functions all over the framework (`SceneLoader.AppendAsync` for instance, which returns a Promise). A polyfill is also integrated to support older browsers ([deltakosh](https://github.com/deltakosh))
 - Introduced [Projection Texture on SpotLight](http://doc.babylonjs.com/babylon101/lights#projection-texture) ([lostink](https://github.com/lostink))
 - Introduced [Projection Texture on SpotLight](http://doc.babylonjs.com/babylon101/lights#projection-texture) ([lostink](https://github.com/lostink))
@@ -80,8 +80,8 @@
 - Support depth maps for multiple active cameras for post processes like depth of field ([trevordev](https://github.com/trevordev))
 - Support depth maps for multiple active cameras for post processes like depth of field ([trevordev](https://github.com/trevordev))
 - Integrates depth texture support in the engine ([sebavan](https://github.com/sebavan))
 - Integrates depth texture support in the engine ([sebavan](https://github.com/sebavan))
 - NPM package now has a dependency system, updated during build. ([RaananW](https://github.com/RaananW))
 - NPM package now has a dependency system, updated during build. ([RaananW](https://github.com/RaananW))
-- Default pipeline will use webGL 2.0 anti aliasing by default if supported, webVR post processing will render to eye texture size ([trevordev](https://github.com/trevordev))
 - WebVRExperienceHelper will create an empty controller model so that controller interactions can be used while the actual model is still loading ([trevordev](https://github.com/trevordev))
 - WebVRExperienceHelper will create an empty controller model so that controller interactions can be used while the actual model is still loading ([trevordev](https://github.com/trevordev))
+- Default pipeline will use webGL 2.0 anti aliasing by default if supported, default fragment shader will clamp negative values to avoid underflow, webVR post processing will render to eye texture size ([trevordev](https://github.com/trevordev))
 
 
 ## Bug fixes
 ## Bug fixes
 
 

+ 3 - 2
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -706,8 +706,9 @@ module BABYLON.GLTF2 {
             };
             };
 
 
             if (skin._loaded) {
             if (skin._loaded) {
-                assignSkeleton();
-                return skin._loaded;
+                return skin._loaded.then(() => {
+                    assignSkeleton();
+                });
             }
             }
 
 
             // TODO: split into two parts so that bones are created before inverseBindMatricesData is loaded (for compiling materials).
             // TODO: split into two parts so that bones are created before inverseBindMatricesData is loaded (for compiling materials).

+ 50 - 0
src/Gamepad/Controllers/babylon.daydreamController.ts

@@ -0,0 +1,50 @@
+module BABYLON {
+    /**
+     * Google Daydream controller
+     */
+    export class DaydreamController extends WebVRController {
+        /**
+         * Base Url for the controller model.
+         */
+        public static MODEL_BASE_URL: string = 'https://controllers.babylonjs.com/generic/';
+
+        /**
+         * File name for the controller model.
+         */
+        public static MODEL_FILENAME: string = 'generic.babylon';
+
+        /**
+         * Gamepad Id prefix used to identify Daydream Controller.
+         */
+        public static readonly GAMEPAD_ID_PREFIX: string = 'Daydream'; // id is 'Daydream Controller'
+
+        constructor(vrGamepad: any) {
+            super(vrGamepad);
+            this.controllerType = PoseEnabledControllerType.DAYDREAM;
+        }
+
+        public initControllerMesh(scene: Scene, meshLoaded?: (mesh: AbstractMesh) => void) {
+            SceneLoader.ImportMesh("", DaydreamController.MODEL_BASE_URL, DaydreamController.MODEL_FILENAME, scene, (newMeshes) => {
+                this._defaultModel = newMeshes[1];
+                this.attachToMesh(this._defaultModel);
+
+                if (meshLoaded) {
+                    meshLoaded(this._defaultModel);
+                }
+            });
+        }
+
+        protected _handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
+            // Daydream controller only has 1 GamepadButton (on the trackpad).
+            if (buttonIdx === 0) {
+                let observable = this.onTriggerStateChangedObservable;
+                if (observable) {
+                    observable.notifyObservers(state);
+                }
+            } else {
+                // If the app or home buttons are ever made available
+                Tools.Warn(`Unrecognized Daydream button index: ${buttonIdx}`)
+            }
+        }
+    }
+}

+ 1 - 1
src/Gamepad/Controllers/babylon.gearVRController.ts

@@ -26,7 +26,7 @@ module BABYLON {
             });
             });
         }
         }
 
 
-        protected handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
+        protected _handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
             if (buttonIdx < this._buttonIndexToObservableNameMap.length) {
             if (buttonIdx < this._buttonIndexToObservableNameMap.length) {
                 const observableName : string = this._buttonIndexToObservableNameMap[buttonIdx];
                 const observableName : string = this._buttonIndexToObservableNameMap[buttonIdx];
                 
                 

+ 1 - 1
src/Gamepad/Controllers/babylon.genericController.ts

@@ -18,7 +18,7 @@ module BABYLON {
             });
             });
         }
         }
 
 
-        protected handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
+        protected _handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
             console.log("Button id: " + buttonIdx + "state: ");
             console.log("Button id: " + buttonIdx + "state: ");
             console.dir(state);
             console.dir(state);
         }
         }

+ 1 - 1
src/Gamepad/Controllers/babylon.oculusTouchController.ts

@@ -87,7 +87,7 @@ module BABYLON {
          4) B / Y 
          4) B / Y 
          5) thumb rest
          5) thumb rest
         */
         */
-        protected handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
+        protected _handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
             let notifyObject = state; //{ state: state, changes: changes };
             let notifyObject = state; //{ state: state, changes: changes };
             let triggerDirection = this.hand === 'right' ? -1 : 1;
             let triggerDirection = this.hand === 'right' ? -1 : 1;
             switch (buttonIdx) {
             switch (buttonIdx) {

+ 8 - 1
src/Gamepad/Controllers/babylon.poseEnabledController.ts

@@ -5,6 +5,10 @@ module BABYLON {
         OCULUS,
         OCULUS,
         WINDOWS,
         WINDOWS,
         GEAR_VR,
         GEAR_VR,
+        /**
+         * Google Daydream
+         */
+        DAYDREAM,
         GENERIC
         GENERIC
     }
     }
 
 
@@ -38,6 +42,10 @@ module BABYLON {
             else if (vrGamepad.id.indexOf(GearVRController.GAMEPAD_ID_PREFIX) === 0) {
             else if (vrGamepad.id.indexOf(GearVRController.GAMEPAD_ID_PREFIX) === 0) {
                 return new GearVRController(vrGamepad);
                 return new GearVRController(vrGamepad);
             }
             }
+            // Google Daydream
+            else if (vrGamepad.id.indexOf(DaydreamController.GAMEPAD_ID_PREFIX) === 0) {
+                return new DaydreamController(vrGamepad);
+            }
             // Generic 
             // Generic 
             else {
             else {
                 return new GenericController(vrGamepad);
                 return new GenericController(vrGamepad);
@@ -120,7 +128,6 @@ module BABYLON {
 
 
                     this._deviceRoomPosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
                     this._deviceRoomPosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
                     this._calculatedPosition.addInPlace(this.position);
                     this._calculatedPosition.addInPlace(this.position);
-
                 }
                 }
                 let pose = this.rawPose;
                 let pose = this.rawPose;
                 if (poseData.orientation && pose.orientation) {
                 if (poseData.orientation && pose.orientation) {

+ 1 - 1
src/Gamepad/Controllers/babylon.viveController.ts

@@ -50,7 +50,7 @@ module BABYLON {
          * 2: left AND right buttons
          * 2: left AND right buttons
          * 3: menu button
          * 3: menu button
          */
          */
-        protected handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
+        protected _handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
             let notifyObject = state; //{ state: state, changes: changes };
             let notifyObject = state; //{ state: state, changes: changes };
             switch (buttonIdx) {
             switch (buttonIdx) {
                 case 0:
                 case 0:

+ 2 - 2
src/Gamepad/Controllers/babylon.webVRController.ts

@@ -45,7 +45,7 @@ module BABYLON {
             }
             }
         }
         }
 
 
-        protected abstract handleButtonChange(buttonIdx: number, value: ExtendedGamepadButton, changes: GamepadButtonChanges): void;
+        protected abstract _handleButtonChange(buttonIdx: number, value: ExtendedGamepadButton, changes: GamepadButtonChanges): void;
 
 
         public abstract initControllerMesh(scene: Scene, meshLoaded?: (mesh: AbstractMesh) => void): void;
         public abstract initControllerMesh(scene: Scene, meshLoaded?: (mesh: AbstractMesh) => void): void;
 
 
@@ -69,7 +69,7 @@ module BABYLON {
             if (this._changes.changed) {
             if (this._changes.changed) {
                 this._onButtonStateChange && this._onButtonStateChange(this.index, buttonIndex, newState);
                 this._onButtonStateChange && this._onButtonStateChange(this.index, buttonIndex, newState);
 
 
-                this.handleButtonChange(buttonIndex, newState, this._changes);
+                this._handleButtonChange(buttonIndex, newState, this._changes);
             }
             }
             this._buttons[buttonIndex].pressed = newState.pressed;
             this._buttons[buttonIndex].pressed = newState.pressed;
             this._buttons[buttonIndex].touched = newState.touched;
             this._buttons[buttonIndex].touched = newState.touched;

+ 1 - 1
src/Gamepad/Controllers/babylon.windowsMotionController.ts

@@ -125,7 +125,7 @@ module BABYLON {
          * @param state New state of the button
          * @param state New state of the button
          * @param changes Which properties on the state changed since last frame
          * @param changes Which properties on the state changed since last frame
          */
          */
-        protected handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
+        protected _handleButtonChange(buttonIdx: number, state: ExtendedGamepadButton, changes: GamepadButtonChanges) {
             let buttonName = this._mapping.buttons[buttonIdx];
             let buttonName = this._mapping.buttons[buttonIdx];
             if (!buttonName) {
             if (!buttonName) {
                 return;
                 return;

+ 1 - 1
src/Shaders/default.fragment.fx

@@ -418,7 +418,7 @@ void main(void) {
 #endif
 #endif
 
 
 #define CUSTOM_FRAGMENT_BEFORE_FOG
 #define CUSTOM_FRAGMENT_BEFORE_FOG
-
+color.rgb = max(color.rgb, 0.);
 #include<logDepthFragment>
 #include<logDepthFragment>
 #include<fogFragment>
 #include<fogFragment>
 
 

+ 23 - 0
tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.ts

@@ -181,6 +181,29 @@ describe('Babylon Scene Loader', function () {
             return Promise.all([promise, deferred.promise, scene.whenReadyAsync()]);
             return Promise.all([promise, deferred.promise, scene.whenReadyAsync()]);
         });
         });
 
 
+        it('Load Alien', () => {
+            const scene = new BABYLON.Scene(subject);
+            return BABYLON.SceneLoader.ImportMeshAsync(null, "/Playground/scenes/Alien/", "Alien.gltf", scene).then(result => {
+                expect(result.skeletons.length, "skeletons.length").to.equal(scene.skeletons.length);
+
+                const mapping = {
+                    "AlienHead_0": "skeleton0",
+                    "Collar_0": "skeleton1",
+                    "LeftEye_0": "skeleton2",
+                    "RightEye_0": "skeleton3",
+                    "CollarClasp_0": "skeleton1",
+                    "Shirt_0": "skeleton1",
+                    "ShirtPlate_0": "skeleton1",
+                    "Teeth_0": "skeleton1",
+                };
+
+                for (const meshName in mapping) {
+                    const skeletonName = mapping[meshName];
+                    expect(scene.getMeshByName(meshName).skeleton.name, `skeleton name of mesh '${meshName}'`).to.equal(skeletonName);
+                }
+            });
+        });
+
         // TODO: test material instancing
         // TODO: test material instancing
         // TODO: test ImportMesh with specific node name
         // TODO: test ImportMesh with specific node name
         // TODO: test KHR_materials_pbrSpecularGlossiness
         // TODO: test KHR_materials_pbrSpecularGlossiness