Forráskód Böngészése

Merge pull request #3326 from BabylonJS/master

Merge
David Catuhe 7 éve
szülő
commit
4edcc2028f
40 módosított fájl, 4486 hozzáadás és 2770 törlés
  1. 1038 1025
      Playground/babylon.d.txt
  2. 4 0
      Tools/Publisher/index.js
  3. 1 0
      Viewer/assets/templates/default/loadingScreen.html
  4. 1897 500
      Viewer/dist/viewer.js
  5. 1 38
      Viewer/dist/viewer.min.js
  6. 0 3
      Viewer/package.json
  7. 1 0
      Viewer/src/configuration/configuration.ts
  8. 1 2
      Viewer/src/index.ts
  9. 53 8
      Viewer/src/viewer/defaultViewer.ts
  10. 0 3
      Viewer/tsconfig-gulp.json
  11. 1 2
      Viewer/tsconfig.json
  12. 968 954
      dist/preview release/babylon.d.ts
  13. 17 17
      dist/preview release/babylon.js
  14. 90 25
      dist/preview release/babylon.max.js
  15. 15 15
      dist/preview release/babylon.worker.js
  16. 18 17
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  17. 92 27
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  18. 1 1
      dist/preview release/gui/package.json
  19. 1 1
      dist/preview release/inspector/package.json
  20. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  21. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  22. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.js
  23. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  24. 2 2
      dist/preview release/loaders/babylonjs.loaders.js
  25. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  26. 1 1
      dist/preview release/loaders/package.json
  27. 1 1
      dist/preview release/materialsLibrary/package.json
  28. 1 1
      dist/preview release/postProcessesLibrary/package.json
  29. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  30. 1 1
      dist/preview release/serializers/package.json
  31. 60 67
      dist/preview release/viewer/babylon.viewer.js
  32. 32 0
      dist/preview release/viewer/package.json
  33. 56 0
      dist/preview release/viewer/readme.md
  34. 15 15
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  35. 1 1
      package.json
  36. 2 2
      sandbox/index.js
  37. 6 2
      src/Cameras/VR/babylon.vrExperienceHelper.ts
  38. 72 14
      src/Cameras/VR/babylon.webVRCamera.ts
  39. 1 1
      src/Engine/babylon.engine.ts
  40. 27 15
      src/Gamepad/Controllers/babylon.poseEnabledController.ts

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1038 - 1025
Playground/babylon.d.txt


+ 4 - 0
Tools/Publisher/index.js

@@ -39,6 +39,10 @@ let packages = [
     {
         name: 'inspector',
         path: basePath + '/inspector/'
+    },
+    {
+        name: 'viewer',
+        path: basePath + '/viewer/'
     }
 ];
 

+ 1 - 0
Viewer/assets/templates/default/loadingScreen.html

@@ -3,6 +3,7 @@
 
     loading-screen {
         position: absolute;
+        left: 0;
         z-index: 100;
         opacity: 1;
         pointer-events: none;

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1897 - 500
Viewer/dist/viewer.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 38
Viewer/dist/viewer.min.js


+ 0 - 3
Viewer/package.json

@@ -36,9 +36,6 @@
     "dependencies": {
         "babylonjs": "^3.1.0-beta6",
         "babylonjs-loaders": "^3.1.0-beta6",
-        "babylonjs-materials": "^3.1.0-beta6",
-        "babylonjs-post-process": "^3.1.0-beta6",
-        "babylonjs-procedural-textures": "^3.1.0-beta6",
         "deepmerge": "^2.0.1",
         "es6-promise": "^4.1.1",
         "handlebars": "^4.0.11"

+ 1 - 0
Viewer/src/configuration/configuration.ts

@@ -98,6 +98,7 @@ export interface ViewerConfiguration {
         size?: number;
         receiveShadows?: boolean;
         shadowOnly?: boolean;
+        mirror?: boolean;
         material?: {
             [propName: string]: any;
         }

+ 1 - 2
Viewer/src/index.ts

@@ -13,13 +13,12 @@ import { AbstractViewer } from './viewer/viewer';
 // load babylon and needed modules.
 import 'babylonjs';
 import 'babylonjs-loaders';
-import 'babylonjs-materials';
 import '../assets/pep.min';
 
 import { InitTags } from './initializer';
 
 // promise polyfill, if needed!
-global.Promise = Promise || require('es6-promise').Promise;
+global.Promise = typeof Promise === 'undefined' ? require('es6-promise').Promise : Promise;
 
 export let disableInit: boolean = false;
 document.addEventListener("DOMContentLoaded", function (event) {

+ 53 - 8
Viewer/src/viewer/defaultViewer.ts

@@ -3,11 +3,9 @@
 import { ViewerConfiguration } from './../configuration/configuration';
 import { Template } from './../templateManager';
 import { AbstractViewer } from './viewer';
-import { ShadowGenerator, Observable, ShadowLight, CubeTexture, BouncingBehavior, FramingBehavior, Behavior, Light, Engine, Scene, AutoRotationBehavior, AbstractMesh, Quaternion, StandardMaterial, ArcRotateCamera, ImageProcessingConfiguration, Color3, Vector3, SceneLoader, Mesh, HemisphericLight } from 'babylonjs';
+import { MirrorTexture, Plane, ShadowGenerator, Texture, BackgroundMaterial, Observable, ShadowLight, CubeTexture, BouncingBehavior, FramingBehavior, Behavior, Light, Engine, Scene, AutoRotationBehavior, AbstractMesh, Quaternion, StandardMaterial, ArcRotateCamera, ImageProcessingConfiguration, Color3, Vector3, SceneLoader, Mesh, HemisphericLight } from 'babylonjs';
 import { CameraBehavior } from '../interfaces';
 
-import { ShadowOnlyMaterial } from 'babylonjs-materials';
-
 export class DefaultViewer extends AbstractViewer {
 
     public camera: ArcRotateCamera;
@@ -158,7 +156,7 @@ export class DefaultViewer extends AbstractViewer {
         this.setupCamera(meshes);
         this.setupLights(meshes);
 
-        return this.initEnvironment();
+        return this.initEnvironment(meshes);
     }
 
     private setModelMetaData() {
@@ -190,7 +188,7 @@ export class DefaultViewer extends AbstractViewer {
 
     }
 
-    public initEnvironment(): Promise<Scene> {
+    public initEnvironment(focusMeshes: Array<AbstractMesh> = []): Promise<Scene> {
         if (this.configuration.skybox) {
             // Define a general environment textue
             let texture;
@@ -215,17 +213,62 @@ export class DefaultViewer extends AbstractViewer {
                 }
 
                 this.extendClassWithConfig(box, this.configuration.skybox);
+
+                box && focusMeshes.push(box);
             }
         }
 
         if (this.configuration.ground) {
             let groundConfig = (typeof this.configuration.ground === 'boolean') ? {} : this.configuration.ground;
 
-            var ground = Mesh.CreateGround('ground', groundConfig.size || 1000, groundConfig.size || 1000, 8, this.scene);
+            let groundSize = groundConfig.size || (this.configuration.skybox && this.configuration.skybox.scale) || 3000;
+
+            let ground = Mesh.CreatePlane("BackgroundPlane", groundSize, this.scene);
+            let backgroundMaterial = new BackgroundMaterial('groundmat', this.scene);
+            ground.rotation.x = Math.PI / 2; // Face up by default.
+            ground.receiveShadows = groundConfig.receiveShadows || false;
+
+            // default values
+            backgroundMaterial.alpha = 0.9;
+            backgroundMaterial.alphaMode = Engine.ALPHA_PREMULTIPLIED_PORTERDUFF;
+            backgroundMaterial.shadowLevel = 0.5;
+            backgroundMaterial.primaryLevel = 1;
+            backgroundMaterial.primaryColor = new Color3(0.2, 0.2, 0.3).toLinearSpace().scale(3);
+            backgroundMaterial.secondaryLevel = 0;
+            backgroundMaterial.tertiaryLevel = 0;
+            backgroundMaterial.useRGBColor = false;
+            backgroundMaterial.enableNoise = true;
+
+            // if config provided, extend the default values
+            if (groundConfig.material) {
+                this.extendClassWithConfig(ground, ground.material);
+            }
+
+            ground.material = backgroundMaterial;
             if (this.configuration.ground === true || groundConfig.shadowOnly) {
-                ground.material = new ShadowOnlyMaterial('groundmat', this.scene);
+                // shadow only:
+                ground.receiveShadows = true;
+                const diffuseTexture = new Texture("https://assets.babylonjs.com/environments/backgroundGround.png", this.scene);
+                diffuseTexture.gammaSpace = false;
+                diffuseTexture.hasAlpha = true;
+                backgroundMaterial.diffuseTexture = diffuseTexture;
+            } else if (groundConfig.mirror) {
+                var mirror = new MirrorTexture("mirror", 512, this.scene);
+                mirror.mirrorPlane = new Plane(0, -1, 0, 0);
+                mirror.renderList = mirror.renderList || [];
+                focusMeshes.length && focusMeshes.forEach(m => {
+                    m && mirror.renderList && mirror.renderList.push(m);
+                });
+
+                backgroundMaterial.reflectionTexture = mirror;
             } else {
-                ground.material = new StandardMaterial('groundmat', this.scene);
+                if (groundConfig.material) {
+                    if (groundConfig.material.diffuseTexture) {
+                        const diffuseTexture = new Texture(groundConfig.material.diffuseTexture, this.scene);
+                        backgroundMaterial.diffuseTexture = diffuseTexture;
+                    }
+                }
+                // ground.material = new StandardMaterial('groundmat', this.scene);
             }
             //default configuration
             if (this.configuration.ground === true) {
@@ -235,6 +278,8 @@ export class DefaultViewer extends AbstractViewer {
             }
 
 
+
+
             this.extendClassWithConfig(ground, groundConfig);
         }
 

+ 0 - 3
Viewer/tsconfig-gulp.json

@@ -24,9 +24,6 @@
             "babylonjs": [
                 "../dist/preview release/babylon.max.js"
             ],
-            "babylonjs-materials": [
-                "../dist/preview release/materialsLibrary/babylonjs.materials.js"
-            ],
             "babylonjs-loaders": [
                 "../dist/preview release/loaders/babylonjs.loaders.js"
             ]

+ 1 - 2
Viewer/tsconfig.json

@@ -20,8 +20,7 @@
         "types": [
             "node",
             "babylonjs",
-            "babylonjs-loaders",
-            "babylonjs-materials"
+            "babylonjs-loaders"
         ]
     }
 }

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 968 - 954
dist/preview release/babylon.d.ts


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 17 - 17
dist/preview release/babylon.js


+ 90 - 25
dist/preview release/babylon.max.js

@@ -8588,7 +8588,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.1-beta-6";
+                return "3.1-rc-0";
             },
             enumerable: true,
             configurable: true
@@ -57064,14 +57064,20 @@ var BABYLON;
         __extends(PoseEnabledController, _super);
         function PoseEnabledController(browserGamepad) {
             var _this = _super.call(this, browserGamepad.id, browserGamepad.index, browserGamepad) || this;
+            // Represents device position and rotation in room space. Should only be used to help calculate babylon space values
+            _this._deviceRoomPosition = BABYLON.Vector3.Zero();
+            _this._deviceRoomRotationQuaternion = new BABYLON.Quaternion();
+            // Represents device position and rotation in babylon space
+            _this.devicePosition = BABYLON.Vector3.Zero();
+            _this.deviceRotationQuaternion = new BABYLON.Quaternion();
             _this.deviceScaleFactor = 1;
             _this._leftHandSystemQuaternion = new BABYLON.Quaternion();
+            _this._deviceToWorld = BABYLON.Matrix.Identity();
+            _this._workingMatrix = BABYLON.Matrix.Identity();
             _this.type = BABYLON.Gamepad.POSE_ENABLED;
             _this.controllerType = PoseEnabledControllerType.GENERIC;
             _this.position = BABYLON.Vector3.Zero();
             _this.rotationQuaternion = new BABYLON.Quaternion();
-            _this.devicePosition = BABYLON.Vector3.Zero();
-            _this.deviceRotationQuaternion = new BABYLON.Quaternion();
             _this._calculatedPosition = BABYLON.Vector3.Zero();
             _this._calculatedRotation = new BABYLON.Quaternion();
             BABYLON.Quaternion.RotationYawPitchRollToRef(Math.PI, 0, 0, _this._leftHandSystemQuaternion);
@@ -57081,10 +57087,13 @@ var BABYLON;
             _super.prototype.update.call(this);
             var pose = this.browserGamepad.pose;
             this.updateFromDevice(pose);
+            BABYLON.Vector3.TransformCoordinatesToRef(this._calculatedPosition, this._deviceToWorld, this.devicePosition);
+            this._deviceToWorld.getRotationMatrixToRef(this._workingMatrix);
+            BABYLON.Quaternion.FromRotationMatrixToRef(this._workingMatrix, this.deviceRotationQuaternion);
             if (this._mesh) {
-                this._mesh.position.copyFrom(this._calculatedPosition);
+                this._mesh.position.copyFrom(this.devicePosition);
                 if (this._mesh.rotationQuaternion) {
-                    this._mesh.rotationQuaternion.copyFrom(this._calculatedRotation);
+                    this._mesh.rotationQuaternion.copyFrom(this.deviceRotationQuaternion.multiplyInPlace(this._calculatedRotation));
                 }
             }
         };
@@ -57092,27 +57101,27 @@ var BABYLON;
             if (poseData) {
                 this.rawPose = poseData;
                 if (poseData.position) {
-                    this.devicePosition.copyFromFloats(poseData.position[0], poseData.position[1], -poseData.position[2]);
+                    this._deviceRoomPosition.copyFromFloats(poseData.position[0], poseData.position[1], -poseData.position[2]);
                     if (this._mesh && this._mesh.getScene().useRightHandedSystem) {
-                        this.devicePosition.z *= -1;
+                        this._deviceRoomPosition.z *= -1;
                     }
-                    this.devicePosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
+                    this._deviceRoomPosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
                     this._calculatedPosition.addInPlace(this.position);
                 }
                 var pose = this.rawPose;
                 if (poseData.orientation && pose.orientation) {
-                    this.deviceRotationQuaternion.copyFromFloats(pose.orientation[0], pose.orientation[1], -pose.orientation[2], -pose.orientation[3]);
+                    this._deviceRoomRotationQuaternion.copyFromFloats(pose.orientation[0], pose.orientation[1], -pose.orientation[2], -pose.orientation[3]);
                     if (this._mesh) {
                         if (this._mesh.getScene().useRightHandedSystem) {
-                            this.deviceRotationQuaternion.z *= -1;
-                            this.deviceRotationQuaternion.w *= -1;
+                            this._deviceRoomRotationQuaternion.z *= -1;
+                            this._deviceRoomRotationQuaternion.w *= -1;
                         }
                         else {
-                            this.deviceRotationQuaternion.multiplyToRef(this._leftHandSystemQuaternion, this.deviceRotationQuaternion);
+                            this._deviceRoomRotationQuaternion.multiplyToRef(this._leftHandSystemQuaternion, this._deviceRoomRotationQuaternion);
                         }
                     }
                     // if the camera is set, rotate to the camera's rotation
-                    this.deviceRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
+                    this._deviceRoomRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
                 }
             }
         };
@@ -71504,12 +71513,23 @@ var BABYLON;
             _this._specsVersion = "1.1";
             _this._attached = false;
             _this._descendants = [];
+            // Represents device position and rotation in room space. Should only be used to help calculate babylon space values
+            _this._deviceRoomPosition = BABYLON.Vector3.Zero();
+            _this._deviceRoomRotationQuaternion = BABYLON.Quaternion.Identity();
+            // Represents device position and rotation in babylon space
             _this.devicePosition = BABYLON.Vector3.Zero();
+            _this.deviceRotationQuaternion = BABYLON.Quaternion.Identity();
             _this.deviceScaleFactor = 1;
+            _this._deviceToWorld = BABYLON.Matrix.Identity();
+            _this._worldToDevice = BABYLON.Matrix.Identity();
             _this.controllers = [];
             _this.onControllersAttachedObservable = new BABYLON.Observable();
             _this.onControllerMeshLoadedObservable = new BABYLON.Observable();
             _this.rigParenting = true; // should the rig cameras be used as parent instead of this camera.
+            _this._workingVector = BABYLON.Vector3.Zero();
+            _this._oneVector = BABYLON.Vector3.One();
+            _this._workingMatrix = BABYLON.Matrix.Identity();
+            _this._cache.position = BABYLON.Vector3.Zero();
             if (webVROptions.defaultHeight) {
                 _this.position.y = webVROptions.defaultHeight;
             }
@@ -71529,7 +71549,6 @@ var BABYLON;
                 _this.webVROptions.defaultLightingOnControllers = true;
             }
             _this.rotationQuaternion = new BABYLON.Quaternion();
-            _this.deviceRotationQuaternion = new BABYLON.Quaternion();
             if (_this.webVROptions && _this.webVROptions.positionScale) {
                 _this.deviceScaleFactor = _this.webVROptions.positionScale;
             }
@@ -71640,15 +71659,15 @@ var BABYLON;
         WebVRFreeCamera.prototype.updateFromDevice = function (poseData) {
             if (poseData && poseData.orientation) {
                 this.rawPose = poseData;
-                this.deviceRotationQuaternion.copyFromFloats(poseData.orientation[0], poseData.orientation[1], -poseData.orientation[2], -poseData.orientation[3]);
+                this._deviceRoomRotationQuaternion.copyFromFloats(poseData.orientation[0], poseData.orientation[1], -poseData.orientation[2], -poseData.orientation[3]);
                 if (this.getScene().useRightHandedSystem) {
-                    this.deviceRotationQuaternion.z *= -1;
-                    this.deviceRotationQuaternion.w *= -1;
+                    this._deviceRoomRotationQuaternion.z *= -1;
+                    this._deviceRoomRotationQuaternion.w *= -1;
                 }
                 if (this.webVROptions.trackPosition && this.rawPose.position) {
-                    this.devicePosition.copyFromFloats(this.rawPose.position[0], this.rawPose.position[1], -this.rawPose.position[2]);
+                    this._deviceRoomPosition.copyFromFloats(this.rawPose.position[0], this.rawPose.position[1], -this.rawPose.position[2]);
                     if (this.getScene().useRightHandedSystem) {
-                        this.devicePosition.z *= -1;
+                        this._deviceRoomPosition.z *= -1;
                     }
                 }
             }
@@ -71690,10 +71709,49 @@ var BABYLON;
         WebVRFreeCamera.prototype._updateRigCameras = function () {
             var camLeft = this._rigCameras[0];
             var camRight = this._rigCameras[1];
-            camLeft.rotationQuaternion.copyFrom(this.deviceRotationQuaternion);
-            camRight.rotationQuaternion.copyFrom(this.deviceRotationQuaternion);
-            camLeft.position.copyFrom(this.devicePosition);
-            camRight.position.copyFrom(this.devicePosition);
+            camLeft.rotationQuaternion.copyFrom(this._deviceRoomRotationQuaternion);
+            camRight.rotationQuaternion.copyFrom(this._deviceRoomRotationQuaternion);
+            camLeft.position.copyFrom(this._deviceRoomPosition);
+            camRight.position.copyFrom(this._deviceRoomPosition);
+        };
+        WebVRFreeCamera.prototype._updateCache = function (ignoreParentClass) {
+            var _this = this;
+            if (!this.rotationQuaternion.equals(this._cache.rotationQuaternion) || !this.position.equals(this._cache.position)) {
+                // Set working vector to the device position in room space rotated by the new rotation
+                this.rotationQuaternion.toRotationMatrix(this._workingMatrix);
+                BABYLON.Vector3.TransformCoordinatesToRef(this._deviceRoomPosition, this._workingMatrix, this._workingVector);
+                // Subtract this vector from the current device position in world to get the translation for the device world matrix
+                this.devicePosition.subtractToRef(this._workingVector, this._workingVector);
+                BABYLON.Matrix.ComposeToRef(this._oneVector, this.rotationQuaternion, this._workingVector, this._deviceToWorld);
+                // Add translation from anchor position
+                this._deviceToWorld.getTranslationToRef(this._workingVector);
+                this._workingVector.addInPlace(this.position);
+                this._workingVector.subtractInPlace(this._cache.position);
+                this._deviceToWorld.setTranslation(this._workingVector);
+                // Set an inverted matrix to be used when updating the camera
+                this._deviceToWorld.invertToRef(this._worldToDevice);
+                // Update the gamepad to ensure the mesh is updated on the same frame as camera
+                this.controllers.forEach(function (controller) {
+                    controller._deviceToWorld = _this._deviceToWorld;
+                    controller.update();
+                });
+                this.update();
+            }
+            if (!ignoreParentClass) {
+                _super.prototype._updateCache.call(this);
+            }
+        };
+        WebVRFreeCamera.prototype.update = function () {
+            // Get current device position in babylon world
+            BABYLON.Vector3.TransformCoordinatesToRef(this._deviceRoomPosition, this._deviceToWorld, this.devicePosition);
+            // Get current device rotation in babylon world
+            BABYLON.Matrix.FromQuaternionToRef(this._deviceRoomRotationQuaternion, this._workingMatrix);
+            this._deviceToWorld.multiplyToRef(this._workingMatrix, this._workingMatrix);
+            BABYLON.Quaternion.FromRotationMatrixToRef(this._workingMatrix, this.deviceRotationQuaternion);
+            _super.prototype.update.call(this);
+        };
+        WebVRFreeCamera.prototype._getViewMatrix = function () {
+            return BABYLON.Matrix.Identity();
         };
         /**
          * This function is called by the two RIG cameras.
@@ -71726,6 +71784,7 @@ var BABYLON;
                 }
                 this._webvrViewMatrix.invert();
             }
+            parentCamera._worldToDevice.multiplyToRef(this._webvrViewMatrix, this._webvrViewMatrix);
             return this._webvrViewMatrix;
         };
         WebVRFreeCamera.prototype._getWebVRProjectionMatrix = function () {
@@ -71768,6 +71827,7 @@ var BABYLON;
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                     var webVrController_1 = gamepad;
+                    webVrController_1._deviceToWorld = _this._deviceToWorld;
                     if (_this.webVROptions.controllerMeshes) {
                         if (webVrController_1.defaultModel) {
                             webVrController_1.defaultModel.setEnabled(true);
@@ -72181,7 +72241,12 @@ var BABYLON;
                 }
                 if (this._btnVR) {
                     this._btnVR.addEventListener("click", function () {
-                        _this.enterVR();
+                        if (!_this.isInVRMode) {
+                            _this.enterVR();
+                        }
+                        else {
+                            _this.exitVR();
+                        }
                     });
                 }
                 window.addEventListener("resize", function () {
@@ -72396,7 +72461,7 @@ var BABYLON;
             this.updateButtonVisibility();
         };
         VRExperienceHelper.prototype.updateButtonVisibility = function () {
-            if (!this._btnVR) {
+            if (!this._btnVR || this._useCustomVRButton) {
                 return;
             }
             this._btnVR.className = "babylonVRicon";

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 15 - 15
dist/preview release/babylon.worker.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 18 - 17
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 92 - 27
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -8588,7 +8588,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.1-beta-6";
+                return "3.1-rc-0";
             },
             enumerable: true,
             configurable: true
@@ -56910,14 +56910,20 @@ var BABYLON;
         __extends(PoseEnabledController, _super);
         function PoseEnabledController(browserGamepad) {
             var _this = _super.call(this, browserGamepad.id, browserGamepad.index, browserGamepad) || this;
+            // Represents device position and rotation in room space. Should only be used to help calculate babylon space values
+            _this._deviceRoomPosition = BABYLON.Vector3.Zero();
+            _this._deviceRoomRotationQuaternion = new BABYLON.Quaternion();
+            // Represents device position and rotation in babylon space
+            _this.devicePosition = BABYLON.Vector3.Zero();
+            _this.deviceRotationQuaternion = new BABYLON.Quaternion();
             _this.deviceScaleFactor = 1;
             _this._leftHandSystemQuaternion = new BABYLON.Quaternion();
+            _this._deviceToWorld = BABYLON.Matrix.Identity();
+            _this._workingMatrix = BABYLON.Matrix.Identity();
             _this.type = BABYLON.Gamepad.POSE_ENABLED;
             _this.controllerType = PoseEnabledControllerType.GENERIC;
             _this.position = BABYLON.Vector3.Zero();
             _this.rotationQuaternion = new BABYLON.Quaternion();
-            _this.devicePosition = BABYLON.Vector3.Zero();
-            _this.deviceRotationQuaternion = new BABYLON.Quaternion();
             _this._calculatedPosition = BABYLON.Vector3.Zero();
             _this._calculatedRotation = new BABYLON.Quaternion();
             BABYLON.Quaternion.RotationYawPitchRollToRef(Math.PI, 0, 0, _this._leftHandSystemQuaternion);
@@ -56927,10 +56933,13 @@ var BABYLON;
             _super.prototype.update.call(this);
             var pose = this.browserGamepad.pose;
             this.updateFromDevice(pose);
+            BABYLON.Vector3.TransformCoordinatesToRef(this._calculatedPosition, this._deviceToWorld, this.devicePosition);
+            this._deviceToWorld.getRotationMatrixToRef(this._workingMatrix);
+            BABYLON.Quaternion.FromRotationMatrixToRef(this._workingMatrix, this.deviceRotationQuaternion);
             if (this._mesh) {
-                this._mesh.position.copyFrom(this._calculatedPosition);
+                this._mesh.position.copyFrom(this.devicePosition);
                 if (this._mesh.rotationQuaternion) {
-                    this._mesh.rotationQuaternion.copyFrom(this._calculatedRotation);
+                    this._mesh.rotationQuaternion.copyFrom(this.deviceRotationQuaternion.multiplyInPlace(this._calculatedRotation));
                 }
             }
         };
@@ -56938,27 +56947,27 @@ var BABYLON;
             if (poseData) {
                 this.rawPose = poseData;
                 if (poseData.position) {
-                    this.devicePosition.copyFromFloats(poseData.position[0], poseData.position[1], -poseData.position[2]);
+                    this._deviceRoomPosition.copyFromFloats(poseData.position[0], poseData.position[1], -poseData.position[2]);
                     if (this._mesh && this._mesh.getScene().useRightHandedSystem) {
-                        this.devicePosition.z *= -1;
+                        this._deviceRoomPosition.z *= -1;
                     }
-                    this.devicePosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
+                    this._deviceRoomPosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
                     this._calculatedPosition.addInPlace(this.position);
                 }
                 var pose = this.rawPose;
                 if (poseData.orientation && pose.orientation) {
-                    this.deviceRotationQuaternion.copyFromFloats(pose.orientation[0], pose.orientation[1], -pose.orientation[2], -pose.orientation[3]);
+                    this._deviceRoomRotationQuaternion.copyFromFloats(pose.orientation[0], pose.orientation[1], -pose.orientation[2], -pose.orientation[3]);
                     if (this._mesh) {
                         if (this._mesh.getScene().useRightHandedSystem) {
-                            this.deviceRotationQuaternion.z *= -1;
-                            this.deviceRotationQuaternion.w *= -1;
+                            this._deviceRoomRotationQuaternion.z *= -1;
+                            this._deviceRoomRotationQuaternion.w *= -1;
                         }
                         else {
-                            this.deviceRotationQuaternion.multiplyToRef(this._leftHandSystemQuaternion, this.deviceRotationQuaternion);
+                            this._deviceRoomRotationQuaternion.multiplyToRef(this._leftHandSystemQuaternion, this._deviceRoomRotationQuaternion);
                         }
                     }
                     // if the camera is set, rotate to the camera's rotation
-                    this.deviceRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
+                    this._deviceRoomRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
                 }
             }
         };
@@ -71350,12 +71359,23 @@ var BABYLON;
             _this._specsVersion = "1.1";
             _this._attached = false;
             _this._descendants = [];
+            // Represents device position and rotation in room space. Should only be used to help calculate babylon space values
+            _this._deviceRoomPosition = BABYLON.Vector3.Zero();
+            _this._deviceRoomRotationQuaternion = BABYLON.Quaternion.Identity();
+            // Represents device position and rotation in babylon space
             _this.devicePosition = BABYLON.Vector3.Zero();
+            _this.deviceRotationQuaternion = BABYLON.Quaternion.Identity();
             _this.deviceScaleFactor = 1;
+            _this._deviceToWorld = BABYLON.Matrix.Identity();
+            _this._worldToDevice = BABYLON.Matrix.Identity();
             _this.controllers = [];
             _this.onControllersAttachedObservable = new BABYLON.Observable();
             _this.onControllerMeshLoadedObservable = new BABYLON.Observable();
             _this.rigParenting = true; // should the rig cameras be used as parent instead of this camera.
+            _this._workingVector = BABYLON.Vector3.Zero();
+            _this._oneVector = BABYLON.Vector3.One();
+            _this._workingMatrix = BABYLON.Matrix.Identity();
+            _this._cache.position = BABYLON.Vector3.Zero();
             if (webVROptions.defaultHeight) {
                 _this.position.y = webVROptions.defaultHeight;
             }
@@ -71375,7 +71395,6 @@ var BABYLON;
                 _this.webVROptions.defaultLightingOnControllers = true;
             }
             _this.rotationQuaternion = new BABYLON.Quaternion();
-            _this.deviceRotationQuaternion = new BABYLON.Quaternion();
             if (_this.webVROptions && _this.webVROptions.positionScale) {
                 _this.deviceScaleFactor = _this.webVROptions.positionScale;
             }
@@ -71486,15 +71505,15 @@ var BABYLON;
         WebVRFreeCamera.prototype.updateFromDevice = function (poseData) {
             if (poseData && poseData.orientation) {
                 this.rawPose = poseData;
-                this.deviceRotationQuaternion.copyFromFloats(poseData.orientation[0], poseData.orientation[1], -poseData.orientation[2], -poseData.orientation[3]);
+                this._deviceRoomRotationQuaternion.copyFromFloats(poseData.orientation[0], poseData.orientation[1], -poseData.orientation[2], -poseData.orientation[3]);
                 if (this.getScene().useRightHandedSystem) {
-                    this.deviceRotationQuaternion.z *= -1;
-                    this.deviceRotationQuaternion.w *= -1;
+                    this._deviceRoomRotationQuaternion.z *= -1;
+                    this._deviceRoomRotationQuaternion.w *= -1;
                 }
                 if (this.webVROptions.trackPosition && this.rawPose.position) {
-                    this.devicePosition.copyFromFloats(this.rawPose.position[0], this.rawPose.position[1], -this.rawPose.position[2]);
+                    this._deviceRoomPosition.copyFromFloats(this.rawPose.position[0], this.rawPose.position[1], -this.rawPose.position[2]);
                     if (this.getScene().useRightHandedSystem) {
-                        this.devicePosition.z *= -1;
+                        this._deviceRoomPosition.z *= -1;
                     }
                 }
             }
@@ -71536,10 +71555,49 @@ var BABYLON;
         WebVRFreeCamera.prototype._updateRigCameras = function () {
             var camLeft = this._rigCameras[0];
             var camRight = this._rigCameras[1];
-            camLeft.rotationQuaternion.copyFrom(this.deviceRotationQuaternion);
-            camRight.rotationQuaternion.copyFrom(this.deviceRotationQuaternion);
-            camLeft.position.copyFrom(this.devicePosition);
-            camRight.position.copyFrom(this.devicePosition);
+            camLeft.rotationQuaternion.copyFrom(this._deviceRoomRotationQuaternion);
+            camRight.rotationQuaternion.copyFrom(this._deviceRoomRotationQuaternion);
+            camLeft.position.copyFrom(this._deviceRoomPosition);
+            camRight.position.copyFrom(this._deviceRoomPosition);
+        };
+        WebVRFreeCamera.prototype._updateCache = function (ignoreParentClass) {
+            var _this = this;
+            if (!this.rotationQuaternion.equals(this._cache.rotationQuaternion) || !this.position.equals(this._cache.position)) {
+                // Set working vector to the device position in room space rotated by the new rotation
+                this.rotationQuaternion.toRotationMatrix(this._workingMatrix);
+                BABYLON.Vector3.TransformCoordinatesToRef(this._deviceRoomPosition, this._workingMatrix, this._workingVector);
+                // Subtract this vector from the current device position in world to get the translation for the device world matrix
+                this.devicePosition.subtractToRef(this._workingVector, this._workingVector);
+                BABYLON.Matrix.ComposeToRef(this._oneVector, this.rotationQuaternion, this._workingVector, this._deviceToWorld);
+                // Add translation from anchor position
+                this._deviceToWorld.getTranslationToRef(this._workingVector);
+                this._workingVector.addInPlace(this.position);
+                this._workingVector.subtractInPlace(this._cache.position);
+                this._deviceToWorld.setTranslation(this._workingVector);
+                // Set an inverted matrix to be used when updating the camera
+                this._deviceToWorld.invertToRef(this._worldToDevice);
+                // Update the gamepad to ensure the mesh is updated on the same frame as camera
+                this.controllers.forEach(function (controller) {
+                    controller._deviceToWorld = _this._deviceToWorld;
+                    controller.update();
+                });
+                this.update();
+            }
+            if (!ignoreParentClass) {
+                _super.prototype._updateCache.call(this);
+            }
+        };
+        WebVRFreeCamera.prototype.update = function () {
+            // Get current device position in babylon world
+            BABYLON.Vector3.TransformCoordinatesToRef(this._deviceRoomPosition, this._deviceToWorld, this.devicePosition);
+            // Get current device rotation in babylon world
+            BABYLON.Matrix.FromQuaternionToRef(this._deviceRoomRotationQuaternion, this._workingMatrix);
+            this._deviceToWorld.multiplyToRef(this._workingMatrix, this._workingMatrix);
+            BABYLON.Quaternion.FromRotationMatrixToRef(this._workingMatrix, this.deviceRotationQuaternion);
+            _super.prototype.update.call(this);
+        };
+        WebVRFreeCamera.prototype._getViewMatrix = function () {
+            return BABYLON.Matrix.Identity();
         };
         /**
          * This function is called by the two RIG cameras.
@@ -71572,6 +71630,7 @@ var BABYLON;
                 }
                 this._webvrViewMatrix.invert();
             }
+            parentCamera._worldToDevice.multiplyToRef(this._webvrViewMatrix, this._webvrViewMatrix);
             return this._webvrViewMatrix;
         };
         WebVRFreeCamera.prototype._getWebVRProjectionMatrix = function () {
@@ -71614,6 +71673,7 @@ var BABYLON;
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                     var webVrController_1 = gamepad;
+                    webVrController_1._deviceToWorld = _this._deviceToWorld;
                     if (_this.webVROptions.controllerMeshes) {
                         if (webVrController_1.defaultModel) {
                             webVrController_1.defaultModel.setEnabled(true);
@@ -72027,7 +72087,12 @@ var BABYLON;
                 }
                 if (this._btnVR) {
                     this._btnVR.addEventListener("click", function () {
-                        _this.enterVR();
+                        if (!_this.isInVRMode) {
+                            _this.enterVR();
+                        }
+                        else {
+                            _this.exitVR();
+                        }
                     });
                 }
                 window.addEventListener("resize", function () {
@@ -72242,7 +72307,7 @@ var BABYLON;
             this.updateButtonVisibility();
         };
         VRExperienceHelper.prototype.updateButtonVisibility = function () {
-            if (!this._btnVR) {
+            if (!this._btnVR || this._useCustomVRButton) {
                 return;
             }
             this._btnVR.className = "babylonVRicon";
@@ -83656,7 +83721,7 @@ var BABYLON;
                             }
                         }
                     }
-                    else {
+                    else if (mesh.material) {
                         remaining++;
                     }
                 }
@@ -83678,7 +83743,7 @@ var BABYLON;
                             }
                         }
                     }
-                    else if (mesh.material !== null) {
+                    else if (mesh.material) {
                         this._compileMaterialAsync(mesh.material, mesh, function () {
                             if (--remaining === 0) {
                                 onSuccess();

+ 1 - 1
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "3.1.0-beta6",
+    "version": "3.1.0-rc-0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "3.1.0-beta6",
+    "version": "3.1.0-rc-0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -1877,7 +1877,7 @@ var BABYLON;
                             }
                         }
                     }
-                    else {
+                    else if (mesh.material) {
                         remaining++;
                     }
                 }
@@ -1899,7 +1899,7 @@ var BABYLON;
                             }
                         }
                     }
-                    else if (mesh.material !== null) {
+                    else if (mesh.material) {
                         this._compileMaterialAsync(mesh.material, mesh, function () {
                             if (--remaining === 0) {
                                 onSuccess();

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -4033,7 +4033,7 @@ var BABYLON;
                             }
                         }
                     }
-                    else {
+                    else if (mesh.material) {
                         remaining++;
                     }
                 }
@@ -4055,7 +4055,7 @@ var BABYLON;
                             }
                         }
                     }
-                    else if (mesh.material !== null) {
+                    else if (mesh.material) {
                         this._compileMaterialAsync(mesh.material, mesh, function () {
                             if (--remaining === 0) {
                                 onSuccess();

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.js

@@ -4989,7 +4989,7 @@ var BABYLON;
                             }
                         }
                     }
-                    else {
+                    else if (mesh.material) {
                         remaining++;
                     }
                 }
@@ -5011,7 +5011,7 @@ var BABYLON;
                             }
                         }
                     }
-                    else if (mesh.material !== null) {
+                    else if (mesh.material) {
                         this._compileMaterialAsync(mesh.material, mesh, function () {
                             if (--remaining === 0) {
                                 onSuccess();

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


+ 1 - 1
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "3.1.0-beta6",
+    "version": "3.1.0-rc-0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.1.0-beta6",
+    "version": "3.1.0-rc-0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.1.0-beta6",
+    "version": "3.1.0-rc-0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.1.0-beta6",
+    "version": "3.1.0-rc-0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "3.1.0-beta6",
+    "version": "3.1.0-rc-0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 60 - 67
dist/preview release/viewer/babylon.viewer.js


+ 32 - 0
dist/preview release/viewer/package.json

@@ -0,0 +1,32 @@
+{
+    "author": {
+        "name": "Raanan Weber"
+    },
+    "name": "babylonjs-viewer",
+    "description": "A simple-to-use viewer based on BabylonJS to display 3D elements natively",
+    "version": "3.1.0-rc-0",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/BabylonJS/Babylon.js.git"
+    },
+    "main": "babylon.viewer.js",
+    "files": [
+        "babylon.viewer.js",
+        "readme.md",
+        "package.json"
+    ],
+    "keywords": [
+        "3D",
+        "javascript",
+        "html5",
+        "webgl",
+        "viewer"
+    ],
+    "license": "Apache-2.0",
+    "peerDependencies": {
+        "babylonjs": ">=3.1.0-alpha"
+    },
+    "engines": {
+        "node": "*"
+    }
+}

+ 56 - 0
dist/preview release/viewer/readme.md

@@ -0,0 +1,56 @@
+Babylon.js Viewer
+=====================
+
+Babylon's viewer is a wrapper around Babylon, that automatically initializes the needed components in order to display a loaded model. It is easy to use, and require no coding at all.
+
+The viewer automatically interacts with the DOM, searching for HTML elements named `babylon`. It will then automatically read the configuration from the DOM element and will create a scene for it.
+
+for basic and advanced usage instructions please read the doc at https://doc.babylonjs.com/extensions/the_babylon_viewer
+
+The source code can be found at https://github.com/BabylonJS/Babylon.js/tree/master/Viewer
+
+# Basic usage
+
+to create a simple viewer add the following code to your HTML>
+
+```HTML
+<babylon model="https://playground.babylonjs.com/scenes/Rabbit.babylon"></babylon>
+<script src="https://viewer.babylonjs.com/viewer.min.js"></script>
+```
+
+Make sure to size the babylon HTML tag. For example:
+
+```css
+babylon {
+    max-width: 800px;
+    max-height: 500px;
+    width: 100%;
+    height: 600px;
+}
+```
+
+# Installation instructions
+
+## CDN
+
+Compiled js files (minified) are offered on our public CDN here:
+
+* https://viewer.babylonjs.com/serializers/viewer.min.js
+
+## NPM
+
+To install using npm :
+
+```
+npm install --save babylonjs-viewer
+```
+
+Afterwards it can be imported to the project using:
+
+```
+import from 'babylonjs-viewer';
+```
+
+This will enable the BabylonViewer namespace.
+
+Using webpack to package your project will use the minified js file.

+ 15 - 15
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -85,7 +85,7 @@ module BABYLON.GLTF2 {
 
         // IE 11 Compatibility.
         private static _progressEventFactory: (name: string, data: IProgressEventData) => ProgressEvent;
-        
+
         private static _createProgressEventByConstructor(name: string, data: IProgressEventData): ProgressEvent {
             return new ProgressEvent(name, data);
         }
@@ -320,8 +320,8 @@ module BABYLON.GLTF2 {
             switch (this._parent.coordinateSystemMode) {
                 case GLTFLoaderCoordinateSystemMode.AUTO: {
                     if (!this._babylonScene.useRightHandedSystem) {
-                        this._rootNode.rotation = [ 0, 1, 0, 0 ];
-                        this._rootNode.scale = [ 1, 1, -1 ];
+                        this._rootNode.rotation = [0, 1, 0, 0];
+                        this._rootNode.scale = [1, 1, -1];
                         this._loadTransform(this._rootNode);
                     }
                     break;
@@ -474,7 +474,7 @@ module BABYLON.GLTF2 {
                 };
             });
 
-            if (primitives.length === 1) {  
+            if (primitives.length === 1) {
                 const primitive = primitives[0];
                 if (primitive.material == null) {
                     node.babylonMesh.material = this._getDefaultMaterial();
@@ -484,14 +484,14 @@ module BABYLON.GLTF2 {
                     if (!material) {
                         throw new Error(context + ": Failed to find material " + primitive.material);
                     }
-    
+
                     this._loadMaterial("#/materials/" + material.index, material, (babylonMaterial, isNew) => {
                         if (isNew && this._parent.onMaterialLoaded) {
                             this._parent.onMaterialLoaded(babylonMaterial);
                         }
                         node.babylonMesh.material = babylonMaterial;
-                    }); 
-                } 
+                    });
+                }
             }
             else {
                 const multiMaterial = new MultiMaterial(node.babylonMesh.name, this._babylonScene);
@@ -499,7 +499,7 @@ module BABYLON.GLTF2 {
                 const subMaterials = multiMaterial.subMaterials;
                 for (let index = 0; index < primitives.length; index++) {
                     const primitive = primitives[index];
-    
+
                     if (primitive.material == null) {
                         subMaterials[index] = this._getDefaultMaterial();
                     }
@@ -508,12 +508,12 @@ module BABYLON.GLTF2 {
                         if (!material) {
                             throw new Error(context + ": Failed to find material " + primitive.material);
                         }
-    
+
                         this._loadMaterial("#/materials/" + material.index, material, (babylonMaterial, isNew) => {
                             if (isNew && this._parent.onMaterialLoaded) {
                                 this._parent.onMaterialLoaded(babylonMaterial);
                             }
-    
+
                             subMaterials[index] = babylonMaterial;
                         });
                     }
@@ -806,7 +806,7 @@ module BABYLON.GLTF2 {
                             // Tangent data for morph targets is stored as xyz delta.
                             // The vertexData.tangent is stored as xyzw.
                             // So we need to skip every fourth vertexData.tangent.
-                            for (let i = 0, j = 0; i < values.length; i++, j++) {
+                            for (let i = 0, j = 0; i < values.length; i++ , j++) {
                                 values[i] += vertexData.tangents![j];
                                 if ((i + 1) % 3 == 0) {
                                     j++;
@@ -1349,7 +1349,7 @@ module BABYLON.GLTF2 {
             this._loaderTrackers.push(tracker);
 
             this._addLoaderPendingData(tracker);
-            
+
             action();
 
             this._removeLoaderPendingData(tracker);
@@ -1653,7 +1653,7 @@ module BABYLON.GLTF2 {
             }
         }
 
-        private static _AssignIndices(array?: Array<{index: number}>): void {
+        private static _AssignIndices(array?: Array<{ index: number }>): void {
             if (array) {
                 for (let index = 0; index < array.length; index++) {
                     array[index].index = index;
@@ -1766,7 +1766,7 @@ module BABYLON.GLTF2 {
                         }
                     }
                 }
-                else {
+                else if (mesh.material) {
                     remaining++;
                 }
             }
@@ -1788,7 +1788,7 @@ module BABYLON.GLTF2 {
                         }
                     }
                 }
-                else if (mesh.material !== null) {
+                else if (mesh.material) {
                     this._compileMaterialAsync(mesh.material, mesh, () => {
                         if (--remaining === 0) {
                             onSuccess();

+ 1 - 1
package.json

@@ -8,7 +8,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "3.1.0-beta6",
+    "version": "3.1.0-rc-0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 2 - 2
sandbox/index.js

@@ -100,7 +100,7 @@ if (BABYLON.Engine.isSupported()) {
             currentScene.activeCamera.pinchDeltaPercentage = 0.01;
         }
 
-        currentScene.activeCamera.attachControl(canvas); 
+        currentScene.activeCamera.attachControl(canvas);
 
         // Environment
         if (currentPluginName === "gltf") {
@@ -236,7 +236,7 @@ if (BABYLON.Engine.isSupported()) {
     }
 }
 
-function sizeScene () {
+function sizeScene() {
     let divInspWrapper = document.getElementsByClassName('insp-wrapper')[0];
     if (divInspWrapper) {
         let divFooter = document.getElementsByClassName('footer')[0];

+ 6 - 2
src/Cameras/VR/babylon.vrExperienceHelper.ts

@@ -228,7 +228,11 @@ module BABYLON {
                 }
                 if (this._btnVR) {
                     this._btnVR.addEventListener("click", () => {
-                        this.enterVR();
+                        if(!this.isInVRMode){
+                            this.enterVR();
+                        }else{
+                            this.exitVR();
+                        }
                     });
                 }
 
@@ -392,7 +396,7 @@ module BABYLON {
         }
 
         private updateButtonVisibility() {
-            if (!this._btnVR) {
+            if (!this._btnVR || this._useCustomVRButton) {
                 return;
             }
             this._btnVR.className = "babylonVRicon";

+ 72 - 14
src/Cameras/VR/babylon.webVRCamera.ts

@@ -52,10 +52,19 @@ module BABYLON {
 
         protected _descendants: Array<Node> = [];
 
+        // Represents device position and rotation in room space. Should only be used to help calculate babylon space values
+        private _deviceRoomPosition = Vector3.Zero();
+        private _deviceRoomRotationQuaternion = Quaternion.Identity(); 
+
+        // Represents device position and rotation in babylon space
         public devicePosition = Vector3.Zero();
-        public deviceRotationQuaternion: Quaternion;
+        public deviceRotationQuaternion = Quaternion.Identity();        
+
         public deviceScaleFactor: number = 1;
 
+        private _deviceToWorld = Matrix.Identity();
+        private _worldToDevice = Matrix.Identity();
+
         public controllers: Array<WebVRController> = [];
         public onControllersAttachedObservable = new Observable<Array<WebVRController>>();
         public onControllerMeshLoadedObservable = new Observable<WebVRController>();
@@ -66,7 +75,7 @@ module BABYLON {
 
         constructor(name: string, position: Vector3, scene: Scene, private webVROptions: WebVROptions = {}) {
             super(name, position, scene);
-
+            this._cache.position = Vector3.Zero();
             if(webVROptions.defaultHeight){
                 this.position.y = webVROptions.defaultHeight;
             }
@@ -90,7 +99,6 @@ module BABYLON {
             }
 
             this.rotationQuaternion = new Quaternion();
-            this.deviceRotationQuaternion = new Quaternion();
 
             if (this.webVROptions && this.webVROptions.positionScale) {
                 this.deviceScaleFactor = this.webVROptions.positionScale;
@@ -210,16 +218,16 @@ module BABYLON {
         updateFromDevice(poseData: DevicePose) {
             if (poseData && poseData.orientation) {
                 this.rawPose = poseData;
-                this.deviceRotationQuaternion.copyFromFloats(poseData.orientation[0], poseData.orientation[1], -poseData.orientation[2], -poseData.orientation[3]);
+                this._deviceRoomRotationQuaternion.copyFromFloats(poseData.orientation[0], poseData.orientation[1], -poseData.orientation[2], -poseData.orientation[3]);
 
                 if (this.getScene().useRightHandedSystem) {
-                    this.deviceRotationQuaternion.z *= -1;
-                    this.deviceRotationQuaternion.w *= -1;
+                    this._deviceRoomRotationQuaternion.z *= -1;
+                    this._deviceRoomRotationQuaternion.w *= -1;
                 }
                 if (this.webVROptions.trackPosition && this.rawPose.position) {
-                    this.devicePosition.copyFromFloats(this.rawPose.position[0], this.rawPose.position[1], -this.rawPose.position[2]);
+                    this._deviceRoomPosition.copyFromFloats(this.rawPose.position[0], this.rawPose.position[1], -this.rawPose.position[2]);
                     if (this.getScene().useRightHandedSystem) {
-                        this.devicePosition.z *= -1;
+                        this._deviceRoomPosition.z *= -1;
                     }
                 }
             }
@@ -269,11 +277,60 @@ module BABYLON {
         public _updateRigCameras() {
             var camLeft = <TargetCamera>this._rigCameras[0];
             var camRight = <TargetCamera>this._rigCameras[1];
-            camLeft.rotationQuaternion.copyFrom(this.deviceRotationQuaternion);
-            camRight.rotationQuaternion.copyFrom(this.deviceRotationQuaternion);
+            camLeft.rotationQuaternion.copyFrom(this._deviceRoomRotationQuaternion);
+            camRight.rotationQuaternion.copyFrom(this._deviceRoomRotationQuaternion);
+
+            camLeft.position.copyFrom(this._deviceRoomPosition);
+            camRight.position.copyFrom(this._deviceRoomPosition);
+        }
+
+        private _workingVector = Vector3.Zero();
+        private _oneVector = Vector3.One();
+        private _workingMatrix = Matrix.Identity();
+        public _updateCache(ignoreParentClass?: boolean): void {
+            if(!this.rotationQuaternion.equals(this._cache.rotationQuaternion) || !this.position.equals(this._cache.position)){
+                // Set working vector to the device position in room space rotated by the new rotation
+                this.rotationQuaternion.toRotationMatrix(this._workingMatrix);
+                Vector3.TransformCoordinatesToRef(this._deviceRoomPosition, this._workingMatrix, this._workingVector);
+
+                // Subtract this vector from the current device position in world to get the translation for the device world matrix
+                this.devicePosition.subtractToRef(this._workingVector, this._workingVector)
+                Matrix.ComposeToRef(this._oneVector, this.rotationQuaternion, this._workingVector, this._deviceToWorld);             
+                
+                // Add translation from anchor position
+                this._deviceToWorld.getTranslationToRef(this._workingVector)
+                this._workingVector.addInPlace(this.position);
+                this._workingVector.subtractInPlace(this._cache.position)
+                this._deviceToWorld.setTranslation(this._workingVector)
+
+                // Set an inverted matrix to be used when updating the camera
+                this._deviceToWorld.invertToRef(this._worldToDevice)
+                
+                // Update the gamepad to ensure the mesh is updated on the same frame as camera
+                this.controllers.forEach((controller)=>{
+                    controller._deviceToWorld = this._deviceToWorld;
+                    controller.update();
+                })
+                this.update();
+            }
 
-            camLeft.position.copyFrom(this.devicePosition);
-            camRight.position.copyFrom(this.devicePosition);
+            if (!ignoreParentClass) {
+                super._updateCache();
+            }
+        }
+        public update() {
+            // Get current device position in babylon world
+            Vector3.TransformCoordinatesToRef(this._deviceRoomPosition, this._deviceToWorld, this.devicePosition);
+            
+            // Get current device rotation in babylon world
+            Matrix.FromQuaternionToRef(this._deviceRoomRotationQuaternion, this._workingMatrix);
+            this._deviceToWorld.multiplyToRef(this._workingMatrix, this._workingMatrix);
+            Quaternion.FromRotationMatrixToRef(this._workingMatrix, this.deviceRotationQuaternion);
+
+            super.update();
+        }
+        public _getViewMatrix(): Matrix {
+            return Matrix.Identity();
         }
 
         /**
@@ -313,7 +370,8 @@ module BABYLON {
 
                 this._webvrViewMatrix.invert();
             }
-
+            
+            parentCamera._worldToDevice.multiplyToRef(this._webvrViewMatrix, this._webvrViewMatrix);
             return this._webvrViewMatrix;
         }
 
@@ -368,7 +426,7 @@ module BABYLON {
             this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add((gamepad) => {
                 if (gamepad.type === BABYLON.Gamepad.POSE_ENABLED) {
                     let webVrController: WebVRController = <WebVRController>gamepad;
-
+                    webVrController._deviceToWorld = this._deviceToWorld;
                     if (this.webVROptions.controllerMeshes) {
                         if (webVrController.defaultModel) {
                             webVrController.defaultModel.setEnabled(true);

+ 1 - 1
src/Engine/babylon.engine.ts

@@ -564,7 +564,7 @@
         }
 
         public static get Version(): string {
-            return "3.1-beta-6";
+            return "3.1-rc-0";
         }
 
         // Updatable statics so stick with vars here

+ 27 - 15
src/Gamepad/Controllers/babylon.poseEnabledController.ts

@@ -41,8 +41,14 @@ module BABYLON {
     }
 
     export class PoseEnabledController extends Gamepad implements PoseControlled {
-        devicePosition: Vector3;
-        deviceRotationQuaternion: Quaternion;
+        // Represents device position and rotation in room space. Should only be used to help calculate babylon space values
+        private _deviceRoomPosition = Vector3.Zero();
+        private _deviceRoomRotationQuaternion = new Quaternion();
+
+        // Represents device position and rotation in babylon space
+        public devicePosition = Vector3.Zero();
+        public deviceRotationQuaternion = new Quaternion();
+
         deviceScaleFactor: number = 1;
 
         public position: Vector3;
@@ -59,29 +65,35 @@ module BABYLON {
 
         private _leftHandSystemQuaternion: Quaternion = new Quaternion();
         
+        public _deviceToWorld = Matrix.Identity();
+
         constructor(browserGamepad: any) {
             super(browserGamepad.id, browserGamepad.index, browserGamepad);
             this.type = Gamepad.POSE_ENABLED;
             this.controllerType = PoseEnabledControllerType.GENERIC;
             this.position = Vector3.Zero();
             this.rotationQuaternion = new Quaternion();
-            this.devicePosition = Vector3.Zero();
-            this.deviceRotationQuaternion = new Quaternion();
 
             this._calculatedPosition = Vector3.Zero();
             this._calculatedRotation = new Quaternion();
             Quaternion.RotationYawPitchRollToRef(Math.PI, 0, 0, this._leftHandSystemQuaternion);
         }
 
+        private _workingMatrix = Matrix.Identity();
         public update() {
             super.update();
             var pose: GamepadPose = this.browserGamepad.pose;
             this.updateFromDevice(pose);
-            
+
+            Vector3.TransformCoordinatesToRef(this._calculatedPosition, this._deviceToWorld, this.devicePosition)
+            this._deviceToWorld.getRotationMatrixToRef(this._workingMatrix);
+            Quaternion.FromRotationMatrixToRef(this._workingMatrix, this.deviceRotationQuaternion);
+
             if (this._mesh) {
-                this._mesh.position.copyFrom(this._calculatedPosition);
+                this._mesh.position.copyFrom(this.devicePosition);
+
                 if (this._mesh.rotationQuaternion) {
-                    this._mesh.rotationQuaternion.copyFrom(this._calculatedRotation);
+                    this._mesh.rotationQuaternion.copyFrom(this.deviceRotationQuaternion.multiplyInPlace(this._calculatedRotation));
                 }
             }
         }
@@ -90,29 +102,29 @@ module BABYLON {
             if (poseData) {
                 this.rawPose = poseData;
                 if (poseData.position) {
-                    this.devicePosition.copyFromFloats(poseData.position[0], poseData.position[1], -poseData.position[2]);
+                    this._deviceRoomPosition.copyFromFloats(poseData.position[0], poseData.position[1], -poseData.position[2]);
                     if (this._mesh && this._mesh.getScene().useRightHandedSystem) {
-                        this.devicePosition.z *= -1;
+                        this._deviceRoomPosition.z *= -1;
                     }
 
-                    this.devicePosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
+                    this._deviceRoomPosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
                     this._calculatedPosition.addInPlace(this.position);
 
                 }
                 let pose = this.rawPose;
                 if (poseData.orientation && pose.orientation) {
-                    this.deviceRotationQuaternion.copyFromFloats(pose.orientation[0], pose.orientation[1], -pose.orientation[2], -pose.orientation[3]);
+                    this._deviceRoomRotationQuaternion.copyFromFloats(pose.orientation[0], pose.orientation[1], -pose.orientation[2], -pose.orientation[3]);
                     if (this._mesh) {
                         if (this._mesh.getScene().useRightHandedSystem) {
-                            this.deviceRotationQuaternion.z *= -1;
-                            this.deviceRotationQuaternion.w *= -1;
+                            this._deviceRoomRotationQuaternion.z *= -1;
+                            this._deviceRoomRotationQuaternion.w *= -1;
                         } else {
-                            this.deviceRotationQuaternion.multiplyToRef(this._leftHandSystemQuaternion, this.deviceRotationQuaternion);
+                            this._deviceRoomRotationQuaternion.multiplyToRef(this._leftHandSystemQuaternion, this._deviceRoomRotationQuaternion);
                         }
                     }
 
                     // if the camera is set, rotate to the camera's rotation
-                    this.deviceRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
+                    this._deviceRoomRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
                 }
             }
         }