Преглед на файлове

Merge remote-tracking branch 'BabylonJS/master' into viewer-extends

Raanan Weber преди 7 години
родител
ревизия
88c9b52a64
променени са 47 файла, в които са добавени 11016 реда и са изтрити 10705 реда
  1. 864 830
      Playground/babylon.d.txt
  2. 1 1
      Playground/js/index.js
  3. 9433 9426
      dist/preview release/babylon.d.ts
  4. 34 34
      dist/preview release/babylon.js
  5. 74 33
      dist/preview release/babylon.max.js
  6. 74 33
      dist/preview release/babylon.no-module.max.js
  7. 35 35
      dist/preview release/babylon.worker.js
  8. 74 33
      dist/preview release/es6.js
  9. 3 3
      dist/preview release/inspector/babylon.inspector.bundle.js
  10. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  11. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  12. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  13. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  14. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.js
  15. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  16. 1 1
      dist/preview release/loaders/babylonjs.loaders.d.ts
  17. 2 2
      dist/preview release/loaders/babylonjs.loaders.js
  18. 1 1
      dist/preview release/loaders/babylonjs.loaders.min.js
  19. 1 1
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  20. 2 31
      dist/preview release/typedocValidationBaseline.json
  21. 62 62
      dist/preview release/viewer/babylon.viewer.js
  22. 76 35
      dist/preview release/viewer/babylon.viewer.max.js
  23. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts
  24. 7 9
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  25. 2 1
      sandbox/index-local.html
  26. 13 15
      sandbox/index.css
  27. 5 4
      sandbox/index.html
  28. 34 6
      sandbox/index.js
  29. 1 7
      src/Animations/babylon.animatable.ts
  30. 31 47
      src/Animations/babylon.runtimeAnimation.ts
  31. 8 1
      src/Cameras/VR/babylon.vrExperienceHelper.ts
  32. 3 0
      src/Engine/babylon.nullEngine.ts
  33. 6 0
      src/Gamepad/Controllers/babylon.poseEnabledController.ts
  34. 14 1
      src/Loading/Plugins/babylon.babylonFileLoader.ts
  35. 1 1
      src/Materials/PBR/babylon.pbrBaseMaterial.ts
  36. 1 14
      src/Math/babylon.math.ts
  37. 3 0
      src/Mesh/babylon.abstractMesh.ts
  38. 4 5
      src/Mesh/babylon.geometry.ts
  39. 2 2
      src/Mesh/babylon.vertexBuffer.ts
  40. 18 1
      src/PostProcess/babylon.fxaaPostProcess.ts
  41. 13 0
      src/Shaders/fxaa.fragment.fx
  42. 1 1
      src/Tools/babylon.sceneOptimizer.ts
  43. 23 15
      src/babylon.scene.ts
  44. 11 2
      tests/nullEngine/app.js
  45. 2 2
      tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.ts
  46. 65 0
      tests/unit/babylon/src/Mesh/babylon.geometry.tests.ts
  47. 1 0
      tests/unit/karma.conf.js

Файловите разлики са ограничени, защото са твърде много
+ 864 - 830
Playground/babylon.d.txt


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
Playground/js/index.js


Файловите разлики са ограничени, защото са твърде много
+ 9433 - 9426
dist/preview release/babylon.d.ts


Файловите разлики са ограничени, защото са твърде много
+ 34 - 34
dist/preview release/babylon.js


Файловите разлики са ограничени, защото са твърде много
+ 74 - 33
dist/preview release/babylon.max.js


Файловите разлики са ограничени, защото са твърде много
+ 74 - 33
dist/preview release/babylon.no-module.max.js


Файловите разлики са ограничени, защото са твърде много
+ 35 - 35
dist/preview release/babylon.worker.js


Файловите разлики са ограничени, защото са твърде много
+ 74 - 33
dist/preview release/es6.js


Файловите разлики са ограничени, защото са твърде много
+ 3 - 3
dist/preview release/inspector/babylon.inspector.bundle.js


+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -797,7 +797,7 @@ declare module BABYLON.GLTF2.Extensions {
 
 declare module BABYLON.GLTF2.Extensions {
     /**
-     * [Specification](https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit) (Experimental)
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
      */
     class KHR_materials_unlit extends GLTFLoaderExtension {
         readonly name: string;

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

@@ -1241,7 +1241,7 @@ var BABYLON;
                 });
                 loadAttribute("TANGENT", BABYLON.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) {
                     var dataIndex = 0;
-                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                    babylonVertexBuffer.forEach(data.length / 3 * 4, function (value, index) {
                         // 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.
@@ -2730,7 +2730,7 @@ var BABYLON;
         (function (Extensions) {
             var NAME = "KHR_materials_unlit";
             /**
-             * [Specification](https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit) (Experimental)
+             * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
              */
             var KHR_materials_unlit = /** @class */ (function (_super) {
                 __extends(KHR_materials_unlit, _super);

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -1373,7 +1373,7 @@ declare module BABYLON.GLTF2.Extensions {
 
 declare module BABYLON.GLTF2.Extensions {
     /**
-     * [Specification](https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit) (Experimental)
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
      */
     class KHR_materials_unlit extends GLTFLoaderExtension {
         readonly name: string;

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

@@ -3456,7 +3456,7 @@ var BABYLON;
                 });
                 loadAttribute("TANGENT", BABYLON.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) {
                     var dataIndex = 0;
-                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                    babylonVertexBuffer.forEach(data.length / 3 * 4, function (value, index) {
                         // 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.
@@ -4945,7 +4945,7 @@ var BABYLON;
         (function (Extensions) {
             var NAME = "KHR_materials_unlit";
             /**
-             * [Specification](https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit) (Experimental)
+             * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
              */
             var KHR_materials_unlit = /** @class */ (function (_super) {
                 __extends(KHR_materials_unlit, _super);

Файловите разлики са ограничени, защото са твърде много
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.d.ts

@@ -1469,7 +1469,7 @@ declare module BABYLON.GLTF2.Extensions {
 
 declare module BABYLON.GLTF2.Extensions {
     /**
-     * [Specification](https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit) (Experimental)
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
      */
     class KHR_materials_unlit extends GLTFLoaderExtension {
         readonly name: string;

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

@@ -4438,7 +4438,7 @@ var BABYLON;
                 });
                 loadAttribute("TANGENT", BABYLON.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) {
                     var dataIndex = 0;
-                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                    babylonVertexBuffer.forEach(data.length / 3 * 4, function (value, index) {
                         // 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.
@@ -5873,7 +5873,7 @@ var BABYLON;
         (function (Extensions) {
             var NAME = "KHR_materials_unlit";
             /**
-             * [Specification](https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit) (Experimental)
+             * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
              */
             var KHR_materials_unlit = /** @class */ (function (_super) {
                 __extends(KHR_materials_unlit, _super);

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -1476,7 +1476,7 @@ declare module BABYLON.GLTF2.Extensions {
 
 declare module BABYLON.GLTF2.Extensions {
     /**
-     * [Specification](https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit) (Experimental)
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
      */
     class KHR_materials_unlit extends GLTFLoaderExtension {
         readonly name: string;

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

@@ -1,7 +1,7 @@
 {
-  "errors": 4325,
+  "errors": 4320,
   "babylon.typedoc.json": {
-    "errors": 4325,
+    "errors": 4320,
     "Animatable": {
       "Class": {
         "Comments": {
@@ -17898,35 +17898,6 @@
             "MissingText": true
           }
         }
-      },
-      "Method": {
-        "serialize": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
-        "Parse": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "source": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "scene": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "rootUrl": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        }
       }
     },
     "StateCondition": {

Файловите разлики са ограничени, защото са твърде много
+ 62 - 62
dist/preview release/viewer/babylon.viewer.js


Файловите разлики са ограничени, защото са твърде много
+ 76 - 35
dist/preview release/viewer/babylon.viewer.max.js


+ 1 - 1
loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts

@@ -4,7 +4,7 @@ module BABYLON.GLTF2.Extensions {
     const NAME = "KHR_materials_unlit";
 
     /**
-     * [Specification](https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit) (Experimental)
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit)
      */
     export class KHR_materials_unlit extends GLTFLoaderExtension {
         public readonly name = NAME;

+ 7 - 9
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -729,7 +729,7 @@ module BABYLON.GLTF2 {
 
             loadAttribute("TANGENT", VertexBuffer.TangentKind, (babylonVertexBuffer, data) => {
                 let dataIndex = 0;
-                babylonVertexBuffer.forEach(data.length, (value, index) => {
+                babylonVertexBuffer.forEach(data.length / 3 * 4, (value, index) => {
                     // 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.
@@ -1062,14 +1062,12 @@ module BABYLON.GLTF2 {
                             outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                         })));
 
-                        const morphTargets = new Array<any>();
                         this._forEachPrimitive(targetNode, babylonMesh => {
                             const morphTarget = babylonMesh.morphTargetManager!.getTarget(targetIndex);
-                            morphTarget.animations.push(babylonAnimation);
-                            morphTargets.push(morphTarget);
+                            const babylonAnimationClone = babylonAnimation.clone();
+                            morphTarget.animations.push(babylonAnimationClone);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimationClone, morphTarget);
                         });
-
-                        babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTargets);
                     }
                 }
                 else {
@@ -1079,10 +1077,10 @@ module BABYLON.GLTF2 {
 
                     if (targetNode._babylonAnimationTargets) {
                         for (const babylonAnimationTarget of targetNode._babylonAnimationTargets) {
-                            babylonAnimationTarget.animations.push(babylonAnimation);
+                            const babylonAnimationClone = babylonAnimation.clone();
+                            babylonAnimationTarget.animations.push(babylonAnimationClone);
+                            babylonAnimationGroup.addTargetedAnimation(babylonAnimationClone, babylonAnimationTarget);
                         }
-
-                        babylonAnimationGroup.addTargetedAnimation(babylonAnimation, targetNode._babylonAnimationTargets);
                     }
                 }
             });

+ 2 - 1
sandbox/index-local.html

@@ -9,6 +9,7 @@
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
 </head>
 <body>
+    <p id="droptext">Drag and drop gltf, glb, obj or babylon files to view them</p>
     <canvas id="renderCanvas"></canvas>
     <div id="logo">
     </div>
@@ -33,7 +34,7 @@
         </div>               
         <div class="footerRight">
             <a href="#" id="btnFullscreen" class="hidden"><img src="./Assets/Icon_Fullscreen.svg" alt="Switch the scene to full screen" title="Switch the scene to full screen" /></a> 
-            <a href="#" id="btnInspector" class="hidden"><img src="./Assets/Icon_EditModel.svg" alt="Display inspector" title="Display inspector" /></i></a> 
+            <a href="#" id="btnInspector" class="hidden"><img src="./Assets/Icon_EditModel.svg" alt="Display inspector" title="Display inspector" /></a> 
             <a href="#">
                 <div class="custom-upload" title="Open your scene from your hard drive (.babylon, .gltf, .glb, .obj)">
                     <input type="file" id="files" multiple />

+ 13 - 15
sandbox/index.css

@@ -106,6 +106,14 @@ a {
     background-size: 50%;
 }
 
+#droptext {
+    position: absolute;;
+    text-align: center;
+    color: #fff;
+    height: 50px;
+    width: 100%;
+    bottom: 5%;    
+}
 #btnDownArrow {
     position: absolute;
     bottom: 35px;
@@ -271,6 +279,8 @@ a {
     z-index: 1;
     min-width: 135px;
     width: 200px;
+    flex-direction: column;
+    transition: all 0.3s ease; /* Add transition for hover effects */
 }
 
 #dropdownContent a,
@@ -278,12 +288,6 @@ a {
     cursor: pointer;
 }
 
-.dropdown:hover #dropdownContent {
-    display: flex;
-    flex-direction: column;
-    transition: all 0.3s ease; /* Add transition for hover effects */
-}
-
 #chevronUp {
     display: inline;
     margin-right: 0px;
@@ -295,13 +299,6 @@ a {
     margin-left: 0px;
 }
 
-.dropdown:hover #chevronUp {
-    display: none;
-}
-.dropdown:hover #chevronDown {
-    display: inline;
-}
-
 #playBtn.play #pauseImg,
 #playBtn.pause #playImg{
     display: none;
@@ -311,9 +308,10 @@ a {
     -webkit-appearance: none;
     cursor: pointer;
     width: 1000px;
+    height: 50px;
     outline: none;
-    border-radius: 5px;
     margin-left: 20px;
+    background-color: transparent;
 }
 
 /*Chrome -webkit */
@@ -329,7 +327,7 @@ a {
 #slider::-webkit-slider-runnable-track {
     height: 2px;
     -webkit-appearance: none;
-    color: white;
+    background-color: white;
 }
 
 

+ 5 - 4
sandbox/index.html

@@ -1,7 +1,9 @@
 <!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-    <title>BabylonJS - Sandbox</title>
+    <title>BabylonJS Sandbox - View glTF, glb, obj and babylon files</title>
+    <meta name="description" content="Viewer for glTF, glb, obj and babylon files powered by BabylonJS" />
+    <meta name="keywords" content="Babylon.js, Babylon, BabylonJS, glTF, glb, obj, viewer, online viewer, 3D model viewer, 3D, webgl" />
     <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
 
     <link rel="shortcut icon" href="http://www.babylonjs.com/img/favicon/favicon.ico">
@@ -23,7 +25,6 @@
     <meta name="msapplication-TileImage" content="http://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
     <meta name="msapplication-config" content="http://www.babylonjs.com/img/favicon/browserconfig.xml">
     <meta name="theme-color" content="#ffffff">
-    <meta name="keywords" content="3D, Babylon.js, webgl, gltf, viewer">
 
     <link href="index.css" rel="stylesheet" />
     <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
@@ -36,8 +37,8 @@
     <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
     <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
 </head>
-
 <body>
+    <p id="droptext">Drag and drop gltf, glb, obj or babylon files to view them</p>
     <canvas id="renderCanvas" touch-action="none"></canvas>
     <div id="logo">
     </div>
@@ -62,7 +63,7 @@
         </div>               
         <div class="footerRight">
             <a href="#" id="btnFullscreen" class="hidden"><img src="./Assets/Icon_Fullscreen.svg" alt="Switch the scene to full screen" title="Switch the scene to full screen" /></a> 
-            <a href="#" id="btnInspector" class="hidden"><img src="./Assets/Icon_EditModel.svg" alt="Display inspector" title="Display inspector" /></i></a> 
+            <a href="#" id="btnInspector" class="hidden"><img src="./Assets/Icon_EditModel.svg" alt="Display inspector" title="Display inspector" /></a> 
             <a href="#">
                 <div class="custom-upload" title="Open your scene from your hard drive (.babylon, .gltf, .glb, .obj)">
                     <input type="file" id="files" multiple />

+ 34 - 6
sandbox/index.js

@@ -9,6 +9,9 @@ var currentGroupIndex;
 var currentScene;
 // html balise
 var animationBar = document.getElementById("animationBar");
+var dropdownBtn = document.getElementById("dropdownBtn");
+var chevronUp = document.getElementById("chevronUp");
+var chevronDown = document.getElementById("chevronDown");
 var dropdownLabel = document.getElementById("dropdownLabel");
 var dropdownContent = document.getElementById("dropdownContent");
 var playBtn = document.getElementById("playBtn");
@@ -187,6 +190,7 @@ if (BABYLON.Engine.isSupported()) {
                 displayDebugLayerAndLogs();
             }
             document.getElementById("logo").className = "hidden";
+            document.getElementById("droptext").className = "hidden";
             canvas.style.opacity = 1;
             if (currentScene.activeCamera.keysUp) {
                 currentScene.activeCamera.keysUp.push(90); // Z
@@ -229,7 +233,7 @@ if (BABYLON.Engine.isSupported()) {
                 });
             });
         }).catch(function (reason) {
-            sceneError({ name: fileName }, null, reason);
+            sceneError({ name: fileName }, null, reason.message || reason);
         });
     }
     else {
@@ -246,7 +250,7 @@ if (BABYLON.Engine.isSupported()) {
 
         window.addEventListener("keydown", function (evt) {
             // Press R to reload
-            if (evt.keyCode === 82) {
+            if (evt.keyCode === 82 && !enableDebugLayer) {
                 filesInput.reload();
             }
         });
@@ -287,8 +291,8 @@ if (BABYLON.Engine.isSupported()) {
     }, false);
 
     window.addEventListener("keydown", function (evt) {
-        // Press Esc to toggle footer
-        if (evt.keyCode === 27 &&!enableDebugLayer) {
+        // Press space to toggle footer
+        if (evt.keyCode === 32 && !enableDebugLayer) {
             if (footer.style.display === "none") {
                 footer.style.display = "block";
             }
@@ -326,6 +330,27 @@ function formatId(name){
     return "data-" + name.replace(/\s/g,'');
 }
 
+function displayDropdownContent(display) {
+    if(display) {
+        dropdownContent.style.display = "flex";
+        chevronDown.style.display = "inline";
+        chevronUp.style.display = "none";
+    }
+    else {
+        dropdownContent.style.display = "none";
+        chevronDown.style.display = "none";
+        chevronUp.style.display = "inline";
+    }
+}
+dropdownBtn.addEventListener("click", function() {
+    if(dropdownContent.style.display === "flex") {
+        displayDropdownContent(false);
+    }
+    else {
+        displayDropdownContent(true);
+    }
+});
+
 function createDropdownLink(group,index) {
     var animation = document.createElement("a");
     animation.innerHTML = group.name;
@@ -348,8 +373,11 @@ function createDropdownLink(group,index) {
         // set the slider
         slider.setAttribute("min", currentGroup.from);
         slider.setAttribute("max", currentGroup.to);
-        currentSliderValue = 0;
-        slider.value = 0;
+        currentSliderValue = currentGroup.from;
+        slider.value = currentGroup.from;
+
+        // hide the content of the dropdown
+        displayDropdownContent(false);
     });
     dropdownContent.appendChild(animation);
 }

+ 1 - 7
src/Animations/babylon.animatable.ts

@@ -136,13 +136,7 @@
             var runtimeAnimations = this._runtimeAnimations;
 
             for (var index = 0; index < runtimeAnimations.length; index++) {
-                runtimeAnimations[index].reset();
-            }
-
-            // Reset to original value
-            for (index = 0; index < runtimeAnimations.length; index++) {
-                var animation = runtimeAnimations[index];
-                animation.animate(0, this.fromFrame, this.toFrame, false, this._speedRatio);
+                runtimeAnimations[index].reset(true);
             }
 
             this._localDelayOffset = null;

+ 31 - 47
src/Animations/babylon.runtimeAnimation.ts

@@ -164,8 +164,13 @@
 
         /**
          * Resets the runtime animation to the beginning
+         * @param restoreOriginal defines whether to restore the target property to the original value
          */
-        public reset(): void {
+        public reset(restoreOriginal = false): void {
+            if (restoreOriginal && this._originalValue != null) {
+                this.setValue(this._originalValue, -1);
+            }
+
             this._offsetsCache = {};
             this._highLimitsCache = {};
             this._currentFrame = 0;
@@ -212,28 +217,11 @@
         }
 
         /**
-         * Affect the interpolated value to the target
+         * Apply the interpolated value to the target
          * @param currentValue defines the value computed by the animation
-         * @param weight defines the weight to apply to this value
+         * @param weight defines the weight to apply to this value (Defaults to 1.0)
          */
         public setValue(currentValue: any, weight = 1.0): void {
-            if (this._target instanceof Array) {
-                for (const target of this._target) {
-                    this._setValue(target, currentValue, weight);
-                }
-            }
-            else {
-                this._setValue(this._target, currentValue, weight);
-            }
-        }
-
-        /**
-         * Sets the value of the runtime animation
-         * @param target The target property of the runtime animation
-         * @param currentValue The current value to use for the runtime animation
-         * @param weight The weight to use for the runtime animation (Defaults to 1.0)
-         */
-        private _setValue(target: any, currentValue: any, weight = 1.0): void {
             // Set value
             var path: any;
             var destination: any;
@@ -241,7 +229,7 @@
             let targetPropertyPath = this._animation.targetPropertyPath
 
             if (targetPropertyPath.length > 1) {
-                var property = target[targetPropertyPath[0]];
+                var property = this._target[targetPropertyPath[0]];
 
                 for (var index = 1; index < targetPropertyPath.length - 1; index++) {
                     property = property[targetPropertyPath[index]];
@@ -251,17 +239,31 @@
                 destination = property;
             } else {
                 path = targetPropertyPath[0];
-                destination = target;
+                destination = this._target;
             }
 
             this._targetPath = path;
             this._activeTarget = destination;
             this._weight = weight;
 
+            if (!this._originalValue) {
+                let originalValue: any;
+
+                if (destination.getRestPose && path === "_matrix") { // For bones
+                    originalValue = destination.getRestPose();
+                } else {
+                    originalValue = destination[path];
+                }
+
+                if (originalValue.clone) {
+                    this._originalValue = originalValue.clone();
+                } else {
+                    this._originalValue = originalValue;
+                }
+            }
+
             // Blending
-            let enableBlending = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
-            let blendingSpeed = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
-            
+            const enableBlending = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
             if (enableBlending && this._blendingFactor <= 1.0) {
                 if (!this._originalBlendValue) {
                     let originalValue = destination[path];
@@ -272,27 +274,7 @@
                         this._originalBlendValue = originalValue;
                     }
                 }
-            }
-
-            if (weight !== -1.0) {
-                if (!this._originalValue) {
-                    let originalValue: any;
 
-                    if (destination.getRestPose && path === "_matrix") { // For bones
-                        originalValue = destination.getRestPose();
-                    } else {
-                        originalValue = destination[path];
-                    }
-
-                    if (originalValue.clone) {
-                        this._originalValue = originalValue.clone();
-                    } else {
-                        this._originalValue = originalValue;
-                    }
-                }
-            }
-
-            if (enableBlending && this._blendingFactor <= 1.0) {
                 if (this._originalBlendValue.m) { // Matrix
                     if (Animation.AllowMatrixDecomposeForInterpolation) {
                         if (this._currentValue) {
@@ -319,6 +301,8 @@
                         this._currentValue = currentValue;
                     }
                 }
+
+                const blendingSpeed = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
                 this._blendingFactor += blendingSpeed;
             } else {
                 this._currentValue = currentValue;
@@ -330,8 +314,8 @@
                 destination[path] = this._currentValue;
             }
 
-            if (target.markAsDirty) {
-                target.markAsDirty(this._animation.targetProperty);
+            if (this._target.markAsDirty) {
+                this._target.markAsDirty(this._animation.targetProperty);
             }
         }
 

+ 8 - 1
src/Cameras/VR/babylon.vrExperienceHelper.ts

@@ -104,7 +104,7 @@ module BABYLON {
 
     class VRExperienceHelperControllerGazer extends VRExperienceHelperGazer{
         private _laserPointer: Mesh;
-
+        private _meshAttachedObserver: Nullable<Observer<AbstractMesh>>;
         constructor(public webVRController: WebVRController, scene: Scene, gazeTrackerToClone:Mesh){
             super(scene, gazeTrackerToClone);
             // Laser pointer
@@ -127,6 +127,10 @@ module BABYLON {
             }
 
             this._setLaserPointerParent(webVRController.mesh!);
+
+            this._meshAttachedObserver = webVRController._meshAttachedObservable.add((mesh)=>{
+                this._setLaserPointerParent(mesh);
+            });
         }
 
         _getForwardRay(length:number):Ray{
@@ -176,6 +180,9 @@ module BABYLON {
         dispose(){
             super.dispose();
             this._laserPointer.dispose();
+            if(this._meshAttachedObserver){
+                this.webVRController._meshAttachedObservable.remove(this._meshAttachedObserver);
+            }
         }
     }
 

+ 3 - 0
src/Engine/babylon.nullEngine.ts

@@ -428,5 +428,8 @@
 
             return false;
         }
+
+        public releaseEffects() {
+        }
     }
 }

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

@@ -239,6 +239,11 @@ module BABYLON {
         }
 
         /**
+         * @hidden
+         */
+        public _meshAttachedObservable = new Observable<AbstractMesh>()
+
+        /**
          * Attaches a mesh to the controller
          * @param mesh the mesh to be attached
          */
@@ -253,6 +258,7 @@ module BABYLON {
             if (!this._mesh.rotationQuaternion) {
                 this._mesh.rotationQuaternion = new Quaternion();
             }
+            this._meshAttachedObservable.notifyObservers(mesh);
         }
 
         /**

+ 14 - 1
src/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -680,7 +680,20 @@
 
                 // Environment texture		
                 if (parsedData.environmentTexture !== undefined && parsedData.environmentTexture !== null) {
-                    scene.environmentTexture = CubeTexture.CreateFromPrefilteredData(rootUrl + parsedData.environmentTexture, scene);
+                    if (parsedData.environmentTextureType && parsedData.environmentTextureType === "BABYLON.HDRCubeTexture") {
+                        var hdrSize:number = (parsedData.environmentTextureSize) ? parsedData.environmentTextureSize : 128;
+                        var hdrTexture = new HDRCubeTexture(rootUrl + parsedData.environmentTexture, scene, hdrSize);
+                        if (parsedData.environmentTextureRotationY) {
+                            hdrTexture.rotationY = parsedData.environmentTextureRotationY;
+                        }
+                        scene.environmentTexture = hdrTexture;
+                    } else {
+                        var cubeTexture = CubeTexture.CreateFromPrefilteredData(rootUrl + parsedData.environmentTexture, scene);
+                        if (parsedData.environmentTextureRotationY) {
+                            cubeTexture.rotationY = parsedData.environmentTextureRotationY;
+                        }
+                        scene.environmentTexture = cubeTexture;                        
+                    }
                     if (parsedData.createDefaultSkybox === true) {
                         var skyboxScale = (scene.activeCamera !== undefined && scene.activeCamera !== null) ? (scene.activeCamera.maxZ - scene.activeCamera.minZ) / 2 : 1000;
                         var skyboxBlurLevel = parsedData.skyboxBlurLevel || 0;

+ 1 - 1
src/Materials/PBR/babylon.pbrBaseMaterial.ts

@@ -1611,7 +1611,7 @@
 
             this._uniformBuffer.update();
 
-            this._afterBind(mesh);
+            this._afterBind(mesh, this._activeEffect);
         }
 
         /**

+ 1 - 14
src/Math/babylon.math.ts

@@ -1565,20 +1565,7 @@
          * @returns a new Quaternion object, computed from the Vector3 coordinates
          */
         public toQuaternion(): Quaternion {
-            var result = new Quaternion(0.0, 0.0, 0.0, 1.0);
-
-            var cosxPlusz = Math.cos((this.x + this.z) * 0.5);
-            var sinxPlusz = Math.sin((this.x + this.z) * 0.5);
-            var coszMinusx = Math.cos((this.z - this.x) * 0.5);
-            var sinzMinusx = Math.sin((this.z - this.x) * 0.5);
-            var cosy = Math.cos(this.y * 0.5);
-            var siny = Math.sin(this.y * 0.5);
-
-            result.x = coszMinusx * siny;
-            result.y = -sinzMinusx * siny;
-            result.z = sinxPlusz * cosy;
-            result.w = cosxPlusz * cosy;
-            return result;
+            return BABYLON.Quaternion.RotationYawPitchRoll(this.x, this.y, this.z);
         }
 
         /**

+ 3 - 0
src/Mesh/babylon.abstractMesh.ts

@@ -1059,6 +1059,9 @@
          * @returns the new bounding vectors
          */
         public getHierarchyBoundingVectors(includeDescendants = true): { min: Vector3, max: Vector3 } {
+            // Ensures that all world matrix will be recomputed.
+            this.getScene().incrementRenderId();
+
             this.computeWorldMatrix(true);
 
             let min: Vector3;

+ 4 - 5
src/Mesh/babylon.geometry.ts

@@ -387,11 +387,10 @@
                  return null;
             }
 
-            const defaultStride = VertexBuffer.DeduceStride(vertexBuffer.getKind());
-            const defaultByteStride = defaultStride * VertexBuffer.GetTypeByteLength(vertexBuffer.type);
-            const count = this._totalVertices * defaultStride;
+            const tightlyPackedByteStride = vertexBuffer.getSize() * VertexBuffer.GetTypeByteLength(vertexBuffer.type);
+            const count = this._totalVertices * vertexBuffer.getSize();
 
-            if (vertexBuffer.type !== VertexBuffer.FLOAT || vertexBuffer.byteStride !== defaultByteStride) {
+            if (vertexBuffer.type !== VertexBuffer.FLOAT || vertexBuffer.byteStride !== tightlyPackedByteStride) {
                 const copy = new Array<number>(count);
                 vertexBuffer.forEach(count, (value, index) => {
                     copy[index] = value;
@@ -399,7 +398,7 @@
                 return copy;
             }
 
-            if (!(data instanceof Array || data instanceof Float32Array) || vertexBuffer.byteOffset !== 0 || data.length !== count) {
+            if (!((data instanceof Array) || (data instanceof Float32Array)) || vertexBuffer.byteOffset !== 0 || data.length !== count) {
                 if (data instanceof Array) {
                     const offset = vertexBuffer.byteOffset / 4;
                     return Tools.Slice(data, offset, offset + count);

+ 2 - 2
src/Mesh/babylon.vertexBuffer.ts

@@ -423,7 +423,7 @@
                 case VertexBuffer.BYTE: {
                     let value = dataView.getInt8(byteOffset);
                     if (normalized) {
-                        value = (value + 0.5) / 127.5;
+                        value = Math.max(value / 127, -1);
                     }
                     return value;
                 }
@@ -437,7 +437,7 @@
                 case VertexBuffer.SHORT: {
                     let value = dataView.getInt16(byteOffset, true);
                     if (normalized) {
-                        value = (value + 0.5) / 16383.5;
+                        value = Math.max(value / 16383, -1);
                     }
                     return value;
                 }

+ 18 - 1
src/PostProcess/babylon.fxaaPostProcess.ts

@@ -4,12 +4,29 @@
         public texelHeight: number;
 
         constructor(name: string, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT) {
-            super(name, "fxaa", ["texelSize"], null, options, camera, samplingMode || Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "fxaa");
+            super(name, "fxaa", ["texelSize"], null, options, camera, samplingMode || Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "fxaa", undefined, true);
+
+            const defines = this._getDefines();
+            this.updateEffect(defines);
 
             this.onApplyObservable.add((effect: Effect) => {
                 var texelSize = this.texelSize;
                 effect.setFloat2("texelSize", texelSize.x, texelSize.y);
             });
         }
+
+        private _getDefines(): Nullable<string> {
+            const engine = this.getEngine();
+            if (!engine) {
+                return null;
+            }
+
+            const glInfo = engine.getGlInfo();
+            if (glInfo && glInfo.renderer && glInfo.renderer.toLowerCase().indexOf("mali") > -1) {
+                return "#define MALI 1\n";
+            }
+
+            return null;
+        }
     }
 }

+ 13 - 0
src/Shaders/fxaa.fragment.fx

@@ -42,11 +42,13 @@ void main(){
 	float range = rangeMax - rangeMin;
 	float rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
 
+#ifndef MALI
 	if(range < rangeMaxClamped) 
 	{
 		gl_FragColor = rgbyM;
 		return;
 	}
+#endif
 
 	float lumaNW = FxaaLuma(texture2D(textureSampler, sampleCoordNW, 0.0));
 	float lumaSE = FxaaLuma(texture2D(textureSampler, sampleCoordSE, 0.0));
@@ -231,5 +233,16 @@ void main(){
 		posM.y += pixelOffsetSubpix * lengthSign;
 	}
 
+#ifdef MALI
+	if(range < rangeMaxClamped) 
+	{
+		gl_FragColor = rgbyM;
+	}
+	else
+	{
+		gl_FragColor = texture2D(textureSampler, posM, 0.0);
+	}
+#else
 	gl_FragColor = texture2D(textureSampler, posM, 0.0);
+#endif
 }

+ 1 - 1
src/Tools/babylon.sceneOptimizer.ts

@@ -433,7 +433,7 @@
                 }
 
                 // Merge meshes
-                Mesh.MergeMeshes(currentPool);
+                Mesh.MergeMeshes(currentPool, undefined, true);
             }
 
             if (updateSelectionTree != undefined) {

+ 23 - 15
src/babylon.scene.ts

@@ -2116,25 +2116,28 @@
                     this._processPointerUp(pickResult, evt, clickInfo);
 
                     // Sprites
-                    if (this.spriteManagers.length > 0) {
-                        let spritePickResult = this.pickSprite(this._unTranslatedPointerX, this._unTranslatedPointerY, this._spritePredicate, false, this.cameraToUseForPointers || undefined);
-
-                        if (spritePickResult) {
-                            if (spritePickResult.hit && spritePickResult.pickedSprite) {
-                                if (spritePickResult.pickedSprite.actionManager) {
-                                    spritePickResult.pickedSprite.actionManager.processTrigger(ActionManager.OnPickUpTrigger, ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, this, evt));
+                    if(!clickInfo.ignore){
+                        if (this.spriteManagers.length > 0) {
+                            let spritePickResult = this.pickSprite(this._unTranslatedPointerX, this._unTranslatedPointerY, this._spritePredicate, false, this.cameraToUseForPointers || undefined);
+    
+                            if (spritePickResult) {
+                                if (spritePickResult.hit && spritePickResult.pickedSprite) {
                                     if (spritePickResult.pickedSprite.actionManager) {
-                                        if (Math.abs(this._startingPointerPosition.x - this._pointerX) < Scene.DragMovementThreshold && Math.abs(this._startingPointerPosition.y - this._pointerY) < Scene.DragMovementThreshold) {
-                                            spritePickResult.pickedSprite.actionManager.processTrigger(ActionManager.OnPickTrigger, ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, this, evt));
+                                        spritePickResult.pickedSprite.actionManager.processTrigger(ActionManager.OnPickUpTrigger, ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, this, evt));
+                                        if (spritePickResult.pickedSprite.actionManager) {
+                                            if (Math.abs(this._startingPointerPosition.x - this._pointerX) < Scene.DragMovementThreshold && Math.abs(this._startingPointerPosition.y - this._pointerY) < Scene.DragMovementThreshold) {
+                                                spritePickResult.pickedSprite.actionManager.processTrigger(ActionManager.OnPickTrigger, ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, this, evt));
+                                            }
                                         }
                                     }
                                 }
-                            }
-                            if (this._pickedDownSprite && this._pickedDownSprite.actionManager && this._pickedDownSprite !== spritePickResult.pickedSprite) {
-                                this._pickedDownSprite.actionManager.processTrigger(ActionManager.OnPickOutTrigger, ActionEvent.CreateNewFromSprite(this._pickedDownSprite, this, evt));
+                                if (this._pickedDownSprite && this._pickedDownSprite.actionManager && this._pickedDownSprite !== spritePickResult.pickedSprite) {
+                                    this._pickedDownSprite.actionManager.processTrigger(ActionManager.OnPickOutTrigger, ActionEvent.CreateNewFromSprite(this._pickedDownSprite, this, evt));
+                                }
                             }
                         }
                     }
+                    
                     this._previousPickResult = this._currentPickResult;
                 });
             };
@@ -2941,12 +2944,13 @@
             this.onNewMeshAddedObservable.notifyObservers(newMesh);
         }
 
-        /**
+      /**
          * Remove a mesh for the list of scene's meshes
          * @param toRemove defines the mesh to remove
+         * @param recursive if all child meshes should also be removed from the scene
          * @returns the index where the mesh was in the mesh list
          */
-        public removeMesh(toRemove: AbstractMesh): number {
+        public removeMesh(toRemove: AbstractMesh, recursive = false): number {
             var index = this.meshes.indexOf(toRemove);
             if (index !== -1) {
                 // Remove from the scene if mesh found
@@ -2954,7 +2958,11 @@
             }
 
             this.onMeshRemovedObservable.notifyObservers(toRemove);
-
+            if(recursive){
+                toRemove.getChildMeshes().forEach((m)=>{
+                    this.removeMesh(m);
+                })
+            }
             return index;
         }
 

+ 11 - 2
tests/nullEngine/app.js

@@ -156,6 +156,15 @@ var engine = new BABYLON.NullEngine();
 
 //             console.log(pos);
 
+// const scene = new BABYLON.Scene(engine);
+// new BABYLON.PBRMetallicRoughnessMaterial("asdfasf", scene);
+// scene.dispose();
+
+BABYLON.Tools.LogLevels = BABYLON.Tools.ErrorLogLevel & BABYLON.Tools.WarningLogLevel;
 const scene = new BABYLON.Scene(engine);
-new BABYLON.PBRMetallicRoughnessMaterial("asdfasf", scene);
-scene.dispose();
+const camera = new BABYLON.ArcRotateCamera("camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene);
+const mesh = BABYLON.MeshBuilder.CreateBox("box", {}, scene);
+mesh.position.set(0.5, 0.5, 0.5);
+mesh.isPickable = true;
+scene.render();
+engine.dispose();

+ 2 - 2
tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.ts

@@ -260,11 +260,11 @@ describe('Babylon Scene Loader', function () {
 
                 const animationGroup = result.animationGroups[0];
                 expect(animationGroup.name, "animationGroup.name").to.equal("TwoTargetBlend");
-                expect(animationGroup.targetedAnimations, "animationGroup.targetedAnimations").to.have.lengthOf(7);
+                expect(animationGroup.targetedAnimations, "animationGroup.targetedAnimations").to.have.lengthOf(19);
                 const influenceAnimations = animationGroup.targetedAnimations.filter(_ => _.animation.targetProperty === "influence");
                 expect(influenceAnimations, "influenceAnimations").to.have.lengthOf(2);
                 const rotationAnimations = animationGroup.targetedAnimations.filter(_ => _.animation.targetProperty === "rotationQuaternion");
-                expect(rotationAnimations, "rotationAnimations").to.have.lengthOf(4);
+                expect(rotationAnimations, "rotationAnimations").to.have.lengthOf(16);
                 const positionAnimations = animationGroup.targetedAnimations.filter(_ => _.animation.targetProperty === "position");
                 expect(positionAnimations, "positionAnimations").to.have.lengthOf(1);
             });

+ 65 - 0
tests/unit/babylon/src/Mesh/babylon.geometry.tests.ts

@@ -0,0 +1,65 @@
+/**
+ * Describes the test suite.
+ */
+describe('Babylon Geometry', () => {
+    let subject: BABYLON.Engine;
+
+    /**
+     * Loads the dependencies.
+     */
+    before(function (done) {
+        this.timeout(180000);
+        (BABYLONDEVTOOLS).Loader
+            .useDist()
+            .load(function () {
+                // Force apply promise polyfill for consistent behavior between PhantomJS, IE11, and other browsers.
+                BABYLON.PromisePolyfill.Apply(true);
+                done();
+            });
+    });
+
+    /**
+     * Create a new engine subject before each test.
+     */
+    beforeEach(function () {
+        subject = new BABYLON.NullEngine({
+            renderHeight: 256,
+            renderWidth: 256,
+            textureSize: 256,
+            deterministicLockstep: false,
+            lockstepMaxSteps: 1
+        });
+    });
+
+    describe('#Geometry get vertices data', () => {
+        it('vec3 float color tightly packed', () => {
+            const scene = new BABYLON.Scene(subject);
+            const data = new Float32Array([0.4, 0.4, 0.4, 0.6, 0.6, 0.6, 0.8, 0.8, 0.8, 1, 1, 1]);
+            const buffer = new BABYLON.Buffer(subject, data, false);
+            var vertexBuffer = new BABYLON.VertexBuffer(subject, buffer, BABYLON.VertexBuffer.ColorKind,
+                undefined, undefined, undefined, undefined, undefined, 3);
+
+            var geometry = new BABYLON.Geometry("geometry1", scene);
+            geometry.setVerticesBuffer(vertexBuffer);
+            geometry.setIndices([0, 1, 2, 3], 4);
+
+            var result = geometry.getVerticesData(BABYLON.VertexBuffer.ColorKind);
+            expect(result).to.equal(data);
+        });
+
+        it('vec3 unsigned byte normalized color with offset of 3 and byte stride of 4', () => {
+            const scene = new BABYLON.Scene(subject);
+            const data = new Uint8Array([0, 0, 0, 102, 102, 102, 0, 153, 153, 153, 0, 204, 204, 204, 0, 255, 255, 255, 0]);
+            const buffer = new BABYLON.Buffer(subject, data, false, 4, undefined, undefined, true);
+            var vertexBuffer = new BABYLON.VertexBuffer(subject, buffer, BABYLON.VertexBuffer.ColorKind,
+                undefined, undefined, undefined, false, 3, 3, BABYLON.VertexBuffer.UNSIGNED_BYTE, true, true);
+
+            var geometry = new BABYLON.Geometry("geometry1", scene);
+            geometry.setVerticesBuffer(vertexBuffer);
+            geometry.setIndices([0, 1, 2, 3], 4);
+
+            var result = geometry.getVerticesData(BABYLON.VertexBuffer.ColorKind);
+            expect(result).to.have.ordered.members([0.4, 0.4, 0.4, 0.6, 0.6, 0.6, 0.8, 0.8, 0.8, 1, 1, 1]);
+        });
+    });
+});

+ 1 - 0
tests/unit/karma.conf.js

@@ -19,6 +19,7 @@ module.exports = function (config) {
             './tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.js',
             './tests/unit/babylon/src/PostProcess/babylon.postProcess.tests.js',
             './tests/unit/babylon/src/Material/babylon.material.tests.js',
+            './tests/unit/babylon/src/Mesh/babylon.geometry.tests.js',
             './tests/unit/babylon/src/Mesh/babylon.mesh.vertexData.tests.js',
             './tests/unit/babylon/src/Tools/babylon.promise.tests.js',
             { pattern: 'dist/**/*', watched: false, included: false, served: true },