浏览代码

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

David Catuhe 7 年之前
父节点
当前提交
577f9e752c
共有 33 个文件被更改,包括 4925 次插入4657 次删除
  1. 35 2
      Playground/js/index.js
  2. 3 1
      Tools/Gulp/config.json
  3. 二进制
      Viewer/assets/babylon.woff
  4. 21 3
      Viewer/assets/templates/default/navbar.html
  5. 1 0
      Viewer/src/configuration/configuration.ts
  6. 6 0
      Viewer/src/configuration/types/default.ts
  7. 4 4
      Viewer/src/managers/sceneManager.ts
  8. 21 0
      Viewer/src/viewer/defaultViewer.ts
  9. 23 3
      Viewer/src/viewer/viewer.ts
  10. 12 0
      Viewer/tests/unit/src/viewer/sceneManager.ts
  11. 4326 4326
      dist/preview release/babylon.d.ts
  12. 2 2
      dist/preview release/inspector/babylon.inspector.bundle.js
  13. 2 2
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  14. 17 64
      dist/preview release/serializers/babylon.glTF2Serializer.js
  15. 2 2
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  16. 2 2
      dist/preview release/serializers/babylonjs.serializers.d.ts
  17. 17 64
      dist/preview release/serializers/babylonjs.serializers.js
  18. 2 2
      dist/preview release/serializers/babylonjs.serializers.min.js
  19. 2 2
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  20. 1 1
      dist/preview release/viewer/babylon.viewer.d.ts
  21. 11 11
      dist/preview release/viewer/babylon.viewer.js
  22. 9 5
      dist/preview release/viewer/babylon.viewer.max.js
  23. 1 1
      dist/preview release/viewer/babylon.viewer.module.d.ts
  24. 2 1
      dist/preview release/what's new.md
  25. 31 83
      serializers/src/glTF/2.0/babylon.glTFMaterial.ts
  26. 101 0
      src/Behaviors/Mesh/babylon.multiPointerScaleBehavior.ts
  27. 74 37
      src/Behaviors/Mesh/babylon.pointerDragBehavior.ts
  28. 143 0
      src/Behaviors/Mesh/babylon.sixDofDragBehavior.ts
  29. 13 0
      src/Gamepad/Controllers/babylon.poseEnabledController.ts
  30. 4 2
      src/Gamepad/Controllers/babylon.windowsMotionController.ts
  31. 1 1
      src/Gizmos/babylon.planeRotationGizmo.ts
  32. 1 1
      src/Mesh/babylon.geometry.ts
  33. 35 35
      tests/unit/babylon/serializers/babylon.glTFSerializer.tests.ts

+ 35 - 2
Playground/js/index.js

@@ -286,8 +286,41 @@
                                     //loadScriptFromIndex(index);
                                     var newPG = "";
                                     switch(index) {
-                                        case 17 : newPG="#J19GYK#0"; break;
-                                        default: newPG=""; break;
+                                        case 1 : newPG = "#TAZ2CB#0"; break; // Basic scene
+                                        case 2 : newPG = "#A1210C#0"; break; // Basic elements
+                                        case 3 : newPG = "#CURCZC#0"; break; // Rotation and scaling
+                                        case 4 : newPG = "#DXARSP#0"; break; // Materials
+                                        case 5 : newPG = "#1A3M5C#0"; break; // Cameras
+                                        case 6 : newPG = "#AQRDKW#0"; break; // Lights
+                                        case 7 : newPG = "#QYFDDP#1"; break; // Animations
+                                        case 8 : newPG = "#9RI8CG#0"; break; // Sprites
+                                        case 9 : newPG = "#U8MEB0#0"; break; // Collisions
+                                        case 10 : newPG = "#KQV9SA#0"; break; // Intersections
+                                        case 11 : newPG = "#NU4F6Y#0"; break; // Picking
+                                        case 12 : newPG = "#EF9X5R#0"; break; // Particles
+                                        case 13 : newPG = "#7G0IQW#0"; break; // Environment
+                                        case 14 : newPG = "#95PXRY#0"; break; // Height map
+                                        case 15 : newPG = "#IFYDRS#0"; break; // Shadows
+                                        case 16 : newPG = "#AQZJ4C#0"; break; // Import meshes
+                                        case 17 : newPG = "#J19GYK#0"; break; // Actions
+                                        case 18 : newPG = "#UZ23UH#0"; break; // Drag and drop
+                                        case 19 : newPG = "#AQZJ4C#0"; break; // Fresnel
+                                        case 20 : newPG = "#8ZNVGR#0"; break; // Easing functions
+                                        case 21 : newPG = "#B2ZXG6#0"; break; // Procedural texture
+                                        case 22 : newPG = "#DXAEUY#0"; break; // Basic sounds
+                                        case 23 : newPG = "#EDVU95#0"; break; // Sound on mesh
+                                        case 24 : newPG = "#N96NXC#0"; break; // SSAO rendering pipeline
+                                        case 25 : newPG = "#7D2QDD#0"; break; // SSAO 2
+                                        case 26 : newPG = "#V2DAKC#0"; break; // Volumetric light scattering
+                                        case 27 : newPG = "#XH85A9#0"; break; // Refraction and reflection
+                                        case 28 : newPG = "#8MGKWK#0"; break; // PBR
+                                        case 29 : newPG = "#0K8EYN#0"; break; // Instanced bones
+                                        case 30 : newPG = "#C245A1#0"; break; // Pointer events handling
+                                        case 31 : newPG = "#TAFSN0#2"; break; // WebVR
+                                        case 32 : newPG = "#3VMTI9#0"; break; // GUI
+                                        case 33 : newPG = "#7149G4#0"; break; // Physics
+                                        
+                                        default: newPG = ""; break;
                                     }
                                     window.location.href = location.protocol + "//" + location.host + location.pathname + "#" + newPG;
                                 } else if (query.indexOf("=") === -1) {

+ 3 - 1
Tools/Gulp/config.json

@@ -313,7 +313,9 @@
         },
         "meshBehaviors": {
             "files": [
-                "../../src/Behaviors/Mesh/babylon.pointerDragBehavior.js"
+                "../../src/Behaviors/Mesh/babylon.pointerDragBehavior.js",
+                "../../src/Behaviors/Mesh/babylon.multiPointerScaleBehavior.js",
+                "../../src/Behaviors/Mesh/babylon.sixDofDragBehavior.js"
             ],
             "dependUpon": [
                 "behaviors"

二进制
Viewer/assets/babylon.woff


+ 21 - 3
Viewer/assets/templates/default/navbar.html

@@ -144,6 +144,16 @@
         content: "\EF4E";
     }
 
+    .hd-icon:after {
+        font-size: 16px;
+        content: "\F765";
+    }
+
+    .sd-icon:after {
+        font-size: 16px;
+        content: "\F766";
+    }
+
     .progress-control {
         display: flex;
         flex: 1;
@@ -483,12 +493,20 @@
     </div>
     {{/unless}}
     <div class="default-control">
-        {{#unless hideHelp}}
-        <button class="help" id="help-button" title="Help">
+        {{#unless hideHdButton}}
+        <button class="hd-button" id="hd-button" title="{{text.hdButton}}">
+            {{#if hdEnabled}}
+            <span class="icon sd-icon"></span>
+            {{else}}
+            <span class="icon hd-icon"></span>
+            {{/if}}
+        </button>
+        {{/unless}} {{#unless hideHelp}}
+        <button class="help" id="help-button" title="{{text.helpButton}}">
             <span class="icon help-icon"></span>
         </button>
         {{/unless}} {{#unless hideFullScreen}}
-        <button class="fullscreen" id="fullscreen-button" title="Fullscreen">
+        <button class="fullscreen" id="fullscreen-button" title="{{text.fullscreenButton}}">
             <span class="icon fullscreen-icon"></span>
         </button>
         {{/unless}}

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

@@ -54,6 +54,7 @@ export interface ViewerConfiguration {
         disableResize?: boolean;
         engineOptions?: EngineOptions;
         adaptiveQuality?: boolean;
+        hdEnabled?: boolean;
     },
     //templateStructure?: ITemplateStructure,
     templates?: {

+ 6 - 0
Viewer/src/configuration/types/default.ts

@@ -49,7 +49,13 @@ export let defaultConfiguration: ViewerConfiguration = {
                 logoText: 'BabylonJS',
                 logoLink: 'https://babylonjs.com',
                 hideHelp: true,
+                hideHdButton: true,
                 disableOnFullscreen: false,
+                text: {
+                    hdButton: "Toggle HD",
+                    fullscreenButton: "Fullscreen",
+                    helpButton: "Help"
+                }
             },
             events: {
                 pointerdown: {

+ 4 - 4
Viewer/src/managers/sceneManager.ts

@@ -71,7 +71,7 @@ export class SceneManager {
     /**
      * Babylon's environment helper of this viewer
      */
-    public environmentHelper: EnvironmentHelper;
+    public environmentHelper?: EnvironmentHelper;
 
     private _animationBlendingEnabled: boolean = true;
 
@@ -447,7 +447,7 @@ export class SceneManager {
                 }
             }
 
-            if (newConfiguration.lab.environmentMainColor) {
+            if (this.environmentHelper && newConfiguration.lab.environmentMainColor) {
                 let mainColor = new Color3().copyFrom(newConfiguration.lab.environmentMainColor as Color3);
                 this.environmentHelper.setMainColor(mainColor);
             }
@@ -1019,7 +1019,7 @@ export class SceneManager {
 
         this.onEnvironmentConfiguredObservable.notifyObservers({
             sceneManager: this,
-            object: this.environmentHelper,
+            object: this.environmentHelper!,
             newConfiguration: {
                 skybox: skyboxConifguration,
                 ground: groundConfiguration
@@ -1229,7 +1229,7 @@ export class SceneManager {
     }
 
     private _updateGroundMirrorRenderList(model?: ViewerModel, resetList?: boolean) {
-        if (this.environmentHelper.groundMirror && this.environmentHelper.groundMirror.renderList) {
+        if (this.environmentHelper && this.environmentHelper.groundMirror && this.environmentHelper.groundMirror.renderList) {
             let focusMeshes = model ? model.meshes : this.scene.meshes;
             let renderList = this.environmentHelper.groundMirror.renderList;
             if (resetList) {

+ 21 - 0
Viewer/src/viewer/defaultViewer.ts

@@ -157,6 +157,9 @@ export class DefaultViewer extends AbstractViewer {
             case "fullscreen-button":
                 this.toggleFullscreen();
                 break;
+            case "hd-button":
+                this.toggleHD();
+                break;
             default:
                 return;
         }
@@ -264,6 +267,24 @@ export class DefaultViewer extends AbstractViewer {
         this._updateAnimationSpeed("1.0", paramsObject);
     }
 
+    public toggleHD() {
+        super.toggleHD();
+
+        // update UI element
+        let navbar = this.templateManager.getTemplate('navBar');
+        if (!navbar) return;
+
+        if (navbar.configuration.params) {
+            navbar.configuration.params.hdEnabled = this._hdToggled;
+        }
+
+        let span = navbar.parent.querySelector("button.hd-button span");
+        if (span) {
+            span.classList.remove(this._hdToggled ? "hd-icon" : "sd-icon");
+            span.classList.add(!this._hdToggled ? "hd-icon" : "sd-icon")
+        }
+    }
+
     /**
      * Toggle fullscreen of the entire viewer
      */

+ 23 - 3
Viewer/src/viewer/viewer.ts

@@ -250,6 +250,21 @@ export abstract class AbstractViewer {
         this._resize();
     }
 
+    protected _hdToggled: boolean = false;
+
+    public toggleHD() {
+        this._hdToggled = !this._hdToggled;
+
+        let currentLevel = this.engine.getHardwareScalingLevel();
+        const scalingFactor = 2;
+
+        if (this._hdToggled) {
+            this.engine.setHardwareScalingLevel(currentLevel / scalingFactor);
+        } else {
+            this.engine.setHardwareScalingLevel(currentLevel * scalingFactor);
+        }
+    }
+
     /**
      * The resize function that will be registered with the window object
      */
@@ -507,9 +522,14 @@ export abstract class AbstractViewer {
             window.addEventListener('resize', this._resize);
         }
 
-        if (this.configuration.engine && this.configuration.engine.adaptiveQuality) {
-            var scale = Math.max(0.5, 1 / (window.devicePixelRatio || 2));
-            this.engine.setHardwareScalingLevel(scale);
+        if (this.configuration.engine) {
+            if (this.configuration.engine.adaptiveQuality) {
+                var scale = Math.max(0.5, 1 / (window.devicePixelRatio || 2));
+                this.engine.setHardwareScalingLevel(scale);
+            }
+            if (this.configuration.engine.hdEnabled) {
+                this.toggleHD();
+            }
         }
 
         // create a new template manager for this viewer

+ 12 - 0
Viewer/tests/unit/src/viewer/sceneManager.ts

@@ -146,6 +146,12 @@ describe(name, function () {
         });
 
         viewer.onInitDoneObservable.add(() => {
+            if (!viewer.sceneManager.environmentHelper) {
+                assert.fail();
+                viewer.dispose();
+                done();
+                return;
+            }
             // ground should be defined, and mirror should be enabled
             assert.isDefined(viewer.sceneManager.environmentHelper.ground);
 
@@ -177,6 +183,12 @@ describe(name, function () {
         });
 
         viewer.onInitDoneObservable.add(() => {
+            if (!viewer.sceneManager.environmentHelper) {
+                assert.fail();
+                viewer.dispose();
+                done();
+                return;
+            }
             // ground should be defined, and mirror should be enabled
             assert.isDefined(viewer.sceneManager.environmentHelper.groundMaterial);
             assert.isDefined(viewer.sceneManager.environmentHelper.groundMaterial!.reflectionTexture);

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


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


+ 2 - 2
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -457,7 +457,7 @@ declare module BABYLON.GLTF2 {
          * @param babylonMaterial Babylon Material
          * @returns The Babylon alpha mode value
          */
-        static _GetAlphaMode(babylonMaterial: Material): Nullable<MaterialAlphaMode>;
+        static _GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode;
         /**
          * Converts a Babylon Standard Material to a glTF Material
          * @param babylonStandardMaterial BJS Standard Material
@@ -482,7 +482,7 @@ declare module BABYLON.GLTF2 {
          * @param useAlpha Specifies if alpha should be preserved or not
          * @returns Promise with texture
          */
-        static _SetAlphaToOneAsync(texture: BaseTexture, useAlpha: boolean): Promise<Texture>;
+        static _SetAlphaToOneAsync(texture: BaseTexture, useAlpha: boolean): Promise<BaseTexture>;
         /**
          * Converts a Babylon PBR Metallic Roughness Material to a glTF Material
          * @param babylonPBRMetalRoughMaterial BJS PBR Metallic Roughness Material

+ 17 - 64
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -1472,64 +1472,14 @@ var BABYLON;
              * @returns The Babylon alpha mode value
              */
             _GLTFMaterial._GetAlphaMode = function (babylonMaterial) {
-                if (babylonMaterial instanceof BABYLON.StandardMaterial) {
-                    var babylonStandardMaterial = babylonMaterial;
-                    if ((babylonStandardMaterial.alpha !== 1.0) ||
-                        (babylonStandardMaterial.diffuseTexture != null && babylonStandardMaterial.diffuseTexture.hasAlpha) ||
-                        (babylonStandardMaterial.opacityTexture != null)) {
-                        return "BLEND" /* BLEND */;
-                    }
-                    else {
-                        return "OPAQUE" /* OPAQUE */;
-                    }
-                }
-                else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                    var babylonPBRMetallicRoughness = babylonMaterial;
-                    switch (babylonPBRMetallicRoughness.transparencyMode) {
-                        case BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE: {
-                            return "OPAQUE" /* OPAQUE */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHABLEND: {
-                            return "BLEND" /* BLEND */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST: {
-                            return "MASK" /* MASK */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND: {
-                            BABYLON.Tools.Warn(babylonMaterial.name + ": GLTF Exporter | Alpha test and blend mode not supported in glTF.  Alpha blend used instead.");
-                            return "BLEND" /* BLEND */;
-                        }
-                        default: {
-                            BABYLON.Tools.Error("Unsupported alpha mode " + babylonPBRMetallicRoughness.transparencyMode);
-                            return null;
-                        }
-                    }
+                if (babylonMaterial.needAlphaBlending()) {
+                    return "BLEND" /* BLEND */;
                 }
-                else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
-                    var babylonPBRMaterial = babylonMaterial;
-                    switch (babylonPBRMaterial.transparencyMode) {
-                        case BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE: {
-                            return "OPAQUE" /* OPAQUE */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHABLEND: {
-                            return "BLEND" /* BLEND */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST: {
-                            return "MASK" /* MASK */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND: {
-                            BABYLON.Tools.Warn(babylonMaterial.name + ": GLTF Exporter | Alpha test and blend mode not supported in glTF.  Alpha blend used instead.");
-                            return "BLEND" /* BLEND */;
-                        }
-                        default: {
-                            BABYLON.Tools.Error("Unsupported alpha mode " + babylonPBRMaterial.transparencyMode);
-                            return null;
-                        }
-                    }
+                else if (babylonMaterial.needAlphaTesting) {
+                    return "MASK" /* MASK */;
                 }
                 else {
-                    BABYLON.Tools.Error("Unsupported Babylon material type");
-                    return null;
+                    return "OPAQUE" /* OPAQUE */;
                 }
             };
             /**
@@ -1640,19 +1590,22 @@ var BABYLON;
                         resolve(texture);
                     }
                     else {
-                        var scene = texture.getScene();
-                        if (scene) {
-                            var proceduralTexture_1 = new BABYLON.ProceduralTexture('texture', texture.getSize(), 'setAlphaToOne', scene);
-                            if (proceduralTexture_1) {
+                        if (texture instanceof BABYLON.Texture) {
+                            var scene = texture.getScene();
+                            if (scene) {
+                                var proceduralTexture_1 = new BABYLON.ProceduralTexture('texture', texture.getSize(), 'setAlphaToOne', scene);
                                 proceduralTexture_1.setTexture('textureSampler', texture);
-                                proceduralTexture_1.onLoadObservable.add(function () { resolve(proceduralTexture_1); });
+                                proceduralTexture_1.onGenerated = function () {
+                                    resolve(proceduralTexture_1);
+                                };
                             }
                             else {
-                                reject("Cannot create procedural texture for " + texture.name + "!");
+                                reject("Scene not available for texture " + texture.name);
                             }
                         }
                         else {
-                            reject("Scene not available for texture " + texture.name);
+                            BABYLON.Tools.Warn("Removing alpha for " + texture.textureType + " not supported");
+                            resolve(texture);
                         }
                     }
                 });
@@ -1801,7 +1754,7 @@ var BABYLON;
                 var resizedTexture1;
                 var resizedTexture2;
                 if (texture1Size.width < texture2Size.width) {
-                    if (texture1) {
+                    if (texture1 && texture1 instanceof BABYLON.Texture) {
                         resizedTexture1 = BABYLON.TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);
                     }
                     else {
@@ -1810,7 +1763,7 @@ var BABYLON;
                     resizedTexture2 = texture2;
                 }
                 else if (texture1Size.width > texture2Size.width) {
-                    if (texture2) {
+                    if (texture2 && texture2 instanceof BABYLON.Texture) {
                         resizedTexture2 = BABYLON.TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);
                     }
                     else {

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


+ 2 - 2
dist/preview release/serializers/babylonjs.serializers.d.ts

@@ -465,7 +465,7 @@ declare module BABYLON.GLTF2 {
          * @param babylonMaterial Babylon Material
          * @returns The Babylon alpha mode value
          */
-        static _GetAlphaMode(babylonMaterial: Material): Nullable<MaterialAlphaMode>;
+        static _GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode;
         /**
          * Converts a Babylon Standard Material to a glTF Material
          * @param babylonStandardMaterial BJS Standard Material
@@ -490,7 +490,7 @@ declare module BABYLON.GLTF2 {
          * @param useAlpha Specifies if alpha should be preserved or not
          * @returns Promise with texture
          */
-        static _SetAlphaToOneAsync(texture: BaseTexture, useAlpha: boolean): Promise<Texture>;
+        static _SetAlphaToOneAsync(texture: BaseTexture, useAlpha: boolean): Promise<BaseTexture>;
         /**
          * Converts a Babylon PBR Metallic Roughness Material to a glTF Material
          * @param babylonPBRMetalRoughMaterial BJS PBR Metallic Roughness Material

+ 17 - 64
dist/preview release/serializers/babylonjs.serializers.js

@@ -1622,64 +1622,14 @@ var BABYLON;
              * @returns The Babylon alpha mode value
              */
             _GLTFMaterial._GetAlphaMode = function (babylonMaterial) {
-                if (babylonMaterial instanceof BABYLON.StandardMaterial) {
-                    var babylonStandardMaterial = babylonMaterial;
-                    if ((babylonStandardMaterial.alpha !== 1.0) ||
-                        (babylonStandardMaterial.diffuseTexture != null && babylonStandardMaterial.diffuseTexture.hasAlpha) ||
-                        (babylonStandardMaterial.opacityTexture != null)) {
-                        return "BLEND" /* BLEND */;
-                    }
-                    else {
-                        return "OPAQUE" /* OPAQUE */;
-                    }
-                }
-                else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                    var babylonPBRMetallicRoughness = babylonMaterial;
-                    switch (babylonPBRMetallicRoughness.transparencyMode) {
-                        case BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE: {
-                            return "OPAQUE" /* OPAQUE */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHABLEND: {
-                            return "BLEND" /* BLEND */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST: {
-                            return "MASK" /* MASK */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND: {
-                            BABYLON.Tools.Warn(babylonMaterial.name + ": GLTF Exporter | Alpha test and blend mode not supported in glTF.  Alpha blend used instead.");
-                            return "BLEND" /* BLEND */;
-                        }
-                        default: {
-                            BABYLON.Tools.Error("Unsupported alpha mode " + babylonPBRMetallicRoughness.transparencyMode);
-                            return null;
-                        }
-                    }
+                if (babylonMaterial.needAlphaBlending()) {
+                    return "BLEND" /* BLEND */;
                 }
-                else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
-                    var babylonPBRMaterial = babylonMaterial;
-                    switch (babylonPBRMaterial.transparencyMode) {
-                        case BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE: {
-                            return "OPAQUE" /* OPAQUE */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHABLEND: {
-                            return "BLEND" /* BLEND */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST: {
-                            return "MASK" /* MASK */;
-                        }
-                        case BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND: {
-                            BABYLON.Tools.Warn(babylonMaterial.name + ": GLTF Exporter | Alpha test and blend mode not supported in glTF.  Alpha blend used instead.");
-                            return "BLEND" /* BLEND */;
-                        }
-                        default: {
-                            BABYLON.Tools.Error("Unsupported alpha mode " + babylonPBRMaterial.transparencyMode);
-                            return null;
-                        }
-                    }
+                else if (babylonMaterial.needAlphaTesting) {
+                    return "MASK" /* MASK */;
                 }
                 else {
-                    BABYLON.Tools.Error("Unsupported Babylon material type");
-                    return null;
+                    return "OPAQUE" /* OPAQUE */;
                 }
             };
             /**
@@ -1790,19 +1740,22 @@ var BABYLON;
                         resolve(texture);
                     }
                     else {
-                        var scene = texture.getScene();
-                        if (scene) {
-                            var proceduralTexture_1 = new BABYLON.ProceduralTexture('texture', texture.getSize(), 'setAlphaToOne', scene);
-                            if (proceduralTexture_1) {
+                        if (texture instanceof BABYLON.Texture) {
+                            var scene = texture.getScene();
+                            if (scene) {
+                                var proceduralTexture_1 = new BABYLON.ProceduralTexture('texture', texture.getSize(), 'setAlphaToOne', scene);
                                 proceduralTexture_1.setTexture('textureSampler', texture);
-                                proceduralTexture_1.onLoadObservable.add(function () { resolve(proceduralTexture_1); });
+                                proceduralTexture_1.onGenerated = function () {
+                                    resolve(proceduralTexture_1);
+                                };
                             }
                             else {
-                                reject("Cannot create procedural texture for " + texture.name + "!");
+                                reject("Scene not available for texture " + texture.name);
                             }
                         }
                         else {
-                            reject("Scene not available for texture " + texture.name);
+                            BABYLON.Tools.Warn("Removing alpha for " + texture.textureType + " not supported");
+                            resolve(texture);
                         }
                     }
                 });
@@ -1951,7 +1904,7 @@ var BABYLON;
                 var resizedTexture1;
                 var resizedTexture2;
                 if (texture1Size.width < texture2Size.width) {
-                    if (texture1) {
+                    if (texture1 && texture1 instanceof BABYLON.Texture) {
                         resizedTexture1 = BABYLON.TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);
                     }
                     else {
@@ -1960,7 +1913,7 @@ var BABYLON;
                     resizedTexture2 = texture2;
                 }
                 else if (texture1Size.width > texture2Size.width) {
-                    if (texture2) {
+                    if (texture2 && texture2 instanceof BABYLON.Texture) {
                         resizedTexture2 = BABYLON.TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);
                     }
                     else {

文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/serializers/babylonjs.serializers.min.js


+ 2 - 2
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -472,7 +472,7 @@ declare module BABYLON.GLTF2 {
          * @param babylonMaterial Babylon Material
          * @returns The Babylon alpha mode value
          */
-        static _GetAlphaMode(babylonMaterial: Material): Nullable<MaterialAlphaMode>;
+        static _GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode;
         /**
          * Converts a Babylon Standard Material to a glTF Material
          * @param babylonStandardMaterial BJS Standard Material
@@ -497,7 +497,7 @@ declare module BABYLON.GLTF2 {
          * @param useAlpha Specifies if alpha should be preserved or not
          * @returns Promise with texture
          */
-        static _SetAlphaToOneAsync(texture: BaseTexture, useAlpha: boolean): Promise<Texture>;
+        static _SetAlphaToOneAsync(texture: BaseTexture, useAlpha: boolean): Promise<BaseTexture>;
         /**
          * Converts a Babylon PBR Metallic Roughness Material to a glTF Material
          * @param babylonPBRMetalRoughMaterial BJS PBR Metallic Roughness Material

+ 1 - 1
dist/preview release/viewer/babylon.viewer.d.ts

@@ -1286,7 +1286,7 @@ declare module BabylonViewer {
             /**
                 * Babylon's environment helper of this viewer
                 */
-            environmentHelper: BABYLON.EnvironmentHelper;
+            environmentHelper?: BABYLON.EnvironmentHelper;
             protected _defaultHighpTextureType: number;
             protected _shadowGeneratorBias: number;
             protected _defaultPipelineTextureType: number;

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


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


+ 1 - 1
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -1286,7 +1286,7 @@ declare module 'babylonjs-viewer/managers/sceneManager' {
             /**
                 * Babylon's environment helper of this viewer
                 */
-            environmentHelper: EnvironmentHelper;
+            environmentHelper?: EnvironmentHelper;
             protected _defaultHighpTextureType: number;
             protected _shadowGeneratorBias: number;
             protected _defaultPipelineTextureType: number;

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

@@ -31,7 +31,7 @@
 - Get a root mesh from an asset container, load a mesh from a file with a single string url ([TrevorDev](https://github.com/TrevorDev))
 - UtilityLayer class to render another scene as a layer on top of an existing scene ([TrevorDev](https://github.com/TrevorDev))
 - AnimationGroup has now onAnimationGroupEnd observable ([RaananW](https://github.com/RaananW))
-- Pointer drag behavior to enable drag and drop with mouse or 6dof controller on a mesh ([TrevorDev](https://github.com/TrevorDev))
+- PointerDragBehavior, SixDofDragBehavior and MultiPointerScaleBehavior to enable drag and drop/scaling with mouse or 6dof controller on a mesh ([TrevorDev](https://github.com/TrevorDev))
 - Gizmo and GizmoManager classes used to manipulate meshes in a scene. Position, rotation, scale, and bounding box gizmos ([TrevorDev](https://github.com/TrevorDev))
 - Added a new `mesh.ignoreNonUniformScaling` to turn off non uniform scaling compensation ([Deltakosh](https://github.com/deltakosh))
 - AssetsManager tasks will only run when their state is INIT. It is now possible to remove a task from the assets manager ([RaananW](https://github.com/RaananW))
@@ -54,6 +54,7 @@
 - Support for model drag and drop onto the canvas ([RaananW](https://github.com/RaananW))
 - New lab feature - global light rotation [#4347](https://github.com/BabylonJS/Babylon.js/issues/4347) ([RaananW](https://github.com/RaananW))
 - New NPM package - babylonjs-viewer-assets, to separate the binary assets and the code of the viewer ([RaananW](https://github.com/RaananW))
+- A new HD-Toggler button allows setting a better hardware scaling rate ([RaananW](https://github.com/RaananW))
 
 ### Documentation
 

+ 31 - 83
serializers/src/glTF/2.0/babylon.glTFMaterial.ts

@@ -238,67 +238,15 @@ module BABYLON.GLTF2 {
          * @param babylonMaterial Babylon Material
          * @returns The Babylon alpha mode value
          */
-        public static _GetAlphaMode(babylonMaterial: Material): Nullable<MaterialAlphaMode> {
-            if (babylonMaterial instanceof StandardMaterial) {
-                const babylonStandardMaterial = babylonMaterial as StandardMaterial;
-                if ((babylonStandardMaterial.alpha !== 1.0) ||
-                    (babylonStandardMaterial.diffuseTexture != null && babylonStandardMaterial.diffuseTexture.hasAlpha) ||
-                    (babylonStandardMaterial.opacityTexture != null)) {
-                    return MaterialAlphaMode.BLEND;
-                }
-                else {
-                    return MaterialAlphaMode.OPAQUE;
-                }
+        public static _GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode {
+            if (babylonMaterial.needAlphaBlending()) {
+                return MaterialAlphaMode.BLEND;
             }
-            else if (babylonMaterial instanceof PBRMetallicRoughnessMaterial) {
-                const babylonPBRMetallicRoughness = babylonMaterial as PBRMetallicRoughnessMaterial;
-
-                switch (babylonPBRMetallicRoughness.transparencyMode) {
-                    case PBRMaterial.PBRMATERIAL_OPAQUE: {
-                        return MaterialAlphaMode.OPAQUE;
-                    }
-                    case PBRMaterial.PBRMATERIAL_ALPHABLEND: {
-                        return MaterialAlphaMode.BLEND;
-                    }
-                    case PBRMaterial.PBRMATERIAL_ALPHATEST: {
-                        return MaterialAlphaMode.MASK;
-                    }
-                    case PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND: {
-                        Tools.Warn(babylonMaterial.name + ": GLTF Exporter | Alpha test and blend mode not supported in glTF.  Alpha blend used instead.");
-                        return MaterialAlphaMode.BLEND;
-                    }
-                    default: {
-                        Tools.Error("Unsupported alpha mode " + babylonPBRMetallicRoughness.transparencyMode);
-                        return null;
-                    }
-                }
-            }
-            else if (babylonMaterial instanceof PBRMaterial) {
-                const babylonPBRMaterial = babylonMaterial as PBRMaterial;
-
-                switch (babylonPBRMaterial.transparencyMode) {
-                    case PBRMaterial.PBRMATERIAL_OPAQUE: {
-                        return MaterialAlphaMode.OPAQUE;
-                    }
-                    case PBRMaterial.PBRMATERIAL_ALPHABLEND: {
-                        return MaterialAlphaMode.BLEND;
-                    }
-                    case PBRMaterial.PBRMATERIAL_ALPHATEST: {
-                        return MaterialAlphaMode.MASK;
-                    }
-                    case PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND: {
-                        Tools.Warn(babylonMaterial.name + ": GLTF Exporter | Alpha test and blend mode not supported in glTF.  Alpha blend used instead.");
-                        return MaterialAlphaMode.BLEND;
-                    }
-                    default: {
-                        Tools.Error("Unsupported alpha mode " + babylonPBRMaterial.transparencyMode);
-                        return null;
-                    }
-                }
+            else if (babylonMaterial.needAlphaTesting) {
+                return MaterialAlphaMode.MASK;
             }
             else {
-                Tools.Error("Unsupported Babylon material type");
-                return null;
+                return MaterialAlphaMode.OPAQUE;
             }
         }
 
@@ -382,7 +330,7 @@ module BABYLON.GLTF2 {
 
             glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
             if (alphaMode !== MaterialAlphaMode.OPAQUE) {
-                switch(alphaMode) {
+                switch (alphaMode) {
                     case MaterialAlphaMode.BLEND: {
                         glTFMaterial.alphaMode = GLTF2.MaterialAlphaMode.BLEND;
                         break;
@@ -410,31 +358,32 @@ module BABYLON.GLTF2 {
          * @param useAlpha Specifies if alpha should be preserved or not
          * @returns Promise with texture
          */
-        public static _SetAlphaToOneAsync(texture: BaseTexture, useAlpha: boolean): Promise<Texture> {
+        public static _SetAlphaToOneAsync(texture: BaseTexture, useAlpha: boolean): Promise<BaseTexture> {
             return new Promise((resolve, reject) => {
                 if (useAlpha) {
-                    resolve(texture as Texture);
+                    resolve(texture);
                 }
                 else {
-                    const scene = texture.getScene();
-                    if (scene) {
-                        const proceduralTexture = new ProceduralTexture('texture', texture.getSize(), 'setAlphaToOne', scene);
-                        
-                        if (proceduralTexture) {
-                            proceduralTexture.setTexture('textureSampler', texture as Texture);
-                            proceduralTexture.onLoadObservable.add(() => { resolve(proceduralTexture) });
+                    if (texture instanceof Texture) {
+                        const scene = texture.getScene();
+                        if (scene) {
+                            const proceduralTexture = new ProceduralTexture('texture', texture.getSize(), 'setAlphaToOne', scene);
+
+                            proceduralTexture.setTexture('textureSampler', texture);
+                            proceduralTexture.onGenerated = () => {
+                                resolve(proceduralTexture);
+                            };
                         }
                         else {
-                            reject(`Cannot create procedural texture for ${texture.name}!`);
+                            reject(`Scene not available for texture ${texture.name}`);
                         }
                     }
                     else {
-                        reject(`Scene not available for texture ${texture.name}`);
+                        Tools.Warn(`Removing alpha for ${texture.textureType} not supported`);
+                        resolve(texture);
                     }
                 }
-
-            })
-
+            });
         }
 
         /**
@@ -538,7 +487,7 @@ module BABYLON.GLTF2 {
             glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
 
             materials.push(glTFMaterial);
-            materialMap[babylonPBRMetalRoughMaterial.uniqueId] = materials.length -1 ;
+            materialMap[babylonPBRMetalRoughMaterial.uniqueId] = materials.length - 1;
 
             return Promise.all(promises).then(() => { /* do nothing */ });
         }
@@ -600,8 +549,8 @@ module BABYLON.GLTF2 {
             let resizedTexture2;
 
             if (texture1Size.width < texture2Size.width) {
-                if (texture1) {
-                    resizedTexture1 = TextureTools.CreateResizedCopy(texture1 as Texture, texture2Size.width, texture2Size.height, true);
+                if (texture1 && texture1 instanceof Texture) {
+                    resizedTexture1 = TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);
                 }
                 else {
                     resizedTexture1 = this._CreateWhiteTexture(texture2Size.width, texture2Size.height, scene);
@@ -609,8 +558,8 @@ module BABYLON.GLTF2 {
                 resizedTexture2 = texture2;
             }
             else if (texture1Size.width > texture2Size.width) {
-                if (texture2) {
-                    resizedTexture2 = TextureTools.CreateResizedCopy(texture2 as Texture, texture1Size.width, texture1Size.height, true);
+                if (texture2 && texture2 instanceof Texture) {
+                    resizedTexture2 = TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);
                 }
                 else {
                     resizedTexture2 = this._CreateWhiteTexture(texture1Size.width, texture1Size.height, scene);
@@ -871,7 +820,7 @@ module BABYLON.GLTF2 {
         private static _GetGLTFTextureSampler(texture: BaseTexture): ISampler {
             const sampler = _GLTFMaterial._GetGLTFTextureWrapModesSampler(texture);
 
-            let samplingMode = texture instanceof Texture ? (texture as Texture).samplingMode : null;
+            let samplingMode = texture instanceof Texture ? texture.samplingMode : null;
             if (samplingMode != null) {
                 switch (samplingMode) {
                     case Texture.LINEAR_LINEAR: {
@@ -958,8 +907,8 @@ module BABYLON.GLTF2 {
         }
 
         private static _GetGLTFTextureWrapModesSampler(texture: BaseTexture): ISampler {
-            let wrapS = _GLTFMaterial._GetGLTFTextureWrapMode(texture instanceof Texture ? (texture as Texture).wrapU : Texture.WRAP_ADDRESSMODE);
-            let wrapT = _GLTFMaterial._GetGLTFTextureWrapMode(texture instanceof Texture ? (texture as Texture).wrapV : Texture.WRAP_ADDRESSMODE);
+            let wrapS = _GLTFMaterial._GetGLTFTextureWrapMode(texture instanceof Texture ? texture.wrapU : Texture.WRAP_ADDRESSMODE);
+            let wrapT = _GLTFMaterial._GetGLTFTextureWrapMode(texture instanceof Texture ? texture.wrapV : Texture.WRAP_ADDRESSMODE);
 
             if (wrapS === TextureWrapMode.REPEAT && wrapT === TextureWrapMode.REPEAT) { // default wrapping mode in glTF, so omitting
                 return {};
@@ -1148,7 +1097,7 @@ module BABYLON.GLTF2 {
             return Promise.all(promises).then(result => { /* do nothing */ });
         }
 
-        private static GetPixelsFromTexture(babylonTexture: Texture): Uint8Array | Float32Array {
+        private static GetPixelsFromTexture(babylonTexture: BaseTexture): Uint8Array | Float32Array {
             const pixels = babylonTexture.textureType === Engine.TEXTURETYPE_UNSIGNED_INT ? babylonTexture.readPixels() as Uint8Array : babylonTexture.readPixels() as Float32Array;
             return pixels;
         }
@@ -1184,7 +1133,6 @@ module BABYLON.GLTF2 {
             else {
                 samplerIndex = foundSamplerIndex;
             }
-            
             return this._SetAlphaToOneAsync(babylonTexture, useAlpha).then((texture) => {
                 const pixels = _GLTFMaterial.GetPixelsFromTexture(texture);
                 const size = babylonTexture.getSize();

+ 101 - 0
src/Behaviors/Mesh/babylon.multiPointerScaleBehavior.ts

@@ -0,0 +1,101 @@
+module BABYLON {
+    /**
+     * A behavior that when attached to a mesh will allow the mesh to be scaled
+     */
+    export class MultiPointerScaleBehavior implements Behavior<Mesh> {
+        private _dragBehaviorA:PointerDragBehavior;
+        private _dragBehaviorB:PointerDragBehavior;
+        private _startDistance = 0;
+        private _initialScale = new Vector3(0,0,0);
+        private _targetScale = new Vector3(0,0,0);
+        private _ownerNode:Mesh;
+        private _sceneRenderObserver:Nullable<Observer<Scene>> = null;
+
+        constructor(){
+            this._dragBehaviorA = new BABYLON.PointerDragBehavior({});
+            this._dragBehaviorA.moveAttached = false;
+            this._dragBehaviorB = new BABYLON.PointerDragBehavior({});
+            this._dragBehaviorB.moveAttached = false;
+        }
+        
+        /**
+         *  The name of the behavior
+         */
+        public get name(): string {
+            return "MultiPointerScale";
+        }
+
+        /**
+         *  Initializes the behavior
+         */
+        public init() {}
+
+        private _getCurrentDistance(){
+            return this._dragBehaviorA.lastDragPosition.subtract(this._dragBehaviorB.lastDragPosition).length();
+        }
+
+        /**
+         * Attaches the scale behavior the passed in mesh
+         * @param ownerNode The mesh that will be scaled around once attached
+         */
+        public attach(ownerNode: Mesh): void {
+            this._ownerNode = ownerNode;
+
+            // Create 2 drag behaviors such that each will only be triggered by a separate pointer
+            this._dragBehaviorA.onDragStartObservable.add((e)=>{
+                if(this._dragBehaviorA.dragging && this._dragBehaviorB.dragging){
+                    if(this._dragBehaviorA.currentDraggingPointerID == this._dragBehaviorB.currentDraggingPointerID){
+                        this._dragBehaviorA.releaseDrag();
+                    }else{
+                        this._initialScale.copyFrom(ownerNode.scaling)
+                        this._startDistance = this._getCurrentDistance();
+                    }
+                }
+            });
+            this._dragBehaviorB.onDragStartObservable.add((e)=>{
+                if(this._dragBehaviorA.dragging && this._dragBehaviorB.dragging){
+                    if(this._dragBehaviorA.currentDraggingPointerID == this._dragBehaviorB.currentDraggingPointerID){
+                        this._dragBehaviorB.releaseDrag();
+                    }else{
+                        this._initialScale.copyFrom(ownerNode.scaling)
+                        this._startDistance = this._getCurrentDistance();
+                    }
+                }
+            });
+
+            // Once both drag behaviors are active scale based on the distance between the two pointers
+            [this._dragBehaviorA, this._dragBehaviorB].forEach((behavior)=>{
+                behavior.onDragObservable.add(()=>{
+                    if(this._dragBehaviorA.dragging && this._dragBehaviorB.dragging){
+                        var ratio = this._getCurrentDistance()/this._startDistance;
+                        this._initialScale.scaleToRef(ratio, this._targetScale);
+                    }
+                });
+            })
+
+            ownerNode.addBehavior(this._dragBehaviorA);
+            ownerNode.addBehavior(this._dragBehaviorB);
+
+            // On every frame move towards target scaling to avoid jitter caused by vr controllers
+            this._sceneRenderObserver = ownerNode.getScene().onBeforeRenderObservable.add(()=>{
+                if(this._dragBehaviorA.dragging && this._dragBehaviorB.dragging){
+                    var change = this._targetScale.subtract(ownerNode.scaling).scaleInPlace(0.1);
+                    if(change.length()>0.01){
+                        ownerNode.scaling.addInPlace(change);
+                    }
+                }
+            });
+        }
+        /**
+         *  Detaches the behavior from the mesh
+         */
+        public detach(): void {
+            this._ownerNode.getScene().onBeforeRenderObservable.remove(this._sceneRenderObserver);
+            [this._dragBehaviorA, this._dragBehaviorB].forEach((behavior)=>{
+                behavior.onDragStartObservable.clear();
+                behavior.onDragObservable.clear();
+                this._ownerNode.removeBehavior(behavior);
+            });
+        }
+    }
+}

+ 74 - 37
src/Behaviors/Mesh/babylon.pointerDragBehavior.ts

@@ -8,7 +8,18 @@ module BABYLON {
         private _scene:Scene;
         private _pointerObserver:Nullable<Observer<PointerInfo>>;
         private static _planeScene:Scene;
-        private _draggingID = -1;
+        /**
+         * The id of the pointer that is currently interacting with the behavior (-1 when no pointer is active)
+         */
+        public currentDraggingPointerID = -1;
+        /**
+         * The last position where the pointer hit the drag plane in world space
+         */
+        public lastDragPosition:Vector3;
+        /**
+         * If the behavior is currently in a dragging state
+         */
+        public dragging = false;
         // Debug mode will display drag planes to help visualize behavior
         private _debugMode = false;
         private _maxDragAngle = Math.PI/5;
@@ -20,15 +31,15 @@ module BABYLON {
          *  * dragPlaneNormal normal of the current drag plane used during the drag
          *  * dragPlanePoint in world space where the drag intersects the drag plane
          */
-        public onDragObservable = new Observable<{delta:Vector3, dragPlanePoint:Vector3, dragPlaneNormal:Vector3, dragDistance:number}>()
+        public onDragObservable = new Observable<{delta:Vector3, dragPlanePoint:Vector3, dragPlaneNormal:Vector3, dragDistance:number, pointerId:number}>()
         /**
          *  Fires each time a drag begins (eg. mouse down on mesh)
          */
-        public onDragStartObservable = new Observable<{dragPlanePoint:Vector3}>()
+        public onDragStartObservable = new Observable<{dragPlanePoint:Vector3, pointerId:number}>()
         /**
          *  Fires each time a drag ends (eg. mouse release after drag)
          */
-        public onDragEndObservable = new Observable<{dragPlanePoint:Vector3}>()
+        public onDragEndObservable = new Observable<{dragPlanePoint:Vector3, pointerId:number}>()
         /**
          *  If the attached mesh should be moved when dragged
          */
@@ -39,11 +50,16 @@ module BABYLON {
         public _dragPlaneParent:Nullable<Mesh>=null;
 
         /**
-         *  If the drag behavior will react to drag events
+         *  If the drag behavior will react to drag events (Default: true)
          */
         public enabled = true;
         
         /**
+         * If set, the drag plane/axis will be rotated based on the attached mesh's world rotation (Default: true)
+         */
+        public useObjectOrienationForDragging = true;
+
+        /**
          * Creates a pointer drag behavior that can be attached to a mesh
          * @param options The drag axis or normal of the plane that will be dragged across. If no options are specified the drag plane will always face the ray's origin (eg. camera)
          */
@@ -75,6 +91,8 @@ module BABYLON {
          */
         public init() {}
 
+        private _tmpVector = new Vector3(0,0,0);
+        private _worldDragAxis = new Vector3(0,0,0);
         /**
          * Attaches the drag behavior the passed in mesh
          * @param ownerNode The mesh that will be dragged around once attached
@@ -95,8 +113,7 @@ module BABYLON {
             this._dragPlane = BABYLON.Mesh.CreatePlane("pointerDragPlane", this._debugMode ? 1 : 10000, PointerDragBehavior._planeScene, false, BABYLON.Mesh.DOUBLESIDE);
 
             // State of the drag
-            var dragging = false;
-            var lastPosition = new BABYLON.Vector3(0,0,0);
+            this.lastDragPosition = new BABYLON.Vector3(0,0,0);
             var delta = new BABYLON.Vector3(0,0,0);
             var dragLength = 0;
 
@@ -110,24 +127,23 @@ module BABYLON {
                 }
                 
                 if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
-                    if(!dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)){
+                    
+                    if(!this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)){
                         this._updateDragPlanePosition(pointerInfo.pickInfo.ray);
                         var pickedPoint = this._pickWithRayOnDragPlane(pointerInfo.pickInfo.ray);
                         if(pickedPoint){
-                            dragging = true;
-                            this._draggingID = (<PointerEvent>pointerInfo.event).pointerId;
-                            lastPosition.copyFrom(pickedPoint);
-                            this.onDragStartObservable.notifyObservers({dragPlanePoint: pickedPoint});
+                            this.dragging = true;
+                            this.currentDraggingPointerID = (<PointerEvent>pointerInfo.event).pointerId;
+                            this.lastDragPosition.copyFrom(pickedPoint);
+                            this.onDragStartObservable.notifyObservers({dragPlanePoint: pickedPoint, pointerId: this.currentDraggingPointerID});
                         }
                     }
                 }else if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERUP){
-                    if(this._draggingID == (<PointerEvent>pointerInfo.event).pointerId){
-                        dragging = false;
-                        this._draggingID = -1;
-                        this.onDragEndObservable.notifyObservers({dragPlanePoint: lastPosition});
+                    if(this.currentDraggingPointerID == (<PointerEvent>pointerInfo.event).pointerId){
+                        this.releaseDrag();
                     }
                 }else if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE){
-                    if(this._draggingID == (<PointerEvent>pointerInfo.event).pointerId && dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray){
+                    if(this.currentDraggingPointerID == (<PointerEvent>pointerInfo.event).pointerId && this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray){
                         var pickedPoint = this._pickWithRayOnDragPlane(pointerInfo.pickInfo.ray);
                         
                          // Get angle between drag plane and ray. Only update the drag plane at non steep angles to avoid jumps in delta position
@@ -140,26 +156,34 @@ module BABYLON {
                             // depending on the drag mode option drag accordingly
                             if(this.options.dragAxis){
                                 // Convert local drag axis to world
-                                var worldDragAxis = Vector3.TransformCoordinates(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix());
+                                Vector3.TransformCoordinatesToRef(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._worldDragAxis);
 
                                 // Project delta drag from the drag plane onto the drag axis
-                                dragLength = BABYLON.Vector3.Dot(pickedPoint.subtract(lastPosition), worldDragAxis)
-                                worldDragAxis.scaleToRef(dragLength, delta);
+                                pickedPoint.subtractToRef(this.lastDragPosition, this._tmpVector);
+                                dragLength = BABYLON.Vector3.Dot(this._tmpVector, this._worldDragAxis)
+                                this._worldDragAxis.scaleToRef(dragLength, delta);
                             }else{
                                 dragLength = delta.length();
-                                pickedPoint.subtractToRef(lastPosition, delta);
+                                pickedPoint.subtractToRef(this.lastDragPosition, delta);
                             }
                             if(this.moveAttached){
-                                (<Mesh>this._attachedNode).position.addInPlace(delta);
+                                (<Mesh>this._attachedNode).absolutePosition.addToRef(delta, this._tmpVector);
+                                (<Mesh>this._attachedNode).setAbsolutePosition(this._tmpVector);
                             }
-                            this.onDragObservable.notifyObservers({dragDistance: dragLength, delta: delta, dragPlanePoint: pickedPoint, dragPlaneNormal: this._dragPlane.forward});
-                            lastPosition.copyFrom(pickedPoint);
+                            this.onDragObservable.notifyObservers({dragDistance: dragLength, delta: delta, dragPlanePoint: pickedPoint, dragPlaneNormal: this._dragPlane.forward, pointerId: this.currentDraggingPointerID});
+                            this.lastDragPosition.copyFrom(pickedPoint);
                         }
                     }
                 }
             });
         }
 
+        public releaseDrag(){
+            this.dragging = false;
+            this.onDragEndObservable.notifyObservers({dragPlanePoint: this.lastDragPosition, pointerId: this.currentDraggingPointerID});
+            this.currentDraggingPointerID = -1;
+        }
+
         private _pickWithRayOnDragPlane(ray:Nullable<Ray>){
             if(!ray){
                 return null;
@@ -172,29 +196,42 @@ module BABYLON {
             }
         }
 
+        // Variables to avoid instantiation in the below method
+        private _pointA = new Vector3(0,0,0);
+        private _pointB = new Vector3(0,0,0);
+        private _pointC = new Vector3(0,0,0);
+        private _lineA = new Vector3(0,0,0);
+        private _lineB = new Vector3(0,0,0);
+        private _localAxis = new Vector3(0,0,0);
+        private _lookAt = new Vector3(0,0,0); 
         // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
         private _updateDragPlanePosition(ray:Ray){
-            var pointA = this._dragPlaneParent ? this._dragPlaneParent.absolutePosition : (<Mesh>this._attachedNode).absolutePosition;
+            this._pointA.copyFrom(this._dragPlaneParent ? this._dragPlaneParent.absolutePosition : (<Mesh>this._attachedNode).absolutePosition);
             if(this.options.dragAxis){
-                var localAxis = Vector3.TransformCoordinates(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix());
+                this.useObjectOrienationForDragging ? Vector3.TransformCoordinatesToRef(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragAxis);
 
                 // Calculate plane normal in direction of camera but perpendicular to drag axis
-                var pointB = pointA.add(localAxis); // towards drag axis
-                var pointC = pointA.add(ray.origin.subtract(pointA).normalize()); // towards camera
+                this._pointA.addToRef(this._localAxis, this._pointB); // towards drag axis
+                ray.origin.subtractToRef(this._pointA, this._pointC)
+                this._pointA.addToRef(this._pointC.normalize(), this._pointC); // towards camera
                 // Get perpendicular line from direction to camera and drag axis
-                var lineA = pointB.subtract(pointA);
-                var lineB = pointC.subtract(pointA);
-                var perpLine = BABYLON.Vector3.Cross(lineA, lineB);
+                this._pointB.subtractToRef(this._pointA, this._lineA);
+                this._pointC.subtractToRef(this._pointA, this._lineB);
+                BABYLON.Vector3.CrossToRef(this._lineA, this._lineB, this._lookAt);
                 // Get perpendicular line from previous result and drag axis to adjust lineB to be perpendiculat to camera
-                var norm = BABYLON.Vector3.Cross(lineA, perpLine).normalize();
+                BABYLON.Vector3.CrossToRef(this._lineA, this._lookAt, this._lookAt);
+                this._lookAt.normalize();
 
-                this._dragPlane.position.copyFrom(pointA);
-                this._dragPlane.lookAt(pointA.subtract(norm));
+                this._dragPlane.position.copyFrom(this._pointA);
+                this._pointA.subtractToRef(this._lookAt, this._lookAt);
+                this._dragPlane.lookAt(this._lookAt);
             }else if(this.options.dragPlaneNormal){
-                this._dragPlane.position.copyFrom(pointA);
-                this._dragPlane.lookAt(pointA.subtract(this.options.dragPlaneNormal));
+                this.useObjectOrienationForDragging ? Vector3.TransformCoordinatesToRef(this.options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(),this._localAxis) : this._localAxis.copyFrom(this.options.dragPlaneNormal);
+                this._dragPlane.position.copyFrom(this._pointA);
+                this._pointA.subtractToRef(this._localAxis, this._lookAt);
+                this._dragPlane.lookAt(this._lookAt);
             }else{
-                this._dragPlane.position.copyFrom(pointA);
+                this._dragPlane.position.copyFrom(this._pointA);
                 this._dragPlane.lookAt(ray.origin);
             }
             this._dragPlane.computeWorldMatrix(true);

+ 143 - 0
src/Behaviors/Mesh/babylon.sixDofDragBehavior.ts

@@ -0,0 +1,143 @@
+module BABYLON {
+    /**
+     * A behavior that when attached to a mesh will allow the mesh to be dragged around based on directions and origin of the pointer's ray
+     */
+    export class SixDofDragBehavior implements Behavior<Mesh> {
+        private static _virtualScene:Scene;
+        private _ownerNode:Mesh;
+        private _sceneRenderObserver:Nullable<Observer<Scene>> = null;
+        private _scene:Scene;
+        private _targetPosition = new Vector3(0,0,0);
+        private _virtualOriginMesh:AbstractMesh;
+        private _virtualDragMesh:AbstractMesh;
+        private _pointerObserver:Nullable<Observer<PointerInfo>>;
+        // How much faster the object should move when its further away
+        private _sixDofZDragFactor = 5;
+        /**
+         * If the behavior is currently in a dragging state
+         */
+        public dragging = false;
+        /**
+         * The id of the pointer that is currently interacting with the behavior (-1 when no pointer is active)
+         */
+        public currentDraggingPointerID = -1;
+
+
+        constructor(){
+        }
+        
+        /**
+         *  The name of the behavior
+         */
+        public get name(): string {
+            return "SixDofDrag";
+        }
+
+        /**
+         *  Initializes the behavior
+         */
+        public init() {}
+
+        /**
+         * Attaches the scale behavior the passed in mesh
+         * @param ownerNode The mesh that will be scaled around once attached
+         */
+        public attach(ownerNode: Mesh): void {
+            this._ownerNode = ownerNode;
+            this._scene = this._ownerNode.getScene();
+            if(!SixDofDragBehavior._virtualScene){
+                SixDofDragBehavior._virtualScene = new BABYLON.Scene(this._scene.getEngine());
+                this._scene.getEngine().scenes.pop();
+            }
+        
+            var pickedMesh:Nullable<AbstractMesh> = null;
+            var lastSixDofOriginPosition = new BABYLON.Vector3(0,0,0);
+
+            // Setup virtual meshes to be used for dragging without dirtying the existing scene
+            this._virtualOriginMesh = new BABYLON.AbstractMesh("", SixDofDragBehavior._virtualScene);
+            this._virtualOriginMesh.rotationQuaternion = new Quaternion();
+            this._virtualDragMesh = new BABYLON.AbstractMesh("", SixDofDragBehavior._virtualScene);
+            this._virtualDragMesh.rotationQuaternion = new Quaternion();
+
+            var pickPredicate = (m:AbstractMesh)=>{
+                return this._ownerNode == m || m.isDescendantOf(this._ownerNode);
+            }
+            
+            this._pointerObserver = this._scene.onPointerObservable.add((pointerInfo, eventState)=>{                
+                if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
+                    if(!this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)){
+                        pickedMesh = pointerInfo.pickInfo.pickedMesh;
+                        lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
+
+                        // Set position and orientation of the controller
+                        this._virtualOriginMesh.position.copyFrom(pointerInfo.pickInfo.ray.origin);
+                        this._virtualOriginMesh.lookAt(pointerInfo.pickInfo.ray.origin.subtract(pointerInfo.pickInfo.ray.direction));
+
+                        // Attach the virtual drag mesh to the virtual origin mesh so it can be dragged
+                        this._virtualOriginMesh.removeChild(this._virtualDragMesh);
+                        this._virtualDragMesh.position.copyFrom(pickedMesh.absolutePosition);
+                        if(!pickedMesh.rotationQuaternion){
+                            pickedMesh.rotationQuaternion = new Quaternion();
+                        }
+                        this._virtualDragMesh.rotationQuaternion!.copyFrom(pickedMesh.rotationQuaternion);
+                        this._virtualOriginMesh.addChild(this._virtualDragMesh);
+
+                        // Update state
+                        this.dragging = true;
+                        this.currentDraggingPointerID = (<PointerEvent>pointerInfo.event).pointerId;
+                    }
+                }else if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERUP){
+                    if(this.currentDraggingPointerID == (<PointerEvent>pointerInfo.event).pointerId){
+                        this.dragging = false;
+                        this.currentDraggingPointerID = -1;
+                        pickedMesh = null;
+                        this._virtualOriginMesh.removeChild(this._virtualDragMesh);
+                    }
+                }else if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE){
+                    if(this.currentDraggingPointerID == (<PointerEvent>pointerInfo.event).pointerId && this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray && pickedMesh){
+                        // Calculate controller drag distance in controller space
+                        var originDragDifference = pointerInfo.pickInfo.ray.origin.subtract(lastSixDofOriginPosition);
+                        lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
+                        var localOriginDragDifference = Vector3.TransformCoordinates(originDragDifference, Matrix.Invert(this._virtualOriginMesh.getWorldMatrix().getRotationMatrix()));
+                        
+                        this._virtualOriginMesh.addChild(this._virtualDragMesh);
+                        // Determine how much the controller moved to/away towards the dragged object and use this to move the object further when its further away
+                        var zDragDistance = Vector3.Dot(localOriginDragDifference, this._virtualOriginMesh.position.normalizeToNew());
+                        this._virtualDragMesh.position.z -= this._virtualDragMesh.position.z < 1 ? zDragDistance*this._sixDofZDragFactor : zDragDistance*this._sixDofZDragFactor*this._virtualDragMesh.position.z;
+                        if(this._virtualDragMesh.position.z < 0){
+                            this._virtualDragMesh.position.z = 0;
+                        }
+                        
+                        // Update the controller position
+                        this._virtualOriginMesh.position.copyFrom(pointerInfo.pickInfo.ray.origin);
+                        this._virtualOriginMesh.lookAt(pointerInfo.pickInfo.ray.origin.subtract(pointerInfo.pickInfo.ray.direction));
+                        this._virtualOriginMesh.removeChild(this._virtualDragMesh)
+                    
+                        // Move the virtualObjectsPosition into the picked mesh's space if needed
+                        this._targetPosition.copyFrom(this._virtualDragMesh.absolutePosition);
+                        if(pickedMesh.parent){
+                            Vector3.TransformCoordinatesToRef(this._targetPosition, Matrix.Invert(pickedMesh.parent.getWorldMatrix()), this._targetPosition);
+                        }
+                    }
+                }
+            });
+
+            // On every frame move towards target scaling to avoid jitter caused by vr controllers
+            this._sceneRenderObserver = ownerNode.getScene().onBeforeRenderObservable.add(()=>{
+                if(this.dragging && pickedMesh){
+                    // Slowly move mesh to avoid jitter
+                    pickedMesh.position.addInPlace(this._targetPosition.subtract(pickedMesh.position).scale(0.2));
+                }
+            });
+        }
+        /**
+         *  Detaches the behavior from the mesh
+         */
+        public detach(): void {
+            this._scene.onPointerObservable.remove(this._pointerObserver);
+            this._ownerNode.getScene().onBeforeRenderObservable.remove(this._sceneRenderObserver);
+            this._virtualOriginMesh.dispose()
+            this._virtualDragMesh.dispose();
+        }
+    }
+}

+ 13 - 0
src/Gamepad/Controllers/babylon.poseEnabledController.ts

@@ -258,6 +258,19 @@ module BABYLON {
             if (!this._mesh.rotationQuaternion) {
                 this._mesh.rotationQuaternion = new Quaternion();
             }
+
+            // Sync controller mesh and pointing pose node's state with controller
+            this.update();
+            if(this._pointingPoseNode){
+                var parents = [];
+                var obj:Node = this._pointingPoseNode;
+                while(obj.parent){
+                    parents.push(obj.parent); 
+                    obj = obj.parent;
+                }
+                parents.reverse().forEach((p)=>{p.computeWorldMatrix(true)});
+            }
+
             this._meshAttachedObservable.notifyObservers(mesh);
         }
 

+ 4 - 2
src/Gamepad/Controllers/babylon.windowsMotionController.ts

@@ -348,14 +348,14 @@ module BABYLON {
 
                 if (meshLoaded) {
                     meshLoaded(this._defaultModel);
-                }
+                }                    
             }, null, (scene: Scene, message: string) => {
                 Tools.Log(message);
                 Tools.Warn('Failed to retrieve controller model from the remote server: ' + path + filename);
                 if (!forceDefault) {
                     this.initControllerMesh(scene, meshLoaded, true);
                 }
-            });
+            });            
         }
 
         /**
@@ -476,6 +476,8 @@ module BABYLON {
             loadedMeshInfo.pointingPoseNode = getChildByName(rootNode, this._mapping.pointingPoseMeshName);
             if (!loadedMeshInfo.pointingPoseNode) {
                 Tools.Warn('Missing pointing pose mesh with name: ' + this._mapping.pointingPoseMeshName);
+            }else{
+                this._pointingPoseNode = loadedMeshInfo.pointingPoseNode;
             }
 
             return loadedMeshInfo;

+ 1 - 1
src/Gizmos/babylon.planeRotationGizmo.ts

@@ -29,7 +29,7 @@ module BABYLON {
             this._rootMesh.lookAt(this._rootMesh.position.subtract(planeNormal));
 
             // Add drag behavior to handle events when the gizmo is dragged
-            this._dragBehavior = new PointerDragBehavior({dragPlaneNormal: planeNormal});
+            this._dragBehavior = new PointerDragBehavior({dragPlaneNormal: new Vector3(0,0,1)});
             this._dragBehavior.moveAttached = false;
             this._rootMesh.addBehavior(this._dragBehavior);
 

+ 1 - 1
src/Mesh/babylon.geometry.ts

@@ -189,7 +189,7 @@
         }
 
         /**
-         * Affects all gemetry data in one call
+         * Affects all geometry data in one call
          * @param vertexData defines the geometry data
          * @param updatable defines if the geometry must be flagged as updatable (false as default)
          */

+ 35 - 35
tests/unit/babylon/serializers/babylon.glTFSerializer.tests.ts

@@ -35,28 +35,28 @@ describe('Babylon glTF Serializer', () => {
      * This tests the glTF serializer help functions 
      */
     describe('#GLTF', () => {
-        it('should get alpha mode from Babylon metallic roughness', () => {
-            let alphaMode: string;
+        // it('should get alpha mode from Babylon metallic roughness', () => {
+        //     let alphaMode: string;
 
-            const scene = new BABYLON.Scene(subject);
-            const babylonMaterial = new BABYLON.PBRMetallicRoughnessMaterial("metallicroughness", scene);
-            babylonMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE;
+        //     const scene = new BABYLON.Scene(subject);
+        //     const babylonMaterial = new BABYLON.PBRMetallicRoughnessMaterial("metallicroughness", scene);
+        //     babylonMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE;
 
-            alphaMode = BABYLON.GLTF2._GLTFMaterial._GetAlphaMode(babylonMaterial);
-            alphaMode.should.be.equal('OPAQUE');
+        //     alphaMode = BABYLON.GLTF2._GLTFMaterial._GetAlphaMode(babylonMaterial);
+        //     alphaMode.should.be.equal('OPAQUE');
 
-            babylonMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_ALPHABLEND;
-            alphaMode = BABYLON.GLTF2._GLTFMaterial._GetAlphaMode(babylonMaterial);
-            alphaMode.should.be.equal('BLEND');
+        //     babylonMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_ALPHABLEND;
+        //     alphaMode = BABYLON.GLTF2._GLTFMaterial._GetAlphaMode(babylonMaterial);
+        //     alphaMode.should.be.equal('BLEND');
 
-            babylonMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND;
-            alphaMode = BABYLON.GLTF2._GLTFMaterial._GetAlphaMode(babylonMaterial);
-            alphaMode.should.be.equal('BLEND');
+        //     babylonMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND;
+        //     alphaMode = BABYLON.GLTF2._GLTFMaterial._GetAlphaMode(babylonMaterial);
+        //     alphaMode.should.be.equal('BLEND');
 
-            babylonMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST;
-            alphaMode = BABYLON.GLTF2._GLTFMaterial._GetAlphaMode(babylonMaterial);
-            alphaMode.should.be.equal('MASK');
-        });
+        //     babylonMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST;
+        //     alphaMode = BABYLON.GLTF2._GLTFMaterial._GetAlphaMode(babylonMaterial);
+        //     alphaMode.should.be.equal('MASK');
+        // });
 
         it('should convert Babylon standard material to metallic roughness', () => {
             const scene = new BABYLON.Scene(subject);
@@ -126,32 +126,32 @@ describe('Babylon glTF Serializer', () => {
                 });
         });
 
-        it('should serialize alpha mode and cutoff', () => {
-            const scene = new BABYLON.Scene(subject);
+        // it('should serialize alpha mode and cutoff', () => {
+        //     const scene = new BABYLON.Scene(subject);
 
-            const plane = BABYLON.Mesh.CreatePlane('plane', 120, scene);
-            const babylonPBRMetalRoughMaterial = new BABYLON.PBRMetallicRoughnessMaterial('metalRoughMat', scene);
-            babylonPBRMetalRoughMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST;
-            const alphaCutoff = 0.8;
-            babylonPBRMetalRoughMaterial.alphaCutOff = alphaCutoff;
+        //     const plane = BABYLON.Mesh.CreatePlane('plane', 120, scene);
+        //     const babylonPBRMetalRoughMaterial = new BABYLON.PBRMetallicRoughnessMaterial('metalRoughMat', scene);
+        //     babylonPBRMetalRoughMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_ALPHATEST;
+        //     const alphaCutoff = 0.8;
+        //     babylonPBRMetalRoughMaterial.alphaCutOff = alphaCutoff;
 
-            plane.material = babylonPBRMetalRoughMaterial;
+        //     plane.material = babylonPBRMetalRoughMaterial;
 
 
-            return BABYLON.GLTF2Export.GLTFAsync(scene, 'test').then(glTFData => {
-                const jsonString = glTFData.glTFFiles['test.gltf'] as string;
-                const jsonData = JSON.parse(jsonString);
+        //     return BABYLON.GLTF2Export.GLTFAsync(scene, 'test').then(glTFData => {
+        //         const jsonString = glTFData.glTFFiles['test.gltf'] as string;
+        //         const jsonData = JSON.parse(jsonString);
 
-                // accessors, asset, buffers, bufferViews, meshes, nodes, scene, scenes, materials
-                Object.keys(jsonData).length.should.be.equal(9);
+        //         // accessors, asset, buffers, bufferViews, meshes, nodes, scene, scenes, materials
+        //         Object.keys(jsonData).length.should.be.equal(9);
 
-                jsonData.materials.length.should.be.equal(2);
+        //         jsonData.materials.length.should.be.equal(2);
 
-                jsonData.materials[0].alphaMode.should.be.equal('MASK');
+        //         jsonData.materials[0].alphaMode.should.be.equal('MASK');
 
-                jsonData.materials[0].alphaCutoff.should.be.equal(alphaCutoff);
-            });
-        });
+        //         jsonData.materials[0].alphaCutoff.should.be.equal(alphaCutoff);
+        //     });
+        // });
         it('should serialize single component translation animation to glTF', () => {
             const scene = new BABYLON.Scene(subject);
             const box = BABYLON.Mesh.CreateBox('box', 1, scene);